看到题目的内容,就知道大概是格式化漏洞了,
马上扔到IDA看个究竟。
不出所料,就是printf的格式化输出漏洞
思路:
1、利用格式化漏洞覆盖任意地址的值,这里我们需要覆盖secret的值,所以先要找到secret的地址,在IDA中,可以看到secret在bss段:
得到secret的地址后,我们就可以对它的值进行覆盖,覆盖成192
2、利用%k$n(k$用于获取格式化字符串中的指定参数)对指定地址进行覆盖
(%n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量)
3、在栈中找到format的位置和 char s的位置,计算出他们的偏移
我们用gdb把断点定在printf处
然后运行,提示输出后,我就随便输入一个 %d%d
观察栈的信息:
可以看出,printf的第一个参数(format)地址为:0xffffd920
这个format指向0xffffd94c,指向的这个就是我们char s的地址
有了这两个地址后,我们就可以计算format与char s的地址偏移,
offset = 0xffffd94c - 0xffffd920 = 0x2c = 44
由于这是32位程序,所以每个format参数占4个字节,即有44/4=11个参数,也就是说,第11个参数的地址,就是我们char s开始的地址。
所以 k=11。
我们把secret的地址放到char s开始的地方,那第11个参数的内容就是secret的地址。
这样,我们的%11$n就会把输出字符的个数写进secret。
所以们需要在 %11$n 构造 192 个字符,即%192d,
但由于我们在char s开始的地方放下了secret的地址,占了4个字节,所以只需要填充188个字符即可,也就是%188d
payload:
from pwn import *
io=process('./format')
io=remote('117.50.13.182', 33865)
payload = p32(0x0804A048) + '%188d' + '%11$n'
io.sendline(payload)
io.interactive()
本人萌新,大佬可以不看。- -