UPDATE APRIL 2018 – I just released a tool that automatically does the logon failure correlation discussed in the below blog post. Click here to read more about this tool and how to download it.
Today we’re going to tackle one of the most frustrating tasks of a Microsoft Remote Desktop Services administrator – tracking failed logons. Many administrators who have migrated their RDS collections from Windows Server 2008 to Windows Server 2012 are shocked to find that auditing RDS logons has changed considerably between the two operating systems.
Auditing Remote Desktop Services Logon Failures on Windows Server 2008 – RDP Security Layer or Bust
Windows Server 2008 can be configured to record detailed information about failed logon attempts with a Logon Type of 10, corresponding to a Terminal Server/Remote Desktop Services session. This is recorded as Event ID 4625 in the Security Event Log. Here’s an example of this event, taken from a system undergoing brute force attack attempts via RDP. You can see that the attacker has used a username of user2, the attack is originating from 118.x.x.x, the logon type is 10 (RDP), and the Logon Process used is User32.
Log Name: Security
Source: Microsoft-Windows-Security-Auditing
Date: 12/23/2016 4:25:40 PM
Event ID: 4625
Task Category: Logon
Level: Information
Keywords: Audit Failure
User: N/A
Computer: HONEYPOT
Description:
An account failed to log on.Subject:
Security ID: SYSTEM
Account Name: HONEYPOT$
Account Domain: WORKGROUP
Logon ID: 0x3e7Logon Type: 10
Account For Which Logon Failed:
Security ID: NULL SID
Account Name: user2
Account Domain: HONEYPOTFailure Information:
Failure Reason: Unknown user name or bad password.
Status: 0xc000006d
Sub Status: 0xc0000064Process Information:
Caller Process ID: 0x87c
Caller Process Name: C:\Windows\System32\winlogon.exeNetwork Information:
Workstation Name: HONEYPOT
Source Network Address: 118.x.x.x
Source Port: 4375Detailed Authentication Information:
Logon Process: User32
Authentication Package: Negotiate
Transited Services: –
Package Name (NTLM only): –
Key Length: 0
However, this level of detail in Event ID 4625 will ONLY be generated if you set the RDP Security Layer to RDP via Group Policy or via the properties of RDP-Tcp in the TSConfig.msc administrative console. If the Security Layer is set to any other level, all pertinent details of the logon failure will not be recorded, nor will you even be able to tell that the logon attempt came over RDP.
Let’s look at a similar event from a server without the Security Layer set to RDP. As you will see, it is completely useless. The only think you know is that the attacker tried to logon with a username of Administrator. Beyond that, you have no idea it came from RDP, as the Logon Type is set to 3 (generic network logon), and there is no Source Network Address recorded.
Log Name: Security
Source: Microsoft-Windows-Security-Auditing
Date: 12/23/2016 6:37:41 PM
Event ID: 4625
Task Category: Logon
Level: Information
Keywords: Audit Failure
User: N/A
Computer: HONEYPOT
Description:
An account failed to log on.Subject:
Security ID: NULL SID
Account Name: –
Account Domain: –
Logon ID: 0x0Logon Type: 3
Account For Which Logon Failed:
Security ID: NULL SID
Account Name: ADMINISTRATOR
Account Domain:Failure Information:
Failure Reason: Unknown user name or bad password.
Status: 0xc000006d
Sub Status: 0xc0000064Process Information:
Caller Process ID: 0x0
Caller Process Name: –Network Information:
Workstation Name:
Source Network Address: –
Source Port: –Detailed Authentication Information:
Logon Process: NtLmSsp
Authentication Package: NTLM
Transited Services: –
Package Name (NTLM only): –
Key Length: 0
OK, so the answer, if you have a Server 2008 RDS farm, is to configure GPOs to always use RDP as the Security Layer, right? Not so fast. Doing so has numerous implications, and the irony is that switching over to the RDP Security Layer actually weakens your security profile, as opposed to using a TLS/SSL Security Layer with Network Level Authentication. It makes your session hosts more vulnerable to denial-of-service attacks, AND it prevents providing SSO (Single Sign-on) in your environment. So, you can either use a weaker security layer, and actually be able to determine where RDP hack attempts are coming from, or use a more secure configuration with TLS/SSL and NLA, and have no clue who is attacking you. A fantastic choice, right?
Auditing Remote Desktop Services Logon Failures on Windows Server 2012 – More Gotchas, Plus Correlation is Key.
In Windows Server 2012, you can still enable RDP as a Security Layer if you want to see complete information in the Event ID 4625 Security Log events (see above). However, in Windows Server 2012, Network Level Authentication is enabled by default, which will prevent this level of detail from being recorded, even if the Security Layer is set to RDP. In order to make full auditing information available, you must set the Security Layer to RDP in the Group Policy Object, and you must also EXPLICITLY DISABLE Network Level Authentication in the same GPO area at the same time. And just like in Windows Server 2008, you weaken your security posture by doing so.
However, in Windows Server 2012, there is a workaround. You can still use TLS/SSL with NLA for authentication, AND figure out the source of the hack attempts by looking at a little known channel event log buried deep inside the Microsoft Event Viewer. That log is: RemoteDesktopServices-RDPCoreTS/Operational
In Windows Server 2012, if an attacker attempts to logon but fails to do so AND uses a username that DOES NOT EXIST on the targeted RDS host or domain that the host is a member of, Event ID 140 is logged, showing you the source IP of the attacker. For example:
Log Name: Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational
Source: Microsoft-Windows-RemoteDesktopServices-RdpCoreTS
Date: 1/2/2017 7:11:29 PM
Event ID: 140
Task Category: RemoteFX module
Level: Warning
Keywords:
User: NETWORK SERVICE
Computer: HONEYPOT
Description:
A connection from the client computer with an IP address of 172.x.x.x failed because the user name or password is not correct.
Note I said username that DOES NOT EXIST. If the attacker is using a username that DOES EXIST on the session host or the domain, Event ID 140 will NOT BE LOGGED. Personally, I think this is a poor implementation of auditing by Microsoft, and I’m not sure why Event ID 140 works that way. Ideally, Event ID 140 should be logged for ALL logon failures, not just logon failures with unknown usernames. After all, the event description itself for Event ID 140 says “failed because the user name OR password is not correct.”
Fortunately for us, the RemoteFX subsystem in Windows Server 2012 and Windows Server 2016 DOES log every RDP connection attempt and the source IP. So even if the attacker is using a username which exists on the target machine, you can still correlate the timestamps of Event ID 4625 (Network Type 3) in the Security Log with the timestamps of Event ID 131 in RemoteDesktopServices-RDPCoreTS/Operational channel event log. Event ID 131 looks like this:
Log Name: Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational
Source: Microsoft-Windows-RemoteDesktopServices-RdpCoreTS
Date: 1/2/2017 7:24:31 PM
Event ID: 131
Task Category: RemoteFX module
Level: Information
Keywords:
User: NETWORK SERVICE
Computer: HONEYPOT
Description:
The server accepted a new TCP connection from client 174.x.x.x:30022.
It has been my experience that Event ID 131 is logged a few seconds before the corresponding Event ID 4625 Logon Failure event in the Security Log. So, if you take the timestamp of an Event ID 4625 logon failure event (with Logon Type 3) in the Security Log, and there is a corresponding Event ID 131 and/or Event ID 140 event logged in the RdpCoreTS log a few seconds prior to the 4625 logon failure, chances are the logon failure is associated with the IP address referenced in the 131 and/or 140 events.
Auditing Remote Desktop Services Logon Failures on Windows Server 2016 – Return of the IP
Auditing Terminal Server logon failures in Windows Server 2016 works exactly the same way as in Windows Server 2012, with one important difference. Yes, Event IDs 131 and 140 are logged in the RemoteDesktopServices-RdpCoreTS log. Yes, Event ID 140 is only logged when the logon failure occurs with an unknown username. Yes, Event ID 4625 is logged in the Security Log with a generic Logon Type of 3 (Network), provided NLA is still enabled and the Security Layer has not been downgraded to RDP.
However, here’s the one big difference. In Windows 2016, the Security Log logon failure event (Event ID 4625) DOES log the IP address of the client/attacker. Mind you, it’s still shown as Logon Type 3, but now, you can directly correlate the IP address shown in Event ID 4625 with either Event ID 131 or Event ID 140 in the RdpCoreTS log to verify that this logon failure was in fact a failed Terminal Services logon.
Here’s an example of Event ID 4625 on Windows Server 2016 with the attacker IP address present (e.g. 5.x.x.x). As you can see, it is now being recorded correctly.
Log Name: Security
Source: Microsoft-Windows-Security-Auditing
Date: 1/4/2017 2:49:09 PM
Event ID: 4625
Task Category: Logon
Level: Information
Keywords: Audit Failure
User: N/A
Computer: HONEYPOT
Description:
An account failed to log on.Subject:
Security ID: NULL SID
Account Name: –
Account Domain: –
Logon ID: 0x0Logon Type: 3
Account For Which Logon Failed:
Security ID: NULL SID
Account Name: TESTING1
Account Domain:Failure Information:
Failure Reason: Unknown user name or bad password.
Status: 0xC000006D
Sub Status: 0xC0000064Process Information:
Caller Process ID: 0x0
Caller Process Name: –Network Information:
Workstation Name:
Source Network Address: 5.x.x.x
Source Port: 0Detailed Authentication Information:
Logon Process: NtLmSsp
Authentication Package: NTLM
Transited Services: –
Package Name (NTLM only): –
Key Length: 0
Auditing Remote Desktop Services Logon Failures – Conclusions
We’ve covered quite a bit of ground in this rather lengthy blog article. Here are the key takeaways:
1.) You can appropriately audit RDS logon failures on Windows Server 2008 RDS farms, but only if you choose RDP for the Security Layer, and disable NLA. This however has a host of nasty consequences, such as making your systems more vulnerable to denial of service attacks, and breaking single sign on.
2.) In Server 2012, you can track down and correlate generic network logon failure events (Event ID 4625 with Logon Type 3) in the Security Log to remote desktop logon attempts by using Event IDs 131 and 140 in the RdpCoreTS channel log mentioned above. This correlation can be done via timestamp similarities only.
3.) In Server 2016, you can track down and correlate generic network logon failure events in the same way as Windows Server 2012, but now you can correlate them via timestamps and IP addresses.
4.) Microsoft REALLY needs to fix Event ID 140 so that it is logged in the RdpCoreTS channel log EVERY TIME a failed RDS logon happens, not only when the username is unknown.
In Part 2 of this blog series, I’ll look at how RDS logon failures work when a Remote Desktop Gateway has been deployed in the environment, and I’ll also design some PowerShell scripts to help correlate the information from different logs. Until then, happy and safe remoting!
roy says
Very good post 8)
Andrew Parker says
An EC2 instance of mine was recently RDP brute forced and had an encryption ransomware ran on the entire filesystem, so this is very usful info to me right now. I’m interested in part two!
Tim Wiser says
Brilliant article – answered several questions. It’s staggering how badly auditing is implemented across the versions of Server.