Someone left a calculator on the front door and forgot you can spell shell commands with arithmetic
CVE-2026-61511 is an eval-injection vulnerability in vBulletin's vB5_Template_Runtime::runMaths() method, located in /includes/vb5/template/runtime.php. The function implements the {vb:math} template tag by feeding user-supplied expressions to PHP's eval() after a regex filter that was supposed to restrict input to digits and math operators. The filter also permits XOR (^), parentheses, and the dot concatenation operator — enough characters for PHPFuck-style encoding to reconstruct arbitrary PHP function calls. Exploitation is trivial: an unauthenticated attacker POSTs to the public ajax/render/pagenav route with a crafted pagenav[pagenumber] parameter, and the payload flows through template rendering directly into eval(). Affected versions span vBulletin 5.0.0 through 5.7.5 and 6.0.0 through 6.2.1. The fix ships in vBulletin 6.2.2 (released July 1, 2026), with Patch Level 1 backports for 6.2.1, 6.2.0, and 6.1.6. There is no patch for the entire 5.x branch — those installations must upgrade.
The vendor's CRITICAL / 9.8 rating is dead-on and, if anything, understates the operational risk. Every vBulletin instance is internet-facing by definition; the vulnerable endpoint requires zero authentication, zero user interaction, and trivial complexity. Researcher Egidio Romano (EgiX) published a working interactive-shell PoC via SSD Secure Disclosure on July 27, 2026 — within 26 days of the patch dropping — and multiple weaponized scanner repos appeared on GitHub within days. vBulletin has a documented pattern of rapid mass exploitation following public PoC release: CVE-2019-16759 and CVE-2020-17496 (both pre-auth RCE, both CISA KEV-listed) were weaponized within hours of disclosure. This CVE shares the same anatomy. The only reason it hasn't hit KEV yet is likely timing; treat it as if it will.
5 steps from start to impact.
Identify vBulletin target
/vb/. Every vBulletin forum is inherently internet-facing and publicly reachable — there is no 'internal-only' deployment model for a community forum.- Target runs vBulletin 5.0.0–5.7.5 or 6.0.0–6.2.1
- vBulletin's overall market share is <0.1% of websites, limiting the raw target pool
- Only ~24.7% of vBulletin installs run affected v5/v6 branches (v3 and v4 dominate at ~75%)
CVE-2026-61511 available for non-destructive version fingerprinting. Sn1per detection module released.Send crafted POST to ajax/render/pagenav
ajax/render/pagenav endpoint. The pagenav[pagenumber] parameter carries a PHPFuck-encoded payload — a string composed only of digits, parentheses, XOR operators, and dots that reconstructs arbitrary PHP function names through XOR arithmetic. No session cookie, CSRF token, or any form of authentication is required. The request looks like a normal pagination call to most WAFs.- Network path to the target on port 80/443
- No WAF rule blocking PHPFuck-encoded payloads in POST body
- A WAF with deep POST-body inspection *might* flag unusually long numeric expressions, but default rulesets do not cover this pattern
- The payload uses only characters the regex explicitly allows — it's valid input by design
pagenav[pagenumber] values (>50 chars) or high density of XOR operators. IDS signatures for PHPFuck patterns in HTTP POST bodies.Template engine routes input to runMaths()
pagenav template, which contains a {vb:math} tag referencing pagenav.currentpage. The attacker-controlled value is assigned to pagenav.currentpage, then flows into vB5_Template_Runtime::runMaths(). The method applies its regex filter, which passes the PHPFuck payload because every character is in the allowed set.- Default vBulletin template configuration (pagenav template is always present)
- None — this is core vBulletin functionality that cannot be disabled without breaking pagination
eval() monitoring via RASP (e.g., Sqreen, Imperva RASP).eval() executes arbitrary PHP
eval(). The PHPFuck payload decodes at runtime into a call like system('id') or file_put_contents(). The attacker achieves arbitrary command execution as the web server user (typically www-data, apache, or nginx). The SSD PoC provides an interactive shell loop, enabling real-time command execution.- PHP eval() function not disabled (it is enabled by default and cannot be disabled via disable_functions in most hosting environments because vBulletin requires it)
- If
eval()were indisable_functions, the chain breaks — but vBulletin itself requireseval()for template rendering, so disabling it breaks the application
Post-exploitation: database access and lateral movement
config.php to extract MySQL credentials, dumps the user database (emails, bcrypt password hashes, PII), and pivots to other hosts on the internal network. vBulletin databases routinely contain hundreds of thousands of user records. The web server's network position inside a DMZ or cloud VPC provides a beachhead for further internal reconnaissance.- Database credentials stored in config.php (always true for vBulletin)
- Network connectivity from web host to database and internal network
- Network segmentation between DMZ and internal network limits lateral movement
- Database firewall or least-privilege DB accounts limit data exfiltration scope
/ajax/render/pagenav or to reject pagenav[pagenumber] values exceeding 20 characters or containing XOR operators (^). This breaks the PoC delivery mechanism without affecting normal pagination (legitimate page numbers are short integers). Deploy within 3 days as a stopgap before patching.eval() calls with dynamic/tainted input. Alternatively, adding eval to disable_functions in php.ini will break the exploit chain — but will also break vBulletin's template engine. Only use disable_functions if you're willing to take the forum offline as an emergency measure.- ModSecurity Core Rule Set (default): The default OWASP CRS does not flag PHPFuck-encoded payloads because the characters used (digits, parentheses, XOR, dots) are all legitimate in form data. Custom rules are required.
- IP-based rate limiting: The exploit requires only a single HTTP request for full RCE. Rate limiting does not help against a one-shot exploit.
- Disabling PHP functions like system() or exec(): The attacker can use
file_put_contents()to drop a webshell,mail()for data exfiltration, orinclude()for further code loading — all without traditional command execution functions. Disablingsystem/exec/passthruslows but does not stop a competent attacker. - Upgrading only to vBulletin 5.7.5: This version is still vulnerable. There is no 5.x patch. You must move to 6.x or apply the 6.x Patch Level 1.
The supporting signals.
| In-the-Wild Exploitation | No confirmed exploitation as of October 2026. Not listed in CISA KEV. However, vBulletin's prior pre-auth RCEs (CVE-2019-16759, CVE-2020-17496) were both rapidly weaponized and added to KEV. Treat this as a matter of *when*, not *if*. |
|---|---|
| Proof-of-Concept Availability | Multiple public PoCs. SSD Secure Disclosure published a full working interactive-shell exploit on July 27, 2026. GitHub repos: codeb0ssx/Ultimate-CVE-2026-61511, tc4dy/CVE-2026-61511-PoC-Exploit, puj790201-lab/cve-2026-61511. Nuclei template available in projectdiscovery/nuclei-templates. |
| EPSS Score | 0.05607 (5.6%) — top ~15th percentile. Some aggregators report 70.8% 30-day probability, suggesting rapid upward movement. Either way, the public PoC and historical exploitation pattern make probability scores academic. |
| KEV Status | Not listed as of 2026-10-07. Given the pattern with CVE-2019-16759 and CVE-2020-17496 (both KEV-listed), expect addition if ITW exploitation is confirmed. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8) — every base metric is at its worst value except Scope. This accurately reflects the zero-prerequisite, network-reachable, full-impact nature of the flaw. |
| Affected Versions | vBulletin 5.0.0 – 5.7.5 (entire 5.x branch) and 6.0.0 – 6.2.1. Per W3Techs, v5 represents ~14% and v6 ~10.7% of all vBulletin installs. The 5.x branch receives no patch — upgrade is the only path. |
| Fixed Versions | vBulletin 6.2.2 (released July 1, 2026). Patch Level 1 backports for 6.2.1, 6.2.0, and 6.1.6. No fix available for any 5.x version — vBulletin has stated 5.x users must upgrade to 6.x. |
| Exposure Surface | vBulletin powers <0.1% of all websites but ~3.5% of community platforms. All instances are internet-facing by design. Shodan queries for http.component:vBulletin return thousands of results. The affected v5/v6 subset is roughly a quarter of all installs. |
| Disclosure Timeline | Reported to vendor June 25, 2026. Patch (6.2.2) released July 1, 2026 (6-day turnaround). SSD Secure Disclosure advisory + PoC published July 27, 2026 (26 days post-patch). |
| Researcher | Egidio Romano (EgiX), independent security researcher, disclosed via SSD Secure Disclosure. EgiX has a track record of high-impact PHP application research. |
Sources.
Why this verdict
- Zero authentication friction: The
ajax/render/pagenavendpoint is unauthenticated by design. No login, no CSRF token, no API key. Every visitor to a vBulletin forum has the network path to trigger this chain. This is the most permissive attacker position possible — unauthenticated remote — and removes the single largest downward pressure on severity. - Always internet-facing: Unlike infrastructure components that *might* be internal, vBulletin forums exist specifically to be publicly accessible. There is no 'internal-only vBulletin deployment' in practice. The AV:N vector component reflects real-world exposure with zero narrowing.
- Public weaponized PoC with interactive shell: SSD Secure Disclosure published a complete, copy-paste exploit that gives an interactive shell on the target. Three additional GitHub repos provide scanner/exploit tooling. A Nuclei detection template exists. The barrier to exploitation is effectively zero for any attacker who can send an HTTP POST.
- Historical pattern demands urgency: vBulletin's last two pre-auth RCEs (CVE-2019-16759 in 2019, CVE-2020-17496 in 2020) followed the identical pattern — public PoC → mass scanning → KEV listing → confirmed breaches. Both are CISA KEV-listed. This CVE shares the same anatomy: same product, same attack surface (ajax/render), same impact class. The exploitation probability is not theoretical.
- Role multiplier: vBulletin occupies the *internet-facing application tier* role in 100% of its deployments. It is not a hypervisor, IdP, or domain controller — its blast radius is host + database, not domain or fleet. However, the database routinely contains hundreds of thousands of user records (emails, hashed passwords, PII), making data exfiltration the primary high-value outcome. The web server also serves as an initial access beachhead for lateral movement into internal networks. For organizations hosting vBulletin in shared environments or alongside other applications, the blast radius extends to co-hosted services. This does not meet the 'canonical high-value component' threshold for a CRITICAL *floor*, but the zero-friction, zero-prerequisite chain to full host RCE independently justifies CRITICAL at the 9.8 level without needing the floor rule.
- No realistic friction to adjust downward: Walking every step of the attack path, there is no step that filters out a meaningful fraction of deployments or requires a prior compromise stage. The regex bypass is deterministic (PHPFuck encoding works against every unpatched instance), the endpoint is always present, and the template cannot be disabled. WAF coverage for this specific pattern is negligible in default rulesets. There is nothing to adjust down for.
Why not higher?
The CVSS 3.1 scale caps at 10.0. This vulnerability scores 9.8, missing 10.0 only because Scope is Unchanged (the attacker compromises the web server but not a different security authority). The Scope assessment is correct — exploitation stays within the PHP/OS context of the vBulletin host. There is no mechanism to score this higher within the framework.
Why not lower?
Downgrading requires identifying real-world friction that meaningfully reduces the exploitable population or raises attacker cost. Here there is none: no authentication, no user interaction, no special configuration, no unusual network position requirement. The target is always internet-facing, the PoC is public and weaponized, and the historical exploitation pattern for identical vBulletin vulns confirms rapid real-world adoption. The only narrowing factor is vBulletin's overall market share (<0.1% of websites), but that affects the *number of targets*, not the *severity per target* — and CVSS correctly ignores installed base. Dropping below CRITICAL would be negligent given the evidence.
Crowdsourced verification payload.
Run this script on the vBulletin web server host (or any machine with HTTP access to the target). It performs a non-destructive version check against the target URL. Invoke as: bash check_cve_2026_61511.sh https://forum.example.com — no special privileges required, only curl and network access to the target.
#!/usr/bin/env bash
# check_cve_2026_61511.sh — Non-destructive version checker for CVE-2026-61511
# Usage: bash check_cve_2026_61511.sh <vBulletin_base_URL>
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <vBulletin_base_URL>"
echo "Example: $0 https://forum.example.com"
exit 2
fi
TARGET="${1%/}"
# Method 1: Check the ajax/render/pagenav endpoint availability
# A patched instance returns a different error structure or blocks the route
RESP=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 \
-X POST "${TARGET}/ajax/render/pagenav" \
-d 'pagenav[pagenumber]=1&pagenav[totalpages]=10' 2>/dev/null || echo "000")
if [[ "$RESP" == "000" ]]; then
echo "UNKNOWN — could not connect to ${TARGET}"
exit 2
fi
# Method 2: Fingerprint vBulletin version from page source
VERSION=$(curl -sS --max-time 10 "${TARGET}/" 2>/dev/null | \
grep -oP 'vBulletin[\s]+\K[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "")
if [[ -z "$VERSION" ]]; then
# Try alternate version detection via meta generator tag
VERSION=$(curl -sS --max-time 10 "${TARGET}/" 2>/dev/null | \
grep -oP 'content="vBulletin\s+\K[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "")
fi
if [[ -z "$VERSION" ]]; then
echo "UNKNOWN — could not fingerprint vBulletin version at ${TARGET}"
echo "Manually check: GET ${TARGET}/ and look for version strings."
echo "If version is 5.0.0-5.7.5 or 6.0.0-6.2.1 → VULNERABLE"
exit 2
fi
echo "Detected vBulletin version: ${VERSION}"
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
# Version comparison logic
if [[ "$MAJOR" -le 4 ]]; then
echo "PATCHED — vBulletin ${VERSION} (v3/v4 branch not affected by CVE-2026-61511)"
exit 0
elif [[ "$MAJOR" -eq 5 ]]; then
# All 5.x versions through 5.7.5 are vulnerable; no 5.x patch exists
echo "VULNERABLE — vBulletin ${VERSION} is in the affected 5.x branch (5.0.0–5.7.5)"
echo "Action: No 5.x patch available. Upgrade to vBulletin 6.2.2+"
exit 1
elif [[ "$MAJOR" -eq 6 ]]; then
if [[ "$MINOR" -lt 2 ]]; then
echo "VULNERABLE — vBulletin ${VERSION} is below 6.2.x"
echo "Action: Apply Patch Level 1 for 6.1.6, or upgrade to 6.2.2+"
exit 1
elif [[ "$MINOR" -eq 2 ]]; then
if [[ "$PATCH" -le 1 ]]; then
echo "VULNERABLE — vBulletin ${VERSION} (affected: 6.0.0–6.2.1)"
echo "Action: Upgrade to 6.2.2 or apply Patch Level 1"
echo "Note: Patch Level 1 does not change the version string."
echo "Verify patch by checking /includes/vb5/template/runtime.php"
echo "for improved regex in runMaths() method."
exit 1
else
echo "PATCHED — vBulletin ${VERSION} (6.2.2+ is fixed)"
exit 0
fi
else
echo "PATCHED — vBulletin ${VERSION} (post-fix release)"
exit 0
fi
else
echo "UNKNOWN — unexpected major version ${MAJOR}"
exit 2
fi