Detection rules › Splunk

RDP Hijacking (Windows Event Log)

Group by
_time, host, user
Source
github.com/anvilogic-forge/armory

Adversaries may hijack a legitimate user’s remote desktop session to move laterally within an environment. Remote desktop is a common feature in operating systems. It allows a user to log into an interactive session with a system desktop graphical user interface on a remote system. Microsoft refers to its implementation of the Remote Desktop Protocol (RDP) as Remote Desktop Services (RDS)

MITRE ATT&CK coverage

References

Event coverage

Rule body yaml

id: '5464.5627'
title: RDP Hijacking
description: 'Adversaries may hijack a legitimate user’s remote desktop session to
  move laterally within an environment. Remote desktop is a common feature in operating
  systems. It allows a user to log into an interactive session with a system desktop
  graphical user interface on a remote system. Microsoft refers to its implementation
  of the Remote Desktop Protocol (RDP) as Remote Desktop Services (RDS) - Threat Actor
  Association: APT10, APT27, APT29/Nobelium/Cozy Bear, APT31, APT41, BlackMatter,
  Carbanak, DarkSide, DragonFly, FIN6, Lazarus, Whisper Spider, Wizard Spider, UNC2628,
  UNC2596 - Software Association: Bazarloader, BlackByte, BlackMatter, Conti, Cuba,
  Dharma, Diavol, Lockbit, LV, Midas, PYSA/Mespinoza, Snatch'
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_winevent` (TERM(EventCode=4778) OR
  "<EventID>4778<" OR TERM(EventCode=4779) OR "<EventID>4779<") OR (("rdpclip.exe"
  OR "tstheme.exe") (TERM(EventCode=4688) OR "<EventID>4688<")) | table _time, host,
  user, signature_id, src_ip, process, process_id, process_name, parent_process_name
  `group_events("host",5m)`| eventstats dc(user) as users by user | where (match(signature_id,
  "(?i)4778") AND match(signature_id, "(?i)4779") AND match(process_name, "(?i)rdpclip.exe")
  AND match(process_name, "(?i)tstheme.exe")) AND users>=2 | lookup dnslookup clientip
  as src_ip OUTPUT clienthost as src_dns | iplocation prefix="src_" src_ip| rename
  src_Country as src_country '
techniques:
- initial-access:external remote services
- lateral-movement:remote service session hijacking:rdp hijacking
technique_id:
- T1133
- T1563.002
data_category:
- Windows event logs
references:
- https://www.hackingarticles.in/rdp-session-hijacking-with-tscon/
- https://www.ired.team/offensive-security/lateral-movement/t1076-rdp-hijacking-for-lateral-movement

Stages and Predicates

Stage 1: search

search ((EventCode=4778 EventCode=4779) OR EventCode=4688) source="*" source IN ("WinEventLog:Security", "XmlWinEventLog:Security")

Stage 2: table

table _time, host, parent_process_name, process, process_id, process_name, signature_id, src_ip, user

Stage 3: bucket

bucket _time

Stage 4: stats

stats BY host, _time

Stage 5: eventstats

eventstatsAS users BY user

Stage 6: where

where process_name="*(?i)rdpclip.exe*" process_name="*(?i)tstheme.exe*" signature_id="*(?i)4778*" signature_id="*(?i)4779*" users>=2

Stage 7: lookup

lookup <lookup> clienthost, clientip, src_dns, src_ip
Lookup table
dnslookup
Key field
clientip as src_ip
Output columns
['clienthost', 'src_dns']

Stage 8: search

search prefix="src_"

Stage 9: rename

rename

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
EventCodeeq
  • 4688 corpus 313 (splunk 283, kusto 30)
  • 4778 corpus 2 (splunk 2)
  • 4779 corpus 3 (splunk 3)
prefixeq
  • "src_" corpus 5 (splunk 5)
process_namematch
  • "(?i)rdpclip.exe"
  • "(?i)tstheme.exe"
signature_idmatch
  • "(?i)4778"
  • "(?i)4779"
usersge
  • 2

Search terms

Bare-string tokens in the SPL search body. Splunk matches each token against _raw (the untyped raw event text) anywhere it appears, not against a specific field. These don't surface in the Indicators table because they aren't predicates on a known field.

StageTerm
1TERM
1"<EventID>4778<"
1TERM
1"<EventID>4779<"
1"rdpclip.exe"
1"tstheme.exe"
1TERM
1"<EventID>4688<"
8iplocation
8src_ip