Talk about IE Object Type Property overflow vulnerability
Creation time: 2003-09-08
Article attribute: original
Article submission:
Eyas (Eyas_AT_XFOCUS.org)
Talk about IE Object Type Property overflow vulnerability
Author: EY4S
Email: Eyas # xfocus.org
Site:
www.xfocus.net
Date: 2003-09-08
First of all, I would like to thank Nanika's study on this vulnerability in the past, and his article made me benefit.
My test environment is
Windows 2000 Server English version SP4 (default CodePage is GB)
IE 6.0 English version SP1
URLMON.DLL 6.0.2800.1106
If the HTML page contains the following characters:
Then the IE's processing process is as follows:
1. String "AAAA" (referred to in this string for m_buff_1) Convert by multibytetowideChar function
Unicode (hereinafter referred to as U_BUFF_1).
2.u_buff_1 is truncated to 0x100 bytes (the string of the truncation is called U_BUFF_2).
3.u_buff_2 As the 5th parameter of the function urlmon! CogetherClassObjectFromurl, do further processing.
4.u_buff_2 Convert by WideChartomultibyte function into multi-byte form (W_Buff_2).
5.w_buff_2 is further processed as the first parameter of the function urlmon! GetClassmime.
6.W_Buff_2 As a function URLMON! ComposehackClsidFrommime for further processing.
The processing process function call relationship is as follows:
URLMON! CogetherClassObjectFromurl
| _ urlmon! asyncgetClassBitsex
| _ urlmon! asyncgetclassbits2ex
| _ urlmon! getClsidFromextormime
| _ WideChartomultibyte
| _ urlmon! getClassmime (overflow)
| _ URLMON! CCODEDEDOAD :: DOCODEDOWNLOAD
| _ urlmon! ccodedownload :: getNextonternetSearchPath
| _ urlmon! ComposehackClsidFrommime (overflow)
After M_Buff_1 After we carefully constructed, STACK can be made separately from the fifth steps in the above process.
overflow. Online existing analysis information seems to only pay attention to the overflow of the 6th step, maybe I am alone ^ _ ^.
OK! Let's see the first one.
URLMON! GetClassmime:
702cc586 55 Push EBP
702cc587 8D6C2494 Lea EBP, [ESP-0x6C]
702cc58b 81eca4030000 sub ev, 0x3a4
// [EBP 0x74] The first parameter, the previous W_Buff_2
702cc591 8b4574 MOV EAX, [EBP 0x74]
....
// "MIME / DATABASE / Content Type /" COPY / "Copy to [EBP-0x38] at 0x7030A754
702cc5b4 8A9154A73070 MOV DL, [ECX 0x7030A754]
702cc5ba 88540dc8 MOV [EBP ECX-0x38], DL702CC5BE 41 Inc ECX
702cc5bf 84d2 Test DL, DL
702cc5c1 75f1 JNZ URLMON! GetClassmime 0x2e (702cc5b4)
// w_buff_2 address Save in EDX
702cc5c3 8bd0 MOV EDX, EAX
// Location W_BUFF_2 end address
702cc5c5 8A08 MOV CL, [EAX]
702cc5c7 40 Inc EAX
702cc5c8 84c9 Test CL, CL
702cc5ca 75f9 JNZ URLMON! GetClassmime 0x3f (702cc5c5)
/ / Calculate the end address of Dest Buffer
702cc5cc 8D7DC8 LEA EDI, [EBP-0X38] // DEST BUFFER
702cc5cf 2bc2 sub eax, edx // calculate W_buff_2 length
702cc5d1 4f Dec EDI
702cc5d2 8A4F01 MOV CL, [EDI 0x1]
702cc5d5 47 inc Edi
702CC5D6 84C9 TEST CL, CL
702cc5d8 75f8 jnz urlmon! GetClassmime 0x4c (702cc5d2)
// Way W_Buff_2 Copy to the stack, overflow!
702cc5da 8bc8 MOV ECX, EAX
702cc5dc C1E902 SHR ECX, 0x2 // W_buff_2 length is from 4
702cc5df 8BF2 MOV ESI, EDX // Source Buffer
702cc5e1 f3a5 rep MOVSD
// w_buff_2 In addition to 4 remaining Copy to the stack
702cc5e3 8bc8 MOV ECX, EAX
702cc5e5 8D4568 Lea Eax, [EBP 0x68]
702cc5e8 50 push eax
702cc5e9 83e103 and ecx, 0x3
702cc5ec 6A01 PUSH 0x1
702CC5EE F3A4 Rep Movsb
......
702cc67d 83c56c add ebp, 0x6c
702cc680 C9 Leave
702cc681 C20C00 RET 0XC
From the above assembly code we can see that the total length of the stack is 0x38 0x6c = 0xA4.
If you restore C-code, you should look like this:
Char * str = "MIME / DATABASE / Content Type /";
GetClassmime (char * w_buff_2, ...)
{
Char buff [0xA4];
STRCPY (BUFF, STR); STRCAT (BUFF, W_BUFF_2);
......
}
The STR length is fixed to 0x1b, 0xA4-0X1B = 0x89, so we offer W_Buff_2 as long as it is equal to 0x89,
The IE can overflow and control the program process. 0x100 bytes of U_BUFF_2 converted to multi-byte w_buff_2, length
More than or equal to 0x80, less than or equal to X100, the specific length depends on the buff as you constructed and the system's CodePage.
When the system defaults is GB, the W_buff_1 is constructed as follows:
[* 68] [A] [AAAA] [BBBB] [ccccddddeeee] [fff]
How come 68? 68 * 2 1 = 137, that is, 0x89.
After IE overflow, EBP = 0x41414141, EIP = 0x42424242, ESP points to "FFFF" starting place. overflow
When SEH is far from Stack Buffer, it is not covered. After the overflow function RET, only ESP points to us.
All JMP ESPs that can only be used in Buffer are controlled. JMP ESP addresses are more difficult to find universal,
Therefore, the vetement of EXP will be relatively low.
We can construct w_buff_1 like this:
[sc (0x89 4 bytes)] [jmp eSP] [NOP * 0XC] [jmp_back_to_sc]
To meet a few conditions:
1) W_BUFF_1 will not be changed after twice.
2) To ensure that W_buff_1 is converted to Unicode, the length is less than or equal to 0x100.
The SC can have 0x89 4 = 0x8d, namely 141 bytes. What can 141 bytes do? SC complex function
It may not be enough, but shellcode it is used to search for the truly functionality in memory.
In addition, after the overflow occurs, several bytes in the SC will be changed, and this should also be noted.
It can be seen from the above analysis that this overflowed Express relies on the JMP ESP address and the system language platform.
If you have a better way of use, please don't enlighten it ^ _ ^.
Let's take a look at the second place.
The prototype of the ComposehackClsidFrommime function is similar to:
ComposehackClsidfrommime (char * poutbuf, int ositbufsize, char * w_buff_2)
Urlmon! ComposehackClsidFrommime:
702F1B7A 55 Push EBP
702F1B7B 8BEC MOV EBP, ESP
702F1B7D 81EC04010000 SUB ESP, 0x104
702F1B83 8B4D10 MOV ECX, [EBP 0x10]
702f1b86 56 Push ESI
702F1B87 8BF1 MOV ESI, ECX
702F1B89 8A09 MOV CL, [ECX]
702F1B8B 84C9 Test CL, CL
702f1b8d 8d85fcfeffff lea EAX, [EBP-0x104]
702F1B93 888DFCFEFFF MOV [EBP-0x104], CL
702f1b99 741e jz 702f1bb9
/ / Judgment is "/", is it to extend to "_2f_", then write to 702F1B9B 80F92F CMP CL, 0x2F in Stack Buffer
702F1B9E 750F JNZ 702F1BAF
702f1ba0 c6005f MOV BYTE PTR [EAX], 0x5F
702F1BA3 40 Inc EAX
702F1BA4 C60032 MOV BYTE PTR [EAX], 0x32
702F1BA7 40 Inc EAX
702F1BA8 C60046 MOV BYTE PTR [EAX], 0x46
702F1BAB 40 INC EAX
702F1BAC C6005F MOV BYTE PTR [EAX], 0x5F
702F1BAF 46 INC ESI
702F1BB0 8A0E MOV CL, [ESI]
702F1BB2 40 Inc EAX
702F1BB3 84C9 Test CL, Cl, Cl, Cl, Cl, Cl, Cl, Cl, Cl, CL
/ / Is not "/" directly written to Stack Buffer
702F1BB5 8808 MOV [EAX], CL
702F1BB7 75E2 JNZ 702F1B9B
// Write the Buffer after the extended extension, write to Poutbuf in a certain format
702f1bb9 8d85fcfeffff lea eax, [EBP-0X104]
702f1bbf 50 push eax
702F1BC0 8B450C MOV EAX, [EBP 0xC]
702F1BC3 68E01B2F70 PUSH 0x702F1BE0
702F1BC8 48 DEC EAX
702F1BC9 50 Push EAX
702F1BCA FF7508 PUSH DWORD PTR [EBP 0x8]
702F1BCD FF15FC132B70 Call DWORD PTR [URLMON! _IMP__WNSPRINTFA]
702F1BD3 83C410 Add ESP, 0x10
702f1bd6 33c0 xor Eax, EAX
702f1bd8 5e POP ESI
702F1BD9 C9 Leave
702F1BDA C20C00 RET 0XC
From the above assembly code we can see that the Stack Buffer length is 0x104. From the previous analysis we know
Road, w_buff_2 length should be controlled within 0x89, otherwise it will overflow in Urlmon! GetClassmime,
Here. At the time of the test, in some platforms, the length of W_buff_2 seems to be controlled within 0x80, or
Can't let it. Let's limit the maximum length of W_buff_2 to 0x80.
There are two ways to use this overflow vulnerability.
First, JMP ESP. This constructs W_BUFF_1:
[/ * 64] [AAAA] [CCCC] [WRITE_ADDR] [WRITE_LEN] [A * 4] [shellcode40bytes] The above character series adds a total of 128 bytes, namely 0x80. After overflow, the function will do the following:
Wnsprintf (write_addr, write_len-1, 0x702f1be0, [eBP-0x104])
The string at 0x702F1Be0 is "clsSID =% s".
So WRITE_ADDR must be an address that can be written without containing 00, and it is necessary to comply with wide character encoding. otherwise
When WNSPRINTFA is called, the function cannot return, plus SEH we can't overwrite, so
The sequence process will not be controlled.
After the function returns, EBP = 0x41414141, EIP = 0x43434343, ESP points to Shellcode.
In this way, the second overflow is more troublesome than the first overflow:
1) To provide a writable address that does not have 0
2) SC can only have 40 bytes
In fact, the WNSPrintfa function is easy to bypass, give it a negative size of the size is OK ^ _ ^, and this
SIZE is we can control. However, only in IE6 SP1 and later versions, calling is WNSPrintfa,
The past version calls are WSPrintfa.
Use another method to construct W_Buff_1 to get a little bit of space to place shellcode:
[SC (x Bytes)] [/ (y bytes)] [EIP] [WRITE_ADDR] [WRITE_LEN] [A * 4] [JMP_BACK_TO_SC]
X and Y should meet the following relationships:
X Y 20 = 0x80 <- Ensure that BUFF will not be shorted
X Y * 4 = 0x104 4 <- It can trigger overflow after ensuring BUFF extension
==> x = 56 y = 52
The mountain is pendant? NO! Why do we not fully use the WSPrintfa function.
Second, use WSPrintfa. Construct the following buffers,
[sc (x bytes)] ["/" (y bytes)] [EIP] [Write_Addr]
Note: Both the buffer we constructed must ensure that they are not changed after twice.
X and Y should meet the following relationships:
(1) X Y * 4 = 0x104 4 <- It can trigger overflow after ensuring BUFF extension
(2) x y 8 = 0x80 <- Ensure that BUFF will not be shorted
It is very simple to calculate, x = 72, y = 48.
Looking for an address that is not 0, the address that can be written is used as Write_Addr. After the WSPRINTFA call is completed,
Write_addr 7 points to SC. So you can directly put WRITE_ADDR 7 as EIP.
The SC can have 72 bytes, and the shellcode used to write the true function in the search memory is sufficient. First
Take over, then search from 0x1000 to the memory, 100% can be searched ^ _ ^.
So use the second overflow, writing a general-purpose EXP for a language platform is fully implemented.
How is the patch repair the above vulnerability? Take Urlmon.dll 6.0.2800.1226 as an Example:
URLMON! GetClassmime:
1A41CA51 55 PUSH EBP
1A41CA52 8D6C2494 LEA EBP, [ESP-0x6C]
1A41CA56 81ECA4030000 SUB ESP, 0x3A4 ......
1A41CA7F 689B000000 PUSH 0x9B // <- Length Limit
1A41CA84 688CA7451A PUSH 0X1A45A78C / / "MIME / DATABASE / Content Type /"
1A41CA89 8D45C8 Lea Eax, [EBP-0x38]
1A41CA8C 50 Push EAX
1A41CA8D FF15E411401A Call DWORD PTR [URLMON! _IMP__LSTRCPYNA (1A4011E4)]
1A41CA93 8D45C8 Lea Eax, [EBP-0x38]
1A41CA96 50 Push EAX
1A41CA97 FF15D411401A CALL DWORD PTR [URLMON! _IMP__LSTRLENA (1A4011D4)]
1A41CA9D B99A000000 MOV ECX, 0x9A
1A41CAA2 2BC8 SUB ECX, EAX // <- Length Limit
1A41CAA4 51 PUSH ECX
1A41CAA5 57 Push EDI
1A41CAA6 8D45C8 LEA EAX, [EBP-0x38]
1A41CAA9 50 Push EAX
1A41CAAA FF157813401A CALL DWORD PTR [URLMON! _IMP__STRNCATA (1A401378)]]
Urlmon! ComposehackClsidFrommime:
1A441D62 55 PUSH EBP
1A441D63 8BEC MOV EBP, ESP
1A441D65 81EC04010000 SUB ESP, 0x104
1A441D6B 8B5510 MOV EDX, [EBP 0x10]
1A441D6E 56 PUSH ESI
1A441D6F 8D85FCFeffff Lea Eax, [EBP-0X104]
1A441D75 33F6 XOR ESI, ESI
1A441D77 8A0A MOV CL, [EDX]
1A441D79 84C9 TEST CL, Cl
1A441D7B 8808 MOV [EAX], CL
1A441D7D 742A JZ URLMON! ComposehackClsidFrommime 0x47 (1A441DA9)
1A441D7F 80F92F CMP CL, 0x2F
1A441D82 751A JNZ URLMON! ComposehackClsidFrommime 0x3c (1A441D9E)
1A441D84 81FE00010000 CMP ESI, 0x100 // <- Length Check
1A441D8A 7D1D JGE URLMON! ComposehackClsidFrommime 0x47 (1A441DA9)
1A441D8C C6005F MOV BYTE PTR [EAX], 0x5F
1A441D8F 40 Inc EAX
1A441D90 C60032 MOV BYTE PTR [EAX], 0x32
1A441D93 40 INC EAX
1A441D94 C60046 MOV BYTE PTR [EAX], 0x46
1A441D97 40 Inc EAX
1A441D98 C6005F MOV BYTE PTR [EAX], 0x5F
1A441D9B 83C603 Add ESI, 0x3
1A441D9E 46 Inc ESI // Length
1A441D9F 42 Inc EDX // SRC Buffer AddR
1A441DA0 40 INC EAX // DEST BUFFER ADDR
1A441DA1 81FE03010000 CMP ESI, 0x103 // <- Length Check
1A441DA7 7CCE JL URLMON! COMPOSEHACKCLSIDFROMMIME 0x15 (1A441D77)
1A441DA9 802000 and byte PTR [EAX], 0x0
1A441DAC 8D85FCFeffff Lea Eax, [EBP-0x104]
1A441DB2 50 PUSH EAX
1A441DB3 8B450C MOV EAX, [EBP 0xC]
1A441DB6 68D01D441A PUSH 0X1A441DD0
1A441DBB 48 DEC EAX
1A441DBC 50 Push EAX
1A441DBD FF7508 PUSH DWORD PTR [EBP 0x8]
1A441DC0 FF15FC13401A Call DWORD PTR [URLMON! _IMP__WNSPRINTFA (1A4013FC)]
1A441DC6 83C410 Add ESP, 0x10
1A441DC9 33C0 XOR EAX, EAX
1A441DCB 5E POP ESI
1A441DCC C9 Leave
1A441DCD C20C00 RET 0XC
Reference:
<> Internet Explorer Object Type Property Overflow research
http://www.xfocus.net/articles/200306/551.html