04. 细说Canary保护

unqique-Elven's Blue Github Chart

一.canary保护:

在第二节课已经提到过,这里我们再把它引用过来复习:
CANARY (栈保护)
这个选项表示栈保护功能是否开启
栈溢出保护是一种缓冲区溢出攻击缓冲手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shsellcode能够得到执行。当启用栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就会停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux中我们将cookie信息称为canary。
为了更加直观,画出有无canary保护的堆栈图对比一下:

无canary 保护有canary保护
局部变量 局部变量
EBP Cookie信息
RET EBP
参数 RET
- 参数

二.实例程序解读

root用户环境:
编写代码: vi canary.c

c
1
2
3
4
5
6
7
#include<stdio.h>
int main(int argc, char const *argv[])
{
char *name = "zhongyuwen";
printf("My name is %s\n");
return 0;
}

保存 :wq

1.无canary保护:

编译,不开启canary保护:gcc -no-pie -fno-stack-protector -m32 -o canary canary.c
图片
编译成功出现一把小锁,权限不足,
图片
提权:chmod 777 canary
这就没限制了:
图片

运行调试器打开canary: gdb canary
先查看mian函数代码段:disass main
图片

查看有什么断点:i b
删除断点:d 断点编号
加断点:b *地址
图片
运行:run
图片
可以看到这就运行到了我们加的断点的地方,也就是main函数入口处吧EP!
单步执行:next
分析代码:
第1行,把esp+4地址保存到ecx
图片

+4行,内存对齐:

plaintext
1
2
主流编译器规则规定“程序访问的地址必须向16字节对齐(被16整除的数)”内存对齐后可以提高访问效率。
我认为这就相当于最近流行的硬盘4K对齐吧!

图片
原来3c往上推了3行到30,刚好16字节

+7行,把mian函数的返回地址压栈
图片

+10行就开始第二节课讲的正常操作,压入栈帧了等等。
退出:q


2.有canary保护

重新覆盖编译:
开启canary保护,为所有函数插入保护:gcc -no-pie -fstack-protector-all -m32 -o canary canary.c
图片
记得提权:chmod 777 canary
调试:gdb canary
查看main函数:disass main
图片
可以看到正如定义红字可知,如上画线部分,向堆栈传入了gs段的一个参数,后面还做对比,决定是否需要跳转!

加断点到加保护处:b *0x080484af
再运行:
图片

+41行,把待验证数据保存到ebx
图片

+41就是把数据转存到堆栈了
一直单步执行到+90,这里进行异或运算,对吧堆栈哪个位置的数据是否还和ebx一样
查看全部寄存器:i r
图片
0x286转化成二进制数后对照eip寄存器表:
图片
je指令看的时ZF位,其实也可以知道【】号里面写出来的都是置1的标识位了

+90运行:
图片
此时ZF位置1了,je达成跳转条件