堆栈的保护机制GS

来源:互联网 发布:前端 知乎 编辑:程序博客网 时间:2024/04/30 10:07

缓冲区溢出是漏洞利用中的重要一步。
通过设置编译选项/gs会给可执行文件中添加一些特殊的代码,来防止缓存区的溢出。

比如

#include <stdio.h>#include <string.h>#define BUF_LEN 16unsigned char str[16+4+4];void fun(unsigned char *data){    unsigned char buffer[BUF_LEN];    strcpy((char*)buffer, (char*)data);//溢出点}int main(){    memset(str, 0xCC, sizeof(str));    fun(str);}

未设置安全检查(/Gs)时候的汇编代码

fun:013E1082 E9 49 03 00 00       jmp         fun (013E13D0h)...     1: #include <stdio.h>     2: #include <string.h>     3: #define BUF_LEN 16     4: unsigned char str[16+4+4];     5: void fun(unsigned char *data)     6: {013E13D0 55                   push        ebp  013E13D1 8B EC                mov         ebp,esp  013E13D3 81 EC D8 00 00 00    sub         esp,0D8h  013E13D9 53                   push        ebx  013E13DA 56                   push        esi  013E13DB 57                   push        edi  013E13DC 8D BD 28 FF FF FF    lea         edi,[ebp-0D8h]  013E13E2 B9 36 00 00 00       mov         ecx,36h  013E13E7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  013E13EC F3 AB                rep stos    dword ptr es:[edi]       7:     unsigned char buffer[BUF_LEN];     8:     strcpy((char*)buffer, (char*)data);//溢出点013E13EE 8B 45 08             mov         eax,dword ptr [data]  

开启了GS选项后

--- c:\users\mrgao1008\documents\visual studio 2013\projects\attack\attack\源.cpp      1: #include <stdio.h>     2: #include <string.h>     3: #define BUF_LEN 16     4: unsigned char str[16+4+4];     5: void fun(unsigned char *data)     6: {002413D0 55                   push        ebp  002413D1 8B EC                mov         ebp,esp  002413D3 81 EC DC 00 00 00    sub         esp,0DCh  002413D9 53                   push        ebx  002413DA 56                   push        esi  002413DB 57                   push        edi  002413DC 8D BD 24 FF FF FF    lea         edi,[ebp-0DCh]  002413E2 B9 37 00 00 00       mov         ecx,37h  002413E7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  002413EC F3 AB                rep stos    dword ptr es:[edi]  002413EE A1 00 80 24 00       mov         eax,dword ptr ds:[00248000h]  002413F3 33 C5                xor         eax,ebp  002413F5 89 45 FC             mov         dword ptr [ebp-4],eax     7:     unsigned char buffer[BUF_LEN];     8:     strcpy((char*)buffer, (char*)data);//溢出点002413F8 8B 45 08             mov         eax,dword ptr [data]  

多出来的3行用于生成stack cookie放在ret地址下方,cookie为data段的一个数(程序载入时候随机生成)和ebp的异或。

002413EE A1 00 80 24 00       mov         eax,dword ptr ds:[00248000h]  002413F3 33 C5                xor         eax,ebp  002413F5 89 45 FC             mov         dword ptr [ebp-4],eax

cookie的验证

0024141C 8B 4D FC             mov         ecx,dword ptr [ebp-4]  0024141F 33 CD                xor         ecx,ebp  00241421 E8 F8 FB FF FF       call        @__security_check_cookie@4 (024101Eh)  

__security_check_cookie的代码是

002416F0 3B 0D 00 80 24 00    cmp         ecx,dword ptr ds:[248000h]  002416F6 75 02                jne         failure (02416FAh)  002416F8 F3 C3                rep ret  002416FA E9 97 F9 FF FF       jmp         ___report_gsfailure (0241096h)  

除了GS 在函数返回的时候会验证堆栈中的其他信息

验证堆栈中字符串,数组等是否越界,字符串和数组的位置信息放在此段函数代码段后面。检测的手段是查看字符串和数组前后变量是否都是0xCCCCCCCC

00241408 52                   push        edx  00241409 8B CD                mov         ecx,ebp  0024140B 50                   push        eax  0024140C 8D 15 38 14 24 00    lea         edx,ds:[241438h]  00241412 E8 7A FC FF FF       call        @_RTC_CheckStackVars@8 (0241091h)

验证ESP和EBP是否相等

0024142C 3B EC                cmp         ebp,esp  0024142E E8 12 FD FF FF       call        __RTC_CheckEsp (0241145h) 
0 0
原创粉丝点击