首页
论坛
课程
招聘
[原创][技术专题]软件漏洞分析入门_9_案例_微软ANI光标文件漏洞彻底分析利用
2008-1-10 10:41 16391

[原创][技术专题]软件漏洞分析入门_9_案例_微软ANI光标文件漏洞彻底分析利用

2008-1-10 10:41
16391
为支持老大failwest的新书《0day安全:软件漏洞分析与利用》的发行,响应看雪在漏洞分析领域的雄起,上期献上一篇《Microsoft TIFF图像文件处理栈溢出漏洞(MS07-055)》,本期继续贡献我在《黑客防线》上发表过得漏洞案例实战分析文章。希望通过这两篇文章,使大家对文件格式漏洞有一个初步的认识。

漏洞概述
        2007年3月30日,ph4nt0m和milw0rm先后公布了今年目前为止危害性最大的windows漏洞——user32.dll的ANI文件处理漏洞。我写这篇文章已是漏洞爆出的第5天了,事实上,30号公布的漏洞,30号晚上利用这个漏洞的网马生成器已经在网上散播了,而且微软迟迟没有发布相关补丁。这给利用这个漏洞的病毒、蠕虫、木马、恶意软件等,一个很难得的机会。漏洞就像一把钥匙,打开了它们侵入互联网的大门。
        虽然eEye推出了一款非官方的补丁,可以拦截一部分远程攻击、网络木马,但是4月1日,milw0rm上又公布了一个能够绕过eEye补丁的exploit。看来又是一场互联网血雨腥风的到来!
       
漏洞分析
        既然这个漏洞是和ANI文件有关的,那么我们在分析漏洞之前,首先需要对ANI文件格式有一定的了解。关于ANI文件格式的详细说明请读者参阅光盘中的附件。
ANI(APPlicedon Startins Hour Glass)文件是MS Windows的动画光标文件,可以作为鼠标指针,其文件扩展名为“.ani”。ANI文件由“块”(chunk)构成。它一般由五部分构成:标志区、文字说明区、信息区、时间控制区和数据区,即RIFF—ACON,LIST—INFO,anih,rate,LIST—fram。ANI文件在播放时所形成的动画效果,其实就是一张张的光标或图标图像按一定的顺序绘制到屏幕上,并保留指定的时间(见时间控制区说明)依序循环显示的结果。一个ANI文件的开头12个字节中,头4个字节为RIFF,后4个字节为ACON,中间4个字节是该ANI文件的长度(字节数)。有了RIFF和ACON,就可断定该文件是一个ANI文件,也就是说,ACON是一个动画光标文件的标志。
在一个ANI文件中,必须有的块标识有以下几个:
        RIFF—多媒体文件识别码
        ACON—ANI文件识别码
        anih—ANI文件信息区识别码
        LIST—LIST列表形式(窗体形式fccType=“fram”)
        icon—icon识别码
在一个ANI文件中,还可能有以下几个块标识中的一个或多个:
        INAM—ANI文件标题区识别码
        IART—ANI文件说明信息区识别码
        rate—ANI文件时间控制数据区识别码
        seq —ANI文件图像显示帧顺序控制区识别码
这些块之间的逻辑层次关系可以如下表示:
"RIFF" {Length of File}
    "ACON"
        "LIST" {Length of List}
            "INAM" {Length of Title} {Data}
            "IART" {Length of Author} {Data}
        "fram"
            "icon" {Length of Icon} {Data}      ; 1st in list
            ...
            "icon" {Length of Icon} {Data}      ; Last in list  (1 to cFrames)
    "anih" {Length of ANI header (36 bytes)} {Data}   ; (see ANI Header TypeDef )
    "rate" {Length of rate block} {Data}      ; ea. rate is a long (length is 1 to cSteps)
    "seq " {Length of sequence block} {Data} ; ea. seq is a long (length is 1 to cSteps)
-END-
        以上仅是对ANI文件格式的结论性描述,要完全明白这些块的作用和意义,以及块与块之间的逻辑关系,确实需要下一番功夫。另外仅研读我给的资料是完全不够的,一定会有理解起来模糊的地方,因此还需要动手做实验,自己跟踪user32.dll对ANI文件的处理过程,从实验中得到结论。这样做有两个好处,一是可以更加深刻的理解漏洞的根源;二是由此可以启发新漏洞的挖掘思想。
        如果你对ANI文件格式已有一定了解,那我们就可以开始分析造成最终user32.dll栈溢出的这个畸形.ani文件了,为了理解,我把这个ANI文件(exp.ani)用十六进制的方式打开,并示意如下:

        这是一个精心构造的1k大小的.ani文件(在XP SP2全补丁下测试通过),其各个部分解释如下表所示:
偏移地址        内容        含义        块
0000-0003h        “RIFF”        多媒体文件识别码        RIFF
0004-0007h        0000 0400h        文件大小(1k)       
0008-000Bh        “ACON”        ANI文件识别码ACON       
000C-000Fh        “anih”        anih识别码(ckID),信息区开始的标志        anih
0010-0013h        0000 0024h        anih块的大小(ckSize,36个字节)       
0014-0037h                anih块内容       
0038-003Bh        “LIST”        LIST识别码,数据区开始的标志        LIST
003C-003Fh        0000 0003        LIST块的大小(3个字节)       
0040-0043h                LIST块内容       
0044-0047h        “LIST”        LIST识别码,数据区开始的标志        LIST
0048-004Bh        0000 0003        LIST块的大小(3个字节)       
004C-004Fh                LIST块内容       
0050-0053h        “anih”        anih识别码(ckID),信息区开始的标志        anih
0054-0057h        0000 03A8h        anih块的大小(ckSize,936个字节)       
0058-03F0h                anih块内容       
        为什么这个文件能使user32.dll栈溢出?据我分析,是因为user32.dll对这个.ani文件中的第二个anih块处理时,未对这个块的长度进行检查,最终导致栈溢出,控制了程序的EIP。通常来说任何一个正常的anih块的长度应该是36个字节,为什么这样说呢?因为anih块内容是有自己的数据结构的,用一个结构体来表示:
typedef DWORD JIF,*PJIF;
typedef struct tagANIHEADER{
        DWORD        cbSizeof;                        //数据块大小,应该是36字节
        DWORD        cFrames;                        //ANI文件保存的图象桢数
        DWORD        cSteps;                        //完成一次动画过程要显示的图象数
        DWORD        cx;                        //图象宽度
        DWORD        cy;                        //图象高度
        DWORD        cBitCount;                        //颜色位数
        DWORD        cPlanes;                        //颜色位面数
        JIF        jifRate;                        //JIF速率
        DWORD        fl;                        //AF_ICON/AF_SEQUENCE设置标记
}ANIHEADER,*PANIHEADER;
        可见,这个anih块内容是一个9个双字的结构体,所以说它的长度应该是9×4=36字节。然而这个畸形的.ani文件中第二个anih块内容的长度偏偏不为36字节,而是936个字节,若程序中把这个块的内容复制到栈中,你说这能不溢出吗?
        下面我们用ollyDBG跟踪一下这个溢出过程,看看根本原因是不是如上所说。
          //user32.dll中的ReadChunk(x,x,x)函数
77D53AC7   8BFF             MOV EDI,EDI
77D53AC9   55               PUSH EBP
77D53ACA   8BEC             MOV EBP,ESP
77D53ACC   56               PUSH ESI
77D53ACD   8B75 08          MOV ESI,DWORD PTR SS:[EBP+8]
77D53AD0   57               PUSH EDI
77D53AD1   8B7D 0C          MOV EDI,DWORD PTR SS:[EBP+C]
77D53AD4   FF77 04          PUSH DWORD PTR DS:[EDI+4]         ;anih块内容的长度
77D53AD7   FF75 10          PUSH DWORD PTR SS:[EBP+10]
77D53ADA   56               PUSH ESI
77D53ADB   E8 7AFFFFFF      CALL USER32.77D53A5A        ;调用ReadFileCopy函数
77D53AE0   85C0             TEST EAX,EAX

//user32.dll中的ReadFileCopy(x,x,x)函数
77D53A5A   8BFF             MOV EDI,EDI
77D53A5C   55               PUSH EBP
77D53A5D   8BEC             MOV EBP,ESP
77D53A5F   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
77D53A62   8B55 10          MOV EDX,DWORD PTR SS:[EBP+10]
77D53A65   56               PUSH ESI
77D53A66   8B70 04          MOV ESI,DWORD PTR DS:[EAX+4]        ;让ESI指向堆中的anih块内容
77D53A69   8D0C16           LEA ECX,DWORD PTR DS:[ESI+EDX]
77D53A6C   3BCE             CMP ECX,ESI
77D53A6E   72 28            JB SHORT USER32.77D53A98
77D53A70   3BCA             CMP ECX,EDX
77D53A72   72 24            JB SHORT USER32.77D53A98
77D53A74   3B48 08          CMP ECX,DWORD PTR DS:[EAX+8]
77D53A77   77 1F            JA SHORT USER32.77D53A98
77D53A79   53               PUSH EBX
77D53A7A   57               PUSH EDI
77D53A7B   8B7D 0C          MOV EDI,DWORD PTR SS:[EBP+C]        ;让EDI指向栈帧中的一个内存单元
77D53A7E   8BCA             MOV ECX,EDX
77D53A80   8BD9             MOV EBX,ECX
77D53A82   C1E9 02          SHR ECX,2        ; 让ECX为.ani文件中第二个anih块的块内容大小的1/4
;一次复制一个双字,所以下面REP指令的循环次数应该为字节数的四分之一
77D53A85   F3:A5            REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
77D53A87   8BCB             MOV ECX,EBX
77D53A89   83E1 03          AND ECX,3
77D53A8C   F3:A4            REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
77D53A8E   0150 04          ADD DWORD PTR DS:[EAX+4],EDX
77D53A91   33C0             XOR EAX,EAX
77D53A93   5F               POP EDI
77D53A94   40               INC EAX
77D53A95   5B               POP EBX
77D53A96   EB 02            JMP SHORT USER32.77D53A9A
77D53A98   33C0             XOR EAX,EAX
77D53A9A   5E               POP ESI
77D53A9B   5D               POP EBP
77D53A9C   C2 0C00          RETN 0C
        上面是对溢出过程的动态跟踪分析,如果用IDA进行静态分析同样也会得到上面的提到的漏洞原因,这里不再赘述!

漏洞利用
        提到利用,大家就笑了!想想多少东西在使用user32.dll啊?!
首当其冲的就是IE了,IE6,IE7已被测试通过,全部中招,也就是说写个网络木马是很容易了,只要有人敢上你的网站,那说都不说了,想干啥就干啥喽!
        其次,Windows的Explorer在打开这个.ani文件所在的目录时也会调用user32.dll中的LoadAniIcon函数,从而触发溢出。因此电子邮件、QQ、ftp、U盘等都可以用来传播利用这个漏洞的病毒、蠕虫、木马、恶意软件。
        另外,还可以利用一些使用user32.dll中LoadAniIcon函数的软件,用这些软件打开这些畸形.ani文件,同样也会中招。譬如,WinHex、IrfanView、Firework、Photoshop等。
        本文主要演示网络木马生成和一次成功的攻击过程。
        网上已经流传了很多木马生成器,使用很简单,输入网页木马远程存放地址和木马程序存放地址即可。
   
        我使用了我的IP地址(202.117.7.209)作为测试,然后启动web服务(IIS5.1),把生成的那三个文件(index.htm,z1.jpg,z2.jpg),还有木马程序(a.exe)放到web跟目录下。
        然后把链接(http://202.117.7.209)给几个朋友,发现他们全部中招了,哈哈,好在我没有下毒手,那个木马程序仅仅是弹出个框框而已!


漏洞防范
        这个漏洞危害这么大,不防不行啊,广大网民岂不是要遭殃啊!因为我写这篇文章时还没有微软的官方补丁,首推的防范措施是下载eEye的非官方补丁,补丁已放在光盘附件中。
        另外如果你的C盘是NTFS格式的,那么还可以使用如下措施:
1.        “开始”菜单“运行”里输入"gpedit.msc"
2.        然后在“本地计算机”策略 => 用户配置 => 管理模板 => 系统 => 停止命令提示符   
设置为“启用”
3.        把“他停用命令提示符脚本处理吗”选为“是”,再按确定!
4.        C:\Documents and Settings\xxxxxx\Local Settings目录的权限设置为不能运行! xxxxxx是你的用户名

总结
        这个漏洞的根本原因是,user32.dll中的ReadChunk()函数未对.ani文件中的anih块内容长度进行检查,就直接调用ReadFilePtrCopy()函数把堆中的anih块内容复制到栈帧中。
无论利用这个漏洞的病毒、蠕虫、木马、恶意软件、网马对互联网的冲击有多大,我们都有理由相信,互联网及我们的PC能顶过这07年的第一次危机!
        值得一提的是,如果您是搞漏洞挖掘方面的,通过这次uesr32.dll爆出的漏洞,您是否体会到漏洞的真正含义呢?不光是那些一般水平程序员写的程序容易出问题,爆漏洞;事实上,高级程序员也会有考虑不周的时候。因此漏洞是一个很微妙的东西,不是说编程经验丰富、实现能力强的程序员写的程序就不会有漏洞,任何程序员只要编程时考虑不周,都有可能爆出漏洞!本漏洞就是一个很好的例子。

[2022冬季班]《安卓高级研修班(网课)》月薪两万班招生中~

上传的附件:
  • 1.JPG (143.33kb,2570次下载)
  • 2.JPG (91.76kb,2560次下载)
收藏
点赞0
打赏
分享
最新回复 (37)
雪    币: 1963
活跃值: 活跃值 (203)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
failwest 活跃值 8 2008-1-10 10:42
2
0
猛顶!

我和shineast最近评分很辛苦啊,分数应该能在月中出来:)

还有就是《0day安全》的封面和排版出了点小问题,电子工业那边耽搁了一下,估计要等节后开学的时候才能上架了,小郁闷
雪    币: 266
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
somuch 活跃值 1 2008-1-10 10:52
3
0
占位,广告请联系
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lOOp 活跃值 2008-1-10 10:57
4
0
我顶啊。。。。。
雪    币: 584
活跃值: 活跃值 (11135)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2008-1-10 11:01
5
0
failwest和shineast评分辛苦了。
希望2008年论坛出现更多的技术热点。
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qandzjl 活跃值 2008-1-10 11:42
6
0
真郁闷啊,要到3月份才能买你那本书吗??
雪    币: 1298
活跃值: 活跃值 (64)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
yijun8354 活跃值 12 2008-1-10 11:46
7
0
目前就期待加解密3和0day安全了~~~
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
iupek 活跃值 2008-1-10 11:57
8
0
希望早点看到那本书,好期待
雪    币: 235
活跃值: 活跃值 (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhtjia 活跃值 2008-1-10 15:01
9
0
期待ing...
雪    币: 210
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
黑色猎鹰 活跃值 2008-1-10 16:31
10
0
做第一排学习~~~
雪    币: 100
活跃值: 活跃值 (44)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
NWMonster 活跃值 1 2008-1-10 16:49
11
0
学习中。。。。。。。。。。。。。。。。。。
雪    币: 236
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
shinechou 活跃值 2008-1-10 18:06
12
0
现在发现学习真是件幸福的事!大侠辛苦了!
雪    币: 232
活跃值: 活跃值 (12)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
firefly 活跃值 4 2008-1-10 18:55
13
0
好事多磨,嘿嘿。
雪    币: 462
活跃值: 活跃值 (983)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
sudami 活跃值 25 2008-1-10 20:04
14
0
学习啊~

shineast大牛在 黑防上的文章受益匪浅啊~
雪    币: 304
活跃值: 活跃值 (46)
能力值: ( LV13,RANK:330 )
在线值:
发帖
回帖
粉丝
HSQ 活跃值 8 2008-1-10 20:07
15
0
LZ的最近两篇漏洞分析都是与文件格式有关,这样说来,有时为了能够利用改漏洞害得了解其文件格式了
雪    币: 324
活跃值: 活跃值 (17)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
likunkun 活跃值 1 2008-1-10 20:10
16
0
经典,赞一个
雪    币: 247
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
evilcode 活跃值 2008-1-10 21:03
17
0
几头大牛挡到我视线
雪    币: 109
活跃值: 活跃值 (218)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
combojiang 活跃值 26 2008-1-10 21:20
18
0
黑客防线好久没有看了,看来还是有不错的文章。07年的黑防合订本真的要买了/。
雪    币: 231
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ikandu 活跃值 2008-1-10 23:16
19
0
高人
小顶下
雪    币: 179
活跃值: 活跃值 (24)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
shineast 活跃值 4 2008-1-10 23:34
20
0
谢谢!谢谢!今后不仅要多写一些漏洞分析,还需要在攻防技术上做一些突破。

目前攻击技术的焦点是如果绕过或突破主动防御和虚拟机查毒技术等;
而防御技术需要更好的完善主动防御,虚拟机技术,更要发展新的非特征码的杀毒技术,例如研究病毒的行为等,来查杀病毒。

确实很难!但是目前是一个关键时期!攻防的对抗逐渐趋于高潮!——我预料!
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
webfly 活跃值 2008-1-11 08:31
21
0
就等你那本书了
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ymzhi 活跃值 2008-1-12 09:36
22
0
来,顶一个,看雪真的不错
雪    币: 208
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
hpxpj 活跃值 1 2008-1-12 16:33
23
0
如何动态调试ReadChunk函数,我本想把ollydbg附加到explorer.exe上,在ReadChunk下断点,然后再浏览ani文件,发现我根本没有机会再动了,所以想知道LZ是怎么做到的,有人能有个提示吗?
雪    币: 200
活跃值: 活跃值 (14)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dragonyjd 活跃值 1 2008-1-12 21:22
24
0
回楼上,我是下了个aniedit.exe,然后OD加载,打开ANI。。。。就可以调试了
雪    币: 208
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
hpxpj 活跃值 1 2008-1-12 22:29
25
0
嗯,谢谢  有更简单的方法吗 比较普遍适用这种类似情况的
游客
登录 | 注册 方可回帖
返回