Audit RDP connections

As you may know, it’s quite urgent to apply MS12-020 and/or at least to apply mitigations.

You may be interested in tracking RDP logons as well. As far as I know there are actually 2 ways to achieve this depending on your audit policy settings.

By default, you can do:

# Extract info from logs            
$allRDPevents = Get-WinEvent -FilterHashtable @{Logname = "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational" ; ID = 1149,1150,1148} -ErrorAction SilentlyContinue            
            
$RDPevents = @()              
foreach ($event in $allRDPevents)            
{            
    $result = $type = $null            
    # http://technet.microsoft.com/en-us/library/ee891195%28v=ws.10%29.aspx            
    switch ($event.ID)            
    {            
        1148 { $result = "failed"    }            
        1149 { $result = "succeeded" }            
        1150 { $result =  "merged"   }            
    }            
    $RDPevents += New-Object -TypeName PSObject -Property @{            
                    ComputerName = $env:computername            
                    User = $event.Properties[0].Value            
                    Domain = $event.Properties[1].Value            
                    SourceNetworkAddress = [net.ipaddress]$Event.Properties[2].Value            
                    TimeCreated = $event.TimeCreated            
                    Result = $result            
                }            
}            
            
# Display results            
$RDPevents | Sort-Object -Descending:$true -Property TimeCreated | Format-Table -AutoSize -Wrap            

If you enable ‘Audit Other Logon/Logoff events’ in your auditing policy settings you can then get additional info like this:

# More filtering can be added to this here-string XML             
$xml=@"

  
    
	*[System
	   [
	    (Level=1  or Level=2 or Level=3 or Level=4 or Level=0 or Level=5)
	    and ( EventID=4778 or EventID=4779 )
	   ]
	]
   
  

"@            
            
$events = Get-WinEvent -FilterXml $xml -ErrorAction SilentlyContinue            
            
$RDPevents = @()              
foreach ($event in $events)            
{            
    # Define a pattern that matches an IP address            
    $pattern = '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'            
    # Reset variable            
    $IP = $type = $null            
            
    switch($Event.Properties[5].Value)            
    {            
        { $_ -ieq "LOCAL"    } { $IP = "Local" }            
        { $_ -match $pattern } { $IP = [system.net.ipaddress]$Event.Properties[5].Value }            
        default                { $IP = $Event.Properties[5].Value }            
    }            
            
    switch ($event.ID)            
    {            
        4778 { $type = "Session Reconnected"  }            
        4779 { $type = "Session Disconnected" }            
    }            
            
    $RDPevents += New-Object -TypeName PSObject -Property @{            
                    ComputerName = $env:computername            
                    User = $event.Properties[0].Value            
                    Domain = $event.Properties[1].Value            
                    SourceNetworkAddress = $IP            
                    SourceComputerName = $event.Properties[4].Value            
                    RDPSessionName = $event.Properties[3].Value            
                    TimeCreated = $event.TimeCreated            
                    Result = "Success"            
                    Type = $type            
                }            
}            
            
$RDPevents | Sort-Object -Descending:$true -Property TimeCreated | Format-Table -AutoSize -Wrap
Advertisements

3 thoughts on “Audit RDP connections

  1. I keep getting this error; any ideas? When I remove the IP address line the script runs fine.

    Cannot convert value “” to type “System.Net.IPAddress”. Error: “An invalid IP address was specified.”
    At C:\scripts\rdlog.ps1:15 char:5
    + $RDPevents += New-Object -TypeName PSObject -Property @{
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastParseTargetInvocation

    • Hi,
      Sorry to ear that.
      I’ve tested the first piece of code on a Windows 7 with powershell 3.0 and it works fine.
      The above code is considered as “quick and dirty” because there’s no error handling.

      To identify what IP is throwing the error you had you can do:

      $allRDPevents = Get-WinEvent -FilterHashtable @{Logname = "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational" ; ID = 1149,1150,1148} -ErrorAction SilentlyContinue                        
      if ($allRDPevents) {            
          $allRDPevents | ForEach-Object -Process {            
              $event = $_            
              try {            
                  [net.ipaddress]$event.Properties[2].Value | Out-Null            
              } catch {            
                  "This IP is invalid: $($event.Properties[2].Value)"            
              }            
          }            
      }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s