CVE-2026-61511: Verified Reproduction
CVE-2026-61511: vBulletin runtime template runMaths pre-auth RCE
CVE-2026-61511 is verified against the affected target. Vulnerability class: RCE. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00307.
What Is CVE-2026-61511?
CVE-2026-61511 is a critical-severity RCE vulnerability. Pruva has independently reproduced it and publishes a verified, runnable proof-of-concept (reproduction REPRO-2026-00307).
CVE-2026-61511 Severity
CVE-2026-61511 is rated critical severity.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
How to Reproduce CVE-2026-61511
pruva-verify REPRO-2026-00307 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00307/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-61511
- reached the target end-to-end
- full exploit chain demonstrated
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
Unauthenticated POST field pagenav[pagenumber] containing a phpfuck/XOR expression
- POST /index.php
- routestring=ajax/render/pagenav
- pagenav template
- vB5_Template_Runtime::runMaths()
- PHP eval
- system()
How the agent worked
Root Cause and Exploit Chain for CVE-2026-61511
CVE-2026-61511 is a pre-authentication remote code execution vulnerability in vBulletin's template runtime. The public ajax/render/pagenav route merges unauthenticated POST data into template variables. The stock pagenav template assigns pagenav[pagenumber] to pagenav.currentpage and embeds it in a {vb:math} expression. vB5_Template_Runtime::runMaths() removes characters with a deny-style regular expression but retains digits, parentheses, concatenation, bitwise XOR, and invocation syntax, then passes the result to PHP eval(). A phpfuck-style expression can therefore synthesize system and an attacker-selected command using only permitted characters. This run reproduced arbitrary command execution through the real HTTP route without a session.
- Affected component: vBulletin 5/6 presentation-layer template engine, specifically
includes/vb5/template/runtime.php, thepagenavtemplate, and the public AJAX renderer. - Affected versions: The published CVE record identifies vBulletin 5.0.0 through 5.7.5 and 6.0.0 through 6.2.1. The exact current-run target was vBulletin 5.1.5.
- Tested runtime: vBulletin 5.1.5 source and original database from digest-pinned image manifest
cck1/vbulletin:v2(sha256:df5a9fa87186c49101db79577a0401c07f1239bf79dd1e5d066328147f6727f8), served by Apache 2.4.25 with PHP 7.0.32. The PHP runtime came from the digest-pinnedwordpress:4.9.8-php7.0-apacheimage manifest (sha256:60cbd13178ed7f629098b1b7a0104ce038d55729f89784739e1bc2eca372f64a); only its Apache/PHP runtime was used, not WordPress code. - Risk: Critical. An unauthenticated network attacker can run commands as the web-service account. Consequences include application/database disclosure, site modification, persistence, credential theft, and potential host compromise depending on service privileges.
- Repository scope note: The ticket-mandated
https://github.com/quangbahoa/vbulletinrepository was inspected at commit6126d15ed2a4023e9efa672c387f98c3e9905d4c, but it contains vBulletin 3.8.11 and has norunMaths,{vb:math}, orajax/renderimplementation. It is outside the CVE's affected 5.x/6.x code family and could not be the runtime target.
Impact Parity
- Disclosed/claimed maximum impact: Unauthenticated remote arbitrary PHP/code execution.
- Reproduced impact: Unauthenticated attacker-selected OS command execution via
system()throughPOST /withroutestring=ajax/render/pagenavandpagenav[pagenumber]. - Parity:
full - Not demonstrated: No privilege escalation beyond the web-service account, persistence, outbound connectivity, or destructive post-exploitation was attempted.
Root Cause
The public light application recognizes any route beginning with ajax/render and dispatches it without an authentication gate. vB5_Frontend_Controller_Ajax::actionRender() combines $_GET, $_POST, and supplied data, then renders the caller-selected server template. In the stock pagenav template, a request-provided pagenav[pagenumber] value becomes pagenav.currentpage; that value is then inserted into math expressions such as:
{vb:math {vb:var pagenav.currentpage} - 1}
vB5_Template_Runtime::runMaths() attempts to make eval() safe with this filter:
$str = preg_replace('#([^+\-*=/\(\)\d\^<>&|\.]*)#', '', $str);
$status = @eval("\$str = $str;");
The filter is not a safe arithmetic parser. The retained character set supports numeric literals, string concatenation, XOR-based string construction, parenthesized expression invocation, and function calls on PHP 7+. The exploit synthesizes the string CHR, uses it to build system and the command byte-by-byte, then invokes the resulting function name. The request is processed more than once in the template, which explains the duplicate response marker; one successful invocation is already sufficient for RCE.
The vulnerable source excerpts captured from the exact tested package are:
bundle/logs/repro/vb515-runmaths-source.txtbundle/logs/repro/vb515-pagenav-source.txt
The vendor fix is available as vBulletin 6.2.2 and as Patch Level 1 packages for 6.2.1, 6.2.0, and 6.1.6. The patches are license-gated at https://members.vbulletin.com/patches.php; no public source commit was found. Vendor references:
- https://forum.vbulletin.com/forum/vbulletin-announcements/vbulletin-announcements_aa/4509358-security-patch-released-for-vbulletin-6-2-1-6-2-0-and-6-1-6
- https://forum.vbulletin.com/forum/vbulletin-announcements/vbulletin-announcements_aa/4509404-vbulletin-6-2-2-is-available
Reproduction Steps
Run
bash -n bundle/repro/reproduction_steps.shto validate shell syntax.Start an isolated affected vBulletin instance with a compatible PHP 7+ runtime, then invoke:
TARGET_URL=http://127.0.0.1:18081/ bash bundle/repro/reproduction_steps.shThe script:
- verifies service reachability;
- generates a fresh nonce and a phpfuck/XOR payload using only characters accepted by the vulnerable filter;
- sends a benign numeric request through the same unauthenticated endpoint and verifies that it does not contain the nonce;
- sends the malicious
pagenav[pagenumber]request; - requires the exact fresh response marker before exiting successfully;
- writes
bundle/repro/runtime_manifest.jsonand request, response, payload, identity, and proof logs.
Expected success evidence is exit code 0 and:
CONFIRMED: unauthenticated pagenav input executed an attacker-selected command through runMaths().
The script exits 1 when the endpoint is reached but command execution is absent and exits 2 for a service/setup blocker.
Evidence
Primary current-run positive evidence (two consecutive self-contained runs):
bundle/logs/repro/durable-positive-3-proof.logandbundle/logs/repro/durable-positive-4-proof.logresponse_marker=truetarget_file_marker=truebenign_control_reached_math=truebenign_control_clean=trueauthentication_material_sent=falseCONFIRMED: unauthenticated pagenav input executed an attacker-selected command through runMaths().
bundle/logs/repro/durable-positive-3-exploit-request.traceandbundle/logs/repro/durable-positive-4-exploit-request.trace— byte-level HTTP traces of unauthenticated exploit requests.bundle/logs/repro/durable-positive-3-exploit-response.txtandbundle/logs/repro/durable-positive-4-exploit-response.txt— each contains its independent fresh marker:__PRUVA_BEGIN__PRUVA_RUNMATHS_durable_positive_3__PRUVA_END__ __PRUVA_BEGIN__PRUVA_RUNMATHS_durable_positive_4__PRUVA_END__bundle/logs/repro/durable-positive-3-marker.txtandbundle/logs/repro/durable-positive-4-marker.txt— independent target-local files written by the command.bundle/logs/repro/durable-positive-3-baseline-response.txtandbundle/logs/repro/durable-positive-4-baseline-response.txt— benign arithmetic controls through the same route, rendering page values 1 and 3 and no nonce.bundle/logs/repro/durable-positive-3-health.txtandbundle/logs/repro/durable-positive-4-health.txt— reachable vBulletin service and PHP 7.0.32 headers.bundle/repro/runtime_manifest.json— structured current-run endpoint and proof-artifact manifest.
Compatibility negative control:
bundle/logs/repro/manual-positive-1-exploit-response.txtandbundle/logs/repro/php55-negative-control.txtshow that the same product route under PHP 5.5.9 returnedInvalid math expression; PHP 5.5 lacks the PHP 7 uniform-variable syntax used by the public payload. This constrains exploitability of this payload but does not negate the confirmed affected configuration.
Source and provenance evidence:
bundle/logs/repro/vb515-runmaths-source.txtbundle/logs/repro/vb515-pagenav-source.txtbundle/logs/repro/CVE-2026-61511-cve-record.jsonbundle/logs/repro/KIS-2026-13.htmlbundle/logs/repro/ssd-post-10702.json
Novelty classification is duplicate: KIS-2026-13, SSD Secure Disclosure, the CVE record, and the public PoC disclose this exact pagenav-to-runMaths route and payload mechanism.
Recommendations / Next Steps
- Upgrade to vBulletin 6.2.2 or later, or apply the official Patch Level 1 package for a supported 6.2.1, 6.2.0, or 6.1.6 installation immediately.
- Replace
eval()with a small, explicitly bounded arithmetic parser. A character filter is not an adequate substitute for grammar validation. - Do not merge arbitrary unauthenticated request arrays into server-template data. Use route-specific schemas and scalar type/length limits.
- Restrict public template rendering to an explicit allowlist and audit every allowed template for request-to-executable-context flows.
- Add regression tests that submit the published payload and nearby character-set variants to every public math-bearing template; assert no command marker, no function call, and a safe validation error.
- Review logs for large
pagenav[pagenumber]values and requests selectingajax/render/pagenav. - Treat disabling dangerous PHP functions only as defense in depth, not the primary fix.
Additional Notes
- Idempotency: The proof uses a unique nonce and marker path per run. Repeating it does not depend on a previous marker and the benign control always runs first. The final self-contained script completed twice consecutively with exit code 0 (
durable-positive-3anddurable-positive-4), producing distinct markers. - PHP limitation: The public phpfuck payload relies on PHP 7's uniform variable syntax. The exact vBulletin 5.1.5 instance under PHP 5.5 reached the sink but returned an invalid-expression control result. PHP 7.0.32 produced command execution.
- Comparator limitation: The vendor's fixed package is license-gated and was not available in this environment. The PHP 5.5 parser control and benign same-route control were both reached, but they are not substitutes for testing vBulletin 6.2.2. Variant analysis should test the official fixed release if licensed bytes become available.
- The local command was deliberately limited to a unique
/tmpmarker plus a matching response marker; no external network target or third-party vBulletin site was touched.
CVE-2026-61511 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
Artifacts and Evidence for CVE-2026-61511
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-61511
FAQ: CVE-2026-61511
Is CVE-2026-61511 exploitable?
How severe is CVE-2026-61511?
How can I reproduce CVE-2026-61511?
Is the CVE-2026-61511 reproduction verified?
References for CVE-2026-61511
Authoritative sources for CVE-2026-61511 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.