Monthly Archives: March 2012

MS12-020 Vulnerabilities in Remote Desktop Could Allow Remote Code Execution

MS12-020 Vulnerabilities in Remote Desktop Could Allow Remote Code Execution

Update(03/19/2012) : Now I understand why MS said “we are not expecting to see the exploit in a few days”. To be honest, I don’t really understand how this vulnerability is working @.@. The actual bug trigger (known by leaked PoC) is in the last two pictures (rdpwd!nm_Disconnect), and you can trigger this routine by making this function fail in the middle after executing “or [esi+1c], 1”. Please see my comments below how to trigger this.

Update(03/16/2012) : Crash PoCs are available now by cool guys from freenode co-work. Here’s big fun. These codes were written based on the wild-PoC, but that wild-PoC seems to be the one originally reported to ZDI (!/luigi_auriemma). Do you see what this means ? 🙂 (python) (by jduck, ruby)

Update : more diffing points. Well… you’re right. I’m still guessing.

NOTE : I haven’t confirmed this vulnerability yet, so basically this is my rough guess on this vulnerability. MS12-020 touched many different files and I don’t think I’ll take a look all of them. Hope we get helpful feed-backs on this issue from you. There’s also other analysis on MS12-020 –

Related CVE : Remote Desktop Protocol Vulnerability – CVE-2012-0002
Terminal Server Denial of Service Vulnerability – CVE-2012-0152
(This post would be about CVE-2012-0002, but need to be confirmed)

Diffed Binary : rdpcore.dll 6.1.7601.17514 (win7sp1_rtm.101119-1850)
rdpcore.dll 6.1.7601.17779 (win7sp1_gdr.120216-1503)

Look at CRDPWDUMXStack:OnMcsCPI(). This function decodes and saves the user data from the GCCUserData structure. When you make the first branch condition fail, you can directly call RDPWDUMXGccFreeUserData() function, which is a simple wrapper function of delete(). It is clear that [ebp+var_10] is uninitialized before the patch. How it is patched ? Just look at where a series of “stosd” instructions are.)

rdpwd!HandleAttachUserReq(). This one is easy to trigger and looks very interesting, but it could be just a memory leak patch.

rdpwd!MCSChannelJoinRequest(). There was some problems in handling channel id. Note that each channel seems to have a corresponding entry in the link list.

tdtcp.sys!DeviceCancelIo(). See different function call has been made, TdiDisconnect() and TdLocalDisconnect(). TdLocalDisconnect() is actually a wrapper function of TdiDisconnect() while doing DEREF like job. Do you remember MS11-083 ? MS11-083’s vulnerability and patch was pretty similar to this.

rdpwd!nm_Disconnect(). After invoking the destructing function, it clears LSB-bit of the variable. See? Before actually invoking the destructing function, this LSB-bit variable is checked. Yeah, it should be double free (or use-after-free).

rdpwd!NMAbortConnect() has a similar pattern patch. Note that these two routines are closely linked together. That is, if you can hit NMAbortConnect(), it is highly likely that you can also hit nm_Disconnect(). In other words, if you can invoke these two routines, at least you will see crash.