ACPI调试
Linux内核调试
Windows内核调试
 
  调试战役
调试原理
新工具观察
 
  Linux
Windows Vista
Windows
 
  Linux驱动
WDF
WDM
 
  PCI Express
PCI/PCI-X
USB
无线通信协议
 
  64位CPU
ARM
IA-32
  CPU Info Center
 
  ACPI标准
系统认证
Desktop
服务器
 
  Embedded Linux
嵌入式开发工具
VxWorks
WinCE
嵌入式Windows
沪ICP备05041459号
About AdvDbg Consult Train Services Products Tools Community Contact   登录 | 注册

基于Cookie编译保护的二进制文件简便鉴别方法


周一早上实在想睡觉,其实也睡了一觉,但写点小随笔提提神还是比真睡着要好~
收到 Raymond 老师的样章也有些日子了,一直无以为馈,feedback 也是一直写写停停的,看来写书真不容易!我要抓紧进度了。


聊点22章“栈和过程调用”里没有的东西吧~ focus on MS's GS Cookie,因为缓冲区溢出(栈下溢)的原理实在是已经说烂了。
随笔可能会有一点天马行空的感觉,那是褒义,其实也就是小我在困倦情况下杂乱无章的BT思维。题目最终选了其中一点,定为《基于Cookie编译保护的二进制文件简便鉴别方法》,因为我的 fingerprint 鉴别方法和 Symantec 的相比不需要编写代码(这是优点吗?!)~ 反正姑且先称之简便,但是简便一词往往也意味着简陋。


“栈下溢”风起云涌于 1988年11月2日 的 Morris 蠕虫事件。Robert Tappan Morris,身为 National Computer Security Center — part of the National Security Agency (NSA) 首席科学家 Robert "Bob" Morris 的儿子,编写并偶然释放了(我们称之为意外好了)世界上第一只计算机蠕虫 Morris Worm。大于 6000 台含有 fingerd 漏洞的机器被溢出,而这基本包括了北美全境。非常有趣的一对父子,父亲当年在 AT&T Bell 实验室和 Douglas Mcllroy、Victor Vysottsky 编写最早的计算机病毒 / 游戏 Code War,30年之后当 Old Morris 开始全面负责 ARPANet 安全的时候,儿子却写出了第一款蠕虫。真不知父亲是该生气好还是应该高兴好~  友情提醒一下,在当年立法不完善的情况下,Robert T. Morris 为自己的大意行为换来了CERT的成立、3年缓刑、10500美元罚金、400小时社会劳动,更何况我们的社会主义和谐社会了。现在 Robert T. Morris 前辈居于 MIT 的副教授,您可以在这里找到他的信息:http://eecsfacweb.mit.edu/facpages/morris.html。—— 其实最具讽刺意味的我认为就是这个了,为了隐藏行踪 Robert T. Morris 当年并没有在 Cornell 大学释放他的虫子,而是选择了 MIT...... 那么现在 Morris 为 MIT 服务,这算是 Morris 的救赎吗? ^_^


同年,一篇具有划时代意义、由10个人撰写的论文也诞生了(Oh God...)! 随着 Crispin Cowan, Calton Pu, Dave Maier, Heather Hintony, Jonathan Walpole, Peat Bakke, Steve Beattie, Aaron Grier, PerryWagle and Qian Zhang 撰写的论文《StackGuard - Automatic Adaptive Detection and Prevention of Buffer-Overflow Attacks》的发表,一种新的缓冲区溢出保护技术进入人们的视野。 论文的开篇就提到“Buffer overflow attacks gained notorietyin 1988 as part of the Morris Worm incident on the Internet.”、“We describe StackGuard: a simple compiler technique that virtually eliminates buffer overflow vulnerabilities with only modest performance penalties.”此时,您一定不禁会感叹,审稿真神速~ 11月2日的攻击,12月就有对应的防御理论论文了。


论文思想的核心就是 —— 金丝雀技术(Canary) —— 而微软称这是 Cookie (此小甜饼非网页缓存的那个小甜饼) —— 所以很多人接受不了这个术语,进而排斥他们。

说白了 Canary 保护的想法其实很简单,栈的形态由高地址到低地址是这样的:

高地址                    ------  栈的生长方向 ------>                    低地址
       参数2 --> 参数1 --> Ret 的 EIP --> EBP --> 栈上的局部变量 --> .....  

局部变量向下溢出时依次覆盖 EBP 和 EIP, 而先插入一个伪随机值(金丝雀)在 EBP 和 栈局部变量之间,ret 之前检查这个随机值是否被覆盖的确是非常有效的方法。此时栈的形态是这样的:

高地址                    ------  栈的生长方向 ------>                    低地址
   参数2 --> 参数1 --> Ret 的 EIP --> EBP --> Canary --> 栈上的局部变量 --> .....
                          <---- 溢出时的覆盖方向 -----


那么,您一定会好奇,为什么要将这项技术命名为“金丝雀”(Canary)呢?论文的注释里有这么一句话“A direct descendent of the Welsh miner's canary.”据说很早以前 Welsh 的煤矿工人下井作业的时候,为了防止瓦斯爆炸、中毒一般都会带一只金丝雀(Canary)下去,这种敏感的小动物如果失去了活力,那么瓦斯的含量应该就不低了,这就是矿井里最早的“warning device”。唉,可怜那 12月6日 山西洪桐县煤矿瓦斯爆炸事故中遇难的100多名工人,你们咋不多带些金丝雀下去呢?Canary 对煤气和溢出负责,那么谁来对你们的生命负责呢?沉重的话题。 :(


然后时间转眼就到了21世纪,微软终于在 Windows XP SP2 时引入了类似的 Cookie 技术,当然,这取决于编译器。Win32下缓冲区溢出的门槛终于被提高了,不过仔细想想我们栈下溢就是为了得到程序的执行权,有些方法可以绕开 Cookie,比如利用 SEH 技术。详细的您可以参看文章《Exploitation in the New Win32 Environment》、《Stack Overflow on Windows XP SP2》等等等等。 还有一些人在研究 Cookie 的生成,尝试猜测出 Cookie 值,但是对于概率论来说,这只不过是痴人说梦罢了。函数级的保护 Cookie 还XOR了当前栈空间的 EBP,8次异或伪随机值的概率和一次性中4个500万没什么区别了~ 至于文章如果您实在感兴趣可以读读《Uninformed》第7期的《Reducing the Effective Entropy of GS Cookies》。


最后一个话题,Symantec 在 2006 年有个宏大的 Vista 研究计划,其中有一个小分支是关于 GS cookie 的研究的。更多的信息您可以参看《Analysis of GS protections in Microsoft Windows Vista》、《GS and ASLR in Windows Vista》。他们关于 GS cookie 研究的目的是这样的:

GS research goals:
– Understand the implementation of GS
– Develop means to be able to identify GS and non-GS binaries
– Understand which binaries in Windows Vista™ are not GS protected
– Understand any impact ASLR has on GS cookies
My original goals:
– To be able to say if a binary is or is not GS compiled
– To be able to do this without symbols


由于我关注的重点是驱动,所以我主要拿驱动说事~  就像 Symantec 文章中解释的一样,并不是所有的驱动都会真正使用 Cookie 机制,许多情况下只是入口点初始化一下 __security_cookie 和 __security_cookie_complement,而不具备真正的保护意义,原因也很简单:

We observed that some kernel drivers initialize a GS cookie but never use it in their execution. Our fingerprints won't match these binaries since they do not have any protected functions, but the binaries are clearly compiled with the GS option. One could argue that these binaries do not leverage GS protection in their execution. However, it is important to understand why: These drivers use pointers and the heap during execution; they do not use local stack variables and hence do not need GS protection.

下面是已经总结好的 Cookie 不工作的情况:
GS won't always be applied however! The Rules Are:
– Functions that do not contain a stack buffer.
– If optimizations (/O Options (Optimize Code)) are not enabled.
– Functions with a variable argument list (...).
– Functions marked with naked (C++).
– Functions containing inline assembly code in the first statement.
– If a parameter is used only in ways that are less likely to be exploitable in the event of a buffer overrun.

还有类似于 UCHAR buffer[4]; 的代码也是不会产生 Cookie 编译保护的,因为 stack buffer <= 4


对于产生保护代码,您可以看到这样的检验过程:
PAGE:00010686 BasicDriverCreate proc near             ; DATA XREF: DriverEntry:loc_109CFo
PAGE:00010686
PAGE:00010686 var_4           = dword ptr -4
PAGE:00010686
PAGE:00010686                 mov     edi, edi
PAGE:00010688                 push    ebp
PAGE:00010689                 mov     ebp, esp
PAGE:0001068B                 push    ecx
PAGE:0001068C                 mov     eax, __security_cookie
PAGE:00010691                 mov     [ebp+var_4], eax
PAGE:00010694                 mov     ecx, [ebp+var_4]
PAGE:00010697                 xor     eax, eax
PAGE:00010699                 call    __security_check_cookie
PAGE:00010699
PAGE:0001069E                 leave
PAGE:0001069F                 retn    8
PAGE:0001069F
PAGE:0001069F BasicDriverCreate endp

.text:000104B0 ; FUNCTION CHUNK AT .text:00010485 SIZE 00000025 BYTES
.text:000104B0
.text:000104B0                 cmp     ecx, __security_cookie
.text:000104B6                 jnz     short loc_104C1
.text:000104B6
.text:000104B8                 test    ecx, 0FFFF0000h
.text:000104BE                 jnz     short loc_104C1
.text:000104BE
.text:000104C0                 retn
.text:000104C0
.text:000104C1 ; ---------------------------------------------------------------------------
.text:000104C1
.text:000104C1 loc_104C1:                              ; CODE XREF: __security_check_cookie+6j
.text:000104C1                                         ; __security_check_cookie+Ej
.text:000104C1                 jmp     __report_gsfailure


在过程 __report_gsfailure 里,编译器为我们的 IAT 大度的导入了 Killer —— KeBugCheckEx()

.text:00010485 __report_gsfailure:                     ; CODE XREF: __security_check_cookie:loc_104C1j
.text:00010485                 mov     edi, edi
.text:00010487                 push    ebp
.text:00010488                 mov     ebp, esp
.text:0001048A                 push    ecx
.text:0001048B                 mov     [ebp-4], ecx
.text:0001048E                 push    0               ; BugCheckParameter4
.text:00010490                 push    __security_cookie_complement ; BugCheckParameter3
.text:00010496                 push    __security_cookie ; BugCheckParameter2
.text:0001049C                 push    dword ptr [ebp-4] ; BugCheckParameter1
.text:0001049F                 push    0F7h            ; BugCheckCode
.text:000104A4                 call    ds:KeBugCheckEx(x,x,x,x,x)
.text:000104A4
.text:000104A4 ; END OF FUNCTION CHUNK FOR __security_check_cookie


代码里的 BugCheckCode 是 0xF7 —— DRIVER_OVERRAN_STACK_BUFFER
---------------------------------------------------------------


回到正题上来,Symantec 为了标识出二进制代码是否由 /GS 编译专门开发了自己的工具“GSAudit”,对于驱动来说,Symantec 的 fingerprint 大致基于这样的初始化流程:

INIT:000109F8 ; Attributes: bp-based frame
INIT:000109F8
INIT:000109F8                 public GsDriverEntry
INIT:000109F8 GsDriverEntry   proc near
INIT:000109F8                 mov     edi, edi
INIT:000109FA                 push    ebp
INIT:000109FB                 mov     ebp, esp
INIT:000109FD                 mov     eax, __security_cookie
INIT:00010A02                 test    eax, eax
INIT:00010A04                 mov     ecx, 0BB40h
INIT:00010A09                 jz      short loc_10A0F
INIT:00010A09
INIT:00010A0B                 cmp     eax, ecx
INIT:00010A0D                 jnz     short loc_10A32
INIT:00010A0D
INIT:00010A0F
INIT:00010A0F loc_10A0F:                              ; CODE XREF: GsDriverEntry+11j
INIT:00010A0F                 mov     edx, ds:KeTickCount
INIT:00010A15                 mov     eax, offset __security_cookie
INIT:00010A1A                 shr     eax, 8
INIT:00010A1D                 xor     eax, [edx]
INIT:00010A1F                 and     eax, 0FFFFh
INIT:00010A24                 mov     __security_cookie, eax
INIT:00010A29                 jnz     short loc_10A32
INIT:00010A29
INIT:00010A2B                 mov     eax, ecx
INIT:00010A2D                 mov     __security_cookie, eax
INIT:00010A2D
INIT:00010A32
INIT:00010A32 loc_10A32:                              ; CODE XREF: GsDriverEntry+15j
INIT:00010A32                                         ; GsDriverEntry+31j
INIT:00010A32                 not     eax
INIT:00010A34                 mov     __security_cookie_complement, eax
INIT:00010A39                 pop     ebp
INIT:00010A3A                 jmp     DriverEntry
INIT:00010A3A
INIT:00010A3A GsDriverEntry   endp


其实,我不用写工具,一句指令就可以完成类似的任务(不过准确度是另一个方面~),这个也就是今天写本随笔的目的之一:

        findstr /M /I KeTickCount %SYSTEMROOT%\system32\drivers\*.sys


打完收功,最后列一下我机器上 drivers 目录下,被 /GS 编译保护的驱动程序:

C:\WINDOWS\system32\drivers\360AntiARP.sys
C:\WINDOWS\system32\drivers\acpi.sys
C:\WINDOWS\system32\drivers\aec.sys
C:\WINDOWS\system32\drivers\afd.sys
C:\WINDOWS\system32\drivers\ALCXWDM.SYS
C:\WINDOWS\system32\drivers\amdk6.sys
C:\WINDOWS\system32\drivers\amdk7.sys
C:\WINDOWS\system32\drivers\arp1394.sys
C:\WINDOWS\system32\drivers\asyncmac.sys
C:\WINDOWS\system32\drivers\atapi.sys
C:\WINDOWS\system32\drivers\atmarpc.sys
C:\WINDOWS\system32\drivers\atmlane.sys
C:\WINDOWS\system32\drivers\BasicDriver.sys
C:\WINDOWS\system32\drivers\bridge.sys
C:\WINDOWS\system32\drivers\cdfs.sys
C:\WINDOWS\system32\drivers\cdrom.sys
C:\WINDOWS\system32\drivers\cinemst2.sys
C:\WINDOWS\system32\drivers\classpnp.sys
C:\WINDOWS\system32\drivers\crusoe.sys
C:\WINDOWS\system32\drivers\disk.sys
C:\WINDOWS\system32\drivers\diskdump.sys
C:\WINDOWS\system32\drivers\dmboot.sys
C:\WINDOWS\system32\drivers\dmio.sys
C:\WINDOWS\system32\drivers\DMusic.sys
C:\WINDOWS\system32\drivers\drmk.sys
C:\WINDOWS\system32\drivers\drmkaud.sys
C:\WINDOWS\system32\drivers\dxg.sys
C:\WINDOWS\system32\drivers\fastfat.sys
C:\WINDOWS\system32\drivers\fdc.sys
C:\WINDOWS\system32\drivers\fips.sys
C:\WINDOWS\system32\drivers\flpydisk.sys
C:\WINDOWS\system32\drivers\fltMgr.sys
C:\WINDOWS\system32\drivers\FSpy.sys
C:\WINDOWS\system32\drivers\hidclass.sys
C:\WINDOWS\system32\drivers\hidparse.sys
C:\WINDOWS\system32\drivers\http.sys
C:\WINDOWS\system32\drivers\i8042prt.sys
C:\WINDOWS\system32\drivers\imapi.sys
C:\WINDOWS\system32\drivers\intelppm.sys
C:\WINDOWS\system32\drivers\ip6fw.sys
C:\WINDOWS\system32\drivers\ipfltdrv.sys
C:\WINDOWS\system32\drivers\ipinip.sys
C:\WINDOWS\system32\drivers\ipnat.sys
C:\WINDOWS\system32\drivers\ipsec.sys
C:\WINDOWS\system32\drivers\irenum.sys
C:\WINDOWS\system32\drivers\kbdclass.sys
C:\WINDOWS\system32\drivers\kmixer.sys
C:\WINDOWS\system32\drivers\ks.sys
C:\WINDOWS\system32\drivers\ksecdd.sys
C:\WINDOWS\system32\drivers\mf.sys
C:\WINDOWS\system32\drivers\modem.sys
C:\WINDOWS\system32\drivers\mouclass.sys
C:\WINDOWS\system32\drivers\mountmgr.sys
C:\WINDOWS\system32\drivers\mqac.sys
C:\WINDOWS\system32\drivers\mrxdav.sys
C:\WINDOWS\system32\drivers\mrxsmb.sys
C:\WINDOWS\system32\drivers\msfs.sys
C:\WINDOWS\system32\drivers\msgpc.sys
C:\WINDOWS\system32\drivers\MSKSSRV.sys
C:\WINDOWS\system32\drivers\MSPCLOCK.sys
C:\WINDOWS\system32\drivers\MSPQM.sys
C:\WINDOWS\system32\drivers\mssmbios.sys
C:\WINDOWS\system32\drivers\mup.sys
C:\WINDOWS\system32\drivers\ndis.sys
C:\WINDOWS\system32\drivers\ndisuio.sys
C:\WINDOWS\system32\drivers\ndiswan.sys
C:\WINDOWS\system32\drivers\ndproxy.sys
C:\WINDOWS\system32\drivers\netbios.sys
C:\WINDOWS\system32\drivers\netbt.sys
C:\WINDOWS\system32\drivers\nic1394.sys
C:\WINDOWS\system32\drivers\nmnt.sys
C:\WINDOWS\system32\drivers\nmwcd.sys
C:\WINDOWS\system32\drivers\nmwcdc.sys
C:\WINDOWS\system32\drivers\nmwcdcj.sys
C:\WINDOWS\system32\drivers\nmwcdcm.sys
C:\WINDOWS\system32\drivers\npfs.sys
C:\WINDOWS\system32\drivers\ntfs.sys
C:\WINDOWS\system32\drivers\nwlnkipx.sys
C:\WINDOWS\system32\drivers\nwlnknb.sys
C:\WINDOWS\system32\drivers\nwrdr.sys
C:\WINDOWS\system32\drivers\p3.sys
C:\WINDOWS\system32\drivers\parport.sys
C:\WINDOWS\system32\drivers\pci.sys
C:\WINDOWS\system32\drivers\pciidex.sys
C:\WINDOWS\system32\drivers\pcmcia.sys
C:\WINDOWS\system32\drivers\portcls.sys
C:\WINDOWS\system32\drivers\processr.sys
C:\WINDOWS\system32\drivers\psched.sys
C:\WINDOWS\system32\drivers\rasl2tp.sys
C:\WINDOWS\system32\drivers\raspppoe.sys
C:\WINDOWS\system32\drivers\raspptp.sys
C:\WINDOWS\system32\drivers\rdbss.sys
C:\WINDOWS\system32\drivers\rdpdr.sys
C:\WINDOWS\system32\drivers\rdpwd.sys
C:\WINDOWS\system32\drivers\redbook.sys
C:\WINDOWS\system32\drivers\rmcast.sys
C:\WINDOWS\system32\drivers\rndismp.sys
C:\WINDOWS\system32\drivers\rspsc.sys
C:\WINDOWS\system32\drivers\scanner.sys
C:\WINDOWS\system32\drivers\scsiport.sys
C:\WINDOWS\system32\drivers\sdbus.sys
C:\WINDOWS\system32\drivers\secdrv.sys
C:\WINDOWS\system32\drivers\serenum.sys
C:\WINDOWS\system32\drivers\serial.sys
C:\WINDOWS\system32\drivers\sffdisk.sys
C:\WINDOWS\system32\drivers\sffp_sd.sys
C:\WINDOWS\system32\drivers\sfloppy.sys
C:\WINDOWS\system32\drivers\SnBus.sys
C:\WINDOWS\system32\drivers\SnSerial.sys
C:\WINDOWS\system32\drivers\sonydcam.sys
C:\WINDOWS\system32\drivers\splitter.sys
C:\WINDOWS\system32\drivers\sr.sys
C:\WINDOWS\system32\drivers\srv.sys
C:\WINDOWS\system32\drivers\srvkp.sys
C:\WINDOWS\system32\drivers\stream.sys
C:\WINDOWS\system32\drivers\swenum.sys
C:\WINDOWS\system32\drivers\sysaudio.sys
C:\WINDOWS\system32\drivers\tape.sys
C:\WINDOWS\system32\drivers\tcpip.sys
C:\WINDOWS\system32\drivers\tcpip6.sys
C:\WINDOWS\system32\drivers\tdi.sys
C:\WINDOWS\system32\drivers\tdpipe.sys
C:\WINDOWS\system32\drivers\tdtcp.sys
C:\WINDOWS\system32\drivers\termdd.sys
C:\WINDOWS\system32\drivers\tunmp.sys
C:\WINDOWS\system32\drivers\UAGP35.SYS
C:\WINDOWS\system32\drivers\udfs.sys
C:\WINDOWS\system32\drivers\update.sys
C:\WINDOWS\system32\drivers\usb8023.sys
C:\WINDOWS\system32\drivers\usbehci.sys
C:\WINDOWS\system32\drivers\usbhub.sys
C:\WINDOWS\system32\drivers\usbintel.sys
C:\WINDOWS\system32\drivers\usbohci.sys
C:\WINDOWS\system32\drivers\usbport.sys
C:\WINDOWS\system32\drivers\USBSTOR.SYS
C:\WINDOWS\system32\drivers\vga.sys
C:\WINDOWS\system32\drivers\videoprt.sys
C:\WINDOWS\system32\drivers\volsnap.sys
C:\WINDOWS\system32\drivers\wanarp.sys
C:\WINDOWS\system32\drivers\wdmaud.sys



NUPT   WANGyu

 
 
 
 
 
 
 
 
 
 

posted on Tuesday, December 11, 2007 11:51 AM 由 WANGyu

# re: 基于Cookie编译保护的二进制文件简便鉴别方法 @ Tuesday, December 11, 2007 5:04 PM

想了解黑客文化先看看这里:
http://www.chi3.org/docs/hackers.html

WANGyu

 
Legal Notice Privacy Statement Corporate Governance Corporate Governance
(C)2004-2005 Advanced Debugging Ltd. All Rights Reserved.