Canary与pie保护机制绕过

发布于 2023-03-08  280 次阅读


在实际情况下程序往往会开启各种保护措施,不太好利用栈溢出直接获取shell,比如canary与pie保护机制。

canary保护机制

前边发布的文章介绍过canary保护机制,可以去详细浏览一下,这里就简单说一下:

当栈上被设置了Canary时,如果再使用栈溢出填充满缓冲区覆盖返回地址时,栈上的Canary的标志也会被覆盖,当函数结束时,fs或gs里的canary值会与栈上的canary再次进行比对,若不相同,则会触发_Stack_chk_fail这个函数,程序就会直接退出并报错。

那如何绕过Canary保护呢?

最常见的绕过姿势,就是格式化字符串泄露canary值。

举个简单的栗子:

该exp流程为:在第一个read处下断点,然后选择 2: overflow,发送payload,缓冲区buf长度为0x20,其中的canary就存在于这0x20的末尾并且最后以0x00结尾,于是exp中的第34行就先用0x18长度的垃圾字符填充缓冲区,再用'b'覆盖掉八字节的canary的低位0x00,让程序能够继续打印canary。接着再选择1:leak 打印出canary,接收canary的值并恢复低位为0x00,再次发送payload即可完成绕过。

pie保护机制

可以看到,ida中显示的地址就只剩后三位了,这三个数字表示该地址与程序加载地址的一个偏移量,而不是一个真实的地址。
也可以通过其他一些漏洞,泄露出程序加载的基地址,再加上偏移量就是实际地址。

举个栗题:

开启了pie保护,程序没有显示真实地址。
用GDB调试,断点下在return read的位置。
由于开启了pie,不能直接利用0x933直接在return read处下断点,可以通过gdb里面的rebase 加上偏移量, 就可以给程序设置一个相对的偏移的断点。
可以看到返回地址是main+74
第32行,由于我们写入的内容是以字节为单位的,要修改最后三位数字,就要修改两个字节,也就是四个数字,但第四个数字不确定,有时候就需要爆破。
可以看到返回地址的最后四个数已经被改成二零88f0,但这个不是后门函数的地址。

关于pie绕过相关文章:

花式栈溢出技巧 - CTF Wiki (ctf-wiki.org)


穿过云层我试着努力向你奔跑