CVE-2026-48908 — SP Page Builder for Joomla: Unauthenticated File Upload → RCE

CVSS 10.0 · exploited as a zero-day · unauthenticated asset.uploadCustomIcon drops a PHP web shell into the web root → OS command execution & hidden Super Admin. Linux web-server telemetry hunt.
Threat
CVE-2026-48908 (SP Page Builder ≤ 6.6.1)
Severity
EXPLOITED ITW · CVSS 10.0
Type
Web-app RCE · unauth file upload
Initial Access
POST task=asset.uploadCustomIcon
Version
v0.2 · 2026-07-12
Author
HuntPack
Confidence
High (vendor advisory + KEV + observed ITW)
01

Executive Summary

CVE-2026-48908 is a maximum-severity (CVSS 4.0 = 10.0) unauthenticated arbitrary-file-upload vulnerability in the SP Page Builder extension for Joomla, one of the most widely deployed Joomla page-builders. The component's asset.uploadCustomIcon controller accepts a file with no authentication and no file-type validation, so any remote attacker can upload a PHP web shell into a web-served directory and execute it — full remote code execution as the web-server user. All versions up to and including 6.6.1 are affected; the fix is 6.6.2 (released 2026-06-14), which gates the controller behind an authenticated session, a permission check, and a CSRF token.

The flaw has been exploited in the wild as a zero-day and was added to the CISA KEV catalog on 2026-07-07 (federal remediation due 2026-07-10). Observed exploitation is automated: a bot POSTs to index.php?option=com_sppagebuilder&task=asset.uploadCustomIcon (HTTP 200), then GETs the planted PHP file, then a brand-new Joomla Super Administrator account appears on the site. Some campaigns upload ZIP archives containing PHP web shells into /media/com_sppagebuilder/assets/iconfont/, and drop persistent PHP file-manager backdoors under /media/com_sppagebuilder/assets/.

Because initial access is a web request, the highest-value endpoint signal is the web server / PHP-FPM process spawning a shell or recon binary — the moment the web shell runs an OS command. The upload itself is best caught in web-server access logs (the uploadCustomIcon → GET-.php sequence) and by the tell-tale hidden admin whose email ends in @secure.local.

Defender priority: Inventory every Joomla site running SP Page Builder and confirm it is on 6.6.2+ today. Then hunt for (1) httpd/php-fpm spawning sh/bash/id/curl (§8 Q1), (2) new files under /media/com_sppagebuilder/assets/, and (3) any Joomla Super Admin with an @secure.local email. Treat a pre-6.6.2, internet-facing instance as presumed-compromised.

02

Source Review & Web Hunter Notes

TierSourceKey FindingCarry Fwd
1 · PrimaryNVD — CVE-2026-48908CVSS 10.0, affected ≤ 6.6.1, unrestricted file upload → RCE.Yes
1 · PrimaryCISA KEV (added 2026-07-07)Confirms active exploitation; FCEB due 2026-07-10.Yes
1 · PrimaryCensys advisory (2026-06-24) · IONIXEndpoint asset.uploadCustomIcon, exposure scale, exploitation detail.Yes
2 · Corrob.mySites.guru — "SP Page Builder Zero Day RCE Fixed in 6.6.2"Attack sequence (POST 200 → GET .php → new Super User), webshell paths, @secure.local admin, 6.6.2 fix (2026-06-14).Yes
2 · Corrob.The Hacker News — CISA KEV additions (2026-07-08)KEV context alongside ColdFusion/Joomla/Langflow adds.Partial
3 · ContextJoomShaper forum threadsVendor discussion; a report that IconsTrait.php handling still warranted review post-6.6.2 — validate you are fully patched.Partial

Provenance note: IOCs here are structural/behavioral (endpoint path, controller task, webshell directories, @secure.local admin email) and are well-corroborated across the vendor advisory and multiple analyses. No reliable attacker C2 IP set is published as of 2026-07-12 — this pack is detection-by-behavior, not IP blocklist.

03

Hunt Brief & Attack Chain

Hunt hypotheses (ordered by fidelity)

  1. H1 (high): A web-server or PHP-FPM process spawns a shell or recon/download binary (sh, bash, id, whoami, uname, curl, wget) — a PHP web shell executing OS commands post-upload.
  2. H2 (med): A ZIP archive or new file is written under /media/com_sppagebuilder/assets/ (esp. iconfont/) — the web-shell delivery artifact.
  3. H3 (med): The web-server process makes outbound network connections (reverse shell or second-stage fetch) to an external host.
  4. H4 (med): The web-server process spawns an interactive reverse-shell one-liner (bash -i, python … pty.spawn, perl … Socket, nc -e).
  5. H5 (high, native): A new Joomla Super Administrator account exists whose email ends in @secure.local, or web-access logs show task=asset.uploadCustomIcon (200) followed by a GET to a new .php under the media path.

Attack chain

#StepTelemetryHunt angle
1Unauth POST to asset.uploadCustomIcon uploads PHP/ZIP web shellWeb access log · ZipFileWrittenLog signature + file write under media path (§7, Q2)
2GET the planted PHP file → OS command executionWeb access log · ProcessRollup2Web server → shell child (Q1)
3Recon / download second stage (id, uname, curl)ProcessRollup2 · NetworkConnectIP4Recon binaries + egress under web parent (Q1, Q3)
4Reverse shell / interactive accessProcessRollup2 · NetworkConnectIP4Reverse-shell one-liners (Q4)
5Create hidden Joomla Super Admin (@secure.local)Joomla DB / app auditRogue admin review (§7, native)
6Drop persistent PHP file-manager backdoorFile write under media pathNew .php under /media/com_sppagebuilder/assets/ (§7)
04

Consolidated IOC Table

TypeValueConfActionContext
URL / controllerindex.php?option=com_sppagebuilder&task=asset.uploadCustomIconhighhuntExploited upload endpoint — POST returning 200 from unauthenticated source
Path/media/com_sppagebuilder/assets/iconfont/highhuntWeb-shell / ZIP drop location
Path/media/com_sppagebuilder/assets/highhuntPersistent PHP file-manager backdoor location
Account artifactJoomla Super Admin email ending @secure.localhighhuntHidden admin created post-exploit; domain never used legitimately
BehaviorWeb server / php-fpm → shell/recon childhighdetectWeb-shell command execution (Q1)
BehaviorAccess-log: POST uploadCustomIcon (200) → GET new .phphighhuntExploitation sequence in web logs (§7)
VersionSP Page Builder ≤ 6.6.1highdetectVulnerable; patch to 6.6.2+
05

Affected Surface & Telemetry Matrix

SurfaceRequired telemetryPriorityGap risk
Joomla web servers running SP Page Builder ≤ 6.6.1Falcon Linux sensor · ProcessRollup2 · NetworkConnectIP4CriticalShared-hosting / unmanaged CMS boxes often lack a sensor
Web root / media upload directoriesFile-write telemetry (ZipFileWritten) · web access logsHighArbitrary PHP writes may not raise a PE/ELF write event — pair with access logs
Joomla application / user storeJoomla admin audit · DB reviewHighRogue Super Admin invisible to endpoint telemetry
Reverse proxy / WAF / CDN in front of JoomlaProxy/WAF logsMediumUpload POST may be observable at the edge before the origin
06

ATT&CK Mapping

TacticTechniqueObserved behaviorQuery / Control
Initial AccessT1190 · Exploit Public-Facing ApplicationUnauth asset.uploadCustomIcon file upload§7 log hunt · patch
PersistenceT1505.003 · Web ShellPHP web shell / file-manager backdoor under media pathQ2 · §7
ExecutionT1059.004 · Unix ShellWeb shell runs OS commandsQ1
DiscoveryT1082 · System Info Discoveryid/uname/whoami under web parentQ1
Command & ControlT1071 · App-Layer Protocol · T1059 reverse shellWeb-server egress / reverse-shell one-linerQ3, Q4
Persistence / Priv-EscT1136.001 · Create Account · T1078 valid accountsHidden Joomla Super Admin (@secure.local)§7 native
Ingress Tool TransferT1105curl/wget second-stage fetch by web processQ1, Q3
07

Native Audit-Log Hunts (non-CQL)

  • Version audit (do first): Confirm SP Page Builder is 6.6.2 or newer on every Joomla site. In the Joomla admin: Extensions → Manage → filter "Page Builder", or check administrator/components/com_sppagebuilder/sppagebuilder.xml for the <version> string.
  • Web access-log signature: Search access logs for task=asset.uploadCustomIcon with a POST and 200, especially from unauthenticated sources, followed shortly by a GET to a .php under /media/com_sppagebuilder/. That POST→GET pair is the exploitation fingerprint.
  • Web-shell file sweep: On the web root, list any .php under /media/com_sppagebuilder/assets/ (and iconfont/) — this tree should contain fonts/icons, never PHP. Also look for recently-modified ZIP archives there.
  • Rogue admin review: In Joomla Users, flag any Super User with an email ending @secure.local or any admin account created around the exploitation window. Verify against your change record.
  • Integrity: Diff the Joomla install against a known-good baseline; review configuration.php exposure and recently-changed files across the web root.
08

CrowdStrike LogScale CQL Hunt Queries

Pick your tenant's cloud first — every "Open in Falcon" button below uses this selection.
Q1 · Web server / PHP-FPM spawns a shell or recon binary
CONF HIGHFP LOWCOST LOW

Looks for: a web-server or PHP-FPM process becoming the parent of a shell or host-recon/download binary — a PHP web shell running OS commands after the uploadCustomIcon drop. FP: low; well-behaved PHP apps rarely shell out to id/uname. Baseline any plugin that legitimately calls system utilities.

// HUNT: Joomla/PHP web server spawning shell or recon binary (web-shell RCE)
// MITRE: T1190, T1505.003, T1059.004, T1082
// CONF: high  FP: low  COST: low | REQUIRES: Linux sensor ProcessRollup2
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| ParentBaseFileName=/^(httpd|apache2|nginx|php-fpm[0-9.]*|php-cgi|php[0-9.]*|litespeed|lsphp)$/i
| FileName=/^(sh|bash|dash|id|uname|whoami|hostname|curl|wget|nc|ncat|python3?|perl)$/i
| table([ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
Q2 · Archive/web-shell written under the SP Page Builder media path
CONF HIGHFP LOWCOST LOW

Looks for: a ZIP archive written under /media/com_sppagebuilder/assets/ — the observed web-shell delivery artifact. FP: low; this tree holds icon fonts, not uploaded archives. Note: a bare .php write may not raise a file-write event — pair with the native file sweep (§7) and Q1.

// HUNT: archive dropped under com_sppagebuilder assets (web-shell delivery)
// MITRE: T1505.003, T1105
// CONF: high  FP: low  COST: low | REQUIRES: Linux sensor ZipFileWritten
#event_simpleName=/ZipFileWritten/
| TargetFileName=/com_sppagebuilder\/assets/i
| table([ComputerName, aid, UserName, TargetFileName], limit=200)
Q3 · Web-server process making outbound connections
CONF MEDFP MEDCOST LOW

Looks for: outbound connections initiated directly by a web-server/PHP process — a reverse shell or second-stage tool fetch from the web shell. FP: medium — apps legitimately call external APIs. TUNING: exclude known outbound API/update destinations and scope to non-standard ports; correlate with Q1/Q4 hits on the same aid.

// HUNT: web-server/php process initiating outbound network connections
// MITRE: T1071, T1105
// CONF: medium  FP: medium  COST: low | REQUIRES: Linux sensor NetworkConnectIP4
// TUNING: exclude sanctioned API/update egress; focus on non-standard ports + Q1/Q4 correlation
#event_simpleName=/NetworkConnectIP4/
| ContextBaseFileName=/^(httpd|apache2|nginx|php-fpm[0-9.]*|php-cgi|php[0-9.]*|lsphp)$/i
| table([ComputerName, aid, ContextBaseFileName, RemoteAddressIP4, RemotePort], limit=200)
Q4 · Reverse-shell one-liner under a web-server parent
CONF HIGHFP LOWCOST LOW

Looks for: classic reverse-shell command-line patterns spawned under a web server — bash -i to /dev/tcp, a Python pty.spawn, a Perl Socket shell, or nc -e. FP: low; these strings under a web parent are almost never benign.

// HUNT: reverse-shell one-liner spawned by a web server (post web-shell)
// MITRE: T1059.004, T1071
// CONF: high  FP: low  COST: low | REQUIRES: Linux sensor ProcessRollup2
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| ParentBaseFileName=/^(httpd|apache2|nginx|php-fpm[0-9.]*|php-cgi|php[0-9.]*|lsphp|sh|bash)$/i
| CommandLine=/(bash\s+-i|\/dev\/tcp\/|pty\.spawn|Socket\;.*exec|\bnc\s+-e|mkfifo)/i
| table([ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
09

CrowdStrike Custom IOA Recommendations

IOA namePatternExclusionsDeploy
Joomla-WebShell-ExecParent = httpd/nginx/php-fpm, Child = shell or recon binary (Q1)Baselined plugins that call system utilitiesLinux process IOA · Detect→Prevent after baseline
WebSvc-ReverseShellWeb parent + reverse-shell command line (Q4)None expectedLinux process IOA · Detect→Prevent (high-signal)
SPPB-Media-Archive-DropZIP written under com_sppagebuilder/assets (Q2)Legitimate extension-update tooling writing to mediaLinux file IOA · Detect

Q1 and Q4 are portable web-shell detections — they generalize beyond this CVE to any PHP-app RCE, so promoting them hardens you against the next Joomla/WordPress upload bug too.

10

Machine-Readable IOC Appendix

Falcon IOC Management CSVbulk import
type,value,action,severity,expiration,description,tags
sha256,REPLACE_WITH_WEBSHELL_SHA256,prevent,critical,2027-01-12,SP Page Builder web shell,cve:CVE-2026-48908
ipv4,REPLACE_WITH_ATTACKER_IP,detect,high,2026-10-12,CVE-2026-48908 exploit source (from your logs),cve:CVE-2026-48908
Behavioral Signaturesdurable
# httpd/nginx/php-fpm -> shell/recon child (web-shell command exec)
# ZIP or .php written under /media/com_sppagebuilder/assets/(iconfont/)
# Reverse-shell one-liner (bash -i /dev/tcp, python pty.spawn, nc -e) under web parent
# Web parent making outbound connections to external host
Log & Account IOCsweb log / DB
# Access log: POST index.php?option=com_sppagebuilder&task=asset.uploadCustomIcon => 200
#   then GET /media/com_sppagebuilder/assets/**/*.php
# Joomla Super Admin with email ending @secure.local
# New/modified .php or .zip under /media/com_sppagebuilder/assets/
Patch / Config Auditprevention
# SP Page Builder >= 6.6.2 (fix released 2026-06-14)
# Deny PHP execution in /media and /images (web-server config)
# Web-app user cannot write into web-served code dirs
# WAF rule: block unauth POST to task=asset.uploadCustomIcon

No reliable attacker C2 IP set is published — the CSV uses REPLACE_WITH_… placeholders you fill from your own access logs after identifying the exploit source. The durable detections are behavioral (above).

11

Detection Validation Gates

  • Telemetry ready: Confirm a Falcon Linux sensor is on every Joomla web host. Shared/managed hosting may not permit a sensor — fall back to web-log hunts (§7).
  • Benign baseline: Run Q1 and Q3 in monitor for 3–7 days; catalog any plugin that legitimately shells out or calls external APIs before promoting to Prevent.
  • Positive test: In a lab, drop a benign PHP page that runs id and request it — confirm Q1 fires. Write a test ZIP under the media path — confirm Q2 fires.
  • Promotion: Q1 and Q4 are strong Prevent candidates after baseline. Q2 → Detect. Q3 stays Detect/hunt (correlate with Q1/Q4).
12

Hardening — Tiered

Immediate (this week)
  • Patch to SP Page Builder 6.6.2+ — the fix (2026-06-14) gates uploadCustomIcon behind auth, permission, and CSRF. This closes the vulnerability. (M1051 · vendor advisory)
  • Deny PHP execution in upload dirs — block .php handling in /media and /images at the web server so an uploaded shell can't run even if written. (M1050 · CIS Apache/NGINX Benchmark)
  • WAF virtual patch — block unauthenticated POST to task=asset.uploadCustomIcon and uploads of non-image content-types to the component. (M1050)
Near term (1–4 weeks)
  • Least-privilege web root — the web-app user should not have write access to web-served code/media where it can plant executable content; separate upload storage from the exec path. (M1022 · CIS)
  • Egress control — restrict outbound connections from web servers to explicit allowlists; this breaks reverse shells and second-stage fetches. (M1037)
  • Rogue-admin sweep & MFA — remove any @secure.local / unexpected Super Admin, rotate admin credentials, and enforce MFA on Joomla admin. (M1032, M1018)
Strategic (1–3 months)
  • File-integrity monitoring on the web root to alert on any new .php in media/upload trees. (M1022)
  • CMS & extension patch program — inventory all Joomla extensions and drive a defined SLA for security updates; page-builders are a recurring RCE surface. (M1051)
  • Reverse proxy + hardened perimeter — terminate Joomla behind a proxy/WAF with upload inspection and rate-limiting. (M1030, M1050)
13

Deployable Playbooks

1 · Find vulnerable version + web shells (Linux, run per web host)

# SP Page Builder version
grep -Ri '<version>' \
  /var/www/*/administrator/components/com_sppagebuilder/sppagebuilder.xml 2>/dev/null

# Any PHP (or ZIP) under the media assets tree = suspicious
find /var/www -path '*com_sppagebuilder/assets*' \( -name '*.php' -o -name '*.zip' \) \
  -printf '%TY-%Tm-%Td %p\n' 2>/dev/null

2 · Access-log signature sweep

# POST to the vulnerable controller returning 200
grep -E 'task=asset\.uploadCustomIcon' /var/log/apache2/*access* /var/log/nginx/*access* 2>/dev/null \
  | grep -E 'POST' | grep -E ' 200 '
# Follow-on GETs to planted php under the media path
grep -E 'GET .*com_sppagebuilder/assets/.*\.php' /var/log/apache2/*access* /var/log/nginx/*access* 2>/dev/null

3 · Block PHP execution in upload dirs (Apache example)

# In the vhost / .htaccess for /media and /images:
<Directory /var/www/html/media>
  <FilesMatch "\.(php|phtml|php[0-9]|phar)$">
    Require all denied
  </FilesMatch>
</Directory>
# NGINX equivalent: location ~* /(media|images)/.*\.php$ { return 403; }
14

Containment Runbook

PhaseActionsOwnerEvidence
IsolateNetwork-contain any web host with Q1/Q4 hits or a confirmed web shell (Falcon RTR). Put a WAF block on the vulnerable controller.SOC / IRFalcon detections, access-log POST 200
EradicateRemove web shells / ZIPs from /media/com_sppagebuilder/assets/; delete rogue @secure.local Super Admin; patch to 6.6.2+.IR / Web teamFile-sweep output, Joomla user list
RecoverRestore any modified core files from a known-good backup; re-verify plugin integrity; re-enable the site behind the WAF virtual patch.Web teamIntegrity diff, restore log
RotateRotate Joomla admin passwords, secret/session keys in configuration.php, and any DB creds the web shell could read.Web team / IAMRotation ticket
ReportPreserve web shells & logs for IR; notify per policy; confirm no downstream data access.IR LeadEvidence bundle, timeline
15

Detection Coverage Map

TechniqueBehaviorCQLIOACoverage
T1190 · Public-facing exploituploadCustomIcon uploadnative §7NoPartial
T1505.003 · Web shellZIP/PHP under media pathQ2YesPartial
T1059.004 · Unix shellweb server → shellQ1YesGood
T1082 · Discoveryid/uname under web parentQ1YesGood
T1071 · C2 / reverse shellegress + reverse-shell one-linerQ3, Q4YesGood
T1136.001 · Create accounthidden @secure.local adminnative §7NoGAP

Known gaps: The initial upload (T1190) and the hidden Joomla Super Admin (T1136.001) are application-layer events not visible to endpoint process telemetry — cover them with the web-access-log and Joomla-user audits in §7. A bare .php web-shell write may not raise a file-write event; Q2 catches the ZIP-delivery variant, and §7 covers direct PHP drops. Managed/shared hosting without a Falcon sensor is the largest gap — rely on §7 there. Validation gates (§11) must pass before promoting Q1/Q4 to Prevent.

16

Hunt Summary Ticket

TITLE:      CVE-2026-48908 — SP Page Builder Unauth File Upload -> RCE
SEVERITY:   Critical (CVSS 10.0, exploited in the wild, KEV 2026-07-07)
SCOPE:      Joomla web servers running SP Page Builder <= 6.6.1 (Linux)
HYPOTHESIS: Unauth uploadCustomIcon -> PHP web shell -> OS exec / reverse shell / hidden Super Admin
QUERIES:    Q1 web-svc->shell (HIGH) | Q2 ZIP under media path | Q3 web egress | Q4 reverse shell (HIGH)
DO FIRST:   Confirm SP Page Builder >= 6.6.2; run Q1 + access-log sweep (§7)
FINDINGS:   <fill after hunt>
GAPS:       Upload event + hidden admin (app-layer/native only); bare .php write; sensorless hosting
ACTIONS:    Patch 6.6.2+; deny PHP exec in /media; WAF-block uploadCustomIcon; remove @secure.local admin
OWNER:      HuntPack
VERSION:    v0.2 · 2026-07-12
17

Changelog

v0.22026-07-24CQL correctness pass. All table() calls now carry an explicit row limit: the default is 200 and truncation is silent, so a capped result was indistinguishable from a complete one. Atomic-IOC sweeps (filters over 5+ hashes or C2 IPs) use limit=max so a wide infection is never silently under-scoped; behavioural hunts use limit=200, where exceeding the cap indicates the query needs tuning. Where present, event names that do not exist in the Falcon data model were corrected (e.g. ServiceInstalled is a Sysmon concept, not a Falcon event; ElfFileWritten is ELFFileWritten) — such queries could never return a row. No detection logic, fields, or IOCs changed.
v0.12026-07-12Initial HuntPack. 4 CQL hunts (web-shell exec, ZIP drop, web egress, reverse shell) plus native web-log & Joomla-user audits for the app-layer steps. Behavioral, portable web-shell detections; placeholders for env-specific atomic IOCs.
18

References

TierSourceUsed forAccessed
1NVD — CVE-2026-48908CVSS, affected versions, vuln class2026-07-12
1CISA KEV Catalog (added 2026-07-07)Active-exploitation confirmation, remediation date2026-07-12
1Censys advisory — CVE-2026-48908 (2026-06-24)Endpoint, exposure, exploitation detail2026-07-12
2mySites.guru — SP Page Builder Zero Day RCE (6.6.2)Attack sequence, webshell paths, @secure.local admin, fix version/date2026-07-12
2The Hacker News — CISA KEV additions (2026-07-08)KEV context2026-07-12
3IONIX threat center — CVE-2026-48908Corroborating technical summary2026-07-12