CL-UNK-1211: SysGoRAT, Web Shells and Reverse Shells on Government Linux Servers
Executive Summary
Unit 42 (Palo Alto Networks, published 2026-10-15) tracks CL-UNK-1211, a campaign against government entities and state-affiliated infrastructure observed from October 2025 to April 2026. The attackers worked almost entirely on Linux servers, mixing web shells, a custom Go remote access Trojan Unit 42 named SysGoRAT, open-source tools, in-memory reverse shells and heavy cleanup. The objective was intelligence gathering: dumping databases and taking government mailboxes to reach linked social media accounts.
Attribution is unknown. The UNK designation means Unit 42 has not determined whether the cluster is nation-state or cybercrime. This pack makes no nation-state claim. Unit 42 also reports AI-generated payloads (conversational comments inside scripts) and says that suggests an LLM or an automated agent, not that either was proven.
Persistence and access: web shells under a php-fpm parent, auto_prepend_file rewritten under /etc/php/ and /opt/plesk/php/ (including a fake /usr/lib/php/plesk_sys_driver.php), a sudo alias in .bashrc that captures passwords, SSH key injection, and SysGoRAT with six persistence methods. Evasion: pkill against Cortex XDR components (Unit 42 says these attempts were detected and mitigated), deletion of auth, history, mail and web logs, timestomping with touch -t, and planted red-team markers.
This pack hunts Linux process, network and DNS telemetry from the Falcon Linux sensor, and says plainly what the sensor cannot see. File contents of PHP web shells, .bashrc edits made by file copy, PHP configuration writes, and the HTTP requests that reach a web shell need a web-server-log and file-integrity review (Sections 7 and 15). All 31 atomic indicators ship as detect because every one comes from a single vendor report.
Defender priority: on every Linux web or mail server, run Q1, Q4, Q6, Q7 and Q10 fleet-wide for 30 days, run the Playbook A read-only audit for auto_prepend_file, hidden SUID files and alias sudo, and review web-server logs for requests to plesk_sys_driver.php and search_social.php. If any hit lands, treat sudo passwords, database and SMTP credentials and mailbox-linked accounts on that host as exposed.
Source Review & Web Hunter Notes
| Tier | Source | Key finding | Carry forward |
|---|---|---|---|
| T1 | Unit 42, AI-Powered Espionage Campaign Targets Government Linux Infrastructure (2026-10-15) | Primary report: TTPs, SysGoRAT command and persist tables, reverse shell forms, evasion, full IOC table (10 SHA-256, 17 IPs, 4 domains) with paths and file names in the body | Yes (primary for every indicator; saved as 01-unit42.txt) |
| T2 | GridinSoft, Linux sudo password theft write-up | Restates the Unit 42 findings with extra defender framing on .bashrc and auto_prepend_file. Adds no new indicators. Unit 42 is its only cited research source | Partial: context only, not independent |
| T2 | GBHackers, AI-assisted hackers compromise government Linux servers | Rewrite of the Unit 42 report. No indicators, no original analysis | Partial: context only, not independent |
| T2 | Cybersecurity News, AI-generated scripts hijack Linux sudo | Rewrite of the Unit 42 report. No indicators, no original analysis | Partial: context only, not independent |
Web hunter decisions
- No independent corroboration was found. Searches returned only outlets that cite Unit 42. Because no indicator has two independent sources, nothing is set to prevent or critical. All 31 atomic indicators are detect.
- Every hash, IP and domain was re-derived from the saved Unit 42 snapshot, not from search summaries. The 10 hashes, 17 IPs and 4 domains in the snapshot match the task brief exactly.
- Unit 42 does not label any hash as the SysGoRAT sample. The hash table covers the React2Shell scanner, a shell backdoor, GSocket, PwnKit and PHP web shells only. This is carried as a gap (Section 15), not filled in.
- The IPs are not mapped to roles except 104.194.158.65, the SysGoRAT default. Unit 42 says reverse shells used at least seven C2 servers; it does not say which of the 17 IPs those are.
- Legitimate services (gsocket.io relay, transfer.sh, bashupload.com, filebin.net, catbox.moe) appear in hunt queries only and are not imported as IOCs. Stock tools (python3, bash, nc, curl) are never indicators.
- Attribution stays at "unknown". The planted RedTeamOps2025 and pentest123 markers are deception artifacts, not evidence of an authorized assessment.
- The page body said the SolarWinds name in Solarwinds.StatusLog.txt is camouflage. Unit 42 states there is no evidence SolarWinds was compromised.
Hunt Brief & Attack Chain
Hypotheses
| ID | Hypothesis | Telemetry | Conf |
|---|---|---|---|
| H1 | A web server worker (php-fpm, Apache, nginx) spawns a shell, matching the interactive web shell activity Unit 42 shows (Q1) | Process creation with command line and parent (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | Medium |
| H2 | Reverse shells use mkfifo /tmp/f with nc, bash to /dev/tcp, or a Python socket (Q2, Q3) | Process creation with command line (same as H1) | High |
| H3 | The attackers run disguised binaries and stage GSocket in /dev/shm (Q4, Q5) | Process creation (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents). Execution only: the write itself is a labelled gap, so pair with file integrity monitoring on /dev/shm | High |
| H4 | Root is obtained with PwnKit, LinPEAS, a setuid(0) Python wrapper or a SUID hidden file (Q6) | Process creation with command line | High |
| H5 | Passwords are captured by a sudo alias and logged to Solarwinds.StatusLog.txt (Q7) | Process creation with command line | High |
| H6 | Cleanup runs history and log deletion commands (Q8) and tries to kill the security agent (Q9) | Process creation with command line | Medium |
| H7 | PHP persistence appears as auto_prepend_file edits or the plesk_sys_driver.php file name (Q10) | Process creation with command line | High |
| H8 | Mail and database data is enumerated, staged and uploaded (Q11, Q12) | Process creation with command line | Medium |
| H9 | SysGoRAT persists with sys-update.service or sys-control-client and calls out to campaign infrastructure (Q13 to Q16) | Process creation; network connection (CrowdStrike: NetworkConnectIP4. Defender: DeviceNetworkEvents); DNS lookup (CrowdStrike: DnsRequest) | High |
| H10 | Lateral movement uses sshpass and SOCKS tunnels, and SSH keys are injected (Q18) | Process creation with command line | Medium |
Attack chain
| Step | Behavior | Telemetry | Hunt angle |
|---|---|---|---|
| 1 | Initial access is not detailed by Unit 42. The attackers ran a custom React2Shell (CVE-2025-55182) scanner and dropped web shells | Web server and WAF logs (outside endpoint telemetry) | Section 7 web-server log review |
| 2 | Web shells deployed; auto_prepend_file rewritten for persistence | Process creation under php-fpm; file integrity | Q1, Q10, Section 7 |
| 3 | Credential harvesting: .bashrc sudo alias, PHP login logger, cleartext password search | Process creation with command line; file integrity | Q7, Section 7 |
| 4 | Privilege escalation: LinPEAS, PwnKit, setuid helpers | Process creation with command line | Q4, Q5, Q6 |
| 5 | SysGoRAT and GSocket persistence, in-memory reverse shells | Process creation, network connection, DNS lookup | Q2, Q3, Q4, Q13 to Q16 |
| 6 | Mailbox and database discovery, staging and exfiltration | Process creation with command line | Q11, Q12 |
| 7 | Lateral movement with sshpass, SSH keys, SOCKS tunnels, MSSQL xp_cmdshell hops | Process creation; database audit logs (outside endpoint telemetry) | Q18, Section 7 |
| 8 | Defense evasion and cleanup: agent kill, log and history deletion, timestomping, planted markers | Process creation with command line | Q7, Q8, Q9; timestomping is a gap |
Consolidated IOC Table
All indicators come from the Unit 42 IOC table (snapshot 01). Unit 42 defangs them; they are shown fanged here for import. Every row is detect: one vendor, no independent second source.
| Type | Value | Confidence | Action | Context | Expiry |
|---|---|---|---|---|---|
| sha256 | 2bf7992e6260c1a98c709fa98ec766fb9f27692f338b30b43ac821b824fd849e | High | detect | React2Shell (CVE-2025-55182) scanner build (Unit 42 IOC table) | 2027-04-17 |
| sha256 | 27d799ceadb570bfca890d4c2572314afe57eecf14083d30409da15afdfc4704 | High | detect | React2Shell (CVE-2025-55182) scanner build (Unit 42 IOC table) | 2027-04-17 |
| sha256 | d73186cea6cf2cf3d48c09139a9d15521365aab675787b4e7a6f81767331c9fd | High | detect | React2Shell (CVE-2025-55182) scanner build (Unit 42 IOC table) | 2027-04-17 |
| sha256 | 9e45830171eb607cf2c0fc80f5cc9cc3db39bb937032136990383a595f6f151e | High | detect | React2Shell (CVE-2025-55182) scanner build (Unit 42 IOC table) | 2027-04-17 |
| sha256 | c527b94e3d21824a674face4cd9d862e536b60ccbf54573839e3360f99188343 | High | detect | custom shell backdoor for privilege escalation (Unit 42 IOC table) | 2027-04-17 |
| sha256 | d94f75a70b5cabaf786ac57177ed841732e62bdcc9a29e06e5b41d9be567bcfa | High | detect | GSocket reverse shell binary (Unit 42 IOC table) | 2027-04-17 |
| sha256 | 44e83f84a5d5219e2f7c3cf1e4f02489cae81361227f46946abe4b8d8245b879 | High | detect | PwnKit (CVE-2021-4034) exploit binary (Unit 42 IOC table) | 2027-04-17 |
| sha256 | 1505a3a727f8899b2ad343519f7bf9c438b8b802f8d6b854f5db3b52f857c76a | High | detect | PHP web shell (Unit 42 IOC table) | 2027-04-17 |
| sha256 | 76c58fad4f70cf277a15a499b9a2151ac60e7a6b5c7a9ab684843dcc19f0d0a5 | High | detect | PHP web shell (Unit 42 IOC table) | 2027-04-17 |
| sha256 | b1e82c6b0caea177e8bb71ad826867f509c65f0a43a651b50253e7c726566eac | High | detect | PHP web shell (Unit 42 IOC table) | 2027-04-17 |
| ipv4 | 45.88.188.140 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 198.23.185.234 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 138.68.244.146 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 185.21.136.6 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 72.61.89.179 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 104.194.158.65 | Medium | detect | SysGoRAT default C2 (hardcoded, port 443) | 2027-04-17 |
| ipv4 | 109.224.53.140 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 162.243.175.162 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 154.93.37.228 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 141.164.58.87 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 88.80.150.232 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 88.119.167.57 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 173.212.247.23 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 104.248.131.53 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 147.182.224.216 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 93.93.112.57 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| ipv4 | 192.210.183.17 | Medium | detect | listed C2 or reverse-shell infrastructure (per-IP role not published) | 2027-04-17 |
| domain | magento.ink | High | detect | campaign domain listed by Unit 42 (role not published) | 2027-04-17 |
| domain | solidmonpe.com | High | detect | campaign domain listed by Unit 42 (role not published) | 2027-04-17 |
| domain | wibu-bau-bawang.online | High | detect | campaign domain listed by Unit 42 (role not published) | 2027-04-17 |
| domain | beraskencur.site | High | detect | campaign domain listed by Unit 42 (role not published) | 2027-04-17 |
Affected Surface & Telemetry Matrix
| Surface | Telemetry | Priority | Gap risk |
|---|---|---|---|
| Linux web servers (Apache, nginx, php-fpm, Plesk) | Process creation with command line and parent; network connection; DNS lookup (Falcon Linux sensor) | High | Medium: no sensor, no data. Also outside endpoint telemetry: HTTP requests to web shells |
| Linux mail servers (qmail under Plesk) | Process creation with command line | High | Medium: mailbox file reads are not a sensor event |
| Linux database and application hosts | Process creation; network connection | High | Medium: SQL-level activity (xp_cmdshell) is in database audit logs |
| PHP configuration and web roots | File integrity monitoring, auditd, or a scheduled hash sweep | High | High: file content and config writes are outside endpoint telemetry |
| Hosts without a Linux sensor, or unsupported kernels | auditd and syslog only | Medium | High: Q1 to Q18 cannot run there |
| Windows hosts running SysGoRAT | Process creation; network connection | Low | Low: only Q13 to Q16 apply; Unit 42 reports Windows support but no Windows intrusion detail |
ATT&CK Mapping
| Tactic | Technique | Behavior | Query or control |
|---|---|---|---|
| Persistence | T1505.003 Web Shell | PHP web shells, plesk_sys_driver.php, php-fpm parent | Q1, Q10, Section 7 |
| Persistence | T1546 Event Triggered Execution | auto_prepend_file rewritten in every PHP config | Q10, Playbook D |
| Persistence | T1543.002 / T1053.003 / T1547.001 | SysGoRAT systemd unit, cron, Windows Run key | Q13 |
| Persistence | T1098.004 SSH Authorized Keys | Public key appended to authorized_keys | Q18 |
| Execution | T1059.004 Unix Shell / T1059.006 Python | Reverse shells, bash -i from Python, Base64 commands | Q1, Q2, Q3 |
| Privilege Escalation | T1068 / T1548.001 | PwnKit (CVE-2021-4034), LinPEAS, setuid(0) helpers, SUID bash copy | Q6, Q4, Q5 |
| Credential Access | T1056.001 / T1546.004 / T1552.001 | sudo alias in .bashrc, PHP login logger, cleartext password search | Q7, Section 7 |
| Defense Evasion | T1036.005 Masquerading | sys-control-client, pip2.7, ea_install, .libpython-helper, fake Plesk file | Q4, Q5 |
| Defense Evasion | T1562.001 Impair Defenses | pgrep/pkill against Cortex XDR components | Q9 |
| Defense Evasion | T1070.002 / T1070.003 / T1070.006 | Log and history deletion, touch -t timestomping | Q8; timestomp is a gap |
| Discovery / Collection | T1114.001 / T1074.001 | Mailbox enumeration, search_social.php, zip_mails.sh, database dumps | Q11, Q12 |
| Command and Control | T1071.001 / T1090 / T1095 | WebSocket C2 to wss://addr/ws, GSocket, revsocks, pysoxy, nc | Q14, Q15, Q16, Q4, Q18 |
| Lateral Movement | T1021.004 SSH | sshpass with hard-coded credentials | Q18 |
| Exfiltration | T1567.002 / T1048 | transfer.sh, bashupload.com, filebin.net, catbox.moe, nc | Q12, Q17 |
| Resource Development | T1587.001 / T1588.002 | Custom Go RAT and scanner, open-source tools | Q4, Q6, Q14 |
Native Audit-Log Hunts
Run these outside Falcon. They cover what the Linux sensor cannot see and the web-server-log review the Coverage Map depends on. All commands are read-only.
Web-server log review (outside endpoint telemetry)
# Requests to the named web shell and mailbox script (adjust log paths for your stack) grep -E 'plesk_sys_driver\.php|search_social\.php' /var/log/apache2/*access* /var/log/nginx/*access* /var/www/vhosts/system/*/logs/*access* 2>/dev/null # POST requests to PHP files that were modified recently (web shell candidates) find /var/www -name '*.php' -mtime -90 -printf '%TY-%Tm-%Td %p\n' | sort | tail -50 # Compare against the CVE-2025-55182 scanner exposure: review your framework advisory and WAF logs for exploit attempts
PHP configuration and web shell files
grep -rn "auto_prepend_file" /etc/php /opt/plesk/php 2>/dev/null
php -i 2>/dev/null | grep -i auto_prepend_file
ls -la /usr/lib/php/plesk_sys_driver.php 2>/dev/null
# Hash sweep of web roots for the three PHP web shell hashes in Section 10
find /var/www -type f -name '*.php' -exec sha256sum {} + 2>/dev/null | grep -F -f /path/to/php-webshell-hashes.txt
Credential, persistence and staging artifacts
grep -n "alias sudo" /home/*/.bashrc /root/.bashrc /etc/bash.bashrc 2>/dev/null find / -xdev -name 'Solarwinds.StatusLog.txt' 2>/dev/null find / -xdev -perm -4000 -type f -name '.*' 2>/dev/null ls -la /dev/shm /usr/lib/x86_64-linux-gnu/.libpython-helper 2>/dev/null systemctl status sys-update.service 2>/dev/null; ls -la /etc/systemd/system/sys-update.service 2>/dev/null crontab -l 2>/dev/null; ls -la /etc/cron.d 2>/dev/null grep -n "ssh-" /home/*/.ssh/authorized_keys /root/.ssh/authorized_keys 2>/dev/null getent passwd | grep -i pentest ls -ld /var/qmail/mailnames/* 2>/dev/null
Logs the attackers tried to delete
- Compare auth.log or secure, btmp, wtmp and mail logs against off-host copies (syslog server or SIEM). A gap or a truncated file is itself a finding.
- Check shell history files for zero length or recent truncation on privileged accounts.
- Check file timestamps against inode change time:
staton suspect scripts shows a change time that postdates the claimed modification time whentouch -twas used.
Database audit logs
- On MSSQL, search for
sp_configure 'xp_cmdshell'being enabled and forxp_cmdshellinvokingsqlcmdagainst a second server (the double-hop chain Unit 42 describes). - Look for new SQLite files such as dump.sqlite in /tmp and bulk CSV exports followed by tar archives.
Hunt Queries: CrowdStrike CQL, SentinelOne PowerQuery and Defender XDR KQL
Use your tenant's own address. SentinelOne does not document a link that pre-fills a query, so each "Copy & open SentinelOne" button copies the query and opens this console: paste it into PowerQuery.
Pick your portal. Microsoft documents a Share link in advanced hunting but not its URL format, so each "Copy & open Defender" button copies the query and opens Advanced hunting: paste it into the editor.
These queries target the Falcon Linux sensor (event_platform=Lin). Add a host-group or ComputerName filter for your Linux servers to cut cost. Section 15 states what they cannot see.
Looks for: A php-fpm, Apache or nginx worker whose child is a shell, interpreter or download tool. Unit 42 shows interactive web shell activity under a php-fpm parent. FP: Applications that call shell_exec or system on purpose, Plesk and cPanel helpers, PHP queue workers. Baseline 14 days first.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
- KQL – Defender XDR assumes: matches regex with the (?i) prefix reproduces the CQL /i flag.
// HUNT: Web server worker spawns a shell or download tool // MITRE: T1505.003, T1059.004 // CONF: medium FP: medium COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: apps that shell out by design, Plesk and cPanel helper jobs, PHP queue workers // TUNING: after a 14-day baseline add !(CommandLine=*your-known-app-script*) exclusions per application // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | ParentBaseFileName=/^(php-fpm[0-9.]*|php[0-9.]*-fpm|lsphp[0-9]*|apache2|httpd|nginx)$/i | FileName=/^(sh|bash|dash|zsh|ash|busybox|nc|ncat|python[0-9.]*|perl|wget|curl)$/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
6 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command linetgt.process.name: Created processsrc.process.name: Creator process
Recommended fields
endpoint.name: Hostsrc.process.user: Creator user
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline, tgt.process.name, src.process.name
// HUNT: Web server worker spawns a shell or download tool // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1505.003, T1059.004 // CONF: medium | FP: medium // FALSE POSITIVES: apps that shell out by design, Plesk and cPanel helper jobs, PHP queue workers // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a web server worker as the creator and a shell, netcat, interpreter or download tool as the created process. On a Process Creation event the creator is src.process and the created process is tgt.process, so the CQL parent maps to src.process.name and the CQL child to tgt.process.name. // REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events) // TUNING: After a 14-day baseline exclude known application scripts per application by adding a negated tgt.process.cmdline predicate. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' endpoint.os = 'linux' src.process.name matches '^(php-fpm[0-9.]*|php[0-9.]*-fpm|lsphp[0-9]*|apache2|httpd|nginx)$' tgt.process.name matches '^(sh|bash|dash|zsh|ash|busybox|nc|ncat|python[0-9.]*|perl|wget|curl)$' | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command lineFileName: Created processInitiatingProcessFileName: Initiating process
Recommended fields
DeviceName: HostAccountName: Account
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine, FileName, InitiatingProcessFileName | take 5
// HUNT: Web server worker spawns a shell or download tool // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1505.003, T1059.004 // CONF: medium | FP: medium // FALSE POSITIVES: apps that shell out by design, Plesk and cPanel helper jobs, PHP queue workers // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the initiating process is a web server worker and the created process is a shell, netcat, interpreter or download tool. The CQL parent is InitiatingProcessFileName. // REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents) // TUNING: After a 14-day baseline exclude known application scripts per application with a negated ProcessCommandLine predicate. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where InitiatingProcessFileName matches regex @"(?i)^(php-fpm[0-9.]*|php[0-9.]*-fpm|lsphp[0-9]*|apache2|httpd|nginx)$" | where FileName matches regex @"(?i)^(sh|bash|dash|zsh|ash|busybox|nc|ncat|python[0-9.]*|perl|wget|curl)$" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: The three reverse shell forms Unit 42 reports: mkfifo /tmp/f piped through nc, bash redirected to /dev/tcp, and a Python script that duplicates a socket onto bash. FP: Rare. Authorized red team or penetration test activity.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
- KQL – Defender XDR assumes: matches regex with the (?i) prefix reproduces the CQL /i flag.
// HUNT: Reverse shell command patterns (named pipe, /dev/tcp, Python socket) // MITRE: T1059.004, T1095 // CONF: high FP: low COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: authorized penetration tests, security training labs // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/(mkfifo\s+\/tmp\/f|\/tmp\/f\s*[|]\s*(\/bin\/)?(ba)?sh|\/dev\/tcp\/[0-9a-z.-]+\/[0-9]+|import\s+socket.{0,200}dup2.{0,200}bash)/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator usersrc.process.name: Creator processtgt.process.name: Created process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline
// HUNT: Reverse shell command patterns (named pipe, /dev/tcp, Python socket)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1059.004, T1095
// CONF: high | FP: low
// FALSE POSITIVES: authorized penetration tests, security training labs
// EQUIVALENCE: equivalent-with-schema-assumptions - Same four command-line patterns: mkfifo on /tmp/f, a pipe from /tmp/f into a shell, a /dev/tcp redirect, and a Python socket with dup2 into bash. The match is on the created process command line.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Authorized penetration tests and training labs trigger this; exclude the lab hosts by endpoint.name.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' tgt.process.cmdline matches 'mkfifo\\s+/tmp/f|/tmp/f\\s*[|]\\s*(/bin/)?(ba)?sh|/dev/tcp/[0-9a-z.-]+/[0-9]+|import\\s+socket.{0,200}dup2.{0,200}bash'
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: Reverse shell command patterns (named pipe, /dev/tcp, Python socket)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1059.004, T1095
// CONF: high | FP: low
// FALSE POSITIVES: authorized penetration tests, security training labs
// EQUIVALENCE: equivalent-with-schema-assumptions - Same four command-line patterns on the created process command line; the (?i) prefix reproduces the CQL /i flag.
// REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude authorized penetration test and training hosts by DeviceName.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine matches regex @"(?i)mkfifo\s+/tmp/f|/tmp/f\s*[|]\s*(/bin/)?(ba)?sh|/dev/tcp/[0-9a-z.-]+/[0-9]+|import\s+socket.{0,200}dup2.{0,200}bash"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: A Python parent whose child is a shell run with -i, the shape of the Python subprocess reverse shell. FP: Admin and automation tooling that wraps a shell in Python (pexpect, Ansible helpers, pty wrappers).
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
// HUNT: Interactive bash spawned by a Python process // MITRE: T1059.006, T1059.004 // CONF: medium FP: medium COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: pexpect or pty-based automation, Ansible helper modules, developer tooling // TUNING: exclude known automation accounts with !(UserName=svc-automation) and known parent command lines after baselining // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | ParentBaseFileName=/^python[0-9.]*$/i | FileName=/^(bash|sh|dash|zsh)$/i | CommandLine=/\s-i(\s|$)/ | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
6 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command linetgt.process.name: Created processsrc.process.name: Creator process
Recommended fields
endpoint.name: Hostsrc.process.user: Creator user
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline, tgt.process.name, src.process.name
// HUNT: Interactive bash spawned by a Python process
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1059.006, T1059.004
// CONF: medium | FP: medium
// FALSE POSITIVES: pexpect or pty-based automation, Ansible helper modules, developer tooling
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a Python creator, a shell as the created process, and an interactive -i flag in the created command line. The -i test is case-sensitive, as in the CQL, so matches:matchcase is used for it.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Exclude known automation accounts and automation parents after baselining.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' src.process.name matches '^python[0-9.]*$' tgt.process.name in:anycase ('bash', 'sh', 'dash', 'zsh') tgt.process.cmdline matches:matchcase '\\s-i(\\s|$)'
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command lineFileName: Created processInitiatingProcessFileName: Initiating process
Recommended fields
DeviceName: HostAccountName: Account
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine, FileName, InitiatingProcessFileName | take 5
// HUNT: Interactive bash spawned by a Python process
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1059.006, T1059.004
// CONF: medium | FP: medium
// FALSE POSITIVES: pexpect or pty-based automation, Ansible helper modules, developer tooling
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: a Python initiating process, a shell as the created process, and a case-sensitive -i flag in the created command line.
// REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude known automation accounts and automation parents after baselining.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where InitiatingProcessFileName matches regex @"(?i)^python[0-9.]*$"
| where FileName in~ ("bash", "sh", "dash", "zsh")
| where ProcessCommandLine matches regex @"\s-i(\s|$)"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: Execution of the file names Unit 42 reports: sys-control-client, ea_install, .libpython-helper, .libsystemd-helper, .tourch, gs-netcat, gs-dbus, and anything running from a /dev/shm/.gs- directory. FP: Low. The hidden dot-names and the /dev/shm path are not used by stock Linux packages. gs-netcat is also a legitimate open-source tool, so treat a hit as a lead, not proof of this campaign.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.name holds the file name including the leading dot of a hidden file.
- PowerQuery assumes: The /dev/shm path test is case-insensitive here; the CQL path test is case-sensitive.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: FolderPath holds the full image path of the created process on Linux sensors.
- KQL – Defender XDR assumes: FileName keeps the leading dot of a hidden file.
// HUNT: Disguised SysGoRAT, hidden root helpers and GSocket staging // MITRE: T1036.005, T1090, T1548.001 // CONF: high FP: low COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: an admin who legitimately runs gs-netcat; a product that ships a binary called ea_install // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | (FileName=/^(sys-control-client|ea_install|\.libpython-helper|\.libsystemd-helper|\.tourch|gs-netcat|gs-dbus)$/i or ImageFileName=/\/dev\/shm\/\.gs-[0-9]+\//) | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, ImageFileName, CommandLine, SHA256HashData])
5 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.name: Created process nametgt.process.image.path: Created process path
Recommended fields
endpoint.name: Hostsrc.process.name: Creator processtgt.process.cmdline: Created command line
Optional fields
tgt.process.image.sha256: Hash
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.name = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.name, tgt.process.image.path
// HUNT: Disguised SysGoRAT, hidden root helpers and GSocket staging // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1036.005, T1090, T1548.001 // CONF: high | FP: low // FALSE POSITIVES: an admin who legitimately runs gs-netcat; a product that ships a binary called ea_install // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the created process is one of the listed disguised names, or runs from a hidden GSocket directory under /dev/shm. The name test is on tgt.process.name and the path test on tgt.process.image.path. // REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events) // TUNING: An admin who legitimately runs gs-netcat, or a product that ships a binary called ea_install, needs an exclusion by image path. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' endpoint.os = 'linux' (tgt.process.name matches '^(sys-control-client|ea_install|\\.libpython-helper|\\.libsystemd-helper|\\.tourch|gs-netcat|gs-dbus)$' or tgt.process.image.path matches '/dev/shm/\\.gs-[0-9]+/') | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.image.path, tgt.process.cmdline, tgt.process.image.sha256 | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameFolderPath: Created process path
Recommended fields
DeviceName: HostInitiatingProcessFileName: Initiating processProcessCommandLine: Created command line
Optional fields
SHA1: Hash
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, FolderPath | take 5
// HUNT: Disguised SysGoRAT, hidden root helpers and GSocket staging // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1036.005, T1090, T1548.001 // CONF: high | FP: low // FALSE POSITIVES: an admin who legitimately runs gs-netcat; a product that ships a binary called ea_install // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the created file name is one of the listed disguised names, or the image path is a hidden GSocket directory under /dev/shm. // REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents) // TUNING: An admin who legitimately runs gs-netcat, or a product that ships a binary called ea_install, needs an exclusion by FolderPath. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FileName matches regex @"(?i)^(sys-control-client|ea_install|\.libpython-helper|\.libsystemd-helper|\.tourch|gs-netcat|gs-dbus)$" or FolderPath matches regex @"/dev/shm/\.gs-[0-9]+/" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, FolderPath, ProcessCommandLine, SHA1, SHA256 | sort by Timestamp desc | take 200
Looks for: Execution out of /dev/shm, or execution under the hidden helper names Unit 42 reports. FP: Software that stages and runs executables in /dev/shm (some installers, memfd-style tooling). Note: this card catches the binary at first execution, not at write time. The write-time angle is a labelled gap in the Coverage Map.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery: The CQL title says written; the CQL itself, and so this query, tests process execution only.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.image.path holds the full path of the created image.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR: The CQL title says written; the CQL itself, and so this query, tests process execution only.
- KQL – Defender XDR assumes: FolderPath holds the full image path of the created process on Linux sensors.
// HUNT: Execution from /dev/shm or under a hidden helper name // MITRE: T1620, T1036.005 // CONF: medium FP: medium COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: installers or runtimes that stage and execute binaries in /dev/shm // TUNING: exclude known staging processes with !(ParentBaseFileName=your-installer) after a 14-day baseline // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | ImageFileName=/(\/dev\/shm\/|\/\.(libpython-helper|libsystemd-helper|tourch)$|\/sys-control-client$)/i | table([@timestamp, ComputerName, aid, UserName, ImageFileName, CommandLine, SHA256HashData, ParentBaseFileName])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.image.path: Created process path
Recommended fields
endpoint.name: Hostsrc.process.name: Creator processtgt.process.cmdline: Created command line
Optional fields
tgt.process.image.sha256: Hash
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.image.path = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.image.path
// HUNT: Execution from /dev/shm or under a hidden helper name // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1620, T1036.005 // CONF: medium | FP: medium // FALSE POSITIVES: installers or runtimes that stage and execute binaries in /dev/shm // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the created process image path is under /dev/shm or ends in one of the hidden helper names or sys-control-client. // REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events) // TUNING: Exclude known staging parents after a 14-day baseline with a negated src.process.name predicate. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded. The CQL title says written; the CQL itself, and so this query, tests process execution only. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' endpoint.os = 'linux' tgt.process.image.path matches '(/dev/shm/|/\\.(libpython-helper|libsystemd-helper|tourch)$|/sys-control-client$)' | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.image.path, tgt.process.cmdline, tgt.process.image.sha256 | limit 200
Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFolderPath: Created process path
Recommended fields
DeviceName: HostInitiatingProcessFileName: Initiating processProcessCommandLine: Created command line
Optional fields
SHA1: Hash
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FolderPath | take 5
// HUNT: Execution from /dev/shm or under a hidden helper name // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1620, T1036.005 // CONF: medium | FP: medium // FALSE POSITIVES: installers or runtimes that stage and execute binaries in /dev/shm // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on the created process image path (FolderPath): under /dev/shm or ending in one of the hidden helper names or sys-control-client. // REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude known staging parents after a 14-day baseline with a negated InitiatingProcessFileName predicate. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured. The CQL title says written; the CQL itself, and so this query, tests process execution only. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FolderPath matches regex @"(?i)(/dev/shm/|/\.(libpython-helper|libsystemd-helper|tourch)$|/sys-control-client$)" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FolderPath, ProcessCommandLine, SHA1, SHA256 | sort by Timestamp desc | take 200
Looks for: Python one-liners that call os.setuid(0) and os.setgid(0), LinPEAS or PwnKit names, and chmod u+s on the hidden helper names Unit 42 reports. FP: Low. Authorized assessments that run LinPEAS.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
- KQL – Defender XDR assumes: matches regex with the (?i) prefix reproduces the CQL /i flag.
// HUNT: Local privilege escalation: setuid(0) wrapper, LinPEAS, PwnKit, SUID on hidden file // MITRE: T1068, T1548.001 // CONF: high FP: low COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: authorized penetration tests running LinPEAS // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/(os\.setuid\(0\)|os\.setgid\(0\)|linpeas|pwnkit|CVE-2021-4034|chmod\s+(u\+s|[0-7]?4[0-7]{3})\s+\S*\.(tourch|libsystemd-helper|libpython-helper))/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator usersrc.process.name: Creator processtgt.process.name: Created process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline
// HUNT: Local privilege escalation: setuid(0) wrapper, LinPEAS, PwnKit, SUID on hidden file
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1068, T1548.001
// CONF: high | FP: low
// FALSE POSITIVES: authorized penetration tests running LinPEAS
// EQUIVALENCE: equivalent-with-schema-assumptions - Same five literal markers plus the chmod setuid pattern on the hidden helper names. The literals use contains, which is case-insensitive like the CQL /i flag.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Authorized penetration tests running LinPEAS need an exclusion by endpoint.name.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' (tgt.process.cmdline contains ('os.setuid(0)', 'os.setgid(0)', 'linpeas', 'pwnkit', 'CVE-2021-4034') or tgt.process.cmdline matches 'chmod\\s+(u\\+s|[0-7]?4[0-7]{3})\\s+\\S*\\.(tourch|libsystemd-helper|libpython-helper)')
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: Local privilege escalation: setuid(0) wrapper, LinPEAS, PwnKit, SUID on hidden file
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1068, T1548.001
// CONF: high | FP: low
// FALSE POSITIVES: authorized penetration tests running LinPEAS
// EQUIVALENCE: equivalent-with-schema-assumptions - Same five literal markers plus the chmod setuid pattern on the hidden helper names; contains is case-insensitive like the CQL /i flag.
// REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents)
// TUNING: Authorized penetration tests running LinPEAS need an exclusion by DeviceName.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine contains "os.setuid(0)" or ProcessCommandLine contains "os.setgid(0)" or ProcessCommandLine contains "linpeas" or ProcessCommandLine contains "pwnkit" or ProcessCommandLine contains "CVE-2021-4034" or ProcessCommandLine matches regex @"(?i)chmod\s+(u\+s|[0-7]?4[0-7]{3})\s+\S*\.(tourch|libsystemd-helper|libpython-helper)"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: Commands that define an alias for sudo or write to .bashrc with a sudo alias, the Solarwinds.StatusLog.txt password log, and the RedTeamOps2025 and pentest123 markers the attackers planted. FP: Low. A user who aliases sudo for a harmless reason will show as a lead to review.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
- KQL – Defender XDR assumes: matches regex with the (?i) prefix reproduces the CQL /i flag.
// HUNT: sudo alias hijack, password log file and planted red-team markers // MITRE: T1056.001, T1546.004, T1036 // CONF: high FP: low COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: users who alias sudo for convenience (for example alias sudo='sudo -E') // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/(alias\s+sudo\s*=|Solarwinds\.StatusLog|RedTeamOps2025|pentest123|\.bashrc.{0,200}alias\s+sudo|alias\s+sudo.{0,200}\.bashrc)/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator usersrc.process.name: Creator processtgt.process.name: Created process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline
// HUNT: sudo alias hijack, password log file and planted red-team markers
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1056.001, T1546.004, T1036
// CONF: high | FP: low
// FALSE POSITIVES: users who alias sudo for convenience (for example alias sudo='sudo -E')
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the three planted marker strings, plus an alias of sudo defined directly or alongside a .bashrc edit. Literals use contains, which is case-insensitive like the CQL /i flag.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Users who alias sudo for convenience need an exclusion by src.process.user.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' (tgt.process.cmdline contains ('Solarwinds.StatusLog', 'RedTeamOps2025', 'pentest123') or tgt.process.cmdline matches 'alias\\s+sudo\\s*=|\\.bashrc.{0,200}alias\\s+sudo|alias\\s+sudo.{0,200}\\.bashrc')
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: sudo alias hijack, password log file and planted red-team markers
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1056.001, T1546.004, T1036
// CONF: high | FP: low
// FALSE POSITIVES: users who alias sudo for convenience (for example alias sudo='sudo -E')
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the three planted marker strings, plus an alias of sudo defined directly or alongside a .bashrc edit.
// REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents)
// TUNING: Users who alias sudo for convenience need an exclusion by AccountName.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine contains "Solarwinds.StatusLog" or ProcessCommandLine contains "RedTeamOps2025" or ProcessCommandLine contains "pentest123" or ProcessCommandLine matches regex @"(?i)alias\s+sudo\s*=|\.bashrc.{0,200}alias\s+sudo|alias\s+sudo.{0,200}\.bashrc"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: Commands that clear history or delete the authentication, mail, web server and PHP session logs Unit 42 lists, plus HISTFILE set to /dev/null (used by the GSocket sessions). FP: Log rotation scripts, image build jobs and admins who run history -c. Expect noise from rotation tooling.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
- KQL – Defender XDR assumes: matches regex with the (?i) prefix reproduces the CQL /i flag.
// HUNT: Shell history and log clearing // MITRE: T1070.002, T1070.003 // CONF: medium FP: medium COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: logrotate and cleanup jobs, golden-image build scripts, admins running history -c // TUNING: exclude the parent of your log rotation jobs with !(ParentBaseFileName=logrotate) and known maintenance accounts // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/(history\s+-c|unset\s+HISTFILE|HISTFILE=\/dev\/null|HISTSIZE=0|(rm|shred|truncate|unlink)\s.{0,120}(\.bash_history|\.zsh_history|\/var\/log\/(auth\.log|secure|btmp|wtmp|lastlog|maillog|mail\.log|apache2|httpd|nginx)|\/var\/lib\/php\/sessions)|>\s*\/var\/log\/(auth\.log|secure|wtmp|btmp|lastlog))/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator usersrc.process.name: Creator processtgt.process.name: Created process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline
// HUNT: Shell history and log clearing
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1070.002, T1070.003
// CONF: medium | FP: medium
// FALSE POSITIVES: logrotate and cleanup jobs, golden-image build scripts, admins running history -c
// EQUIVALENCE: equivalent-with-schema-assumptions - Same patterns: history clearing, HISTFILE or HISTSIZE disabling, removal of history files, logs and PHP sessions, and a redirect that truncates an auth log.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Exclude log rotation parents and known maintenance accounts after baselining.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' tgt.process.cmdline matches 'history\\s+-c|unset\\s+HISTFILE|HISTFILE=/dev/null|HISTSIZE=0|(rm|shred|truncate|unlink)\\s.{0,120}(\\.bash_history|\\.zsh_history|/var/log/(auth\\.log|secure|btmp|wtmp|lastlog|maillog|mail\\.log|apache2|httpd|nginx)|/var/lib/php/sessions)|>\\s*/var/log/(auth\\.log|secure|wtmp|btmp|lastlog)'
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: Shell history and log clearing
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1070.002, T1070.003
// CONF: medium | FP: medium
// FALSE POSITIVES: logrotate and cleanup jobs, golden-image build scripts, admins running history -c
// EQUIVALENCE: equivalent-with-schema-assumptions - Same patterns: history clearing, HISTFILE or HISTSIZE disabling, removal of history files, logs and PHP sessions, and a redirect that truncates an auth log.
// REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude log rotation parents and known maintenance accounts after baselining.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine matches regex @"(?i)history\s+-c|unset\s+HISTFILE|HISTFILE=/dev/null|HISTSIZE=0|(rm|shred|truncate|unlink)\s.{0,120}(\.bash_history|\.zsh_history|/var/log/(auth\.log|secure|btmp|wtmp|lastlog|maillog|mail\.log|apache2|httpd|nginx)|/var/lib/php/sessions)|>\s*/var/log/(auth\.log|secure|wtmp|btmp|lastlog)"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: pkill, killall, pgrep, kill or systemctl stop against security agent names. Unit 42 reports pgrep and pkill against Cortex XDR components. The other agent names are this pack's extension of the same behavior, not named in the source. FP: Admins restarting agents, upgrade scripts and uninstall jobs. pgrep alone is often benign reconnaissance.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
- KQL – Defender XDR assumes: matches regex with the (?i) prefix reproduces the CQL /i flag.
// HUNT: Attempts to kill or stop endpoint security agents // MITRE: T1562.001 // CONF: medium FP: medium COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: agent upgrade or uninstall jobs, admins restarting services, config management runs // TUNING: exclude your patching and config-management parents (for example !(ParentBaseFileName=ansible-playbook)) and review pgrep-only hits separately // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/(\b(pkill|killall|pgrep|kill)\b.{0,120}(cortex|cyserver|cytool|falcon-sensor|falcond|sentinelagent|sentinelone|mdatp|wdavdaemon|wazuh|ossec|osqueryd|auditd|clamd|elastic-agent)|systemctl\s+(stop|disable|mask)\s+\S*(cortex|cyserver|falcon-sensor|sentinel|mdatp|wazuh|ossec|osqueryd|auditd|clamd|elastic-agent))/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator usersrc.process.name: Creator processtgt.process.name: Created process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline
// HUNT: Attempts to kill or stop endpoint security agents
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1562.001
// CONF: medium | FP: medium
// FALSE POSITIVES: agent upgrade or uninstall jobs, admins restarting services, config management runs
// EQUIVALENCE: equivalent-with-schema-assumptions - Same patterns: a kill-family tool aimed at a security agent name, or systemctl stop, disable or mask on a security service.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Exclude patching and configuration-management parents with a negated src.process.name predicate, and review pgrep-only hits separately.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' tgt.process.cmdline matches '(\\b(pkill|killall|pgrep|kill)\\b.{0,120}(cortex|cyserver|cytool|falcon-sensor|falcond|sentinelagent|sentinelone|mdatp|wdavdaemon|wazuh|ossec|osqueryd|auditd|clamd|elastic-agent)|systemctl\\s+(stop|disable|mask)\\s+\\S*(cortex|cyserver|falcon-sensor|sentinel|mdatp|wazuh|ossec|osqueryd|auditd|clamd|elastic-agent))'
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: Attempts to kill or stop endpoint security agents
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1562.001
// CONF: medium | FP: medium
// FALSE POSITIVES: agent upgrade or uninstall jobs, admins restarting services, config management runs
// EQUIVALENCE: equivalent-with-schema-assumptions - Same patterns: a kill-family tool aimed at a security agent name, or systemctl stop, disable or mask on a security service.
// REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude patching and configuration-management parents with a negated InitiatingProcessFileName predicate, and review pgrep-only hits separately.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine matches regex @"(?i)(\b(pkill|killall|pgrep|kill)\b.{0,120}(cortex|cyserver|cytool|falcon-sensor|falcond|sentinelagent|sentinelone|mdatp|wdavdaemon|wazuh|ossec|osqueryd|auditd|clamd|elastic-agent)|systemctl\s+(stop|disable|mask)\s+\S*(cortex|cyserver|falcon-sensor|sentinel|mdatp|wazuh|ossec|osqueryd|auditd|clamd|elastic-agent))"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: Command lines that set or search auto_prepend_file, or reference the plesk_sys_driver.php file name. Unit 42 reports the attackers rewrote auto_prepend_file in every PHP configuration under /etc/php/ and /opt/plesk/php/. FP: Config management that sets auto_prepend_file on purpose (application firewalls, profilers) and admins auditing the setting with grep.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
// HUNT: PHP auto_prepend_file tampering and the plesk_sys_driver.php web shell // MITRE: T1505.003, T1546 // CONF: high FP: medium COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: WAF or profiler products that use auto_prepend_file, admin audit greps, Ansible template runs // TUNING: exclude approved prepend files with !(CommandLine=*your-approved-prepend.php*) and your config-management parent // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/(auto_prepend_file|plesk_sys_driver\.php)/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator usersrc.process.name: Creator processtgt.process.name: Created process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline
// HUNT: PHP auto_prepend_file tampering and the plesk_sys_driver.php web shell
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1505.003, T1546
// CONF: high | FP: medium
// FALSE POSITIVES: WAF or profiler products that use auto_prepend_file, admin audit greps, Ansible template runs
// EQUIVALENCE: equivalent-with-schema-assumptions - Same two literals in the created command line; contains is case-insensitive like the CQL /i flag.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Exclude approved prepend files and the configuration-management parent with a negated tgt.process.cmdline predicate.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' tgt.process.cmdline contains ('auto_prepend_file', 'plesk_sys_driver.php')
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: PHP auto_prepend_file tampering and the plesk_sys_driver.php web shell // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1505.003, T1546 // CONF: high | FP: medium // FALSE POSITIVES: WAF or profiler products that use auto_prepend_file, admin audit greps, Ansible template runs // EQUIVALENCE: equivalent-with-schema-assumptions - Same two literals in the created command line; contains is case-insensitive like the CQL /i flag. // REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude approved prepend files and the configuration-management parent with a negated ProcessCommandLine predicate. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where ProcessCommandLine contains "auto_prepend_file" or ProcessCommandLine contains "plesk_sys_driver.php" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Enumeration of /var/qmail/mailnames/ or Maildir/cur/ with find, ls, wc, grep, zip or tar, and the search_social.php and zip_mails.sh script names Unit 42 reports. FP: Plesk mail backup agents, migration jobs and admins sizing mailboxes.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
- KQL – Defender XDR assumes: matches regex with the (?i) prefix reproduces the CQL /i flag.
// HUNT: Mailbox enumeration, search and archive staging // MITRE: T1114.001, T1074.001 // CONF: medium FP: medium COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: mail backup agents, mailbox migrations, quota reporting scripts // TUNING: exclude your backup service account and parent process with !(UserName=svc-mailbackup) // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/(search_social\.php|zip_mails\.sh|\b(find|ls|wc|grep|zip|tar|cat)\b.{0,200}(\/var\/qmail\/mailnames|Maildir\/cur))/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator usersrc.process.name: Creator processtgt.process.name: Created process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline
// HUNT: Mailbox enumeration, search and archive staging
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1114.001, T1074.001
// CONF: medium | FP: medium
// FALSE POSITIVES: mail backup agents, mailbox migrations, quota reporting scripts
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the two helper script names, or a listing, search or archive tool aimed at the Plesk mail store or a Maildir folder.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Exclude the backup service account and its parent with a negated src.process.user predicate.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' (tgt.process.cmdline contains ('search_social.php', 'zip_mails.sh') or tgt.process.cmdline matches '\\b(find|ls|wc|grep|zip|tar|cat)\\b.{0,200}(/var/qmail/mailnames|Maildir/cur)')
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: Mailbox enumeration, search and archive staging
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1114.001, T1074.001
// CONF: medium | FP: medium
// FALSE POSITIVES: mail backup agents, mailbox migrations, quota reporting scripts
// EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate: the two helper script names, or a listing, search or archive tool aimed at the Plesk mail store or a Maildir folder.
// REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude the backup service account and its parent with a negated AccountName predicate.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine contains "search_social.php" or ProcessCommandLine contains "zip_mails.sh" or ProcessCommandLine matches regex @"(?i)\b(find|ls|wc|grep|zip|tar|cat)\b.{0,200}(/var/qmail/mailnames|Maildir/cur)"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: curl or wget uploads to transfer.sh, bashupload.com, filebin.net or catbox.moe, a tar of a *_dump.tar.gz sent with nc, and the dump.sqlite staging file. These are the exfiltration methods Unit 42 lists. FP: Developers and admins who use transfer.sh or filebin.net for legitimate file sharing.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
- KQL – Defender XDR assumes: matches regex with the (?i) prefix reproduces the CQL /i flag.
// HUNT: Database dump staging and exfiltration to file-hosting services or netcat // MITRE: T1567.002, T1048, T1074.001 // CONF: medium FP: medium COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: staff who share files through public hosting services, support bundles sent with curl // TUNING: allow-list approved upload destinations or users with !(UserName=jdoe) after a 14-day baseline // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/((curl|wget)\b.{0,300}(transfer\.sh|bashupload\.com|filebin\.net|catbox\.moe)|\bnc\b.{0,60}<\s*\S*_dump\.tar\.gz|tar\s+-czf\s+\/tmp\/\S+_dump\.tar\.gz|dump\.sqlite)/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator usersrc.process.name: Creator processtgt.process.name: Created process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline
// HUNT: Database dump staging and exfiltration to file-hosting services or netcat
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1567.002, T1048, T1074.001
// CONF: medium | FP: medium
// FALSE POSITIVES: staff who share files through public hosting services, support bundles sent with curl
// EQUIVALENCE: equivalent-with-schema-assumptions - Same four patterns: curl or wget aimed at a file-hosting domain, netcat fed from a dump archive, tar writing a dump archive under /tmp, and a dump.sqlite reference.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Allow-list approved upload destinations or users with a negated predicate after a 14-day baseline.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' tgt.process.cmdline matches '(curl|wget)\\b.{0,300}(transfer\\.sh|bashupload\\.com|filebin\\.net|catbox\\.moe)|\\bnc\\b.{0,60}<\\s*\\S*_dump\\.tar\\.gz|tar\\s+-czf\\s+/tmp/\\S+_dump\\.tar\\.gz|dump\\.sqlite'
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: Database dump staging and exfiltration to file-hosting services or netcat
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1567.002, T1048, T1074.001
// CONF: medium | FP: medium
// FALSE POSITIVES: staff who share files through public hosting services, support bundles sent with curl
// EQUIVALENCE: equivalent-with-schema-assumptions - Same four patterns: curl or wget aimed at a file-hosting domain, netcat fed from a dump archive, tar writing a dump archive under /tmp, and a dump.sqlite reference.
// REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents)
// TUNING: Allow-list approved upload destinations or accounts with a negated predicate after a 14-day baseline.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine matches regex @"(?i)(curl|wget)\b.{0,300}(transfer\.sh|bashupload\.com|filebin\.net|catbox\.moe)|\bnc\b.{0,60}<\s*\S*_dump\.tar\.gz|tar\s+-czf\s+/tmp/\S+_dump\.tar\.gz|dump\.sqlite"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: References to the sys-update.service unit and the sys-control-client binary on Linux, and the Onedrive Update\Updater.exe path on Windows. Unit 42 documents these as SysGoRAT persist sub-actions. Not limited to the Linux sensor because SysGoRAT also runs on Windows. FP: Low. The unit name and install paths are attacker-chosen masquerades.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: The separator in the Windows updater path is matched by a single non-alphanumeric character class.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
// HUNT: SysGoRAT persistence artifacts (systemd unit, binary name, Windows updater path) // MITRE: T1543.002, T1053.003, T1547.001 // CONF: high FP: low COST: low | REQUIRES: Linux or Windows sensor, ProcessRollup2 // FALSE POSITIVES: none expected beyond analysts running these names in a lab // LOOKBACK: 7d #event_simpleName=ProcessRollup2 | CommandLine=/(sys-update\.service|sys-control-client|Onedrive Update\\Updater\.exe)/i | table([@timestamp, ComputerName, aid, event_platform, UserName, ParentBaseFileName, FileName, CommandLine])
3 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typetgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator processtgt.process.name: Created process
Optional fields
src.process.user: Creator user
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, tgt.process.cmdline
// HUNT: SysGoRAT persistence artifacts (systemd unit, binary name, Windows updater path) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1543.002, T1053.003, T1547.001 // CONF: high | FP: low // FALSE POSITIVES: none expected beyond analysts running these names in a lab // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on both Linux and Windows agents: the systemd unit name, the binary name, or the Windows updater path in the created command line. The path separator is matched by a single non-alphanumeric character so the test works for either slash style and needs no backslash escaping. // REQUIRES: SentinelOne process-creation telemetry on Linux and Windows agents (Process Creation events) // TUNING: No tuning expected beyond analysts running these names in a lab; exclude those hosts by endpoint.name. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A process the agent did not observe starting is not captured. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.cmdline matches 'sys-update\\.service|sys-control-client|Onedrive Update[^a-z0-9]Updater\\.exe' | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: SysGoRAT persistence artifacts (systemd unit, binary name, Windows updater path) // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1543.002, T1053.003, T1547.001 // CONF: high | FP: low // FALSE POSITIVES: none expected beyond analysts running these names in a lab // EQUIVALENCE: equivalent-with-schema-assumptions - Same predicate on Linux and Windows sensors: the systemd unit name, the binary name, or the Windows updater path in the created command line. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: No tuning expected beyond analysts running these names in a lab; exclude those hosts by DeviceName. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A process the sensor did not observe starting is not captured. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where ProcessCommandLine matches regex @"(?i)(sys-update\.service|sys-control-client|Onedrive Update\\Updater\.exe)" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Any of the ten SHA-256 values Unit 42 publishes seen on a process start. Only ELF binaries (the PwnKit binary, the scanner builds, the GSocket binary and any compiled backdoor) can match here. PHP web shell hashes are script files that a process-start event never carries, so pair this card with a file-system hash sweep. FP: Very low. Hash matches are exact.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The CQL tests process execution only; a hash on a file that is written but never run is not matched.
- PowerQuery assumes: tgt.process.image.sha256 is populated on the tenant; confirm with the readiness test.
- PowerQuery assumes: in:anycase makes the hash comparison case-insensitive.
- KQL – Defender XDR: Microsoft marks SHA256 as usually not populated in this table, so an empty result is not proof of absence.
- KQL – Defender XDR: Advanced Hunting keeps 30 days of data, the same window as the CQL.
- KQL – Defender XDR: The CQL tests process execution only; a hash on a file that is written but never run is not matched.
- KQL – Defender XDR assumes: SHA256 is populated in DeviceProcessEvents on the tenant; confirm with the readiness test.
// HUNT: Known campaign hashes executing // MITRE: T1204, T1105 // CONF: high FP: low COST: low | REQUIRES: Linux or Windows sensor, ProcessRollup2 // FALSE POSITIVES: none expected for an exact hash match // LOOKBACK: 30d #event_simpleName=ProcessRollup2 | in(SHA256HashData, values=["2bf7992e6260c1a98c709fa98ec766fb9f27692f338b30b43ac821b824fd849e", "27d799ceadb570bfca890d4c2572314afe57eecf14083d30409da15afdfc4704", "d73186cea6cf2cf3d48c09139a9d15521365aab675787b4e7a6f81767331c9fd", "9e45830171eb607cf2c0fc80f5cc9cc3db39bb937032136990383a595f6f151e", "c527b94e3d21824a674face4cd9d862e536b60ccbf54573839e3360f99188343", "d94f75a70b5cabaf786ac57177ed841732e62bdcc9a29e06e5b41d9be567bcfa", "44e83f84a5d5219e2f7c3cf1e4f02489cae81361227f46946abe4b8d8245b879", "1505a3a727f8899b2ad343519f7bf9c438b8b802f8d6b854f5db3b52f857c76a", "76c58fad4f70cf277a15a499b9a2151ac60e7a6b5c7a9ab684843dcc19f0d0a5", "b1e82c6b0caea177e8bb71ad826867f509c65f0a43a651b50253e7c726566eac"]) | table([@timestamp, ComputerName, aid, event_platform, UserName, FileName, ImageFileName, SHA256HashData])
3 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typetgt.process.image.sha256: Image hash
Recommended fields
endpoint.name: Hosttgt.process.name: Created processtgt.process.image.path: Image path
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.image.sha256 = * | limit 5 | columns event.time, event.type, tgt.process.image.sha256
// HUNT: Known campaign hashes executing
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1204, T1105
// CONF: high | FP: low
// FALSE POSITIVES: none expected for an exact hash match
// EQUIVALENCE: equivalent-with-schema-assumptions - Same ten SHA-256 values matched against the created process image hash on Linux and Windows agents.
// REQUIRES: SentinelOne process-creation telemetry with image SHA-256 populated
// TUNING: No tuning expected for an exact hash match.
// LOOKBACK: 30d on the CQL tab; set the console time range to 30d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The CQL tests process execution only; a hash on a file that is written but never run is not matched.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' tgt.process.image.sha256 in:anycase ('2bf7992e6260c1a98c709fa98ec766fb9f27692f338b30b43ac821b824fd849e', '27d799ceadb570bfca890d4c2572314afe57eecf14083d30409da15afdfc4704', 'd73186cea6cf2cf3d48c09139a9d15521365aab675787b4e7a6f81767331c9fd', '9e45830171eb607cf2c0fc80f5cc9cc3db39bb937032136990383a595f6f151e', 'c527b94e3d21824a674face4cd9d862e536b60ccbf54573839e3360f99188343', 'd94f75a70b5cabaf786ac57177ed841732e62bdcc9a29e06e5b41d9be567bcfa', '44e83f84a5d5219e2f7c3cf1e4f02489cae81361227f46946abe4b8d8245b879', '1505a3a727f8899b2ad343519f7bf9c438b8b802f8d6b854f5db3b52f857c76a', '76c58fad4f70cf277a15a499b9a2151ac60e7a6b5c7a9ab684843dcc19f0d0a5', 'b1e82c6b0caea177e8bb71ad826867f509c65f0a43a651b50253e7c726566eac')
| columns event.time, endpoint.name, src.process.user, tgt.process.name, tgt.process.image.path, tgt.process.image.sha256
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeSHA256: Image hash
Recommended fields
DeviceName: HostFileName: Created processFolderPath: Image path
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | where isnotempty(SHA256) | project Timestamp, SHA256 | take 5
// HUNT: Known campaign hashes executing
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1204, T1105
// CONF: high | FP: low
// FALSE POSITIVES: none expected for an exact hash match
// EQUIVALENCE: equivalent-with-schema-assumptions - Same ten SHA-256 values matched against the created process hash. The CQL carries SHA-256 only, so there is no SHA1 pivot to fall back on.
// REQUIRES: Defender for Endpoint process-creation telemetry with SHA256 populated
// TUNING: No tuning expected for an exact hash match.
// LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 30d)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Microsoft marks SHA256 as usually not populated in this table, so an empty result is not proof of absence. Advanced Hunting keeps 30 days of data, the same window as the CQL. The CQL tests process execution only; a hash on a file that is written but never run is not matched.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where SHA256 in~ ("2bf7992e6260c1a98c709fa98ec766fb9f27692f338b30b43ac821b824fd849e", "27d799ceadb570bfca890d4c2572314afe57eecf14083d30409da15afdfc4704", "d73186cea6cf2cf3d48c09139a9d15521365aab675787b4e7a6f81767331c9fd", "9e45830171eb607cf2c0fc80f5cc9cc3db39bb937032136990383a595f6f151e", "c527b94e3d21824a674face4cd9d862e536b60ccbf54573839e3360f99188343", "d94f75a70b5cabaf786ac57177ed841732e62bdcc9a29e06e5b41d9be567bcfa", "44e83f84a5d5219e2f7c3cf1e4f02489cae81361227f46946abe4b8d8245b879", "1505a3a727f8899b2ad343519f7bf9c438b8b802f8d6b854f5db3b52f857c76a", "76c58fad4f70cf277a15a499b9a2151ac60e7a6b5c7a9ab684843dcc19f0d0a5", "b1e82c6b0caea177e8bb71ad826867f509c65f0a43a651b50253e7c726566eac")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, FolderPath, SHA256
| sort by Timestamp desc
| take 200Looks for: NetworkConnectIP4 to any of the 17 IPs Unit 42 lists. SysGoRAT defaults to 104.194.158.65 on port 443, but the operator can change it on the command line, so a miss does not clear a host. FP: IPs on shared hosting providers can be reused by other tenants over time, so confirm the process and timing before acting.
Known limitations and deployment notes
- PowerQuery: Connections the agent did not record are not captured.
- PowerQuery assumes: dst.ip.address holds the remote address of the connection.
- PowerQuery assumes: Both inbound and outbound IP Connect events are matched, as the CQL remote-address test does not test direction.
- KQL – Defender XDR: Connections the sensor did not record are not captured.
- KQL – Defender XDR: Advanced Hunting keeps 30 days of data, the same window as the CQL.
- KQL – Defender XDR assumes: RemoteIP holds the remote address of the connection.
// HUNT: Outbound connections to the listed campaign IPs // MITRE: T1071.001, T1095, T1571 // CONF: medium FP: low COST: low | REQUIRES: Linux or Windows sensor, NetworkConnectIP4 // FALSE POSITIVES: reuse of the same IP by an unrelated hosting tenant after the campaign ended // LOOKBACK: 30d #event_simpleName=NetworkConnectIP4 | in(RemoteAddressIP4, values=["45.88.188.140", "198.23.185.234", "138.68.244.146", "185.21.136.6", "72.61.89.179", "104.194.158.65", "109.224.53.140", "162.243.175.162", "154.93.37.228", "141.164.58.87", "88.80.150.232", "88.119.167.57", "173.212.247.23", "104.248.131.53", "147.182.224.216", "93.93.112.57", "192.210.183.17"]) | table([@timestamp, ComputerName, aid, event_platform, ContextProcessId, RemoteAddressIP4, RemotePort])
3 required fields · View requirements
Required telemetry
- IP Connect events
Required fields
event.time: Event timeevent.type: Event typedst.ip.address: Remote address
Recommended fields
endpoint.name: Hostsrc.process.name: Connecting processdst.port.number: Remote port
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'IP Connect' dst.ip.address = * | limit 5 | columns event.time, event.type, dst.ip.address
// HUNT: Outbound connections to the listed campaign IPs
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1071.001, T1095, T1571
// CONF: medium | FP: low
// FALSE POSITIVES: reuse of the same IP by an unrelated hosting tenant after the campaign ended
// EQUIVALENCE: equivalent-with-schema-assumptions - Same seventeen remote addresses matched against the destination address of a connection event on Linux and Windows agents. The CQL matches the remote address without a direction test, and so does this query.
// REQUIRES: SentinelOne network telemetry (IP Connect events)
// TUNING: Unrelated tenants may reuse these addresses after the campaign; confirm the process before escalating.
// LOOKBACK: 30d on the CQL tab; set the console time range to 30d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Connections the agent did not record are not captured.
// VALIDATION LEVEL: static-reviewed
event.type = 'IP Connect' dst.ip.address in ('45.88.188.140', '198.23.185.234', '138.68.244.146', '185.21.136.6', '72.61.89.179', '104.194.158.65', '109.224.53.140', '162.243.175.162', '154.93.37.228', '141.164.58.87', '88.80.150.232', '88.119.167.57', '173.212.247.23', '104.248.131.53', '147.182.224.216', '93.93.112.57', '192.210.183.17')
| columns event.time, endpoint.name, src.process.name, src.ip.address, dst.ip.address, dst.port.number
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceNetworkEvents
Required fields
Timestamp: Event timeRemoteIP: Remote address
Recommended fields
DeviceName: HostInitiatingProcessFileName: Connecting processRemotePort: Remote port
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceNetworkEvents | where Timestamp > ago(1d) | project Timestamp, RemoteIP | take 5
// HUNT: Outbound connections to the listed campaign IPs
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1071.001, T1095, T1571
// CONF: medium | FP: low
// FALSE POSITIVES: reuse of the same IP by an unrelated hosting tenant after the campaign ended
// EQUIVALENCE: equivalent-with-schema-assumptions - Same seventeen remote addresses matched against RemoteIP. The CQL matches the remote address without a direction test, and so does this query.
// REQUIRES: Defender for Endpoint network telemetry (DeviceNetworkEvents)
// TUNING: Unrelated tenants may reuse these addresses after the campaign; confirm the process before escalating.
// LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 30d)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Connections the sensor did not record are not captured. Advanced Hunting keeps 30 days of data, the same window as the CQL.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceNetworkEvents
| where Timestamp >= ago(30d)
| where RemoteIP in ("45.88.188.140", "198.23.185.234", "138.68.244.146", "185.21.136.6", "72.61.89.179", "104.194.158.65", "109.224.53.140", "162.243.175.162", "154.93.37.228", "141.164.58.87", "88.80.150.232", "88.119.167.57", "173.212.247.23", "104.248.131.53", "147.182.224.216", "93.93.112.57", "192.210.183.17")
| project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemotePort
| sort by Timestamp desc
| take 200Looks for: DnsRequest for magento.ink, solidmonpe.com, wibu-bau-bawang.online or beraskencur.site and their subdomains. FP: Very low. Validate that your Linux sensor version emits DnsRequest before relying on this query; DNS resolver or firewall logs are the fallback.
Known limitations and deployment notes
- PowerQuery: The DNS Resolved event on Linux agents has to be confirmed on the tenant; if it is not emitted this query returns nothing.
- PowerQuery: The field is event.dns.request; some schema versions name it dns.request, so the readiness test prints both.
- PowerQuery assumes: event.dns.request holds the queried name.
- PowerQuery assumes: DNS Resolved events are emitted for Linux agents on the tenant.
- KQL – Defender XDR: DnsQueryResponse coverage on Linux sensors has to be confirmed on the tenant.
- KQL – Defender XDR: Advanced Hunting keeps 30 days of data, the same window as the CQL.
- KQL – Defender XDR assumes: DnsQueryResponse events are recorded for the hosts in scope.
- KQL – Defender XDR assumes: The queried name is in the DnsQueryString or QueryName key of AdditionalFields; the readiness test shows which one the tenant fills.
// HUNT: DNS lookups for the four campaign domains // MITRE: T1071.004, T1583.001 // CONF: high FP: low COST: low | REQUIRES: Linux or Windows sensor, DnsRequest (validate Linux emission in tenant) // FALSE POSITIVES: researchers or sinkholes resolving the domains // LOOKBACK: 30d #event_simpleName=DnsRequest | DomainName=/(^|\.)(magento\.ink|solidmonpe\.com|wibu-bau-bawang\.online|beraskencur\.site)$/i | table([@timestamp, ComputerName, aid, event_platform, ContextProcessId, DomainName])
3 required fields · View requirements
Required telemetry
- DNS Resolved events
Required fields
event.time: Event timeevent.type: Event typeevent.dns.request: Queried name
Recommended fields
endpoint.name: Hostsrc.process.name: Requesting process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'DNS Resolved' event.dns.request = * | limit 5 | columns event.time, event.type, event.dns.request
// HUNT: DNS lookups for the four campaign domains
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1071.004, T1583.001
// CONF: high | FP: low
// FALSE POSITIVES: researchers or sinkholes resolving the domains
// EQUIVALENCE: equivalent-with-schema-assumptions - Same four domains matched as an exact name or as a parent of the queried name. DNS Resolved events carry the requesting process under src.process.
// REQUIRES: SentinelOne DNS telemetry (DNS Resolved events) on Linux and Windows agents
// TUNING: Researchers or sinkholes resolving the domains are the only expected benign hits.
// LOOKBACK: 30d on the CQL tab; set the console time range to 30d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The DNS Resolved event on Linux agents has to be confirmed on the tenant; if it is not emitted this query returns nothing. The field is event.dns.request; some schema versions name it dns.request, so the readiness test prints both.
// VALIDATION LEVEL: static-reviewed
event.type = 'DNS Resolved' (event.dns.request in:anycase ('magento.ink', 'solidmonpe.com', 'wibu-bau-bawang.online', 'beraskencur.site') or event.dns.request matches '[.](magento[.]ink|solidmonpe[.]com|wibu-bau-bawang[.]online|beraskencur[.]site)$')
| columns event.time, endpoint.name, src.process.name, event.dns.request
| limit 200Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: Action typeAdditionalFields: Event details
Recommended fields
DeviceName: HostInitiatingProcessFileName: Requesting process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, ActionType, AdditionalFields | take 5
// HUNT: DNS lookups for the four campaign domains
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1071.004, T1583.001
// CONF: high | FP: low
// FALSE POSITIVES: researchers or sinkholes resolving the domains
// EQUIVALENCE: equivalent-with-schema-assumptions - Same four domains matched as an exact name or as a parent of the queried name. There is no endpoint DNS table, so the name is read from AdditionalFields on DnsQueryResponse events.
// REQUIRES: Defender for Endpoint DNS telemetry (DeviceEvents, ActionType DnsQueryResponse)
// TUNING: Researchers or sinkholes resolving the domains are the only expected benign hits.
// LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 30d)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DnsQueryResponse coverage on Linux sensors has to be confirmed on the tenant. Advanced Hunting keeps 30 days of data, the same window as the CQL.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceEvents
| where Timestamp >= ago(30d)
| where ActionType == "DnsQueryResponse"
| extend DnsName = tolower(tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])))
| where DnsName in~ ("magento.ink", "solidmonpe.com", "wibu-bau-bawang.online", "beraskencur.site") or DnsName endswith ".magento.ink" or DnsName endswith ".solidmonpe.com" or DnsName endswith ".wibu-bau-bawang.online" or DnsName endswith ".beraskencur.site"
| project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessFileName, DnsName
| sort by Timestamp desc
| take 200Looks for: DNS lookups for gsocket.io, the public relay GSocket's gs-netcat connects out to, and for the four file-hosting services used for exfiltration. These are legitimate services, so this is a hunt lead, never an IOC import. FP: transfer.sh, filebin.net and catbox.moe have many legitimate users. Treat results as leads to correlate with Q4 and Q11.
Known limitations and deployment notes
- PowerQuery: The DNS Resolved event on Linux agents has to be confirmed on the tenant; if it is not emitted this query returns nothing.
- PowerQuery: The field is event.dns.request; some schema versions name it dns.request, so the readiness test prints both.
- PowerQuery assumes: event.dns.request holds the queried name.
- PowerQuery assumes: DNS Resolved events are emitted for Linux agents on the tenant.
- KQL – Defender XDR: DnsQueryResponse coverage on Linux sensors has to be confirmed on the tenant.
- KQL – Defender XDR assumes: DnsQueryResponse events are recorded for the hosts in scope.
- KQL – Defender XDR assumes: The queried name is in the DnsQueryString or QueryName key of AdditionalFields; the readiness test shows which one the tenant fills.
// HUNT: GSocket relay and file-hosting DNS lookups (hunt only) // MITRE: T1090, T1567.002 // CONF: low FP: medium COST: low | REQUIRES: Linux or Windows sensor, DnsRequest (validate Linux emission in tenant) // FALSE POSITIVES: staff using public file-hosting services, developers testing GSocket // TUNING: scope to server host groups only with a ComputerName or host group filter, where outbound web browsing should not occur // LOOKBACK: 14d #event_simpleName=DnsRequest | DomainName=/(^|\.)(gsocket\.io|transfer\.sh|bashupload\.com|filebin\.net|catbox\.moe)$/i | groupBy([ComputerName, DomainName], function=count(as=lookups)) | sort(lookups, order=desc, limit=200)
4 required fields · View requirements
Required telemetry
- DNS Resolved events
Required fields
event.time: Event timeevent.type: Event typeevent.dns.request: Queried nameendpoint.name: Host
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'DNS Resolved' event.dns.request = * | limit 5 | columns event.time, event.type, event.dns.request, endpoint.name
// HUNT: GSocket relay and file-hosting DNS lookups (hunt only)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1090, T1567.002
// CONF: low | FP: medium
// FALSE POSITIVES: staff using public file-hosting services, developers testing GSocket
// EQUIVALENCE: equivalent-with-schema-assumptions - Same five domains matched as an exact name or as a parent of the queried name, counted per host and name and sorted by count, as in the CQL.
// REQUIRES: SentinelOne DNS telemetry (DNS Resolved events) on Linux and Windows agents
// TUNING: Scope to server host groups where outbound web browsing should not occur, by adding an endpoint.name predicate.
// LOOKBACK: 14d on the CQL tab; set the console time range to 14d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The DNS Resolved event on Linux agents has to be confirmed on the tenant; if it is not emitted this query returns nothing. The field is event.dns.request; some schema versions name it dns.request, so the readiness test prints both.
// VALIDATION LEVEL: static-reviewed
event.type = 'DNS Resolved' (event.dns.request in:anycase ('gsocket.io', 'transfer.sh', 'bashupload.com', 'filebin.net', 'catbox.moe') or event.dns.request matches '[.](gsocket[.]io|transfer[.]sh|bashupload[.]com|filebin[.]net|catbox[.]moe)$')
| group lookups=count() by endpoint.name, event.dns.request
| sort -lookups
| limit 200Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: Action typeAdditionalFields: Event detailsDeviceName: Host
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, ActionType, AdditionalFields, DeviceName | take 5
// HUNT: GSocket relay and file-hosting DNS lookups (hunt only)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1090, T1567.002
// CONF: low | FP: medium
// FALSE POSITIVES: staff using public file-hosting services, developers testing GSocket
// EQUIVALENCE: equivalent-with-schema-assumptions - Same five domains matched as an exact name or as a parent of the queried name, counted per host and name and sorted by count, as in the CQL.
// REQUIRES: Defender for Endpoint DNS telemetry (DeviceEvents, ActionType DnsQueryResponse)
// TUNING: Scope to server device groups where outbound web browsing should not occur, by adding a DeviceName predicate.
// LOOKBACK: 14d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DnsQueryResponse coverage on Linux sensors has to be confirmed on the tenant.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0
DeviceEvents
| where Timestamp >= ago(14d)
| where ActionType == "DnsQueryResponse"
| extend DnsName = tolower(tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])))
| where DnsName in~ ("gsocket.io", "transfer.sh", "bashupload.com", "filebin.net", "catbox.moe") or DnsName endswith ".gsocket.io" or DnsName endswith ".transfer.sh" or DnsName endswith ".bashupload.com" or DnsName endswith ".filebin.net" or DnsName endswith ".catbox.moe"
| summarize lookups = count() by DeviceName, DnsName
| sort by lookups desc
| take 200Looks for: sshpass with StrictHostKeyChecking=no, the revsocks and pysoxy proxy tools, GSOCKET_ARGS set inline, and echo appending a key to authorized_keys. All appear in Unit 42's lateral movement and persistence sections. FP: Automation that uses sshpass, and admins who add keys by echo.
Known limitations and deployment notes
- PowerQuery: A process the agent did not observe starting is not captured.
- PowerQuery: The match is on the command line text only; an obfuscated or encoded command line is not decoded.
- PowerQuery assumes: endpoint.os holds the lowercase value linux for Linux agents.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL /i flag.
- KQL – Defender XDR: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process on Linux sensors.
- KQL – Defender XDR assumes: matches regex with the (?i) prefix reproduces the CQL /i flag.
// HUNT: sshpass lateral movement, SOCKS proxy tools and authorized_keys injection // MITRE: T1021.004, T1098.004, T1090 // CONF: medium FP: medium COST: low | REQUIRES: Linux sensor, ProcessRollup2 // FALSE POSITIVES: legacy automation that uses sshpass, admins appending keys manually // TUNING: exclude known jump hosts and automation accounts with !(UserName=svc-automation) after baselining // LOOKBACK: 7d #event_simpleName=ProcessRollup2 event_platform=Lin | CommandLine=/(sshpass\s+-p\s.{0,200}StrictHostKeyChecking=no|\b(revsocks|pysoxy)\b|GSOCKET_ARGS=|echo\s.{0,600}>>\s*\S*\.ssh\/authorized_keys)/i | table([@timestamp, ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine])
4 required fields · View requirements
Required telemetry
- Process Creation events
Required fields
event.time: Event timeevent.type: Event typeendpoint.os: Operating systemtgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator usersrc.process.name: Creator processtgt.process.name: Created process
Fallbacks
endpoint.name→agent.uuid: Changes the displayed host identifier only.
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.os, tgt.process.cmdline
// HUNT: sshpass lateral movement, SOCKS proxy tools and authorized_keys injection
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1021.004, T1098.004, T1090
// CONF: medium | FP: medium
// FALSE POSITIVES: legacy automation that uses sshpass, admins appending keys manually
// EQUIVALENCE: equivalent-with-schema-assumptions - Same four patterns: sshpass with host-key checking off, the revsocks and pysoxy proxy tools, the GSOCKET_ARGS variable, and an echo appended to authorized_keys.
// REQUIRES: SentinelOne Linux process-creation telemetry (Process Creation events)
// TUNING: Exclude known jump hosts and automation accounts with a negated src.process.user predicate after baselining.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the agent did not observe starting is not captured. The match is on the command line text only; an obfuscated or encoded command line is not decoded.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' endpoint.os = 'linux' tgt.process.cmdline matches 'sshpass\\s+-p\\s.{0,200}StrictHostKeyChecking=no|\\b(revsocks|pysoxy)\\b|GSOCKET_ARGS=|echo\\s.{0,600}>>\\s*\\S*\\.ssh/authorized_keys'
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
DeviceName: HostAccountName: AccountInitiatingProcessFileName: Initiating processFileName: Created process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: sshpass lateral movement, SOCKS proxy tools and authorized_keys injection
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1021.004, T1098.004, T1090
// CONF: medium | FP: medium
// FALSE POSITIVES: legacy automation that uses sshpass, admins appending keys manually
// EQUIVALENCE: equivalent-with-schema-assumptions - Same four patterns: sshpass with host-key checking off, the revsocks and pysoxy proxy tools, the GSOCKET_ARGS variable, and an echo appended to authorized_keys.
// REQUIRES: Defender for Endpoint on Linux process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude known jump hosts and automation accounts with a negated AccountName predicate after baselining.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: DeviceProcessEvents has no platform column, so the query is not limited to Linux hosts; scope it with a Linux device group. A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine matches regex @"(?i)sshpass\s+-p\s.{0,200}StrictHostKeyChecking=no|\b(revsocks|pysoxy)\b|GSOCKET_ARGS=|echo\s.{0,600}>>\s*\S*\.ssh/authorized_keys"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200CrowdStrike Custom IOA Recommendations
These IOA candidates map to Linux process-creation behavior that survives infrastructure rotation. Linux Custom IOA rule-type support depends on sensor and platform version, so confirm in your tenant before building. Every IOA starts in detect mode; none is set to prevent.
IOA-1 · Reverse shell command line HIGH PRIORITY
Promote Q2. Pattern: Process Creation (Linux), command line matches mkfifo /tmp/f, /dev/tcp/ redirect or the Python socket and dup2 form. Exclusions: approved red team hosts. Deployment: detect first.
IOA-2 · Hidden root helpers and SysGoRAT binary names
Promote Q4. Pattern: Process Creation, image name is .libpython-helper, .libsystemd-helper, .tourch, sys-control-client or ea_install, or image path under /dev/shm/.gs-. Exclusions: none identified. Deployment: detect first; never use prevent on gs-netcat by name because it is a legitimate open-source tool.
IOA-3 · sudo alias and password log
Promote Q7. Pattern: command line contains alias sudo= together with .bashrc, or Solarwinds.StatusLog. Exclusions: approved sudo wrappers. Deployment: detect.
IOA-4 · auto_prepend_file change
Promote Q10. Pattern: command line contains auto_prepend_file with sed, echo, tee or php -d. Exclusions: config-management parents and approved WAF prepend files. Deployment: detect, tune two weeks.
IOA-5 · Security agent termination attempt
Promote Q9. Pattern: pkill, killall or systemctl stop against security agent service names. Exclusions: patching and upgrade parents. Deployment: detect.
IOC Management
Import the Section 10 CSV. Every row is detect. Do not import python3, bash, nc, curl, gs-netcat by name, gsocket.io, transfer.sh, bashupload.com, filebin.net or catbox.moe as IOCs.
Machine-Readable IOC Appendix
type,value,action,severity,expiration,description,tags sha256,2bf7992e6260c1a98c709fa98ec766fb9f27692f338b30b43ac821b824fd849e,detect,high,2027-04-17,CL-UNK-1211 React2Shell (CVE-2025-55182) scanner build,campaign:CL-UNK-1211 sha256,27d799ceadb570bfca890d4c2572314afe57eecf14083d30409da15afdfc4704,detect,high,2027-04-17,CL-UNK-1211 React2Shell (CVE-2025-55182) scanner build,campaign:CL-UNK-1211 sha256,d73186cea6cf2cf3d48c09139a9d15521365aab675787b4e7a6f81767331c9fd,detect,high,2027-04-17,CL-UNK-1211 React2Shell (CVE-2025-55182) scanner build,campaign:CL-UNK-1211 sha256,9e45830171eb607cf2c0fc80f5cc9cc3db39bb937032136990383a595f6f151e,detect,high,2027-04-17,CL-UNK-1211 React2Shell (CVE-2025-55182) scanner build,campaign:CL-UNK-1211 sha256,c527b94e3d21824a674face4cd9d862e536b60ccbf54573839e3360f99188343,detect,high,2027-04-17,CL-UNK-1211 custom shell backdoor for privilege escalation,campaign:CL-UNK-1211 sha256,d94f75a70b5cabaf786ac57177ed841732e62bdcc9a29e06e5b41d9be567bcfa,detect,high,2027-04-17,CL-UNK-1211 GSocket reverse shell binary,campaign:CL-UNK-1211 sha256,44e83f84a5d5219e2f7c3cf1e4f02489cae81361227f46946abe4b8d8245b879,detect,high,2027-04-17,CL-UNK-1211 PwnKit (CVE-2021-4034) exploit binary,campaign:CL-UNK-1211 sha256,1505a3a727f8899b2ad343519f7bf9c438b8b802f8d6b854f5db3b52f857c76a,detect,high,2027-04-17,CL-UNK-1211 PHP web shell,campaign:CL-UNK-1211 sha256,76c58fad4f70cf277a15a499b9a2151ac60e7a6b5c7a9ab684843dcc19f0d0a5,detect,high,2027-04-17,CL-UNK-1211 PHP web shell,campaign:CL-UNK-1211 sha256,b1e82c6b0caea177e8bb71ad826867f509c65f0a43a651b50253e7c726566eac,detect,high,2027-04-17,CL-UNK-1211 PHP web shell,campaign:CL-UNK-1211 ipv4,45.88.188.140,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,198.23.185.234,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,138.68.244.146,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,185.21.136.6,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,72.61.89.179,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,104.194.158.65,detect,high,2027-04-17,CL-UNK-1211 SysGoRAT default C2,campaign:CL-UNK-1211 ipv4,109.224.53.140,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,162.243.175.162,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,154.93.37.228,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,141.164.58.87,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,88.80.150.232,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,88.119.167.57,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,173.212.247.23,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,104.248.131.53,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,147.182.224.216,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,93.93.112.57,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 ipv4,192.210.183.17,detect,medium,2027-04-17,CL-UNK-1211 C2 or reverse-shell infrastructure,campaign:CL-UNK-1211 domain,magento.ink,detect,high,2027-04-17,CL-UNK-1211 campaign domain,campaign:CL-UNK-1211 domain,solidmonpe.com,detect,high,2027-04-17,CL-UNK-1211 campaign domain,campaign:CL-UNK-1211 domain,wibu-bau-bawang.online,detect,high,2027-04-17,CL-UNK-1211 campaign domain,campaign:CL-UNK-1211 domain,beraskencur.site,detect,high,2027-04-17,CL-UNK-1211 campaign domain,campaign:CL-UNK-1211
indicatorType,indicatorValue,action,title,description,expirationTime,severity,recommendedActions,rbacGroups,category,mitretechniques,GenerateAlert FileSha256,2bf7992e6260c1a98c709fa98ec766fb9f27692f338b30b43ac821b824fd849e,Audit,CL-UNK-1211 React2Shell,CL-UNK-1211 React2Shell (CVE-2025-55182) scanner build,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,27d799ceadb570bfca890d4c2572314afe57eecf14083d30409da15afdfc4704,Audit,CL-UNK-1211 React2Shell,CL-UNK-1211 React2Shell (CVE-2025-55182) scanner build,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,d73186cea6cf2cf3d48c09139a9d15521365aab675787b4e7a6f81767331c9fd,Audit,CL-UNK-1211 React2Shell,CL-UNK-1211 React2Shell (CVE-2025-55182) scanner build,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,9e45830171eb607cf2c0fc80f5cc9cc3db39bb937032136990383a595f6f151e,Audit,CL-UNK-1211 React2Shell,CL-UNK-1211 React2Shell (CVE-2025-55182) scanner build,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,c527b94e3d21824a674face4cd9d862e536b60ccbf54573839e3360f99188343,Audit,CL-UNK-1211 custom shell backdoor for privilege escalation,CL-UNK-1211 custom shell backdoor for privilege escalation,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,d94f75a70b5cabaf786ac57177ed841732e62bdcc9a29e06e5b41d9be567bcfa,Audit,CL-UNK-1211 GSocket reverse shell binary,CL-UNK-1211 GSocket reverse shell binary,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,44e83f84a5d5219e2f7c3cf1e4f02489cae81361227f46946abe4b8d8245b879,Audit,CL-UNK-1211 PwnKit,CL-UNK-1211 PwnKit (CVE-2021-4034) exploit binary,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,1505a3a727f8899b2ad343519f7bf9c438b8b802f8d6b854f5db3b52f857c76a,Audit,CL-UNK-1211 PHP web shell,CL-UNK-1211 PHP web shell,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,76c58fad4f70cf277a15a499b9a2151ac60e7a6b5c7a9ab684843dcc19f0d0a5,Audit,CL-UNK-1211 PHP web shell,CL-UNK-1211 PHP web shell,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha256,b1e82c6b0caea177e8bb71ad826867f509c65f0a43a651b50253e7c726566eac,Audit,CL-UNK-1211 PHP web shell,CL-UNK-1211 PHP web shell,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True IpAddress,45.88.188.140,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,198.23.185.234,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,138.68.244.146,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,185.21.136.6,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,72.61.89.179,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,104.194.158.65,Audit,CL-UNK-1211 SysGoRAT default C2,CL-UNK-1211 SysGoRAT default C2,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True IpAddress,109.224.53.140,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,162.243.175.162,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,154.93.37.228,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,141.164.58.87,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,88.80.150.232,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,88.119.167.57,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,173.212.247.23,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,104.248.131.53,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,147.182.224.216,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,93.93.112.57,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True IpAddress,192.210.183.17,Audit,CL-UNK-1211 C2 or reverse-shell infrastructure,CL-UNK-1211 C2 or reverse-shell infrastructure,2027-04-17T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True DomainName,magento.ink,Audit,CL-UNK-1211 campaign domain,CL-UNK-1211 campaign domain,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True DomainName,solidmonpe.com,Audit,CL-UNK-1211 campaign domain,CL-UNK-1211 campaign domain,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True DomainName,wibu-bau-bawang.online,Audit,CL-UNK-1211 campaign domain,CL-UNK-1211 campaign domain,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True DomainName,beraskencur.site,Audit,CL-UNK-1211 campaign domain,CL-UNK-1211 campaign domain,2027-04-17T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
Column names and allowed values are from Microsoft's documented parameter table. Check each expirationTime before importing: an indicator whose date has passed is already expired. Download the sample CSV from the Import page to confirm the column order before a bulk import. Each file takes at most 500 indicators. Learn describes the import per entity type, so if a mixed file is rejected, split it by indicatorType. An imported indicator does nothing unless the matching Advanced features are on (for example Custom network indicators and Allow or block file).
This pack does not ship a SentinelOne import block: the import format could not be verified against SentinelOne's own documentation. Export a sample from your console and the block can be added with confidence.
2bf7992e6260c1a98c709fa98ec766fb9f27692f338b30b43ac821b824fd849e 27d799ceadb570bfca890d4c2572314afe57eecf14083d30409da15afdfc4704 d73186cea6cf2cf3d48c09139a9d15521365aab675787b4e7a6f81767331c9fd 9e45830171eb607cf2c0fc80f5cc9cc3db39bb937032136990383a595f6f151e c527b94e3d21824a674face4cd9d862e536b60ccbf54573839e3360f99188343 d94f75a70b5cabaf786ac57177ed841732e62bdcc9a29e06e5b41d9be567bcfa 44e83f84a5d5219e2f7c3cf1e4f02489cae81361227f46946abe4b8d8245b879 1505a3a727f8899b2ad343519f7bf9c438b8b802f8d6b854f5db3b52f857c76a 76c58fad4f70cf277a15a499b9a2151ac60e7a6b5c7a9ab684843dcc19f0d0a5 b1e82c6b0caea177e8bb71ad826867f509c65f0a43a651b50253e7c726566eac
45.88.188.140 198.23.185.234 138.68.244.146 185.21.136.6 72.61.89.179 104.194.158.65 109.224.53.140 162.243.175.162 154.93.37.228 141.164.58.87 88.80.150.232 88.119.167.57 173.212.247.23 104.248.131.53 147.182.224.216 93.93.112.57 192.210.183.17 magento.ink solidmonpe.com wibu-bau-bawang.online beraskencur.site
# Behavioral signatures (hunt, never IOC import). Source: Unit 42, 2026-10-15 file /usr/lib/php/plesk_sys_driver.php web shell dropped as a fake Plesk file file /usr/lib/x86_64-linux-gnu/.libpython-helper renamed Python 3, run with os.setuid(0) file .libsystemd-helper custom SUID root shell file .tourch renamed /bin/bash with u+s set file /dev/shm/.gs-10085/ GSocket gs-netcat and gs-dbus staging file /etc/systemd/system/sys-update.service SysGoRAT systemd persistence file Solarwinds.StatusLog.txt sudo password capture log file search_social.php, zip_mails.sh, dump.sqlite mailbox and database staging dir /var/qmail/mailnames/ mailbox enumeration target pipe /tmp/f mkfifo named pipe for the nc reverse shell string auto_prepend_file rewritten under /etc/php/ and /opt/plesk/php/ string RedTeamOps2025, pentest123 planted red-team markers proc php-fpm parent -> sh/bash interactive web shell proc python parent -> bash -i Python subprocess reverse shell proc pgrep/pkill vs Cortex XDR components agent kill attempt cmd touch -t timestomping of long-lived scripts
# Named malware and tooling in the Unit 42 report
SysGoRAT custom Go RAT, Windows and Linux, WebSocket C2 wss://<addr>/ws, default 104.194.158.65:443
binary names: sys-control-client, pip2.7, ea_install, ./semanage
persist: systemd (sys-update.service), cron (5 min), HKCU Run (Onedrive Update\Updater.exe), schtasks (Onedrive)
GSocket gs-netcat, gs-dbus, process name [kcached], GSOCKET_ARGS env var, relay gsocket.io
LinPEAS open-source local privilege escalation checker
PwnKit open-source CVE-2021-4034 exploit
revsocks open-source reverse SOCKS5 tunnel
pysoxy open-source Python SOCKS proxy
sshpass used with StrictHostKeyChecking=no for lateral SSH
React2Shell custom Go scanner for CVE-2025-55182
# Patch / config audit checklist (read-only) polkit / pkexec patched for CVE-2021-4034 (PwnKit)? rpm -q polkit or dpkg -l policykit-1 php auto_prepend_file empty or approved on every PHP SAPI? grep -rn auto_prepend_file /etc/php /opt/plesk/php /dev/shm, /tmp mounted nodev,nosuid,noexec? findmnt -no OPTIONS /dev/shm SUID inventory no hidden or unexpected SUID files? find / -xdev -perm -4000 -type f -name ".*" React2Shell CVE-2025-55182 patched on exposed apps? (check vendor advisory for your framework version) egress web servers cannot reach arbitrary internet hosts?
Detection Validation Gates
| Gate | Requirement |
|---|---|
| Telemetry ready | Confirm the Falcon Linux sensor is installed on web, mail and database servers and that process creation with command line and parent (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) flows for event_platform=Lin. Confirm network connection (NetworkConnectIP4) and DNS lookup (DnsRequest) events appear for a Linux test host. No card here depends on a file-write event, so pair these queries with file integrity monitoring to cover payloads that land on disk without executing. |
| Benign baseline | Run Q1, Q3, Q8, Q9, Q10, Q11, Q12 and Q18 for 14 days and fill the TUNING exclusions with observed automation, backup agents, log rotation and config management. |
| Positive tests | Safe simulation only on a lab Linux host: run bash -c "alias sudo=true" to hit Q7, create a copy of /bin/true named sys-control-client and run it for Q4, and run pkill -0 nonexistent-agent for Q9. Do not run any real payload, reverse shell or exploit. |
| Promotion path | Investigate-only to Custom IOA after two clean baseline weeks. IOA-1 and IOA-2 are the strongest candidates. No IOA moves to prevent without a second independent source and a legitimate-tool review. |
Hardening: Tiered
- Restrict outbound traffic from web, mail and database servers to an allowlist; log first, then drop (Playbook E logs only). MITRE M1037 Filter Network Traffic. Best-practice, no formal benchmark for this exact control.
- Patch polkit for CVE-2021-4034 (PwnKit) and confirm with the package manager (Playbook F). MITRE M1051 Update Software; the Linux vendor advisory is the authority.
- Audit
auto_prepend_file, hidden SUID files,alias sudoand authorized_keys (Playbook A). MITRE M1047 Audit. - Rotate the sudo, database, SMTP and mailbox credentials on any host with a hit (Section 14). MITRE M1027 Password Policies.
- Mount
/dev/shmand/tmpwithnodev,nosuid,noexec(Playbook C). MITRE M1038 Execution Prevention, M1028 Operating System Configuration; CIS Linux Benchmark covers the partition mount options. - Disable PHP command execution functions (
disable_functions) for sites that do not need them (Playbook B). MITRE M1042 Disable or Remove Feature. Vendor/PHP best-practice, no formal benchmark; pilot per site. - Deploy auditd watches on PHP configuration, systemd units, authorized_keys and log files (Playbook D). MITRE M1047 Audit; DISA Linux STIG auditd requirements.
- Enable Falcon sensor tamper protection and alert on stop attempts. MITRE M1040 Behavior Prevention on Endpoint.
- Ship auth, mail and web logs to an off-host collector so on-host deletion does not erase evidence. MITRE M1029 Remote Data Storage.
- Replace hard-coded credentials and sshpass use with SSH certificates or a secrets manager; require key-based SSH and restrict who can sudo. MITRE M1026 Privileged Account Management, M1032 Multi-factor Authentication; CIS Linux Benchmark SSH and sudo sections.
- Segment web servers from mail and database tiers so a web shell cannot reach internal SQL servers directly. MITRE M1030 Network Segmentation.
- Deploy file integrity monitoring on web roots and PHP configuration. MITRE M1022 Restrict File and Directory Permissions, M1047 Audit.
Deployable Playbooks
Playbook A · read-only host audit
# Playbook A: read-only audit for CL-UNK-1211 artifacts on a Linux host # Prerequisites: root or sudo, bash, standard coreutils; run on the suspect host # Reboot required: No # Rollback: none required, this playbook only reads files echo "== auto_prepend_file =="; grep -rn "auto_prepend_file" /etc/php /opt/plesk/php 2>/dev/null echo "== fake Plesk file =="; ls -la /usr/lib/php/plesk_sys_driver.php 2>/dev/null echo "== hidden SUID files =="; find / -xdev -perm -4000 -type f -name '.*' 2>/dev/null echo "== GSocket staging =="; ls -la /dev/shm 2>/dev/null echo "== sudo alias =="; grep -n "alias sudo" /home/*/.bashrc /root/.bashrc /etc/bash.bashrc 2>/dev/null echo "== password log =="; find / -xdev -name 'Solarwinds.StatusLog.txt' 2>/dev/null echo "== SysGoRAT unit =="; ls -la /etc/systemd/system/sys-update.service 2>/dev/null echo "== authorized_keys =="; ls -la /home/*/.ssh/authorized_keys /root/.ssh/authorized_keys 2>/dev/null
Playbook B · disable PHP command functions
# Playbook B: disable PHP command execution functions via a conf.d drop-in # Prerequisites: test on a staging site first; the application must not call exec, system or shell_exec; adjust PHP_CONF_DIR for your distribution # Reboot required: No (reload php-fpm only) # Rollback: delete the drop-in file and reload php-fpm (command below) PHP_CONF_DIR=/etc/php/8.2/fpm/conf.d # example path, verify with: php-fpm8.2 -i | grep 'Scan this dir' cat > "$PHP_CONF_DIR/99-huntpack-disable-exec.ini" <<'EOF' disable_functions = exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec EOF systemctl reload php8.2-fpm # Verify: php-fpm8.2 -i 2>/dev/null | grep disable_functions # Rollback: # rm "$PHP_CONF_DIR/99-huntpack-disable-exec.ini" && systemctl reload php8.2-fpm # Note: Plesk per-domain PHP settings can override this; set them in the Plesk panel as well.
Playbook C · harden /dev/shm mount options
# Playbook C: mount /dev/shm noexec,nosuid,nodev # Prerequisites: confirm no workload runs executables from /dev/shm (check with: findmnt -no OPTIONS /dev/shm) # Reboot required: No for the remount; the fstab line makes it persistent across reboots # Rollback: remount with exec and restore the saved fstab copy cp /etc/fstab /etc/fstab.bak-huntpack mount -o remount,noexec,nosuid,nodev /dev/shm grep -q '^tmpfs /dev/shm' /etc/fstab || echo 'tmpfs /dev/shm tmpfs defaults,noexec,nosuid,nodev 0 0' >> /etc/fstab # Verify: findmnt -no OPTIONS /dev/shm # Rollback: # mount -o remount,exec /dev/shm && cp /etc/fstab.bak-huntpack /etc/fstab
Playbook D · auditd watches
# Playbook D: auditd watches for CL-UNK-1211 persistence and cleanup # Prerequisites: auditd installed and running; root # Reboot required: No (note: if your policy sets -e 2 the rules are immutable until reboot) # Rollback: remove the rules file and reload (command below) cat > /etc/audit/rules.d/huntpack-cl-unk-1211.rules <<'EOF' -w /etc/php -p wa -k huntpack_php_conf -w /opt/plesk/php -p wa -k huntpack_php_conf -w /etc/systemd/system -p wa -k huntpack_systemd -w /root/.ssh/authorized_keys -p wa -k huntpack_ssh_keys -w /var/log/auth.log -p wa -k huntpack_logs -w /var/log/secure -p wa -k huntpack_logs -w /etc/bash.bashrc -p wa -k huntpack_bashrc EOF augenrules --load # Verify: auditctl -l | grep huntpack # Rollback: # rm /etc/audit/rules.d/huntpack-cl-unk-1211.rules && augenrules --load
Playbook E · log-only egress rule for campaign IPs
# Playbook E: LOG (not drop) outbound traffic to the listed campaign IPs with nftables
# Prerequisites: nftables installed; root; this rule only logs and counts, it does not block
# Reboot required: No (rule is not persistent unless you add it to nftables.conf)
# Rollback: delete the table (command below)
nft add table inet huntpack_cl_unk_1211
nft add set inet huntpack_cl_unk_1211 c2 '{ type ipv4_addr; }'
nft add element inet huntpack_cl_unk_1211 c2 '{ 45.88.188.140, 198.23.185.234, 138.68.244.146, 185.21.136.6, 72.61.89.179, 104.194.158.65, 109.224.53.140, 162.243.175.162, 154.93.37.228, 141.164.58.87, 88.80.150.232, 88.119.167.57, 173.212.247.23, 104.248.131.53, 147.182.224.216, 93.93.112.57, 192.210.183.17 }'
nft add chain inet huntpack_cl_unk_1211 out '{ type filter hook output priority 0; }'
nft add rule inet huntpack_cl_unk_1211 out ip daddr @c2 counter log prefix \"CL-UNK-1211 \"
# Verify:
nft list table inet huntpack_cl_unk_1211
# Rollback:
# nft delete table inet huntpack_cl_unk_1211
# Posture: this matches the detect-only IOC import. Change to 'drop' only after a second independent source and a hosting-reuse check.
Playbook F · PwnKit patch check
# Playbook F: confirm polkit is patched for CVE-2021-4034 (PwnKit); temporary mitigation if it is not # Prerequisites: root; package manager access; nothing on the host depends on pkexec # Reboot required: No # Rollback: restore the SUID bit (command below) rpm -q polkit 2>/dev/null || dpkg -l policykit-1 2>/dev/null # Apply the vendor update for your distribution first (preferred): # dnf update polkit or apt-get install --only-upgrade policykit-1 # Only if you cannot patch yet, remove the SUID bit from pkexec: # chmod 0755 /usr/bin/pkexec # Rollback after patching: # chmod 4755 /usr/bin/pkexec # Verify: ls -l /usr/bin/pkexec
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate | Network-contain the Linux host in Falcon (or pull it from the network at the hypervisor). Before any reboot, capture volatile data: process list, /dev/shm contents, network connections, and a memory image where policy allows. Preserve web and system logs off-host. | SOC / IR | Containment timestamp, volatile capture, log copies |
| Isolate: by platform | CrowdStrike: network-contain the host. SentinelOne: network quarantine (Disconnect from Network; confirm the label in your console version). Microsoft Defender: Isolate device (full network isolation). Keep the host powered on for memory capture on all of them. | SOC / IR | Containment timestamp, volatile capture, log copies |
| Scope | Run Q1 to Q18 for 30 days across all Linux servers; run Playbook A on hosts with no sensor; review web logs for the web shell paths; list every host that shares credentials with the affected one (sshpass targets, database logins). | SOC / IR | Hit list, host inventory |
| Eradicate | Remove attacker entries from every PHP config under /etc/php and /opt/plesk/php, and delete the files they point to; remove plesk_sys_driver.php and other web shells; delete hidden SUID files (.libsystemd-helper, .tourch, .libpython-helper); stop and remove sys-update.service and the cron entry; remove GSocket files under /dev/shm; restore .bashrc from a clean copy; remove injected authorized_keys and any account such as pentest123. Prefer a rebuild from a known-good image for any host where root was obtained. | IR / Sysadmin | File and unit removal log, config diff |
| Credentials | From a clean system, rotate sudo and root passwords, database, SMTP and application credentials, SSH keys and any shared secrets on the host. Treat mailboxes in /var/qmail/mailnames/ as exposed: force password resets and review the linked social media accounts of the affected government addresses. | IAM / Mail admin | Rotation tickets, account review notes |
| Recover | Rebuild or restore from a pre-October-2025 known-good backup, patch polkit and the web framework, apply Playbooks B to E, and re-baseline with Q1, Q7 and Q10 for 14 days. | Engineering | Clean query results, patch report |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | CrowdStrike coverage | SentinelOne | Defender XDR |
|---|---|---|---|---|---|---|
| T1505.003 / T1059.004 | Web shell command execution under a php-fpm parent | Q1 | No | Partial sees the child process, not the web shell file or the HTTP request. Needs the Linux sensor plus web-server-log review | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1505.003 | PHP web shell files on disk and in web roots | Q14 | No | GAP file content is outside endpoint telemetry. Use the Section 7 hash sweep and file integrity monitoring | GAP: same limit as CrowdStrike | GAP: same limit as CrowdStrike |
| T1546 | auto_prepend_file tampering | Q10 | IOA-4 | Partial catches command-line edits; a PHP script or editor writing the config directly is not visible | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1059.004 / T1095 | Reverse shells (named pipe, /dev/tcp, Python) | Q2, Q3, Q15 | IOA-1 | Good needs the Linux sensor; the network leg depends on NetworkConnectIP4 on Linux | Good, with assumptions | Good, with assumptions |
| T1036.005 / T1090 | SysGoRAT and GSocket disguised binaries | Q4, Q5, Q13, Q14 | IOA-2 | Partial name-based; the operator can rename again. No SysGoRAT sample hash is published | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1068 / T1548.001 | PwnKit, LinPEAS, setuid helpers | Q6 | No | Good | Good, with assumptions | Good, with assumptions |
| T1056.001 / T1546.004 | sudo alias password capture | Q7 | IOA-3 | Partial visible only when the alias is written by a command; a replaced .bashrc file copy is not | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1552.001 | Cleartext password search in configs and history | n/a | No | GAP grep and cat are too common to hunt by name without noise; use auditd read watches | GAP | GAP |
| T1070.002 / T1070.003 | Log and history deletion | Q8 | No | Partial command line only; unlink from a script or PHP is invisible. Compare off-host log copies | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1070.006 | Timestomping with touch -t | n/a | No | GAP touch -t is common in build tooling; check ctime against mtime in Section 7 | GAP | GAP |
| T1562.001 | Security agent kill attempts | Q9 | IOA-5 | Partial only the Cortex XDR behavior is named by the source; other agent names are an extension | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1114.001 / T1074.001 | Mailbox enumeration and staging | Q11 | No | Partial command lines only; reading Maildir files from a web shell is not a sensor event | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1567.002 / T1048 | Exfiltration to file hosts or nc | Q12, Q16, Q17 | No | Partial command line and DNS; legitimate hosting services make DNS-only results leads | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1071 / T1571 | SysGoRAT WebSocket C2 (TLS) and operator-changed IPs | Q15, Q16 | No | Partial IP list is static; the operator can change the C2 on the command line and the WebSocket body is encrypted | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1021.004 / T1098.004 | sshpass, SOCKS tools, authorized_keys | Q18 | No | Partial key injected through a script file is not visible | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1190 | Initial access (React2Shell CVE-2025-55182 and web shell upload) | n/a | No | GAP Unit 42 does not detail initial access. This is web-server-log, WAF and patch-level work, outside endpoint telemetry | GAP | GAP |
| T1505 / T1059 | MSSQL xp_cmdshell double hop and SQL dumps | n/a | No | GAP database audit logs, outside endpoint telemetry | GAP | GAP |
| Sensor reach | Hosts without the Linux sensor or on unsupported kernels | n/a | No | GAP Q1 to Q18 cannot see these hosts at all; auditd and syslog are the only source | GAP | GAP |
What needs the Linux sensor and what needs something else. Q1 to Q14 and Q18 depend on process creation events from the Falcon Linux sensor (event_platform=Lin), and Q16 and Q17 on DnsRequest on Linux; validate that DNS events emit in your tenant. Write-time visibility is a gap. Every query here catches a binary at execution, not at the moment it lands on disk, so a payload written and then deleted without running leaves no trace in these cards. Close that gap with file integrity monitoring on /dev/shm, /tmp and the web roots, plus the hash sweep in Section 11. A web-server-log review has to cover the HTTP side (web shell requests, exploit attempts), file integrity or a hash sweep has to cover web shell and config contents, and database audit logs have to cover the SQL hops. Validation gates are in Section 11.
Hunt Summary Ticket
TITLE: CL-UNK-1211: SysGoRAT and web shell intrusion against Linux government servers
SEVERITY: HIGH, espionage-style activity on Linux web and mail servers, attribution unknown
SCOPE: Linux web, mail and database servers (Apache, nginx, php-fpm, Plesk, qmail);
hosts running SysGoRAT on Windows are secondary
HYPOTHESIS: A compromised host shows a shell under a php-fpm parent, an auto_prepend_file
change, a sudo alias or Solarwinds.StatusLog.txt, a hidden SUID helper,
SysGoRAT persistence (sys-update.service), log deletion, or traffic to the
listed IPs and domains.
QUERIES: Q1-Q18 (Section 8); IOA-1 to IOA-5 (Section 9)
DO FIRST: 1. Run Playbook A on every Linux web and mail server.
2. Run Q1, Q4, Q6, Q7, Q10 fleet-wide for 30 days.
3. Run Q14 to Q16 for the hash, IP and domain indicators.
4. Review web-server logs for plesk_sys_driver.php and search_social.php.
FINDINGS: REPLACE_WITH_FINDINGS_SUMMARY_AFTER_HUNT_EXECUTION
GAPS: Web shell file contents, PHP config writes, HTTP requests, initial access,
database audit logs, hosts without the Linux sensor, timestomping,
no published SysGoRAT sample hash (Section 15).
ACTIONS: Deploy IOA-1 to IOA-5 in detect mode; rotate credentials on any hit host;
apply Playbooks B to F; all IOCs stay detect (single vendor).
OWNER: REPLACE_WITH_HUNT_OWNER
VERSION: v0.1 (Draft) 2026-10-17
Changelog
References
| Tier | Source | Used for | Access date |
|---|---|---|---|
| T1 | Unit 42, AI-Powered Espionage Campaign Targets Government Linux Infrastructure | All TTPs and every atomic indicator | 2026-10-17 |
| T2 | GridinSoft, Linux sudo password theft write-up | Context only (restates Unit 42) | 2026-10-17 |
| T2 | GBHackers, AI-assisted hackers compromise government Linux servers | Context only (restates Unit 42) | 2026-10-17 |
| T2 | Cybersecurity News, AI-generated scripts hijack Linux sudo | Context only (restates Unit 42) | 2026-10-17 |
Four fetched sources were saved to SysGoRAT-CL-UNK-1211-Hunt-sources/ for the provenance gate. The three T2 sources are derivative of the Unit 42 report and are not counted as independent corroboration.
Generated 2026-10-17 by HuntPack · defensive content only