Blog

Monitoring RDP Session Hijacking

In addition to all the fuss around Spectre and Meltdown, there are several other security flaws which are worth mentioning. One of these is RDP session hijacking.

How RDP Session Hijacking Works

In his excellent article, Kevin Beaumont explains in great detail what RDP session hijacking is and how to do it.
Here is a summary:

  • Windows lets you connect to other user’s RDP sessions via tscon.exe. You typically need the other user’s password for this.
  • If you run tscon.exe with SYSTEM privileges, you can connect to any other RDP session without a password.
  • There are several ways to get SYSTEM privileges if you have administrator permissions
    • PSEXEC from the Sysinternals suite
    • Create and start a service
    • Use a scheduled task
  • There are even RDP backdoor methods to get SYSTEM privileges. Mimikatz is probably the best-known example.
  • It is hard to monitor because there isn’t a specific Windows event log entry

How to Monitor Session Hijacking

Eric from XenAppBlog.com asked if it is possible to monitor RDP session hijacking with uberAgent. It is. Here is one way to do it.

Requirements

uberAgent uses Splunk to visualize collected data from your endpoints. As Splunk is licensed by daily indexed traffic, we have a strong incentive for keeping the amount of indexed data as small as possible. Therefore, we do not store command line information about each started process by default. One can enable this via the setting EnableExtendedInfo=true in our configuration. Keep in mind that your daily indexed traffic will increase.

The Simplest Solution

As stated above, you have to run tscon.exe with SYSTEM privileges to connect to another RDP session without the need to enter the user’s password. That is easy to accomplish with uberAgent and Splunk.

First, we have a look at all process startups and choose the fields host, SessionID, and ProcCmdline.

| pivot uberAgent Process_ProcessStartup
   values(ProcCmdline) as "Command line(s)" 
   splitrow 
      host as "Machine name"
   splitrow 
      SessionID as "Session ID"

In the second step, we filter the events for the process name tscon.exe and the process user SYSTEM. We do some sorting, too.

| pivot uberAgent Process_ProcessStartup
   values(ProcCmdline) as "Command line(s)" 
   splitrow 
      host as "Machine name"
   splitrow       
      SessionID as "Session ID"
   filter ProcName is "tscon.exe"
   filter ProcUser is "SYSTEM" 
| eval sortfield=lower('Machine name')
| sort limit=0 sortfield
| table
   "Machine name"
   "Session ID"
   "Command line(s)"

The result may look like this.

Goal achieved! But we only see session IDs, not usernames. It would be laborious to manually figure out the right username for the ID.

The More Sophisticated Solution

Not only does uberAgent give you details like name or id for the tscon.exe process but also for its parent. With this information, you can see how tscon.exe was started.

| pivot uberAgent Process_ProcessStartup
   values(ProcCmdline) as "Command line(s)"   
   splitrow 
      host as "Machine name"
   splitrow 
      SessionID as "Session ID"
   splitrow 
      ProcParentName as "Parent process name"
   filter ProcName is "tscon.exe"
   filter ProcUser is "SYSTEM" 
| eval sortfield=lower('Machine name')
| sort limit=0 sortfield
| table
   "Machine name"
   "Session ID"
   "Parent process name"   
   "Command line(s)"

Additionally, uberAgent can combine different datasets. By combining process startup data with session detail data, we can find out the usernames of the attacking and target sessions.

| pivot uberAgent Process_ProcessStartup
   latest(_time) as Time
   splitrow 
      host as "Machine name"
   splitrow 
      SessionID as "Attacking session ID"
   splitrow 
      ProcParentName as "Attacking session process name"
   splitrow
      ProcCmdline as "Command line"
   filter ProcName is "tscon.exe"
   filter ProcUser is "SYSTEM"
| eval Time = strftime (strptime (Time, "%Y-%m-%dT%H:%M:%S.%Q%z"), "%Y-%m-%d %H:%M:%S")
| rex field="Command line" "(?<temp>\d+)"
| rename temp as "Target session ID"
| join type=outer "Machine name" "Target session ID"
[
   | pivot uberAgent Session_SessionDetail_Users 
      latest(User) as "Target session username"
      splitrow 
         host as "Machine name"
      splitrow 
         SessionID as "Target session ID"
   | fields + "Target session username" "Machine name" "Target session ID"
]
| join type=outer "Machine name" "Attacking session ID"
[
   | pivot uberAgent Session_SessionDetail_Users 
      latest(User) as "Attacking session username"
      splitrow 
         host as "Machine name"
      splitrow 
         SessionID as "Attacking session ID"
   | fields + "Attacking session username" "Machine name" "Attacking session ID" 
]
| eval sortfield=lower('Machine name')
| sort limit=0 sortfield
| table
   Time
   "Machine name"
   "Attacking session ID"
   "Attacking session username"
   "Attacking session process name"   
   "Command line"   
   "Target session ID"
   "Target session username"

The result may look like this.

Conclusion

RDP session hijacking really is a thing. It could do massive damage, cannot be prevented and is hard to monitor. At least with the monitoring part, uberAgent may help.

Leave a Reply

Your email address will not be published. Required fields are marked *