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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
HTTP3ONSTEROIDS — HTTP3ONSTEROIDS - بحث حول CVE-2023-25950 حيث يفشل تنفيذ HAProxy الخاص ببروتوكول HTTP/3 في حظر اسم حقل ترويسة HTTP مشوّه. | Kitploit
أدوات/GitHubGitHub/dhmosfunk/http3onsteroids
تحليل الثغرات الأمنيةاستغلال تطبيقات الويبالتعلم والتعليممختبرات وتدريب عملي
GitHubdhmosfunk/http3onsteroids

HTTP3ONSTEROIDS

HTTP3ONSTEROIDS - بحث حول CVE-2023-25950 حيث يفشل تنفيذ HAProxy الخاص ببروتوكول HTTP/3 في حظر اسم حقل ترويسة HTTP مشوّه.

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

الأكثر شعبية

عرض الكل →

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

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

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

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

جدول المحتويات

  • وصف الثغرة
    • مراجعة الكود المصدري
  • إعداد المختبر
    • تحديد المشكلة
  • المراجع

وصف الثغرة

إن تنفيذ HAProxy لبروتوكول HTTP/3 لا ينجح في حظر اسم حقل ترويسة HTTP غير صالح، وعند نشره أمام خادم يعالج هذه الترويسة غير الصالحة بشكل غير صحيح، قد يُستخدم لشن هجوم تهريب طلب/استجابة HTTP (HTTP request/response smuggling). قد يتمكن مهاجم عن بُعد من تغيير طلب مستخدم شرعي. ونتيجة لذلك، قد يحصل المهاجم على معلومات حساسة أو يتسبب في حالة حرمان من الخدمة (DoS).

https://jvn.jp/en/jp/JVN38170084/

مراجعة الكود المصدري

من أفضل الممارسات قبل البدء في أي بحث حول ثغرات CVE هي قراءة وصف الثغرة أولاً ثم التحقق من توفر الالتزامات (commits) الخاصة بالتصحيح.
في حالتي، كان الالتزام متاحًا، ومن الواضح أن مطوري HAProxy نسوا تضمين فحوصات RFC 9114 4.1.2. الطلبات والاستجابات غير الصالحة أثناء تحليل الترويسات القياسية في تنفيذ HTTP/3.

ارجع إلى التزام التصحيح بالأسفل.

root@kitploit:~
--- a/src/h3.c
+++ b/src/h3.c
@@ -352,7 +352,27 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
        //struct ist scheme = IST_NULL, authority = IST_NULL;
        struct ist authority = IST_NULL;
        int hdr_idx, ret;
-       int cookie = -1, last_cookie = -1;
+       int cookie = -1, last_cookie = -1, i;
+
+       /* RFC 9114 4.1.2. Malformed Requests and Responses
+        *
+        * A malformed request or response is one that is an otherwise valid
+        * sequence of frames but is invalid due to:
+        * - the presence of prohibited fields or pseudo-header fields,
+        * - the absence of mandatory pseudo-header fields,
+        * - invalid values for pseudo-header fields,
+        * - pseudo-header fields after fields,
+        * - an invalid sequence of HTTP messages,
+        * - the inclusion of uppercase field names, or
+        * - the inclusion of invalid characters in field names or values.
+        *
+        * [...]
+        *
+        * Intermediaries that process HTTP requests or responses (i.e., any
+        * intermediary not acting as a tunnel) MUST NOT forward a malformed
+        * request or response. Malformed requests or responses that are
+        * detected MUST be treated as a stream error of type H3_MESSAGE_ERROR.
+        */
 
        TRACE_ENTER(H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
 
@@ -416,6 +436,14 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
                if (isteq(list[hdr_idx].n, ist("")))
                        break;
 
+               for (i = 0; i < list[hdr_idx].n.len; ++i) {
+                       const char c = list[hdr_idx].n.ptr[i];
+                       if ((uint8_t)(c - 'A') < 'Z' - 'A' || !HTTP_IS_TOKEN(c)) {
+                               TRACE_ERROR("invalid characters in field name", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
+                               return -1;
+                       }
+               }
+
                if (isteq(list[hdr_idx].n, ist("cookie"))) {
                        http_cookie_register(list, hdr_idx, &cookie, &last_cookie);
                        continue;

المستودعات - haproxy-2.7.git/commit

بالأسفل، يمكنك العثور على الكود الذي يوضح غياب تنقية أسماء الترويسات في تنفيذ معالجة الترويسات القياسية على HAProxy 2.7.0.

root@kitploit:~
/* 
src/h3.c 
lines: 413 - 428
*/

/* now treat standard headers */
hdr_idx = 0;
while (1) {
    if (isteq(list[hdr_idx].n, ist("")))
        break;
    if (isteq(list[hdr_idx].n, ist("cookie"))) {
        http_cookie_register(list, hdr_idx, & cookie, & last_cookie);
        continue;
    }
    if (!istmatch(list[hdr_idx].n, ist(":")))
        htx_add_header(htx, list[hdr_idx].n, list[hdr_idx].v);
    ++hdr_idx;
}

بالأسفل، يمكنك العثور على الكود المستخدم للتحقق من صلاحية اسم الترويسة.

يبدأ الكود بحلقة for تتكرر عبر كل حرف من اسم حقل الترويسة. تعمل الحلقة من i = 0 إلى i < list[hdr_idx0.n.len]، حيث list هي مصفوفة أو بنية تحتوي على معلومات الترويسة، وhdr_idx هو فهرس يمثل الترويسة المحددة التي يتم فحصها.
داخل الحلقة، يستخرج الكود الحرف الحالي c من اسم حقل الترويسة. list[hdr_idx].n.ptr[i] يصل إلى الحرف في الموضع i من اسم حقل الترويسة. يحتوي الجزء التالي من الكود على عبارة if. تتحقق مما إذا كان الحرف الحالي c يحقق أحد الشرطين:

  • (uint8_t)(c - 'A') < 'Z' - 'A': يتحقق هذا الشرط مما إذا كان الحرف حرفًا كبيرًا (من A إلى Z) عن طريق طرح 'A' من c وتحويل النتيجة إلى uint8_t. إذا كانت النتيجة أقل من الفرق بين 'Z' و'A'، فإن الحرف هو حرف كبير.
  • !HTTP_IS_TOKEN(c): يتحقق هذا الشرط مما إذا كان الحرف حرف رمز HTTP صالحًا. يعمل HTTP_IS_TOKEN أولاً عن طريق التحقق مما إذا كان اسم الترويسة يحتوي على أي رموز. الرمز (token) هو سلسلة من الأحرف التي ليست أحرفًا محجوزة في بروتوكول HTTP. الأحرف المحجوزة هي أحرف لها معنى خاص في بروتوكول HTTP، مثل : و/ و? و#.
root@kitploit:~
/* 
src/h3.c 
lines: 439 - 445
*/
for (i = 0; i < list[hdr_idx].n.len; ++i) {
    const char c = list[hdr_idx].n.ptr[i];
    if ((uint8_t)(c - 'A') < 'Z' - 'A' || !HTTP_IS_TOKEN(c)) {
        TRACE_ERROR("invalid characters in field name", H3_EV_RX_FRAME | H3_EV_RX_HDR, qcs -> qcc -> conn, qcs);
        return -1;
    }
}

إعداد المختبر

يعمل المختبر بالكامل على Docker. يمكنك تشغيل المختبر باستخدام الأوامر التالية:

  1. cd /lab
  2. docker-compose up --build

يُرجى ملاحظة أن بناء Docker سيستغرق 15-20 دقيقة لإكماله.
ومع ذلك، قبل تشغيل المختبر، يجب إجراء بعض التغييرات في الإعدادات:

/lab/haproxy/conf/haproxy.cfg

root@kitploit:~
...
default_backend api_server

backend api_server
  balance roundrobin
  server api_server [YOUR-LOCAL-IPv4]:8080 # replace with local IPv4

/etc/hosts

root@kitploit:~
[YOUR-LOCAL-IPv4]   foo.com

/lab/docker-compose.yml
يمكنك الاختيار بين النسخة غير المصححة والنسخة المصححة عن طريق تغيير قيمة الوسيط إلى 'vuln' أو 'patched' لإجراء اختبارك عليها.

root@kitploit:~
...
    args:
        - haproxy_version=patched || vuln
...

وأخيرًا، استورد شهادة minica.crt في متصفحك.

⚠️ يُرجى تشغيل المختبر في بيئة لينكس.

تحديد المشكلة

إرسال طلب curl التالي:

  • curl --http3 -H "foooooo\r\n: barr" -iL -k https://192.168.1.104/

استجابة النسخة غير المصححة:

root@kitploit:~
HTTP/3 200 
server: Werkzeug/2.3.6 Python/3.8.17  
date: Sat, 12 Aug 2023 13:10:52 GMT   
content-type: text/html; charset=utf-8
content-length: 76
alt-svc: h3=":443";ma=900;

Host: 192.168.1.104
User-Agent: curl/8.1.2-DEV
Accept: */*
Foooooo\R\N: barr <-- Malformed header

استجابة النسخة المصححة:

root@kitploit:~
curl: (56) HTTP/3 stream 0 reset by server

بناءً على النتائج أعلاه، تشير الاستجابات المقابلة إلى أن النسخة غير المصححة من HAProxy سمحت بتمرير بادئة \r\n إلى الخادم الخلفي، بينما أسقطت النسخة المصححة الاتصال بين العميل وHAProxy.


يمكن للمهاجم شن هجوم تهريب طلب HTTP (HTTP Request Smuggling) بناءً على سلوك الخادم الخلفي وكيفية تعامل الخادم الخلفي مع الترويسة غير الصالحة. من وجهة نظري، أكثر ما يثير القلق هو أن المهاجم قد يستغل الثغرة المذكورة أعلاه لتنفيذ هجوم حرمان من الخدمة (DoS).

المراجع:

https://jvn.jp/en/jp/JVN38170084/
https://github.com/haproxytechblog/haproxy-2.6-http3
https://www.haproxy.com/blog/how-to-enable-quic-load-balancing-on-haproxy
https://git.haproxy.org/
https://github.com/jsha/minica
https://curl.se/docs/http3.html

تنزيل الأداة