Detection rules › Splunk
Scheduled Task with Potential SSH Tunnel - Windows (Sysmon)
Threat actors have been observed using scheduled tasks to create reverse SSH tunnels to facilitate persistence on a compromised machine as reported by DFIR. This use case detects scheduled tasks created with commands indicating potential SSH tunnels. The regex filtering matches on the patterns <user>@<IP address> and <port number>:<IP Address> :<port number>
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Execution | T1053 Scheduled Task/Job |
| Persistence | T1053 Scheduled Task/Job |
| Privilege Escalation | T1053 Scheduled Task/Job |
| Command & Control | T1572 Protocol Tunneling |
References
Event coverage
| Provider | Event | Title |
|---|---|---|
| Sysmon | Event ID 1 | Process creation |
Rule body yaml
id: '25326.47104'
title: Scheduled Task with Potential SSH Tunnel - Windows
description: Threat actors have been observed using scheduled tasks to create reverse
SSH tunnels to facilitate persistence on a compromised machine as reported by DFIR.
This use case detects scheduled tasks created with commands indicating potential
SSH tunnels. The regex filtering matches on the patterns <user>@<IP address> and
<port number>:<IP Address> :<port number>. Living Off the Land Binary and Scripts
(LOLBAS) (LOLBIN)
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=1) OR "<EventID>1<")
"@" "/create" ("-L" OR "-R" OR "-N" OR "-D" OR "-C" OR "IdentitiesOnly=yes" OR "StrictHostKeyChecking=no"
OR "ssh") | where match(process, "\w+@\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}") and match(process,
"\d{1,5}:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}") and match(process, "(?i)\-(L|R|N|D|C)|IdentitiesOnly=yes|StrictHostKeyChecking=no|ssh")
| table _time, host, user, process, process_*, parent_process_name, parent_process_*,
signature_id | bin span=1s | stats values(*) as * by _time, host '
techniques:
- execution:scheduled task/job
- command-and-control:protocol tunneling
technique_id:
- T1053
- T1572
data_category:
- Windows Sysmon
references:
- https://thedfirreport.com/2023/10/30/netsupport-intrusion-results-in-domain-compromise/
Stages and Predicates
Stage 1: search
`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=1) OR "<EventID>1<") "@" "/create" ("-L" OR "-R" OR "-N" OR "-D" OR "-C" OR "IdentitiesOnly=yes" OR "StrictHostKeyChecking=no" OR "ssh")
Stage 2: where
| where match(process, "\w+@\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}") and match(process, "\d{1,5}:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,5}") and match(process, "(?i)\-(L|R|N|D|C)|IdentitiesOnly=yes|StrictHostKeyChecking=no|ssh")
Stage 3: table
| table _time, host, user, process, process_*, parent_process_name, parent_process_*, signature_id
Stage 4: bucket
| bin span=1s
Stage 5: stats
| stats values(*) as * by _time, host
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.
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.
| Stage | Term |
|---|---|
| 1 | TERM |
| 1 | "<EventID>1<" |
| 1 | "@" |
| 1 | "/create" |
| 1 | "-L" |
| 1 | "-R" |
| 1 | "-N" |
| 1 | "-D" |
| 1 | "-C" |
| 1 | "IdentitiesOnly=yes" |
| 1 | "StrictHostKeyChecking=no" |
| 1 | "ssh" |