The purpose of this document is to present a technical report of the CVE-2013-5065 vulnerability. A few days ago, FireEye identified a 0 day kernel exploit embedded within a PDF document actively used in the wild. The vulnerability itself is present in the NDProxy kernel driver. Whilst this is present in all versions of Windows, the vulnerability itself is only present in Windows 2003 and XP. The NDProxy driver is responsible for interfacing NDISWAN and CoNDIS WAN drivers to the TAPI services.
Binary Information
OS: | Windows XP SP3 |
Name: | ndproxy.sys |
Base address: | 0xF874A000 |
File version: | 5.1.2600.6048 |
Default path: | C:\Windows\System32\drivers\ndproxy.sys |
Vulnerability
The vulnerability itself is present in the PxIODispatch() function that is reachable from a simple IO Control.
DeviceIoControl(hDev, 0x8fff23cc, buffer, sizeof(buffer), buffer, sizeof(buffer), &dwRet, 0);
The function works as follows:
- Reads an index value using the IO control message.
- Calls a function from a function array using the received index.
.text:F874CE92 PxIODispatch .text:F874CE92 .text:F874CE92 var_8 = dword ptr -8 .text:F874CE92 var_4 = dword ptr -4 .text:F874CE92 arg_0 = dword ptr 8 .text:F874CE92 LockState = _LOCK_STATE ptr 0Ch .text:F874CE92 .text:F874CE92 mov edi, edi .text:F874CE94 push ebp .text:F874CE95 mov ebp, esp .text:F874CE97 push ecx .text:F874CE98 push ecx .text:F874CE99 and [ebp+var_4], 0 .text:F874CE9D push ebx .text:F874CE9E mov ebx, dword ptr [ebp+LockState.LockState] .text:F874CEA1 mov eax, [ebx+60h] .text:F874CEA4 cmp byte ptr [eax], 0Eh .text:F874CEA7 mov ecx, [eax+8] .text:F874CEAA push esi .text:F874CEAB mov esi, [ebx+0Ch] // Data sent from the IO control. .text:F874CEAE mov dword ptr [ebp+LockState.LockState], ecx .text:F874CEB1 mov ecx, [eax+4] ... .text:F874CEEE cmp eax, 8FFF23C8h // Checking the IO Control code. .text:F874CEF3 jz loc_F874D07C .text:F874CEF9 cmp eax, 8FFF23CCh // two possibilities. .text:F874CEFE jz loc_F874D07C ... .text:F874D07C loc_F874D07C: .text:F874D07C mov edi, dword ptr [ebp+LockState.LockState] // EDI = 0x54. .text:F874D07F push 24h .text:F874D081 pop edx ... .text:F874D092 mov eax, [esi+14h] // Data sent from the IO control at 0x14. .text:F874D095 sub eax, 7030101h // Compute an index using the given value. .text:F874D09A cmp eax, edx .text:F874D09C mov [ebp+var_4], edx .text:F874D09F jbe short loc_F874D0AD // It must be between 0 and 0x24 included! ... .text:F874D0AD loc_F874D0AD: .text:F874D0AD mov ecx, [esi+1Ch] // Data sent from the IO control at 0x1c. .text:F874D0B0 lea eax, [eax+eax*2] .text:F874D0B3 shl eax, 2 // Index * 12. .text:F874D0B6 cmp ecx, dword_F8752184[eax] .text:F874D0BC mov dword ptr [ebp+LockState.LockState], eax // Save the index. .text:F874D0BF jnb short loc_F874D0CD ; 0x54 - 0x20 ... .text:F874D0CD loc_F874D0CD: .text:F874D0CD add edi, 0FFFFFFE0h // 0x54 - 0x20. .text:F874D0D0 cmp ecx, edi // The value at 0x1c must be lower than 0x34. .text:F874D0D2 ja short loc_F874D0C1 ... .text:F874D11B loc_F874D11B: .text:F874D11B mov eax, dword_F87528B4 .text:F874D120 mov [esi+0Ch], eax .text:F874D123 mov [esi+8], ebx .text:F874D126 mov dl, byte_F87528C0 .text:F874D12C mov ecx, edi .text:F874D12E call ds:__imp_@KfReleaseSpinLock@8 .text:F874D134 mov eax, [ebx+60h] .text:F874D137 or byte ptr [eax+3], 1 .text:F874D13B mov eax, dword ptr [ebp+LockState.LockState] // Saved index. .text:F874D13E push esi .text:F874D13F call off_F8752188[eax] // Call the function at index.
The function table can be seen from the memory, from the first entry to the last one.
kd> .for (r $t0=0; @$t0<=0x24; r $t0=@$t0+1) { dd f8752188+($t0*0xc) L3 } f8752188 f874d38a 07030102 00000010 f8752194 f874e4ce 07030103 00000008 f87521a0 f874f994 07030104 00000008 f87521ac f874e824 07030105 000000c0 f87521b8 f874d398 07030106 0000001c f87521c4 f874d398 07030107 00000018 f87521d0 f874d398 07030108 00000010 f87521dc f874d38a 07030109 00000010 f87521e8 f874e89c 0703010a 000000f4 f87521f4 f874fac6 0703010b 00000018 f8752200 f874fcae 0703010c 0000004c f875220c f874d38a 0703010d 0000000c f8752218 f874e944 0703010e 00000160 f8752224 f874e9b2 0703010f 0000002c f8752230 f874eca6 07030110 00000130 f875223c f874f5c4 07030111 00000028 f8752248 f874d38a 07030112 00000018 f8752254 f874d38a 07030113 00000034 f8752260 f874e58e 07030114 00000054 f875226c f874fd12 07030115 000000d0 f8752278 f874f240 07030116 00000014 f8752284 f874d370 07030117 00000024 f8752290 f874ff3a 07030118 00000010 f875229c f874d398 07030119 00000004 f87522a8 f874d398 0703011a 00000008 f87522b4 f874d38a 0703011b 0000000c f87522c0 f874d398 0703011c 00000010 f87522cc f874d38a 0703011d 0000000c f87522d8 f874ed7c 0703011e 00000028 f87522e4 f874d38a 0703011f 0000000c f87522f0 f874fd8c 07030120 00000018 f87522fc f874d38a 07030121 0000000c f8752308 f874edea 07030122 00000010 f8752314 f874d38a 07030123 00000034 f8752320 f874ee78 07030124 00000008 f875232c f874f05e 00000030 00000034 f8752338 00000038 0000003c 00000040
The last function in the array (index 0×24) points to address 0×00000038. Indeed, if the index submitted through the IO Control is 0×24, this address is called.
Access violation - code c0000005 (!!! second chance !!!) eax=000001b0 ebx=82263a78 ecx=00000000 edx=00000000 esi=81ffa720 edi=f87528bc eip=00000038 esp=b2419c18 ebp=b2419c34 iopl=0 nv up ei pl nz na po nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202 00000038 ?? ???
Exploitation
This vulnerability is present in Windows XP and Windows 2003. Based on tests, both versions can be leveraged into code execution.
Exploitation of this vulnerability is trivial since it is possible to map address 0×00000001 on those operating systems. Therefore the attacker just needs to insert his kernel shellcode at address 0×00000038 to get it executed. Writing a full exploit for those operating systems is left as an exercise to the reader.
Conclusion
This vulnerability has been seen to be actively used in the wild. As seen in the present blog post, exploitation of this vulnerability is easy and public exploits have already been published. It is recommended to disable NDProxy by running the following commands and rebooting the system while Microsoft issues a fix.
> sc stop ndproxy > reg add HKLM\System\CurrentControlSet\Services\ndproxy /v ImagePath /t REG_EXPAND_SZ /d system32\drivers\null.sys /f
Disabling NDProxy however can cause side effects including issues in Remote Access Service (RAS), dial-up networking and the interruption of virtual private networking (VPN).
References
- Microsoft’s advisory: http://technet.microsoft.com/en-us/security/advisory/2914486
- FireEye blog post: http://www.fireeye.com/blog/technical/cyber-exploits/2013/11/ms-windows-local-privilege-escalation-zero-day-in-the-wild.html
Editor’s note: We’ve corrected a slight ambiguity around which versions of Windows are affected, the initial post did not clearly differentiate between versions of Windows that had NDProxy and those that are actually vulnerable.