This post describes how network eavesdroppers might record encrypted RDP sessions and at some later time (after a server compromise) be able to decrypt them. This could expose any data sent over the RDP connection including keystrokes, usernames and passwords.
Put in more technical language: This post is about Perfect Forward Secrecy, how SSL connections often lack this desirable security property, that RDP uses SSL and therefore could also be vulnerable to retrospective decryption.
Recording encrypted RDP connections with Wireshark
I simply started recorded all traffic on my ethernet interface, then connected to an RDP server using mstsc and entered a password. I stopped the capture straight after entering a password.
How to tell if your RDP session is vulnerable
If you first “Analyze | Follow TCP Stream” for the TCP port 3389 traffic, then “Analyze | Decode As… | SSL”, Wireshark will show you the SSL Server Hello message. Check if it’s an RSA-based cipher suite. If it is, this post applies to your RDP session and will show you how to decrypt it.
Note that I’ve only tried this for plain SSL-based RDP connection – as opposed to CredSSP (SSL+NLA) connections, so YMMV.
On with the decryption…
Extracting private SSL keys for service certificates
Following a compromise of a server, an attacker with administrator level privileges could simply extract the private keys used for server authentication from the certificate store.
The geocerts site provides as good a walkthrough of how to do this as any other. The certificate used by the Terminal Server are in the “Personal” or “Remote Desktop” certificate store for the “Computer Account”. Simply use MMC’s “Certificates” plugin to export the private key for the SSL certificate. I exported in .pfx format, which requires you to set a password.
I’m using Windows 2003 Server for this demo. I’m aware that extracting the required certificates from later versions of Windows is harder. This is left as an exercise for the reader.
Converting from .pfc to .pem
In order to decrypt the SSL traffic we’ll use Wireshark which requires the private key to be in PEM format (.cer here). Simply convert using this OpenSSL one-liner:
$ openssl pkcs12 -in server-cert.pfx -out server-cert.cer -nodes
Decrypting traffic with Wireshark
Although Wireshark is slightly awkward to use for the decryption of SSL traffic, it worked first time for me using this tutorial.
I specified the RSA key list as:
It was then possible to see all the cleartext traffic in Wireshark. In the “Follow TCP Stream” dialogue, I selected hexdump and scrolled down quite a long way. I was looking for a lot of short messages that corresponded to the keystrokes of the password I entered.
Shown in red are the messages from the RDP client. We’ll inspect each of the 4-byte message starting “44 04 00″. These correspond to keys being pressed down – as opposed to “44 04 01″ which are keys being released.
The first message of interest is:
44 04 00 2a
Then (omitting a few that aren’t interesting):
44 04 00 19 44 04 01 2a 44 04 00 1e 44 04 00 1f 44 04 00 1f 44 04 00 11 44 04 00 18 44 04 00 13 44 04 00 20 44 04 00 02
In each case the last of the 4 bytes in the key scan code. If we look up each in turn we find:
44 04 00 2a is Left-Shift-Down 44 04 00 19 is P 44 04 01 2a is Left-Shift-Up 44 04 00 1e is A 44 04 00 1f is S 44 04 00 1f is S 44 04 00 11 is W 44 04 00 18 is O 44 04 00 13 is R 44 04 00 20 is D 44 04 00 02 is 1
Making the password `Password1′ when we take account of the position of the SHIFT key.
The ability for an attacker to retrospectively decrypt SSL traffic can be undesirable in some (fairly unlikely) circumstances. This is not an unusual or isolated example. A great many HTTPS websites are prone to the same issue.
This is not a vulnerability in the traditional sense. It rather raises the impact any vulnerability that allows an attacker to steal the private SSL key – at which point all security claims are naturally null and void anyway.
Actually, it’s interesting to review the lack of perfect forward secrecy against Microsoft’s definition of a security vulnerability. It does not seem to fit the definition. If lack of forward secrecy does indeed present a problem, the problem results ”from adhering to imperfect but widely accepted standards”.
Disabling support for RSA as the Key Exchange Algorithm is the usual remedy for this SSL issue. However, I haven’t been able to find a working solution on Windows 2003. I did experiment with setting this registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\PKCS\Enabled = 0 (don't do this)
after reading KB245030. However, I only succeeded in preventing RDP connections entirely!