Monitoring Windows RDP Sessions with Splunk

Install Splunk UF on Windows via Command Prompt/PowerShell:

This little one-liner can be used to install the Splunk Universal Forwarder (UF) on Windows Systems supporting powershell. Ofcourse you need administrative priviliges for the user running the powershell session and the installer MSI file needs to be accessible in the provided location (Network paths can also be used)

msiexec.exe /i \temp\splunkforwarder-7.2.0-x64.msi DEPLOYMENT_SERVER="<splunk-deployment-server>:8089" RECEIVING_INDEXER="<splunk-indexer>:9997" AGREETOLICENSE=Yes SPLUNKPASSWORD="SP#fc82kre" /L*v \temp\logfile.txt

Monitoring RDP Login Users with Source IP

Generally the Windows Security Logs have a decent bunch of information and can be monitored by default using the Splunk UF and the Splunk Add-On for Windows but there is a major pain when it comes to corelating Logon IDs with the actual Source IP Address of the incoming RDP connection and also differentiating local console sessions from RDP sessions. The better approach is to monitor the TerminalServices-LocalSessionManager -> Operational logs. To get it running, add the following stanza to your inputs.conf.

#$SPLUNKPATH/apps/Splunk_TA_windows/local/inputs.conf
[WinEventLog:Microsoft-Windows-TerminalServices-LocalSessionManager/Operational]
disabled = 0

Once you have logs rolling in for the above source, you can use the below search queries to show “completed” or “currently running” RDP sessions. I have yet to test whether it also logs “Local” console sessions but I think it does.

RDP Completed Sessions:

index=main source="wineventlog:microsoft-windows-terminalservices-localsessionmanager/operational" NOT Message="*arbitration*" NOT Message="Session *" host="<your-host-here>"
| eval Message = replace(Message,"[\n\r]+", " ")
| eval userstring = mvindex(User, -1)
| eval Domain = mvindex(split(userstring,"\\"),0)
| eval Domain=mvfilter(NOT match(Domain,"NOT_TRANSLATED") )
| eval User = mvindex(split(userstring,"\\"),1)
| transaction Session_ID, User, Source_Network_Address startswith=( ( Message="*logon succeeded*") OR (Message="*reconnection succeeded*") ) endswith=( ( Message="*logoff succeeded*") OR (Message="*Session has been disconnected*") )
| eval start_time = strftime(_time, "%Y-%m-%d %H:%M:%S")
| eval end_time = strftime(_time+duration, "%Y-%m-%d %H:%M:%S")
| table start_time, end_time, Session_ID, Domain, User, Source_Network_Address, duration
| rename Session_ID as "Session ID", Source_Network_Address as "Source Address", duration as "Duration", start_time as "Start Time", end_time as "End Time"

RDP Timeline: (Requires Timeline Visualization Addon)

index=main host="<your-host-here>" source="wineventlog:microsoft-windows-terminalservices-localsessionmanager/operational" NOT Message="*arbitration*" NOT Message="Session *" 
| eval Message = replace(Message,"[\n\r]+", " ") 
| eval userstring = mvindex(User, -1) 
| eval Domain = mvindex(split(userstring,"\\"),0) 
| eval Domain=mvfilter(NOT match(Domain,"NOT_TRANSLATED") ) 
| eval User = mvindex(split(userstring,"\\"),1) 
| transaction Session_ID, User, Source_Network_Address startswith=( ( Message="*logon succeeded*") OR (Message="*reconnection succeeded*") ) endswith=( ( Message="*logoff succeeded*") OR (Message="*Session has been disconnected*") ) 
| eval durationmilliseconds=duration*1000 
| eval usersession=User." (S#".Session_ID.")" 
| table _time usersession Source_Network_Address durationmilliseconds Session_ID

Happy Splunking!