Application: Microsoft Terminal Services / Remote Desktop Services
http://www.microsoft.com
http://msdn.microsoft.com/en-us/library/aa383015(v=vs.85).aspx
Versions: any Windows version before 13 Mar 2012
Platforms: Windows
Bug: use after free
Exploitation: remote, versus server
Date: 16 Mar 2012 (found 16 May 2011)
Author: Luigi Auriemma
e-mail: aluigi@autistici.org
web: aluigi.org
From vendor's homepage:
"The Microsoft Remote Desktop Protocol (RDP) provides remote display
and input capabilities over network connections for Windows-based
applications running on a server. RDP is designed to support different
types of network topologies and multiple LAN protocols."
The Remote Desktop Protocol is used by the "Terminal Services / Remote
Desktop Services" and works at kernel level on port 3389.
There is an use-after-free vulnerability located in the handling of the
maxChannelIds field of the T.125 ConnectMCSPDU packet (offset 0x2c of
the provided proof-of-concept) when set to a value minor/equal than 5.
The problem happens during the disconnection of the user started with
RDPWD!NM_Disconnect while the effect of the possible code execution is
visible in termdd!IcaBufferAlloc (or termdd!IcaBufferAllocEx on
Windows 7/2008) after termdd!IcaGetPreviousSdLink returns an invalid
memory pointer, the following dump is taken from Windows 2003 Server:
f761887c 8bff mov edi,edi
f761887e 55 push ebp
f761887f 8bec mov ebp,esp
f7618881 56 push esi
f7618882 57 push edi
f7618883 8b7d08 mov edi,dword ptr [ebp+8]
f7618886 8d47ec lea eax,[edi-14h]
f7618889 50 push eax
f761888a eb09 jmp termdd!IcaBufferAlloc+0x19 (f7618895)
f761888c 8b4618 mov eax,dword ptr [esi+18h] ; we are here
f761888f 833800 cmp dword ptr [eax],0 ; or here
f7618892 7527 jne termdd!IcaBufferAlloc+0x3f (f76188bb) ; must jump
f7618894 56 push esi
f7618895 e878290000 call termdd!IcaGetPreviousSdLink (f761b212) ; the new ESI is returned by this function
f761889a 8bf0 mov esi,eax
f761889c 85f6 test esi,esi
f761889e 75ec jne termdd!IcaBufferAlloc+0x10 (f761888c)
f76188a0 ff751c push dword ptr [ebp+1Ch]
f76188a3 ff7518 push dword ptr [ebp+18h]
f76188a6 ff7514 push dword ptr [ebp+14h]
f76188a9 ff7510 push dword ptr [ebp+10h]
f76188ac ff750c push dword ptr [ebp+0Ch]
f76188af 57 push edi
f76188b0 e8b9fcffff call termdd!IcaBufferAllocInternal (f761856e)
f76188b5 5f pop edi
f76188b6 5e pop esi
f76188b7 5d pop ebp
f76188b8 c21800 ret 18h
f76188bb 33c0 xor eax,eax
f76188bd 53 push ebx
f76188be 8d7e10 lea edi,[esi+10h]
f76188c1 40 inc eax
f76188c2 f00fc107 lock xadd dword ptr [edi],eax
f76188c6 ff751c push dword ptr [ebp+1Ch]
f76188c9 8b4618 mov eax,dword ptr [esi+18h] ; the same value of before
f76188cc ff7518 push dword ptr [ebp+18h]
f76188cf ff7514 push dword ptr [ebp+14h]
f76188d2 ff7510 push dword ptr [ebp+10h]
f76188d5 ff750c push dword ptr [ebp+0Ch]
f76188d8 ff761c push dword ptr [esi+1Ch]
f76188db ff10 call dword ptr [eax] ; code execution
f76188dd 8bd8 mov ebx,eax
f76188df 83c8ff or eax,0FFFFFFFFh
f76188e2 f00fc107 lock xadd dword ptr [edi],eax
f76188e6 7506 jne termdd!IcaBufferAlloc+0x72 (f76188ee)
f76188e8 56 push esi
f76188e9 e8382f0000 call termdd!_IcaUnloadSd (f761b826)
f76188ee 8bc3 mov eax,ebx
f76188f0 5b pop ebx
f76188f1 ebc2 jmp termdd!IcaBufferAlloc+0x39 (f76188b5)
eax=040b0402 ebx=e1492090 ecx=00390080 edx=00000003 esi=040b0402 edi=e1438240
eip=f762888c esp=b832f9d8 ebp=b832f9e0 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202
termdd!IcaBufferAlloc+0x10:
f762888c 8b4618 mov eax,dword ptr [esi+18h] ds:0023:040b041a=????????
On Windows 2003 that zone of the memory pointed by ESI+18 using the
provided proof-of-concept is ever in the range 040b02??-040b04??.
The exploitability depends by the possibility of controlling ESI or the
content pointed by it (maybe via a form of heap spraying?), indeed in
my quick tests this zone sometimes is allocated and others it isn't.
Note that on the post-Vista Windows versions (like 7 and 2008) "seems"
necessary to have "Allow connections from computers running any version
of Remote Desktop" for being vulnerable.
Anyway I'm not totally sure about this so-called limitation because it
looks like dependent by my proof-of-concept only.
The provided proof-of-concept uses the BER integer values set at 32bit
(big endian) in case they could be useful for easier debugging.
Additional details about the protocol:
http://msdn.microsoft.com/en-us/library/cc240836%28v=prot.10%29.aspx
resend it multiple times in case of no results and note that this is
just a simple proof-of-concept packet to quickly test the bug so it's
not optimized at all.