Windows下GS保护机制详情及其绕过
字数 1337 2025-08-23 18:31:24
Windows下GS保护机制及其绕过技术详解
一、GS保护机制概述
GS(Buffer Security Check)是微软针对栈溢出攻击设计的一种保护机制,其核心思想是通过在栈帧中插入一个随机值(称为Security Cookie或Canary)来检测缓冲区溢出。
1. GS保护机制工作原理
-
Canary布局:在栈帧中,Canary被放置在局部变量和返回地址之间
-
典型栈布局:
... 变量a ... ... 变量 ... ... 变量 ... Canary EBP 返回地址 -
Canary生成与验证过程:
- 取出.data节的第一个双字作为Cookie种子
- 将Cookie种子与ESP异或
- 将异或后的值存入Canary地址
- 函数返回前进行逆过程验证
2. 变量重排技术
GS还采用了变量重排技术来防止覆盖其他变量:
重排前:
Buff (字符串类型)
Char
Int
重排后:
Char
Int
Buff
Canary
EBP
返回地址
二、不会启用GS的情况
以下情况编译器不会为函数启用GS保护:
- 函数不包含缓冲区
- 函数被定义为具有变量参数列表
- 函数使用无保护关键字标记
- 函数在第一个语句中包含内嵌汇编代码
- 缓冲区不是8字节类型并且不大于4字节
强制启用GS:
#pragma strict_gs_check(on)
三、GS保护机制的绕过技术
1. 攻击未启用GS的函数
直接寻找并攻击程序中未启用GS保护的函数进行溢出攻击。
2. 覆盖虚函数绕过GS
原理:在Canary检查之前劫持程序流程,利用C++虚函数机制实现。
示例代码:
class GSVirtual {
public:
void gsv(char *src) {
char buf[200];
memcpy(buf, src, 204); // 溢出点
MyFunc(); // 虚函数调用
}
virtual void MyFunc() {}
};
攻击步骤:
- 通过溢出覆盖对象的虚函数表指针
- 将虚函数表指针指向攻击者控制的数据
- 精心构造数据使程序执行攻击代码
Payload构造要点:
- 前4字节设置为shellcode地址
- 后续数据包含实际shellcode
- 覆盖虚表指针使其指向攻击数据
3. 攻击异常处理绕过GS
原理:GS不保护SEH(结构化异常处理),通过覆盖异常处理指针实现攻击。
示例代码:
void test(char *szBuffer) {
char buf[200]{0};
strcpy(buf, szBuffer); // 溢出点
strcat(buf, szBuffer);
}
攻击步骤:
- 计算异常处理指针相对于缓冲区的偏移
- 构造超长字符串覆盖异常处理指针
- 触发异常使程序执行攻击代码
Payload构造要点:
- 在异常处理指针偏移处放置shellcode地址
- 确保触发异常(如非法内存访问)
4. 同时替换栈和.data中的Cookie绕过GS
原理:同时修改栈中的Canary和.data中的Cookie种子,使验证通过。
示例代码:
void test(char *s, int i, char *src) {
char dest[200]{0};
if(i < 0x9995) {
char *buf = s + i;
*buf = *src;
*(buf+1) = *(src+1);
*(buf+2) = *(src+2);
*(buf+3) = *(src+3);
memcpy(dest, (char*)(src+8), 212); // 溢出点
}
}
攻击步骤:
- 计算堆地址到.data节Cookie种子的偏移
- 构造Payload:
- 前4字节:期望的Cookie值(通常为0x90909090 ^ EBP)
- 4-8字节:指向.data节Cookie种子的偏移
- 后续数据:shellcode和返回地址覆盖
Payload示例:
unsigned char hexData[212] = {
0x10,0x6D,0x89,0x90, // 修改后的Cookie值
0x54,0x01,0xE7,0xFF, // 指向.data的偏移
// 后续为shellcode...
};
四、实验环境配置
为进行GS绕过实验,需进行以下VS配置:
- 在C/C++ → 常规属性中关闭SDL检查
- 在代码生成中将基本运行时检查设置为默认值
- 运行库修改为MTD
- 禁用Spectre缓解(如安装了驱动开发)
- 在所有选项中关闭控制流防护
- 禁用安全检查(/GS-)(仅用于测试特定绕过方法)
五、总结
GS保护机制虽然有效,但仍存在多种绕过方法。安全防护与攻击技术总是在不断对抗中发展,理解这些机制和绕过技术对于二进制安全研究至关重要。随着防护技术的演进,如CFG(控制流防护)等新机制的引入,攻击技术也在不断发展,安全研究人员需要持续学习和跟进最新技术发展。