• ___security_cookie机制


    .text:00411500 ; int __cdecl wmainCRTStartup()
    .text:00411500 _wmainCRTStartup proc near              ; CODE XREF: startj
    .text:00411500                 mov     edi, edi
    .text:00411502                 push    ebp
    .text:00411503                 mov     ebp, esp
    .text:00411505                 call    j____security_init_cookie
    .text:0041150A                 call    __tmainCRTStartup
    .text:0041150F                 pop     ebp
    .text:00411510                 retn
    .text:00411510 _wmainCRTStartup endp

    __tmainCRTStartup前调用___security_init_cookie进行全局___security_cookie初始化,___security_cookie开始时固定为0BB40E64Eh:

    .data:00417014 ___security_cookie dd 0BB40E64Eh

     ___security_init_cookie负责___security_cookie初始化工作,首先将___security_cookie与0BB40E64Eh比较,相同则表示未初始化过,跳入初始化代码loc_411D01,否则向下执行。将___security_cookie和0FFFF0000h进行与操作,高4字节为0则跳入初始化代码loc_411D01,否则保存___security_cookie到ecx。

    初始化代码中,首先取时间,分别与进程ID,线程ID,TickCount,性能计数器等异或,保证随机性,结果存入___security_cookie。到此全局的___security_cookie初始化完毕,并且初始化后在进程中这个值不再变化。

    使用/GS选项编译,或使用了Windows SEH的代码,都会在CRT中加入 ___security_init_cookie。在受保护的函数中:

    .text:00413200 var_4           = dword ptr -4
    ……
    .text:0041321E                 mov     eax, ___security_cookie
    .text:00413223                 xor     eax, ebp
    .text:00413225                 mov     [ebp+var_4], eax

    首先取 ___security_cookie与ebp异或存入eax,将eax值放到栈上ebp-4位置。与ebp异或保证了栈上cookie值不可预测。栈上的cookie是放在ebp&返回地址与本地变量之间,这样可以保护ebp&返回地址及以上地址空间不被覆写。

    但保护不了本地变量,微软没有实现本地变量重排:

    0106321E  mov         eax,dword ptr [___security_cookie (1067014h)]  
    01063223  xor         eax,ebp  
    01063225  mov         dword ptr [ebp-4],eax  

    int a = 10;
    01063228  mov         dword ptr [ebp-0Ch],0Ah  

    int b = 2;
    0106322F  mov         dword ptr [ebp-18h],2  

    char str[16];
    printf("%p ", str);
    01063236  mov         esi,esp  
    01063238  lea         eax,[ebp-30h]  
    0106323B  push        eax  
    0106323C  push        offset string "%s " (10657A0h)  
    01063241  call        dword ptr [__imp__printf (10682ACh)]  

    受保护的函数返回前:

    .text:00413283                 mov     ecx, [ebp+var_4]
    .text:00413286                 xor     ecx, ebp        ; cookie
    .text:00413288                 call    j_@__security_check_cookie@4 ;__security_check_cookie(x)

    从栈上取出cookie与ebp异或,将还原后___security_cookie存入ecx,然后调用__security_check_cookie检查。

    .text:00412A00 @__security_check_cookie@4 proc near    ; CODE XREF: __security_check_cookie(x)j
    .text:00412A00
    .text:00412A00 cookie          = dword ptr -4
    .text:00412A00
    .text:00412A00                 cmp     ecx, ___security_cookie
    .text:00412A06                 jnz     short failure
    .text:00412A08                 rep retn
    .text:00412A0A ; ---------------------------------------------------------------------------
    .text:00412A0A
    .text:00412A0A failure:                                ; CODE XREF: __security_check_cookie(x)+6j
    .text:00412A0A                 jmp     j____report_gsfailure
    .text:00412A0A @__security_check_cookie@4 endp

    __security_check_cookie函数将全局___security_cookie与ecx中存放的还原出的___security_cookie比较,若不同则表示发生了溢出,调用____report_gsfailure执行异常处理。

    下面分析一下StackCookie绕过的可行性,有利条件:

    1、__security_cookie可以从内存读到。
    2、ebp与esp地址相邻,通过泄漏esp可猜测ebp。

    不利条件:

    1、程序检测到溢出,____report_gsfailure崩溃退出。
    2、栈布局随机化,重新运行程序,ebp变化即上次泄漏的esp失效。

    Hook掉____report_gsfailure等异常处理函数可以轻松绕过stack cookie,但已经能在目标系统执行代码,再写这个溢出就没什么意义了。

    因为___security_cookie+ASLR的存在,Windows的栈溢出漏洞已经很难利用。覆盖SEH链这类方法虽然可行,但并不是获取了cookie值,所以不能算作对cookie机制的破解。

    下面引用tombkeeper在微博上的一段话:

    内存破坏类漏洞攻防对抗的发展形势大概会是这样:目前所有已知攻击方式在未来几年内被逐渐阻止或充分缓解,新的攻击方式将不仅难以被设计出来,而且实现过程也很复杂——如果没有相关研究作为基础,即使捕捉到野外样本,分析者甚至可能难以理解样本是如何被制作出来的。

  • 相关阅读:
    SQL 强化练习 (七)
    SQL 强化练习 (六)
    SQL 强化练习 (五)
    SQL 强化练习 (四)
    典型相关分析 CCA
    SQL 强化练习(三)
    双向 和 多重 RNN
    SQL 强化练习 (二)
    SQL 强化练习 (一)
    SQL 查询强化
  • 原文地址:https://www.cnblogs.com/gm-201705/p/9864079.html
Copyright © 2020-2023  润新知