← All hunts high TLP:CLEAR Part 1 of 2

Linux Persistence and Credential Hijacking

An adversary has established persistence on Linux web servers using AI-generated PHP web shells and hijacked administrative credentials by tampering with shell profiles and configuration files.

Based on research by Unit 42 2026-10-17 9 steps · 3 queries T1041 T1059 T1071 T1505.003

Brief

Why this hunt

Unit 42 recently published AI-Powered Espionage Campaign Targets Government Linux Infrastructure (https://unit42.paloaltonetworks.com/ai-campaign-targets-linux-infrastructure/). The report details how the CL-UNK-1211 actor uses AI-assisted code to create unique PHP web shells and modify Linux system profiles. These automated techniques allow the adversary to maintain stealthy foothills on government infrastructure. This hunt provides a structured way to find these artifacts.

How the hunt flows

The hunt starts by scoping the environment. The first query searches the hb_software_inventory surface for Linux hosts running PHP, Plesk, Nginx, or Apache. This step identifies the systems most likely to host the adversary’s web-based persistence. The analyst uses these results to focus the following detection steps.

After scoping, the hunt executes two detection branches in parallel. The process activity branch monitors the hb_process_activity surface for web server process managers spawning interactive shells or interpreters like bash, sh, or python. This behavior often indicates an active web shell session where the adversary executes commands in the context of the web user or a privileged account.

The file activity branch examines the hb_file_activity surface for modifications to critical configuration paths. It targets PHP configuration directories and user .bashrc profiles. This step uses a prevalence baseline to surface modifications that occur on five or fewer hosts. It also looks for specific deceptive filenames mentioned in the source report, such as plesk_sys_driver.php or Solarwinds.StatusLog.txt.

An automated agent then correlates the findings from both branches. It compares the user context of anomalous process execution against the actors involved in file tampering. This pivot helps the analyst distinguish between legitimate administrative maintenance and an automated intrusion. If the agent finds rare file modifications alongside suspicious shell execution, it flags the host for isolation and forensic review.

What this hunt cannot see

This hunt faces limitations against high-speed automation. If an adversary uses an AI-driven agent to deploy a web shell, execute commands, and delete the shell within seconds, process-only telemetry might miss the brief execution window. Additionally, the hunt depends on active logging for configuration directories. If the system does not record file activity for /etc/php/ or /opt/plesk/, the modification to the persistent state will not appear in the results.

In this series

Steps

  1. Identify Linux web server estate

    Query · scoping

    Scope the hunt to Linux hosts running PHP, Plesk, or common web server packages where these persistence techniques are viable.

    reads hb_software_inventorysql
    SELECT device_hostname, package_name, package_version FROM hb_software_inventory WHERE (LOWER(package_name) LIKE '%php%' OR LOWER(package_name) LIKE '%plesk%' OR LOWER(package_name) LIKE '%nginx%' OR LOWER(package_name) LIKE '%apache%') AND asset_scope = 'endpoint'

    What a hit looks like. A list of hostnames serving as web infrastructure. Use these results to populate the scope_hosts parameter for subsequent steps.

  2. Web shell execution patterns

    Query · detection candidate

    Identify the primary behavioral signature of a web shell: a web server process manager spawning an interactive shell or interpreter.

    reads hb_process_activitysql
    SELECT device_hostname, user_name, process_name, process_cmd_line, parent_process_name, time FROM hb_process_activity WHERE (LOWER(parent_process_name) LIKE '%php-fpm%' OR LOWER(parent_process_name) LIKE '%httpd%' OR LOWER(parent_process_name) LIKE '%nginx%' OR LOWER(parent_process_name) LIKE '%apache%') AND (LOWER(process_name) LIKE '%bash%' OR LOWER(process_name) LIKE '%sh%' OR LOWER(process_name) LIKE '%nc%' OR LOWER(process_name) LIKE '%python%' OR LOWER(process_name) LIKE '%perl%' OR LOWER(process_name) LIKE '%php%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. Web server child processes that are shell interpreters. User name 'www-data' or similar indicates web shell context; 'root' indicates successful privilege escalation.

  3. Rare modifications to configurations and profiles

    Query · baseline

    Identify modifications to PHP configuration directories and shell profiles that are rare across the fleet, suggesting targeted tampering.

    reads hb_file_activitysql
    SELECT device_hostname, actor_user_name, file_path, time FROM hb_file_activity WHERE (LOWER(file_path) LIKE '%/etc/php/%' OR LOWER(file_path) LIKE '%/opt/plesk/php/%' OR LOWER(file_path) LIKE '%/.bashrc' OR instr(',' || '{{known_malicious_files}}' || ',', ',' || LOWER(file_name) || ',') > 0) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND file_path IN (SELECT file_path FROM hb_file_activity WHERE (LOWER(file_path) LIKE '%/etc/php/%' OR LOWER(file_path) LIKE '%/opt/plesk/php/%' OR LOWER(file_path) LIKE '%/.bashrc' OR instr(',' || '{{known_malicious_files}}' || ',', ',' || LOWER(file_name) || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY file_path HAVING COUNT(DISTINCT device_hostname) <= 5) AND time >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. Rare file modifications in critical paths. The presence of deceptive names like Solarwinds.StatusLog.txt or plesk_sys_driver.php on specific hosts is a strong indicator of the CL-UNK-1211 playbook.

  4. Triage compromise indicators

    Agent triage

    Correlate rare file tampering with anomalous web server processes to identify persistent foothills and credential hijacking.

  5. Route on verdict

    Decision

    Initiate response or forensic review based on the agent's evaluation.

  6. Isolate compromised host

    Response action

    Contain the threat to prevent further credential harvesting or data exfiltration.

  7. Forensic verification

    Analyst task

    Manually verify the findings for AI-generated artifacts.

  8. Hunt closure

    Analyst task

    Document findings and telemetry gaps.

Coverage

Scenario coverage

StageCoveredHow, or why not
Web Shell Deployment
T1505.003
Yes webshell-execution-patterns, rare-config-modifications
PHP Configuration Tampering
T1505.003
Yes rare-config-modifications
Sudo Command Hijacking
T1059
Yes rare-config-modifications
SysGoRAT Backdoor Execution
T1059
Out of scope Belongs to another part of the 'AI-Powered Espionage Campaign Targets Government Linux Infrastructure' series.
In-Memory Reverse Shells
T1059
Out of scope Belongs to another part of the 'AI-Powered Espionage Campaign Targets Government Linux Infrastructure' series.
WebSocket Command and Control
T1071
Out of scope Belongs to another part of the 'AI-Powered Espionage Campaign Targets Government Linux Infrastructure' series.
Mailbox and Database Collection
T1041
Out of scope Belongs to another part of the 'AI-Powered Espionage Campaign Targets Government Linux Infrastructure' series.

Blind spots

  • Needs hb_linux_audit or real-time FIM on /etc/php and /opt/plesk. If file activity logging is not enabled for system configuration paths, the initial modification by the web shell may be missed, leaving only the persistent state visible. It would answer Which process originally modified the PHP configuration files.
  • Needs hb_process_activity with low latency. AI-automated agents may deploy a web shell, execute commands, and delete the file within seconds, making it invisible to file system snapshots. It would answer Whether a web shell was deployed and deleted in a very short window.

Parameters & data

Parameters

ParameterTypeDefaultWhat it is
known_malicious_fileslist[string]plesk_sys_driver.php, search_social.php, Solarwinds.StatusLog.txt, zip_mails.shMalicious filenames or decoy logs identified in the campaign.
lookback_daysnumber14Days of history to examine.
scope_hostslist[host]—List of hostnames identified in the scoping step; refresh this list with results from identify-linux-web-servers before running detection steps.

Telemetry

SourceCategoryTelemetry
Endpoint telemetry (hb_ surfaces)endpointendpoint

Source

Download hunt.md Definition (JSON) An open hunt.md file; it runs anywhere that reads the format.
---
analysis: A static rule can find the plesk_sys_driver.php filename, but this hunt
  correlates rare configuration changes with live behavioral anomalies like web server
  process managers spawning shells, identifying AI-generated payloads that use varying
  filenames or paths to evade simple rules.
blind_spots:
- id: missing-file-telemetry
  question: Which process originally modified the PHP configuration files
  requires: hb_linux_audit or real-time FIM on /etc/php and /opt/plesk
  risk: If file activity logging is not enabled for system configuration paths, the
    initial modification by the web shell may be missed, leaving only the persistent
    state visible.
  stage: php-persistence-tampering
- id: ephemeral-webshell-execution
  question: Whether a web shell was deployed and deleted in a very short window
  requires: hb_process_activity with low latency
  risk: AI-automated agents may deploy a web shell, execute commands, and delete the
    file within seconds, making it invisible to file system snapshots.
  stage: web-shell-deployment
coverage:
- stage: web-shell-deployment
  status: covered
  steps:
  - webshell-execution-patterns
  - rare-config-modifications
- stage: php-persistence-tampering
  status: covered
  steps:
  - rare-config-modifications
- stage: credential-harvesting-sudo
  status: covered
  steps:
  - rare-config-modifications
- reason: Belongs to another part of the 'AI-Powered Espionage Campaign Targets Government
    Linux Infrastructure' series.
  stage: sysgorat-execution
  status: out_of_scope
- reason: Belongs to another part of the 'AI-Powered Espionage Campaign Targets Government
    Linux Infrastructure' series.
  stage: reverse-shell-activity
  status: out_of_scope
- reason: Belongs to another part of the 'AI-Powered Espionage Campaign Targets Government
    Linux Infrastructure' series.
  stage: c2-communication
  status: out_of_scope
- reason: Belongs to another part of the 'AI-Powered Espionage Campaign Targets Government
    Linux Infrastructure' series.
  stage: data-collection-exfiltration
  status: out_of_scope
guardrails:
  claims: no_unsupported
  evidence: citation_required
  missing_data: not_benign
  telemetry: untrusted
hunt:
  applicability: campaign-specific
  handoff: promote-to-detection
  justification: Protects Linux web infrastructure from automated, AI-driven persistence
    that bypasses standard signatures by masquerading as legitimate administrative
    configuration changes.
  methodology: model-assisted
  trigger: intel-report
hypothesis: An adversary has established persistence on Linux web servers using AI-generated
  PHP web shells and hijacked administrative credentials by tampering with shell profiles
  and configuration files.
labels:
- hunt
- attack.t1505.003
- attack.t1059
- attack.t1071
- attack.t1041
- collection
- command and control
- credential access
- execution
- persistence
name: Linux Persistence and Credential Hijacking
parameters:
  known_malicious_files:
    default:
    - plesk_sys_driver.php
    - search_social.php
    - Solarwinds.StatusLog.txt
    - zip_mails.sh
    description: Malicious filenames or decoy logs identified in the campaign.
    from:
      kind: article
      observed: '2026-10-15'
      ref: Unit 42 CL-UNK-1211
    type: list[string]
  lookback_days:
    default: '14'
    description: Days of history to examine.
    type: number
  scope_hosts:
    default: []
    description: List of hostnames identified in the scoping step; refresh this list
      with results from identify-linux-web-servers before running detection steps.
    type: list[host]
provenance:
  authors:
  - name: Huntbase hunt generation
    org: huntbase.io
  generated:
    by: huntbase-hunt-generation
    from: https://unit42.paloaltonetworks.com/ai-campaign-targets-linux-infrastructure/
    gates:
    - dry-run
    - lint
    model: hb_google/gemini-3-flash-preview
rationale: Start with Linux servers running Plesk or public-facing PHP applications.
  The identify-linux-web-servers query finds these based on installed software. Use
  the resulting host list to populate scope_hosts for the detection queries.
references:
- name: "Unit 42 \u2014 AI-Powered Espionage Campaign Targets Government Linux Infrastructure"
  url: https://unit42.paloaltonetworks.com/ai-campaign-targets-linux-infrastructure/
related:
- hunt: sysgorat-rat-detection
  reason: Detection of the custom Go-based SysGoRAT binary is handled in a separate
    hunt focused on binary-on-disk analysis.
  relation: out-of-scope-alternative
scenario:
  stages:
  - name: Web Shell Deployment
    observables:
    - /usr/lib/php/plesk_sys_driver.php
    - POST requests to PHP files via php-fpm parent process
    - search_social.php
    slug: web-shell-deployment
    tactic: persistence
    techniques:
    - T1505.003
  - name: PHP Configuration Tampering
    observables:
    - Modification of auto_prepend_file in /etc/php/
    - Modification of auto_prepend_file in /opt/plesk/php/
    slug: php-persistence-tampering
    tactic: persistence
    techniques:
    - T1505.003
  - name: Sudo Command Hijacking
    observables:
    - Modification of .bashrc with sudo aliases
    - Solarwinds.StatusLog.txt
    - Commands searching for SMTP or database passwords in config files
    slug: credential-harvesting-sudo
    tactic: credential-access
    techniques:
    - T1059
  - name: SysGoRAT Backdoor Execution
    observables:
    - sys-control-client
    - pip2.7
    - ea_install
    - ./semanage
    - Go-based multi-platform RAT
    slug: sysgorat-execution
    tactic: execution
    techniques:
    - T1059
  - name: In-Memory Reverse Shells
    observables:
    - mkfifo /tmp/f; cat /tmp/f | bash -i 2>&1 | nc
    - bash -i >& /dev/tcp/
    - python3 -c "import socket,subprocess,os; s=socket.socket(...)"
    slug: reverse-shell-activity
    tactic: execution
    techniques:
    - T1059
  - name: WebSocket Command and Control
    observables:
    - wss://<addr>/ws
    - 104.194.158.65:443
    - proxy_connect command via RAT
    slug: c2-communication
    tactic: command-and-control
    techniques:
    - T1071
  - name: Mailbox and Database Collection
    observables:
    - Enumeration of /var/qmail/mailnames/
    - zip_mails.sh
    - Iteration through Maildir/cur/ directories
    slug: data-collection-exfiltration
    tactic: collection
    techniques:
    - T1041
  summary: CL-UNK-1211 is an AI-assisted campaign targeting government Linux infrastructure
    to exfiltrate mailboxes and sensitive databases. The attackers utilize custom
    Go-based backdoors (SysGoRAT), extensive web shell deployments, and creative credential
    theft such as hijacking the sudo command through .bashrc modifications.
series:
  index: 1
  slug: ai-powered-espionage-campaign-targets-government-linux-infrastructure
  title: AI-Powered Espionage Campaign Targets Government Linux Infrastructure
  total: 2
severity: high
targets:
  analyst:
    name: Tier-2 analyst
    role: analyst
  endpoint:
    category: endpoint
    name: Endpoint telemetry (hb_ surfaces)
    telemetry:
    - endpoint
  hunter:
    agent: true
    name: Hunt agent
tlp: clear
type: investigation
---


# Linux Persistence and Credential Hijacking

The adversary uses AI-assisted code to modify PHP configuration directories and .bashrc profiles, ensuring that malicious code executes whenever a web request is processed or a user elevates privileges. This hunt targets the activity of CL-UNK-1211, focusing on the specialized Linux persistence and credential theft observed in their campaign. The hunt identifies the web server estate and executes parallel checks: one to find anomalous shell execution originating from web server process managers, and another to baseline rare file modifications across critical configuration paths. The analyst evaluates the results to differentiate legitimate administrative activity from AI-automated intrusion artifacts.

## identify-linux-web-servers
<!-- Identify Linux web server estate -->
Scope the hunt to Linux hosts running PHP, Plesk, or common web server packages where these persistence techniques are viable.

```sqlite target=endpoint role=scoping
~~~yaml
expected: A list of hostnames serving as web infrastructure. Use these results to
  populate the scope_hosts parameter for subsequent steps.
reads:
- device_hostname
- package_name
- package_version
- asset_scope
silence: not_evidence_of_absence
source: hb_software_inventory
verified: dry-run
verified_at: '2026-10-17'
~~~
SELECT device_hostname, package_name, package_version FROM hb_software_inventory WHERE (LOWER(package_name) LIKE '%php%' OR LOWER(package_name) LIKE '%plesk%' OR LOWER(package_name) LIKE '%nginx%' OR LOWER(package_name) LIKE '%apache%') AND asset_scope = 'endpoint'
```

## corroborate-threat-evidence
<!-- Corroborate behavior and rare persistence -->
parallel:
- → webshell-execution-patterns
- → rare-config-modifications
join: → triage-compromise

## webshell-execution-patterns
<!-- Web shell execution patterns -->
Identify the primary behavioral signature of a web shell: a web server process manager spawning an interactive shell or interpreter.

```sqlite target=endpoint role=detection-candidate params=(lookback_days=lookback_days, scope_hosts=scope_hosts)
~~~yaml
expected: Web server child processes that are shell interpreters. User name 'www-data'
  or similar indicates web shell context; 'root' indicates successful privilege escalation.
reads:
- device_hostname
- user_name
- process_name
- process_cmd_line
- parent_process_name
- time
silence: not_evidence_of_absence
source: hb_process_activity
verified: dry-run
verified_at: '2026-10-17'
~~~
SELECT device_hostname, user_name, process_name, process_cmd_line, parent_process_name, time FROM hb_process_activity WHERE (LOWER(parent_process_name) LIKE '%php-fpm%' OR LOWER(parent_process_name) LIKE '%httpd%' OR LOWER(parent_process_name) LIKE '%nginx%' OR LOWER(parent_process_name) LIKE '%apache%') AND (LOWER(process_name) LIKE '%bash%' OR LOWER(process_name) LIKE '%sh%' OR LOWER(process_name) LIKE '%nc%' OR LOWER(process_name) LIKE '%python%' OR LOWER(process_name) LIKE '%perl%' OR LOWER(process_name) LIKE '%php%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```

## rare-config-modifications
<!-- Rare modifications to configurations and profiles -->
Identify modifications to PHP configuration directories and shell profiles that are rare across the fleet, suggesting targeted tampering.

```sqlite target=endpoint role=baseline params=(lookback_days=lookback_days, scope_hosts=scope_hosts, known_malicious_files=known_malicious_files)
~~~yaml
baseline:
  compare: first_seen
  window: '{{lookback_days}}d'
expected: Rare file modifications in critical paths. The presence of deceptive names
  like Solarwinds.StatusLog.txt or plesk_sys_driver.php on specific hosts is a strong
  indicator of the CL-UNK-1211 playbook.
prevalence:
  by: device_hostname
  key:
  - file_path
  rare_below: 5
reads:
- device_hostname
- actor_user_name
- file_path
- file_name
- time
silence: not_evidence_of_absence
source: hb_file_activity
verified: dry-run
verified_at: '2026-10-17'
~~~
SELECT device_hostname, actor_user_name, file_path, time FROM hb_file_activity WHERE (LOWER(file_path) LIKE '%/etc/php/%' OR LOWER(file_path) LIKE '%/opt/plesk/php/%' OR LOWER(file_path) LIKE '%/.bashrc' OR instr(',' || '{{known_malicious_files}}' || ',', ',' || LOWER(file_name) || ',') > 0) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND file_path IN (SELECT file_path FROM hb_file_activity WHERE (LOWER(file_path) LIKE '%/etc/php/%' OR LOWER(file_path) LIKE '%/opt/plesk/php/%' OR LOWER(file_path) LIKE '%/.bashrc' OR instr(',' || '{{known_malicious_files}}' || ',', ',' || LOWER(file_name) || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY file_path HAVING COUNT(DISTINCT device_hostname) <= 5) AND time >= datetime('now', '-{{lookback_days}} days')
```

## triage-compromise
<!-- Triage compromise indicators -->
```agent target=hunter
cite: required
context:
- webshell-execution-patterns
- rare-config-modifications
max_iterations: 4
objective: Identify persistent web shells or credential harvesting artifacts by correlating
  rare file modifications with anomalous shell execution under web server processes.
  Compare the user context of process execution against the file actors to identify
  suspicious elevation.
success_criteria: A per-host verdict of malicious, suspicious, or benign citing the
  relevant process and file rows.
tools:
- endpoint
```

## route-on-verdict
<!-- Route on verdict -->
if~: "the triage verdict is malicious for at least one host based on shell execution and config tampering" (confidence: high, judge=hunter)
then: → isolate-host
indeterminate: → forensic-verification
unavailable: → forensic-verification (blind_spot: missing-file-telemetry)
else: → close-out

## isolate-host
<!-- Isolate compromised host -->
```action target=endpoint
~~~yaml
approval: required
~~~
Isolate the host from the network and revoke any active sessions for administrative accounts seen in the interactive shell telemetry.
```
→ forensic-verification

## forensic-verification
<!-- Forensic verification -->
```manual target=analyst
Examine the identified .bashrc and PHP configuration files on the isolated host. Check for conversational comments or 'AI-reasoning' markers within the code. Recover the content of any deceptive log files like Solarwinds.StatusLog.txt to identify captured administrative passwords and force immediate resets for those accounts.
```
→ close-out

## close-out
<!-- Hunt closure -->
```manual target=analyst
Record the effectiveness of the prevalence check for identifying configuration tampering. Note any hosts that lacked software inventory for web services.
```
→ end

Run it

Take this hunt into your environment.

Open it in Huntbase to run every step against your own connections, with Scout weighing the evidence and your analysts in command. Or take the open hunt.md file anywhere that reads the format.

Machine-drafted by huntbase-hunt-generation using hb_google/gemini-3-flash-preview, gated by dry-run, lint, then reviewed by a person.