RDP Fingerprinting
Profiling RDP Clients with JA3 and RDFP
Network fingerprinting methods, such as JA3¹ for SSL/TLS and HASSH² for SSH, are excellent techniques for profiling attackers and their tools. I presented some of their use cases for analyzing internet-wide scans at the AusCERT and Honeynet Project conference earlier this year.
Remote Desktop Protocol (RDP) is another interesting protocol that is commonly used as an attack vector and lateral movement technique³. This blog post will explore RDP client fingerprinting and introduce RDFP, a profiling method for RDP clients in Standard Security mode.
Updates:
- In March 2020, Jeff Atkinson released a RDFP Zeek script based on my work and my initial implementation in fatt. The blog post: “Announcing RDFP for Zeek”.
- In May 2021, Corelight introduced RDP inferences and mentioned that they’ve incorporated the rdfp fingerprinting technique into their RDP inference package.
RDP is a proprietary Microsoft protocol based on the ITU T.120 series of protocols. You can find more in-depth details about RDP and its relationship to other protocols in Microsoft’s “Remote Desktop Protocol: Basic Connectivity and Graphics Remoting” document⁴.
RDP Connection Initiation
For the purpose of RDP client fingerprinting, we just focus on client messages. The first message in the RDP connection sequence is Client X.224 Connection Request. Two interesting fields in this packet are:
- cookie: an optional variable-length string terminated by 0x0D0A
- requestedProtocols: a 4-byte unsigned integer in the RDP Negotiation Request structure (optional) indicating the supported security protocols.
RDP has two security modes: Standard and Enhanced RDP Security. In Standard mode, requestedProtocols flag is set to 0x00000000 and RSA + RC4/3DES is used for encryption. This mode supports four levels of encryption: Low, Client Compatible, High, and FIPS Compliant.
Enhanced RDP Security uses one of the following External Security Protocols instead of implementing its own protocol security mechanisms: TLS 1.0, TLS 1.1, TLS 1.2, CredSSP, RDSTLS.
Profiling RDP Clients with JA3
JA3 is a fingerprinting method for SSL/TLS clients¹. This great blog post by John Althouse explores SSL/TLS fingerprinting and JA3 in detail.
When Enhanced RDP Security is used, traffic is sent over an encrypted TLS channel, so the RDP client can be fingerprinted using the TLS ClientHello message!
I generated JA3 hash of different version of RDP clients (Remote Desktop Connection — RDC) on different Windows versions. The result shows that JA3 is unique per RDP client. Here you can see a list of generated JA3 values for different RDP clients.
JA3 would probably be different for different Windows builds or service packs. If you have a packet capture of different RDC versions, please share it so I can update the list!
Introducing RDFP
RDFP is a profiling method for RDP clients in Standard Security mode. I first implemented this method in FATT⁵ — a pyshark based script for extracting network metadata and fingerprints from pcap files and live network traffic. The Bro/Zeek script is under development/test and will be released soon!
As mentioned earlier, Standard RDP Security uses its own encryption mechanism based on RSA and RC4/3DES. In the Basic Settings Exchange phase, client sends the MCS Connect Initial PDU containing GCC Conference Create Request⁴. This request contains some interesting data that can potentially be used for fingerprinting RDP clients. You can find an annotated dump of MCS Connect Initial PDU with GCC Conference Create Request here.
The current version of RDFP method uses Version, Cluster Flags, Encryption Methods, Ext Encryption Methods, and a list of requested Virtual Channels (channelDefArray) extracted from the clientSecurityData, clientClusterData, clientNetworkData and clientCoreData structures in the following order.
versionMajor,versionMinor,clusterFlags,encryptionMethods,extEncryptionMethods,channelDef
channelDef in the RDFP string is used in the following format:name1:option1-name2:option2-...-nameN:optionN
The string is then hashed with MD5 to produce the fingerprint (ie. RDFP).
You can use FATT script to test the technique on your PCAP files or the live network traffic: https://github.com/0x4D31/fatt
Here are some examples:
Windows 10, RDC 10.0.17134
String: "10,8,00000015,0000001b,00000000,rdpdr:80800000-rdpsnd:c0000000-cliprdr:c0a00000-drdynvc:c0800000"RDFP: b7ab0ffd49f5700c138a08e2cdd5a948
FreeRDP, macOS
String: "4,8,0000000d,00000013,00000000,"
RDFP: 2895083f4400ab6a9b8763d1d1c27381
rdpscan, CVE-2019–0708 bluekeep vuln scanner
String: "4,8,00000009,00000003,00000000,MS_T120:00008080"
RDFP: daeb0f3467798401324445d3721aa887
Morto malware
String: "4,8,00000009,00000003,00000000,rdpdr:80800000"
RDFP: a14873352a918e90634ac9d46352ace6
Observations
I’ve deployed a few honeypots for monitoring/profiling internet-wide scans since late 2017, and so far identified some interesting SSL/TLS activities like the ClientHello fields randomization to avoid TLS client fingerprinting! I will explore this in a separate blog post later. Here is a quick review of some RDP activities observed by my honeypots.
BlueKeep scans
The following connection is probably a scan for BlueKeep vulnerability (CVE-2019–0708) using the Metasploit auxiliary scanner!
RDFP raw string:4,8,09000000,03000000,00000000,cliprdr:c0a00000,MS_T120:80800000,rdpsnd:c0000000,snddbg:c0000000,rdpdr:80800000
RDFP: 3ba3d115055e593e3550575a36e68153
{
"timestamp":"2019-06-19T16:18:02.523215",
"sourceIp":"185.246.XXX.XX",
"destinationIp":"192.168.33.10",
"sourcePort":"55200",
"destinationPort":"3389",
"protocol":"rdp",
"rdp":{
"cookie":"mstshash=wmUTj",
"requestedProtocols":"0x00000000",
"rdfp":"3ba3d115055e593e3550575a36e68153", "rdfpAlgorithms":"4,8,09000000,03000000,00000000,cliprdr:c0a00000-MS_T120:80800000-rdpsnd:c0000000-snddbg:c0000000-rdpdr:80800000",
"rdfpVersion":"0.3",
"verMajor":"4",
"verMinor":"8",
"desktopWidth":"800",
"desktopHeight":"600",
"colorDepth":"0x0000ca01",
"sasSequence":"43523",
"keyboardLayout":"1033",
"clientBuild":"2600",
"clientName":"x1810",
"keyboardSubtype":"0",
"keyboardType":"4",
"keyboardFuncKey":"12",
"postbeta2ColorDepth":"0x0000ca01",
"clientProductId":"1",
"serialNumber":"0",
"highColorDepth":"0x00000018",
"supportedColorDepths":"0x00000007",
"earlyCapabilityFlags":"1",
"clientDigProductId":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"connectionType":"0",
"pad1Octet":"00",
"clusterFlags":"09000000",
"encryptionMethods":"03000000",
"extEncMethods":"00000000",
"channelDefArray":{
"0":{
"name":"cliprdr",
"options":"c0a00000"
},
"1":{
"name":"MS_T120",
"options":"80800000"
},
"2":{
"name":"rdpsnd",
"options":"c0000000"
},
"3":{
"name":"snddbg",
"options":"c0000000"
},
"4":{
"name":"rdpdr",
"options":"80800000"
}
}
}
}
References
[1] John B. Althouse, Jeff Atkinson and Josh Atkins, “JA3 — a method for profiling SSL/TLS clients”
[2] Ben Reardon and Adel Karimi, “HASSH — a profiling method for SSH clients and servers”
[3] MITRE ATT&CK, “Remote Desktop Protocol — T1076” and “Exploitation of Remote Services — T1210”
[4] Microsoft corporation, “Remote Desktop Protocol: Basic Connectivity and Graphics Remoting”, March 2019.
[5] Adel Karimi, “Fingerprint All the Things!”
Further Reading
- “What Happens Before Hello?” by Matt Bromiley and Aaron Soto
- “How to Use Corelight and Zeek Logs to Mitigate RDS/RDP Vulnerabilities” by Richard Bejtlich
- “Remote Desktop Protocol”, Wikipedia
- “TLS Fingerprinting with JA3 and JA3S” by John Althouse