GUESS
题目链接:GUESS
查看题目
首先checksec查看保护
然后扔进ida查看源码
分析题目
很明显的一个栈溢出漏洞,但是打开了canary,在反汇编代码可以看到在 main 函数结束时检查了 canary 的值,与 rcx 进行比较, canary 的值是放在 fs 寄存器中的,理论上我们是不能正常查看的,且只有三次溢出机会,没办法爆破出canary,加上flag在栈上以及未开启PIE保护,想到了Stack Smash
在程序加了canary 保护之后,如果我们读取的 buffer 覆盖了对应的值时,程序就会报错,会执行 __stack_chk_fail 函数来打印出 argv[0] 指针所指向的字符串,而Stack Smash技巧则就是利用打印这一信息的程序来得到我们想要的内容
argv[0] 一般指向的是程序名
漏洞利用
总思路为先找到argv[0] 指针地址,然后打印出函数实际地址,从而减去函数偏移的到libc基址,然后打印environ 变量的值(environ 变量作为一个指针指向了环境变量的字符指针数组的首地址,可以简单的理解为environ 变量的实际地址是指向栈的基地址(高地址)),从而得到栈基址,然后在计算flag与栈基址的偏移从而打印出flag
泄漏函数实际地址
首先使用gdb进行调试,计算出输入的字符串与argv[0]之间的偏移
在gets函数处打下断点,执行过去输入”aaa”后查看栈空间
可得argv[0] 指针为0x7fffffffde58,与输入字符串所在处0x7fffffffdd30的偏移为0x128
于是得到第一步payload = ‘a’*0x128 + p64(libc_start_main_got)
得到栈基址
计算出libc基址后,只需打印environ 变量的值即可得到栈基址
所以得到第二步payload = ‘a’*0x128 + p64(environ_addr)
get flag
与前两步同样的思路,只需要计算flag的偏移即可
我们可以通过在gdb里面为environ 变量下断点获得栈基址
然后计算偏移(这里我为了调试新建了一个测试的flag.txt)
可得偏移为0x168
所以第三步payload = ‘a’*0x128 + p64(stack_addr - 0x168)
EXP
最后的EXP为
1 | from pwn import * |