security cookie

在微软的c/c++ 编译器中,增加了对于栈溢出进行检测的参数 “/GS”,在调试shellcode 的时候,发现vs2005 产生的code 和 vc6 产生的code 有些不同,才让我注意到这个问题。

     写了这样的一个测试程序:

     void foo(const char * datas)

     {

       char szbuf[32];

        strcpy(szbuf, datas);

     }

     汇编的代码如下:

00411F70  push        ebp 

00411F71  mov         ebp,esp

00411F73  sub         esp,0ECh

00411F79  push        ebx 

00411F7A  push        esi 

00411F7B  push        edi 

00411F7C  lea         edi,[ebp-0ECh]

00411F82  mov         ecx,3Bh

00411F87  mov         eax,0CCCCCCCCh ;0x0c is equal to the machine code of int3

00411F8C  rep stos    dword ptr es:[edi]

00411F8E  mov         eax,dword ptr [___security_cookie (419004h)]

00411F93  xor         eax,ebp

00411F95  mov         dword ptr [ebp-4],eax

00411F98  mov         eax,dword ptr [ebp+8]

00411F9B  push        eax 

00411F9C  lea         ecx,[ebp-28h]

00411F9F  push        ecx 

00411FA0  call        @ILT+625(_strcpy) (411276h)

00411FA5  add         esp,8 ; strcpy's call conversation is __cdecl, so the caller should help callee cleanup stack

00411FA8  push        edx 

00411FA9  mov         ecx,ebp ; pass the stack top by ecx

00411FAB  push        eax 

00411FAC  lea         edx,[ (411FD8h)] ; pointer to a _RTC_framedesc structure

00411FB2  call        @ILT+195(@_RTC_CheckStackVars@8) (4110C8h)

00411FB7  pop         eax 

00411FB8  pop         edx 

00411FB9  pop         edi 

00411FBA  pop         esi 

00411FBB  pop         ebx 

00411FBC  mov         ecx,dword ptr [ebp-4]

00411FBF  xor         ecx,ebp

00411FC1  call        @ILT+45(@__security_check_cookie@4) (411032h)

00411FC6  add         esp,0ECh

00411FCC  cmp         ebp,esp

00411FCE  call        @ILT+430(__RTC_CheckEsp) (4111B3h)

00411FD3  mov         esp,ebp

00411FD5  pop         ebp 

00411FD6  ret             

00411FD7  nop             

00411FD8  db          01h 

00411FD9  db          00h 

00411FDA  db          00h 

00411FDB  db          00h 

00411FDC  db          e0h 

00411FDD  db          1fh 

00411FDE  db          41h 

00411FDF  db          00h 

00411FE0  db          d8h 

00411FE1  db          ffh 

00411FE2  db          ffh 

00411FE3  db          ffh 

00411FE4  db          20h 

00411FE5  db          00h 

00411FE6  db          00h 

00411FE7  db          00h 

00411FE8  db          ech 

00411FE9  db          1fh 

00411FEA  db          41h 

00411FEB  db          00h 

00411FEC  db          62h 

00411FED  db          75h 

00411FEE  db          66h 

00411FEF  db          66h 

00411FF0  db          65h 

00411FF1  db          72h 

00411FF2  db          00h 

    从程序可以看出在函数被调用之后,在正确的把ebp压入stack 之后,把当前的esp存储到ebp 中,在往下就是这个函数体自身需要的stack 空间了,微软的编译器会在debug 版本的程序中,在每一个函数的堆栈顶分配一定数目的空间,把int3的机器码写入,这样做的目的是可以防止程序跑飞,如果程序跑飞,且eip落入这个空间,那么取出的指令都是int 3,从而能程序被中断。

    ___security_cookie 变量是一个 UINT_PTR 类型的数值,这个数值应该被编译到bufferoverflowU.lib 这个库中,数值的初始值定义如下:

#ifdef _WIN64

#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232

#else  /* _WIN64 */

#define DEFAULT_SECURITY_COOKIE 0xBB40E64E

#endif  /* _WIN64 */

DECLSPEC_SELECTANY UINT_PTR __security_cookie = DEFAULT_SECURITY_COOKIE;

    函数在取到该值之后,会和当前的ebp 相异或(xor),异或的值保持在stack 的顶部。在函数的体被执行完成之后,__security_check_cookie 会被调用,来检测security cookie 是否被修改过,__security_check_cookie 函数需要一个参数,不过这个参数没有使用,函数中,只是把ecx 的值和 _security_cookie 的值相比较,看看是否相同,如果不相同则认定为stack overflow。从上面的汇编代码可以看出在调用_security_check_cookie 之前,就把_security_cookie 的值取到ecx 中,且与ebp 进行异或(xor)操作。这样通常能够很好的防范stack 的overflow,通常的exploit code 都要覆盖函数的返回地址,而覆盖过程中写入的stack 的值是基本不会等于(__security_cookie & ebp ) 的值。

    其实在调用 _security_check_cookie 函数之前,还调用了函数 _RTC_CheckStackVars,这个函数的原型是:

    void   __fastcall _RTC_CheckStackVars(void *_Esp, _RTC_framedesc *_Fd);

    其中_RTC_framedesc 结构为 :

    typedef struct _RTC_framedesc {

        int varCount;

        _RTC_vardesc *variables;

    } _RTC_framedesc;

    _RTC_vardesc 的结构为:RTC 可能是run time check 的缩写,而 vardesc 可能是 variable descritpion 的缩写

     typedef struct _RTC_vardesc {

        int addr;

        int size;

        char *name;

    } _RTC_vardesc;

  _RTC_CheckStackVars 的汇编代码如下:

004122D0  push        ebp 

004122D1  mov         ebp,esp

004122D3  push        ecx 

004122D4  push        ebx 

004122D5  push        esi 

004122D6  push        edi 

004122D7  xor         edi,edi

004122D9  mov         esi,edx

004122DB  cmp         dword ptr [esi],edi ;比较是否有数组变量

004122DD  mov         ebx,ecx             ; 需要比较的堆栈顶是通过ecx 传递进来的,把这个值保持到 ebx

004122DF  mov         dword ptr [i],edi  ; i 应该是记录当前比较了几个 _RTC_vardesc

004122E2  jle         _RTC_CheckStackVars+58h (412328h)  ;如果没有,则不必检测了,程序跳转退出

004122E4  mov         eax,dword ptr [esi+4]              ;eax 指向_RTC_vardesc 结构

004122E7  mov         ecx,dword ptr [eax+edi]            ;ecx 为 _RTC_vardesc.addr 的值

004122EA  add         eax,edi

004122EC  cmp         dword ptr [ecx+ebx-4],0CCCCCCCCh   ; 根据addr 算出堆栈中的一个地址,addr 的来历不详

004122F4  jne         _RTC_CheckStackVars+34h (412304h)  ; 如果不是初始化的 0xCCCCCCCC ; 报错

004122F6  mov         edx,dword ptr [eax+4]

004122F9  add         edx,ecx

004122FB  cmp         dword ptr [edx+ebx],0CCCCCCCCh

00412302  je          _RTC_CheckStackVars+48h (412318h)

00412304  mov         eax,dword ptr [esi+4]

00412307  mov         ecx,dword ptr [eax+edi+8]

0041230B  mov         edx,dword ptr [ebp+4]

0041230E  push        ecx 

0041230F  push        edx 

00412310  call        _RTC_StackFailure (411127h)

00412315  add         esp,8

00412318  mov         eax,dword ptr [i]

0041231B  add         eax,1

0041231E  add         edi,0Ch

00412321  cmp         eax,dword ptr [esi]

00412323  mov         dword ptr [i],eax

00412326  jl          _RTC_CheckStackVars+14h (4122E4h)

00412328  pop         edi 

00412329  pop         esi 

0041232A  pop         ebx 

0041232B  mov         esp,ebp

0041232D  pop         ebp 

0041232E  ret   

    

        从函数的汇编代码可以看出虽然 CheckStackVars 需要两个参数,但是函数并没有使用这两个参数,而实际需要检测的数值,是通过edx、ecx 两个寄存器传递的,edx 指向一个_RTC_framedesc 的结构,ecx 指向函数的堆栈的顶部,可见编译器在每一个函数的结束处添加了一个_RTC_framedesc 的对象。

       _RTC_framedesc 结构,好在只是记录函数中用到的数组变量的情况。上面的 _RTC_framedesc 值为:

       _RTC_framedesc.varCount = 1;

       _RTC_framedesc.variables = 0x00411fe0

       _RTC_vardesc.addr = 0xFFFFFFD8  /* -40 */

       _RTC_vardesc.size = 0x00000020 /* buffer size is : 0x20 */

       _RTC_vardesc.name = 0x00411fec /* poiner to string 'buffer' */

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/free2o/archive/2008/06/20/2570168.aspx

作者:码瘾少年·麒麟子 
出处:http://www.cnblogs.com/geniusalex/ 
蛮牛专栏:麒麟子 
简介:09年入行,喜欢游戏和编程,对3D游戏和引擎尤其感兴趣。 
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/geniusalex/archive/2010/05/09/1940495.html

时间: 2024-10-16 06:19:30

security cookie的相关文章

IE漏洞攻防编年简史

× loading.. 企业网D1Net 登入注册 CIO频道 云计算 智慧城市 数据中心 大数据 数据网络 移动办公 服务器 存储 安全 统一通信 视频会议 视频监控 呼叫中心 物联网 虚拟化 IP语音 更多 首   页 内网安全 防火墙 云安全 VPN UTM IPS|IDS 更多 当前位置:安全 → 行业动态 → 正文 IE漏洞攻防编年简史 责任编辑:editor005 作者:阿尔法实验室 |  2016-01-20 14:40:32 本文摘自:FreeBuf.COM 本文对历史上的微软I

微软ASP.NET爆高危漏洞

微软9月17日发布安全预警,ASP.NET爆出最新安全漏洞, 即Microsoft Security Advisory (2416728).SecurityFocus上已将此漏洞定义成了"Design Error".此次发现的安全漏洞源自ASP.NET对加密组件的底层实现, 所以它将影响所有基于ASP.NET的应用程序, 包括 Web Form 应用程序以及所有使用ASP.NET MVC 框架的应用程序. 包括xp,2003,vista,win7,2008, 2008r2等服务器版本,

<转> xor eax, ebp” being used

I just tried compiling a couple of C++ snippets on VS2010 and analyzed the executables on IDA Pro. Something I noticed is that there most of them have something like the following at the start(shortly after a call to __security_check_cookie) xor eax,

ASP.NET教程:form验证用户登录的Cookie

做用户登录,我一直用form验证的方式.有时候,为了节省时间,用户希望用户名输入框能够记住用户名,省得下次重新输入.这个时候光用form验证是不行的,因为form验证的话,用户一退出系统就失效了,所以需要借助于Cookie. 本以为做这个会很轻松,谁知花了不少时间也没有成功.虽然检验用户名和密码都是正确的,但系统总是拒绝登录,然后返回到登录页面.登录页面的用户名输入框记是记住用户名了,但用户名是乱码的. 真是郁闷至极!一度以为系统发生了错乱,重启机器也还是无济于事.经反复检查和测试发现,如果在f

从ASP.NE T 1.1升级到ASP.NET 2.0需要考虑的Cookie问题

asp.net|cookie|问题 当你准备将Web应用程序从ASP.NET 1.1升级到ASP.NET 2.0,你将面对这样一个cookie问题:在ASP.NET 1.1应用程序中客户端保存的所有cookie将失效. 博客园也遇到了这样的问题,对博客园来说,意味着所有使用cookie的用户都需要重新登录,虽然这不是一个很大的问题,但的确给大家带来了麻烦,如果忘记了密码,将更加麻烦. 对于一个非常重视用户满意度的网站来说,应该努力去解决这个问题.博客园希望尽可能减少升级带来的影响,所以这两天我一

ASP.NET 1.1 无 Cookie SessionID 重写

asp.net|cookie|session 浏览器的会话使用存储在 SessionID 属性中的唯一标识符进行标识.会话 ID 使 ASP.NET 应用程序能够将特定的浏览器与 Web 服务器上相关的会话数据和信息相关联.会话 ID 的值在浏览器和 Web 服务器间通过 Cookie 进行传输,如果指定了无 Cookie 会话,则通过 URL 进行传输. ASP.NET 通过自动在页的 URL 中插入唯一的会话 ID 来保持无 Cookie 会话状态.例如,下面的 URL 已被 ASP.NET

IsLine FrameWork系列之十二--使用Session、Cookie与安全支持

今天来介绍IsLine.HttpContent.HttpContentProvider命名空间中关于Session与Cookie的支持. 这是IsLine FrameWork中一个常用的组件,使用这个组件可以为整站程序提供统一的Cookie配置属性,例如Cookie加密方式.是否HttpOnly.是否打开https安全选项.以及默认作用域.CookieProvider是该命名空间下的类,在该类初始化时,会自动加载web.config文件中的 Cookie节点配置,读取成功后会加载于整个web站点

Cookie操作类、压缩、序列化

1.cookie类 CartCookie.cs using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.

cookie操作类(加密,获取,删除)

  using System; using System.IO; using System.Text; using System.Diagnostics; using System.Web.Security; using System.Security; using System.Security.Cryptography; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace ASPN