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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-70376 — نشرة أمنية وإثبات مفهوم (PoC) بلغة Python لثغرة CSRF في نظام إدارة المحتوى Pluck CMS: فحص مُحيل (Referer) يعمل بنمط الفتح عند الفشل (fail-open) إلى جانب رفع الملفات بامتداد مزدوج، ما يتيح نشر قشرة ويب (webshell) وتنفيذ أكواد برمجية عن بُعد. | Kitploit
أدوات/GitHubGitHub/ilhomjonr/cve-2026-70376
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبأمن الويباختبار الاختراقالتعلم والتعليم
GitHubilhomjonr/cve-2026-70376

CVE-2026-70376

نشرة أمنية وإثبات مفهوم (PoC) بلغة Python لثغرة CSRF في نظام إدارة المحتوى Pluck CMS: فحص مُحيل (Referer) يعمل بنمط الفتح عند الفشل (fail-open) إلى جانب رفع الملفات بامتداد مزدوج، ما يتيح نشر قشرة ويب (webshell) وتنفيذ أكواد برمجية عن بُعد.

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

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2026-70376 — ثغرة CSRF على مستوى الموقع في Pluck CMS تؤدي إلى RCE

فحص Referer مفتوح الفشل + غياب رموز CSRF + رفع بامتداد مزدوج

زيارة واحدة من مسؤول لصفحة تحذف المحتوى، وتحقن الصفحات، وتُسقط قشرة ويب

CVE CVSS 3.1 CWE CWE

Product Status Researcher

نظرة سريعة · الملخص · السبب الجذري · سلسلة الهجوم · الاستغلال · المعالجة · الجدول الزمني


📋 نظرة سريعة

معرّف CVECVE-2026-70376
معرّف التتبعPT-2026-68036
المنتجpluck-cms/pluck — Pluck CMS (PHP بتخزين ملفات مسطحة)
المتأثر4.7.x حتى 4.7.21-dev / فرع master الحالي
نقطة الضعفCWE-352 (CSRF) · CWE-434 (رفع غير مقيد، مضخِّم)
CVSS v3.18.0 — عالية · AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:H
ناقل الهجومشبكة · بدون صلاحيات · زيارة واحدة لصفحة من مسؤول (UI:R)
الأثرتدمير المحتوى/DoS، حقن محتوى مخزَّن، RCE على Apache/mod_php
أُدخلت فيcommit f79f916 (ديسمبر 2019) — المنطق الهش موجود منذ ذلك الحين
الباحثIlhomjon Rustamov (@IlhomjonR)

🔎 الملخص

لا يحتوي لوحة إدارة Pluck على أي رموز CSRF لكل طلب في أي مكان في قاعدة الكود. كل إجراء إداري يغيّر الحالة محكوم بوظيفة واحدة، requestedByTheSameDomain()، التي لا دفاع لها سوى مقارنة مضيف Referer — وهذا الفحص يفشل بشكل مفتوح: عندما يصل طلب بدون ترويسة Referer إطلاقًا، تُرجع الوظيفة true ويُسمح بالإجراء.

ولأن صفحة المهاجم تتحكم بالكامل في ما إذا كان Referer سيُرسل (<meta name="referrer" content="no-referrer">)، يمكن إجبار أي مسؤول مسجّل دخوله يزور صفحة خبيثة على تنفيذ إجراءات مميّزة عبر المواقع. تعمل عدة إجراءات تدميرية عبر GET، ولا يضع Pluck أي سمة SameSite على PHPSESSID (تطبّق المتصفحات SameSite=Lax، التي ما تزال تُرسل مع تنقّلات GET ذات المستوى الأعلى)، لذا يمكن الوصول إليها عبر المواقع في ظل إعدادات المتصفح الافتراضية.

كما تتيح نقطة ضعف ثانوية في فلتر الرفع لنفس الـCSRF زرع ملف shell.php.jpg بامتداد مزدوج — محوّلةً الـCSRF إلى RCE فوري عند الزيارة (drive-by) على مضيفات Apache/mod_php.


🧬 السبب الجذري

1. فحص Referer مفتوح الفشل — data/inc/functions.admin.php

function requestedByTheSameDomain() {
    if (isset($_SERVER['HTTP_HOST'])) { $myDomain = $_SERVER['HTTP_HOST']; }
    elseif (isset($_SERVER['SCRIPT_URI'])) { $myDomain = $_SERVER['SCRIPT_URI']; }
    else { $myDomain = NULL; }

    if (isset($_SERVER['HTTP_REFERER'])) { $requestsSource = $_SERVER['HTTP_REFERER']; }
    else { $requestsSource = NULL; }

    $referelDomain = parse_url($requestsSource, PHP_URL_HOST);

    if ($myDomain != NULL && $requestsSource != NULL &&
        (strcmp(trim($myDomain), trim($referelDomain)) === 0)) {
        return true;                 // Referer host == our host  -> allow
    } elseif ($myDomain == NULL || $requestsSource == NULL) {
        show_error("Be carefull with clicking links, ...", 1);
        return true;                 // Referer ABSENT -> FAIL OPEN -> allow  <==
    } else {
        return false;                // Referer host mismatch -> block
    }
}

يُرفض طلب عبر المواقع يحمل Referer أجنبيًا بشكل صحيح (فرع else)، وهذا يخلق إحساسًا زائفًا بالحماية — لكن المهاجم ببساطة يمنع إرسال Referer، فيصل إلى فرع الفشل المفتوح، ويُسمح بالطلب. لا توجد طبقة رموز خلف هذا الفحص.

يُطبَّق هذا الحاجز مرة واحدة في admin.php ويُعتمد عليه لكامل مبدّل الإجراءات:

$isCSRF = requestedByTheSameDomain();
if (isset($_GET['action']) && $isCSRF) {
    switch ($_GET['action']) {
        case 'deletefile':  include_once('data/inc/deletefile.php');  break;
        case 'deleteimage': include_once('data/inc/deleteimage.php'); break;
        case 'deletepage':  include_once('data/inc/deletepage.php');  break;
        case 'module_delete': /* ... */
        case 'images':      include_once('data/inc/images.php');      break; // upload
        // ...
    }
}

2. لا سمة SameSite على كعكة الجلسة (مضخِّم)

لا يستدعي Pluck أبدًا session_set_cookie_params()، لذلك يرث PHPSESSID القيمة الافتراضية الفارغة → تطبّق المتصفحات SameSite=Lax، التي ما تزال تُرسل مع تنقّلات GET ذات المستوى الأعلى. وبالتالي فإن الإجراءات المعرّضة عبر GET (deletefile, deleteimage, deletepage, module_delete, theme_delete, logout) قابلة للتزوير بزيارة صفحة واحدة.

3. رفع بامتداد مزدوج — data/inc/images.php (مضخِّم RCE)

if (in_array($_FILES['imagefile']['type'],                       // client-controlled MIME
    array('image/pjpeg','image/jpeg','image/png','image/gif'))) {
    $imagewhitelist = array('jfif', '.png', '.jpg', '.gif', 'jpeg');
    if (!in_array(strtolower(substr($_FILES['imagefile']['name'], -4)), $imagewhitelist)) {
        show_error($lang['general']['upload_failed'], 1);         // only checks LAST 4 chars
    } else {
        copy($_FILES['imagefile']['tmp_name'], 'images/'.latinOnlyInput($_FILES['imagefile']['name']));
        // ...
    }
}

كلا الفحصين يمكن تجاوزهما بسهولة:

  • نوع MIME يأتي من العميل ($_FILES[...]['type']) → اضبطه على image/jpeg;
  • يُتحقق فقط من آخر 4 أحرف من اسم الملف → shell.php.jpg ينتهي بـ .jpg ويجتاز الفحص.

يُكتب الملف إلى images/shell.php.jpg؛ على مضيف Apache/mod_php مع معالجة الامتدادات المتعددة، يُنفَّذ كـ PHP.


⛓️ سلسلة الهجوم

زيارة واحدة لصفحة من مسؤول مصادَق — دون أي نقرة.

flowchart LR
    A[Admin logged into Pluck] --> B[Opens attacker page]
    B --> C["meta referrer=no-referrer<br/>suppresses Referer"]
    C --> D[Top-level nav / auto-form to admin.php]
    D --> E["Lax PHPSESSID cookie rides along<br/>Referer absent"]
    E --> F["requestedByTheSameDomain() -> FAIL OPEN -> true"]
    F --> G1[deletefile / deletepage -> destruction / DoS]
    F --> G2[editpage -> stored-content injection]
    F --> G3["images upload -> shell.php.jpg -> RCE"]

الإجراءات القابلة للتزوير تشمل:

الإجراءالطريقةالأثر
admin.php?action=deletefile&var1=<f>GETحذف أي ملف مرفوع
admin.php?action=deletepage&...GETحذف صفحات الموقع (DoS)
admin.php?action=module_delete&...GETإزالة الوحدات
admin.php?action=logoutGETتسجيل خروج المسؤول
admin.php?action=editpagePOSTحقن محتوى صفحات مخزَّن
admin.php?action=images (رفع)POSTزرع shell.php.jpg → RCE

💥 الاستغلال

توجد مجموعة أدوات PoC عاملة في exploit/:

  • pluck_csrf_rce.py — لإثبات منطق الفشل المفتوح، رفع قشرة ويب عبر CSRF وتنفيذ أوامر، حذف ملفات عبر CSRF، أو توليد صفحة إغراء.
  • csrf_poc.html — صفحة drive-by المستقلة التي تُسلَّم إلى مسؤول ضحية.
pip install requests

# Prove the fail-open Referer logic
python3 exploit/pluck_csrf_rce.py -u http://127.0.0.1/pluck -p 'AdminPass1!' probe
تنزيل الأداة