栈溢出之绕过CANARY保护
上周从NJCTF的其中一题messager,学到了绕CANARY保护的一种姿势
bin我拖下来了: https://github.com/Hcamael/CTF_repo/tree/master/NJCTF%202017/pwn150(messager)
其实很简单的一个思路.
CANARY保护机制的原理,是在一个函数入口处从fs,内存的某个地方获取一个值,可以想象成是cookie,存到栈中,在程序要返回的时候,判断栈中的这个cookie是否正确,如果不正确则判断为栈溢出
因为cookie是从内存的一个未知的地方获取到的,值是未知,当我们进行栈溢出攻击的时候,控制ret跳转的地址,肯定是会把cookie给覆盖掉,导致程序判断为栈溢出,程序退出,攻击失败
这题的问题出在fork函数,该题是自己写了一个socket, 接受到请求后fork出一个子进程,和用户做交互,父进程继续监听端口
fork函数的作用相当于自我复制,每一次复制出来的程序,内存布局都是一样的,当然cookie值也是一样的
这样就存在一个可能,我们可以一个byte一个byte的对cookie进行爆破,如果程序跪了则表明cookie错误,如果程序正常返回则表示cookie正确,我们通过栈溢出对cookie的最低位开始逐个覆盖,爆破出该位的正确cookie值
我的爆破脚本:
1 | #! /usr/bin/env python |
这里还有个知识点,上面代码中我只爆破了7 byte,因为最低位的byte一定是\x00
,这为了防止其他漏洞会导致栈信息泄露,有个\x00
cookie后面的数据就不会被泄露出来了.
得到cookie值了后,就是很简单的栈溢出了,栈溢出的时候把爆破出来的cookie值覆盖掉栈中的cookie(也就相当于cookie不变),从而绕过CANARY保护机制.
附之后的利用脚本:
1 | #! /usr/bin/env python |
上面代码中ret
指向的函数是一个读取flag的函数,ret2
为输出读入的信息,bin就有获取flag的函数了,所以不需要再麻烦的去跑libc了, 如果是要getshell的话,则还需要去跑下libc
栈溢出之绕过CANARY保护