|
|
|
|
| |
| "Realtek devotes itself to offering a comprehensive range of ICs of exceptional value for the communications network, computer peripheral, and multimedia markets. By its continued commitment to innovation, quality, and service, Realtek has successfully built trust with its customers." Realtek HD Audio Codec Drivers are prone to a local privilege escalation due to insufficient validation of user-mode buffers. Successful exploitation grants SYSTEM privileges to authenticated users, no special privileges are required to exploit the flaw. |
| |
Credit:
The information has been provided by Ruben Santamarta.
The original article can be found at: http://www.wintercore.com/advisories/advisory_W010408.html
|
| |
Vulnerable Systems:
* RTKVHDA.sys version prior to 6.0.1.5605 (32-bit) running on Windows Vista
* RTKVHDA64.sys (signed) version prior to 6.0.1.5605 (64-bit) running on Windows Vista
According to Realtek, the vulnerable code was originally intended to be used at the development stage although, by error, the release version was shipped still containing it.
These internal routines allow to user-mode applications to create, read or write arbitrary registry keys by issuing a specially crafted IOCTL request.
Module: RTKVHDA.sys (32-bit) Writing Arbitrary Key
PAGE:001AAA88 mov esi, [ebp+Handle] ; user-controlled
PAGE:001AAA8B mov eax, [esi+10h]
PAGE:001AAA8E add eax, [esi+8]
PAGE:001AAA91 mov ecx, [esi+1Ch]
PAGE:001AAA94 mov ebx, [esi+4]
PAGE:001AAA97 lea eax, [eax+ecx+20h]
PAGE:001AAA9B add ebx, esi
PAGE:001AAA9D cmp [esi], eax
PAGE:001AAA9F jnb short loc_1AAAA8
PAGE:001AAAA1 mov eax, 0C0000023h
PAGE:001AAAA6 jmp short loc_1AAB22
PAGE:001AAAA8 ; ---------------
PAGE:001AAAA8
PAGE:001AAAA8 loc_1AAAA8: ; CODE XREF: sub_1AAA7E+21j
PAGE:001AAAA8 mov eax, [esi+0Ch]
PAGE:001AAAAB push edi
PAGE:001AAAAC mov edi, ds:RtlInitUnicodeString
PAGE:001AAAB2 add eax, esi
PAGE:001AAAB4 push eax ; SourceString
PAGE:001AAAB5 lea eax, [ebp+ValueName]
PAGE:001AAAB8 push eax ; DestinationString
PAGE:001AAAB9 call edi ; RtlInitUnicodeString
PAGE:001AAABB push ebx ; SourceString
PAGE:001AAABC lea eax, [ebp+var_8]
PAGE:001AAABF push eax ; DestinationString
PAGE:001AAAC0 call edi ; RtlInitUnicodeString
PAGE:001AAAC2 lea eax, [ebp+var_8]
PAGE:001AAAC5 mov [ebp+ObjectAttributes.ObjectName], eax
PAGE:001AAAC8 lea eax, [ebp+ObjectAttributes]
PAGE:001AAACB push eax ; ObjectAttributes
[...]
PAGE:001AAAEE call ds:ZwOpenKey
PAGE:001AAAF4 mov ebx, eax
PAGE:001AAAF6 cmp ebx, edi
PAGE:001AAAF8 jl short loc_1AAB1F
PAGE:001AAAFA push dword ptr [esi+1Ch] ; DataSize
PAGE:001AAAFD mov eax, [esi+18h]
PAGE:001AAB00 add eax, esi
PAGE:001AAB02 push eax ; Data
PAGE:001AAB03 push dword ptr [esi+14h] ; Type
PAGE:001AAB06 lea eax, [ebp+ValueName]
PAGE:001AAB09 push edi ; TitleIndex
PAGE:001AAB0A push eax ; ValueName
PAGE:001AAB0B push [ebp+Handle] ; KeyHandle
PAGE:001AAB0E call ds:ZwSetValueKey
In addition to these privileged routines, there is a flaw that lies in how the user-mode buffers are validated. In the code above, certain arithmetic calculations are performed without checking for integer overflows. These values are controlled by the user so it could lead to an arbitrary memory overwrite as we can see in the following piece of code, note the memory is overwritten with controlled values.
Module: RTKVHDA.sys (32-bit) Reading Arbitrary Key into controlled buffer
PAGE:001AABD1 lea eax, [ebp+ValueName]
PAGE:001AABD4 push edi ; KeyValueInformation
PAGE:001AABD5 push 2 ; KeyValueInformationClass
PAGE:001AABD7 push eax ; ValueName
PAGE:001AABD8 push [ebp+Handle] ; KeyHandle
PAGE:001AABDB call ds:ZwQueryValueKey
PAGE:001AABE1 cmp eax, ebx
PAGE:001AABE3 mov [ebp+arg_0], eax
PAGE:001AABE6 jl short loc_1AAC09
PAGE:001AABE8 mov eax, [edi+4]
PAGE:001AABEB mov [esi+14h], eax
PAGE:001AABEE mov eax, [edi+8]
PAGE:001AABF1 mov [esi+1Ch], eax
PAGE:001AABF4 push dword ptr [edi+8] ; size_t
PAGE:001AABF7 lea eax, [edi+0Ch]
PAGE:001AABFA push eax ; void *
PAGE:001AABFB mov eax, [esi+18h] ;(integer overflow is possible)
PAGE:001AABFE add eax, esi ; base + offset
PAGE:001AAC00 push eax ; user-controlled
PAGE:001AAC01 call memcpy
Exploit:
We can choose between a couple of attack vectors, either to create an arbitrary registry key (trival) or to take advantage of the arbitrary memory overwrite to divert to flow towards a ring0 shellcode. Initially, the problem with the arbitrary memory overwrite (by triggering an integer overflow) approach, is that the IOCTL is METHOD_BUFFERED so we are missing an important term in the equation (base) to control the first address where the memory will be overwritten since we cannot accurately predict the pool associated with our buffer (Mdl->MappedSystemVa). Fortunately, the driver fails checking for NULL MDLs, thus allowing us to solve this issue. NULL buffers are valid in METHOD_BUFFERED IRPs, so we can emulate a fake MDL by allocating user-mode memory at 0x0, thus controlling the pointer that will be returned by MmGetSystemAddressForMdlSafe
Module: RTKVHDA.sys (32-bit)
PAGE:001AAC94 loc_1AAC94: ; CODE XREF: sub_1AAC32+24j
PAGE:001AAC94 mov eax, [esi+4]
PAGE:001AAC97 test byte ptr [eax+6], 5 ; IoManager s MDL NULL
PAGE:001AAC9B jz short loc_1AACA2
PAGE:001AAC9D mov eax, [eax+0Ch] ; FakeMdl->MappedSystemVa => controlled
Now, we have completed the last piece of the puzzle that allows us to calculate accurately the offset needed to overwrite the kernel address we desire.
For example, a simple exploit would be:
1. Create an arbitrary key that holds the address of our ring0 shellcode
2. Read that value into the desired kernel address by using the "integer overflow" trick.
|
|
|
|
|
|
|
|
|
|