预备知识
本题涉及到的知识点:
- 格式化字符串漏洞(泄露canary)
- 栈溢出漏洞(ret2text)
程序分析
首先,使用checksec查看保护情况。
64位程序,开启了Canary和NX保护。
1
2
3
4
5
6[*] '/root/Desktop/ADworld/1.Mary_Morton/Mary_Morton'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)运行程序,发现有三个选项,分别对应栈溢出漏洞、格式化字符串漏洞、退出程序。
每个选项都可以进行一次输入。
拖入IDA进行分析。main函数对三个选项依次处理。
继续跟进到格式化字符串漏洞函数里。
可以发现,存在格式化字符串漏洞。通过该漏洞,我们可以泄露canary的值。
继续跟进到栈溢出漏洞函数。
发现存在栈溢出漏洞,可以依次填充 垃圾字符 -> canary -> ebp -> 返回地址。
但是要ret到哪里呢?我们继续寻找。
最后发现一个system后门函数,直接cat flag。
利用思路
根据上述分析,我们可以进行如下两步:
- 通过格式化字符串漏洞泄露canary的值。
- 通过栈溢出依次填充 垃圾字符 -> canary -> ebp -> system后门函数地址 从而ret2text得到flag。
格式化字符串漏洞计算偏移
运行程序,我们输入 “AAAAAAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p”:
根据输出的结果,可以发现,格式化字符串到buf变量的偏移量为6个自然长度。
继续根据前面的分析,buf位于rbp-90h的位置,v2(保存canary)位于rbp-8h的位置。
即两者相差0x90 - 0x8 = 0x88,64位程序中,一个指针占8字节,0x88 / 0x8 = 0x11 = 17。
也就是说,格式化字符串到canary的距离为 6 + 17 = 23个自然长度。
注:以上自然长度指的是指针在64位环境下所占空间大小,即8字节。
泄露canary
1 | from pwn import * |
栈溢出ret2text
1 | # ret2text |
exp
1 | from pwn import * |