[Practice] Let's Talk About the IE Object Type property Overflow Vulnerability.

Source: Internet
Author: User
Tags truncated
Internet Explorer Object Type property Overflow Vulnerability

Created:
Article attributes: original
Article submission: eyas (eyas_at_xfocus.org)

Internet Explorer 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 for his research experience on this vulnerability released some time ago. His article has benefited me a lot.

My test environment is
Windows 2000 Server English version + SP4 (the default codePage is GB)
IE 6.0 English version + SP1
Urlmon. dll 6.0.2800.1106

Assume that the HTML page contains the following characters:
<Object type = "aaaa"> XXXX </Object>

The IE processing process is as follows:
1. the string "aaaa" (later called m_buff_1) is converted
Unicode (u_buff_1 ).
2. u_buff_1 is truncated to 0x100 bytes (the truncated string is called u_buff_2 ).
3. u_buff_2 serves as the urlmon function! Cogetclassobjectfromurl's 5th parameters for further processing.
4. Use the widechartomultibyte function to convert u_buff_2 to a multibyte format (w_buff_2 ).
5. w_buff_2 serves as the urlmon function! The getclassmime 1st parameters are further processed.
6. w_buff_2 serves as the urlmon function! Composehackclsidfrommime parameters for further processing.

The process function call relationship is as follows:

Urlmon! Cogetclassobjectfromurl
| _ Urlmon! Asyncgetclassbitsex
| _ Urlmon! Asyncgetclassbits2ex
| _ Urlmon! Getclsidfromtormime
| _ Widechartomultibyte
| _ Urlmon! Getclassmime (overflow)
| _ Urlmon! Ccodedownload: docodedownload
| _ Urlmon! Ccodedownload: getnextoninternetsearchpath
| _ Urlmon! Composehackclsidfrommime (overflow)

M_buff_1 after careful construction, the stack can be created in steps 1 and 2 of the above processes respectively.
Overflow. The existing analysis data on the Internet seems to have only noticed the overflow in step 1. Maybe it is my ignorance.

OK! Let's take a look at the first one.

Urlmon! Getclassmime:
702cc586 55 push EBP
702cc587 8d6c2494 Lea EBP, [esp-0x6c]
702cc58b 81eca4030000 sub ESP, 0x3a4
// [EBP + 0x74] is the first parameter, which is called w_buff_2.
702cc591 8b4574 mov eax, [EBP + 0x74]
....

// Copy the "mime/database/content type/" at 0x7030a754 to the [ebp-0x38]
702cc5b4 8a9154a73070 mov DL, [ECx + 0x7030a754]
702cc5ba 88540dc8 mov [EBP + ecx-0x38], DL
702cc5be 41 Inc ECx
702cc5bf 84d2 test DL, DL
702cc5c1 75f1 jnz urlmon! Getclassmime + 0x2e (702cc5b4)

// The w_buff_2 address is stored in EDX.
702cc5c3 8bd0 mov edX, eax

// Locate the 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 the Dest Buffer
702cc5cc 8d7dc8 Lea EDI, [ebp-0x38] // DEST Buffer
702cc5cf 2bc2 sub eax, EDX // calculate the length of w_buff_2
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)

// Copy w_buff_2 to the stack, overflow!
702cc5da 8bc8 mov ECx, eax
702cc5dc c1e902 SHR ECx, 0x2 // w_buff_2 length except 4
702cc5df 8bf2 mov ESI, EDX // source Buffer
702cc5e1 f3a5 rep movsd

// Copy the remaining content of w_buff_2 to the stack after 4
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 assembly code above, we can see that the total buffer length of the stack is 0x38 + 0x6c = 0xa4.

To restore the code to C, it should be similar to the following:

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 the w_buff_2 we provide must be greater than or equal to 0x89,
IE overflow is allowed to control the program flow. The length after converting 0x100 bytes of u_buff_2 into multi-byte w_buff_2
It must be greater than or equal to 0x80 and less than or equal to x100. The length depends on the buff you constructed and the codePage of the system.

When the default codePage is GB, The w_buff_1 structure is as follows:

[Ha * 68] [a] [AAAA] [BBBB] [ccccddddeeee] [FFFF]

68 why? 68*2 + 1 = 137, that is, 0x89.

After ie overflows, EBP = 0x41414141, EIP = 0x42424242, and ESP points to the starting point of "ffff. Overflow
Seh is far away from the stack buffer and cannot be overwritten. After the overflow function ret, only ESP points to our
Buffer, so we can only use the jmp esp method for control. Jmp esp address is difficult to find common,
So exp is less universal.

We can construct w_buff_1 as follows:
[SC (0x89 + 4 bytes)] [JMP esp] [NOP * 0xc] [jmp_back_to_ SC]

The following conditions must be met:
1) w_buff_1 will not be changed after two conversions.
2) Ensure that the length is less than or equal to 0x100 after w_buff_1 is converted to Unicode.

SC can have a maximum of 0x89 + 4 = 0x8d, that is, 141 bytes. What can we do in 141 bytes? SC for writing complex functions
It may not be enough, but it is enough to search for the shellcode that actually functions in the memory.

In addition, after overflow occurs, several bytes in SC will be changed before the RET function.

From the above analysis, we can see that the overflow exp depends on the jmp esp address and the system language platform.
If you have a better way to use it, please kindly advise ^_^.

Next, let's look at 2nd overflow areas.

The prototype of the composehackclsidfrommime function is similar:
Composehackclsidfrommime (char * poutbuf, int ioutbufsize, 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]
702f1b93888 dfcfeffff mov [ebp-0x104], Cl
702f1b99 741e JZ 702f1bb9
// Determine whether it is "/". If yes, it is extended to "_ 2f _" and then written to the stack buffer.
702f1b9b 80f92f CMP Cl, 0x2f
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
// If it is not "/", it is directly written to the stack buffer.
702f1bb 5 8808 mov [eax], Cl
702f1bb7 75e2 jnz 702f1b9b

// Write the extended buffer 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
702f1rjc20c00 RET 0xc

From the assembly code above, we can see that the stack buffer length is 0x104. From the previous analysis, we know that
The length of w_buff_2 must be within 0x89, otherwise it will be in urlmon! Getclassmime overflows, so it cannot.
Here. During the test, in some platforms, the length of w_buff_2 seems to have to be controlled within 0x80. Otherwise
Not here. Let's set the maximum length of w_buff_2 to 0x80.

There are two ways to exploit this overflow vulnerability.

First, jmp esp. Construct w_buff_1 as follows:

[/* 64] [BBBB] [AAAA] [CCCC] [write_addr] [write_len] [A * 4] [shellcode40bytes]

The preceding string is added with a total of 128 bytes, that is, 0x80. After overflow, the function performs the following operations:

Wnsprintf (write_addr, write_len-1, 0x702f1be0, [ebp-0x104])

The string at 0x702f1be0 is "clssid = % s ".

Therefore, write_addr must be an address that can be written without 00 and must conform to the wide character encoding. Otherwise
An exception occurs when wnsprintfa is called, and the function cannot be returned. We cannot overwrite the Seh, so the process
We will not be able to control the sequential process.

After the function returns, EBP = 0x41414141, EIP = 0x43434343, and ESP points to shellcode.

In this case, the second overflow is more difficult to use than the first one:
1) provide a writable address without 0.
2) SC can only contain 40 bytes

In fact, the wnsprintfa function is very easy to bypass. If you provide it with a negative size, it will be OK ^ _ ^, and this
We can control the size. However, wnsprintfa is called only in IE6 + SP1 and later versions,
Previous versions call wsprintfa.

You can use another method to construct w_buff_1 to get a little more space for storing shellcode:

[SC (x bytes)] [/(Y bytes)] [EIP] [write_addr] [write_len] [A * 4] [jmp_back_to_ SC]

X and Y must meet the following requirements:
X + Y + 20 = 0x80 <-ensure that the buff will not be truncated
X + Y * 4 = 0x104 + 4 <-used to ensure that overflow can be triggered after the buff Extension

==> X = 56 y = 52

? No! Why do we not make full use of the wsprintfa function.


Second, use wsprintfa. Construct the following buffer,

[SC (x bytes)] ["/" (Y bytes)] [EIP] [write_addr]

Note: The buffer we construct must ensure that it is not changed after two conversions.

X and Y must meet the following requirements:
(1) x + y * 4 = 0x104 + 4 <-used to ensure that overflow can be triggered after the buff Extension
(2) x + y + 8 = 0x80 <-ensure that the buff will not be truncated

It is easy to calculate, x = 72, y = 48.

Find a address not 0 that can be written as write_addr. After wsprintfa is called,
Write_addr + 7 points to SC. Therefore, write_addr + 7 can be directly used as an EIP.
SC can have a maximum of 72 bytes. It is sufficient to write the Shellcode For the real function in the search memory. Yes
Take over the exception, and then start from 0x1000 to search for memory height, 100% can search for ^_^.

Therefore, using 2nd overflows, writing a general exp for a language platform is completely achievable.

How does the patch fix 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

References:
<> Internet Explorer Object Type property Overflow
Http://www.xfocus.net/articles/200306/551.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.