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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2024-38063 — CVE-2024-38063 - استغلال النواة عن بُعد عبر IPv6 | Kitploit
أدوات/GitHubGitHub/faizan-khanx/cve-2024-38063
تحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالاستغلالالهندسة العكسيةأمن الشبكاتالأوراق والأبحاثالتعلم والتعليماستغلال الملفات الثنائية
GitHubfaizan-khanx/cve-2024-38063

CVE-2024-38063

CVE-2024-38063 - استغلال النواة عن بُعد عبر IPv6

عرض المستودع
114منذ 2 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2024-38063 - استغلال النواة عن بُعد عبر IPv6

  • منذ إصدار أحدث تصحيح لنظام Windows في 13 أغسطس، كنت غارقًا في تفاصيل tcpip.sys (برنامج تشغيل النواة المسؤول عن معالجة حزم TCP/IP). ثغرة بتقييم 9.8 على مقياس CVSS في الجزء الأكثر سهولة في الوصول من نواة Windows كان شيئًا لم أستطع ببساطة التخلي عنه. لم ألقِ نظرة فعلية على IPv6 من قبل (أو برامج التشغيل المسؤولة عن تحليله)، لذا كنت أعلم أن محاولة هندسة هذه الثغرة عكسيًا ستكون صعبة للغاية، لكنها تجربة تعليمية جيدة.

أسهل تحليل للتصحيح على الإطلاق

  • عادةً، حتى مجرد هندسة التصحيح عكسيًا لمعرفة أي تغيير في الكود يتوافق مع الثغرة يمكن أن يستغرق أيامًا أو حتى أسابيع، لكن في هذه الحالة كان فوريًا. وكان الأمر بهذه السهولة لدرجة أن عدة أشخاص على وسائل التواصل الاجتماعي أخبروني أنني مخطئ وأن الخطأ في مكان آخر. هل استمعت إليهم بالفعل وأضعت يومًا كاملًا في هندسة برنامج تشغيل خاطئ عكسيًا؟ ربما لن نعرف أبدًا.

كان هناك تغيير واحد فقط في ملف برنامج التشغيل بأكمله، وقد اتضح أنه بالفعل كان الخطأ. image نظرة عامة من bindiff على tcpip.sys قبل وبعد تثبيت التصحيح.

تم تعديل دالة واحدة فقط في برنامج التشغيل بأكمله. في العادة، قد أقضي يومًا كاملًا في مراجعة أكثر من 20 تغييرًا مختلفًا في الدوال فقط لأعرف أيها يجب أن أركز عليه، لكن ليس هذه المرة. image

Ipv6pProcessOptions() قبل التصحيح.

image Ipv6pProcessOptions() . بعد التصحيح.

لم يكن مجرد تغيير دالة واحدة، بل تغيير سطر واحد من الكود.

  • الدالة ذات الاسم الطويل للغاية Feature_2660322619__private_IsEnabledDeviceUsage_3() هي شيء تضيفه Microsoft أحيانًا لتمكين التراجع الجزئي عن التصحيحات. يتحقق الاستدعاء من وجود علامة عامة أو إعداد في السجل، وإذا تم ضبطه، فسيؤدي إلى جعل الدالة تُرجع false، مما يؤدي إلى تنفيذ الكود الأصلي بدلاً من النسخة المصححة.

  • السبب في قيام Microsoft بذلك هو أن التصحيحات الأمنية قد تكسر أشياءً عن غير قصد في بعض الأحيان، لذا يتيح هذا الإعداد للمسؤول إلغاء تصحيح ثغرة واحدة دون إلغاء تثبيت حزمة التصحيح الشهرية بأكملها وإضعاف أمان نظامه بشكل كبير.

  • مع أخذ هذا في الاعتبار، من الواضح أن كل ما يفعله هذا التصحيح هو استبدال استدعاء IppSendErrorList() بـ IppSendError()، مما يعطينا دليلًا على أن المشكلة تكمن في نوع من القوائم. أسهل مقارنة تصحيح على الإطلاق (أو هكذا اعتقدت)

الثغرات اختيارية، الاستغلال إلزامي

  • هندسة التصحيح عكسيًا للعثور على الكود المعدل ليست سوى نصف التحدي (أو في هذه الحالة أقل من 0.1%). أما باقي العملية فيتمثل في هندسة جزء كافٍ من قاعدة الكود عكسيًا لفهم ما يحدث أصلًا، ومعرفة نوع الثغرة التي تم تصحيحها، وكيفية صياغة طلب للوصول إلى الكود المستهدف، وما الحالة التي تؤدي إلى شرط قابل للاستغلال.

  • الجزء الأول سهل بما يكفي. التغيير موجود في Ipv6pProcessOptions()، وهو ما يخبرنا بأن الأمر يتعلق بـ IPv6 ويتضمن معالجة الخيارات. لذا، فإن مراجعة سريعة لـ RFC تخبرنا بالضبط ما هو خيار IPv6 وأين يمكننا العثور عليه.

image تخطيط ترويسة خيارات الوجهة من ويكيبيديا.

حسنًا، رائع. يبدو أن ما نبحث عنه هو ترويسة خيارات الوجهة، والتي تأتي مباشرة بعد ترويسة IPv6 الرئيسية. دعنا نستخدم مكتبة بايثون 'scapy' لصياغة حزمة IPv6 تجريبية.

ملاحظة: للتخفيف من هجمات حجب الخدمة الموزعة (DDoS) التي تستخدم عناوين IP مزيفة، تقيد Windows القدرة على إنشاء حزم IP خام. لهذا السبب، اخترت استخدام Linux لتطوير إثبات المفهوم الخاص بي. بينما يتيح Linux للمستخدمين إنشاء وإرسال حزم خام من الطبقة الثانية والثالثة، فإنه يتطلب تشغيل سكربت Python بصلاحيات الجذر.

import sys
import struct
from scapy.all import *


def send_ipv6_option_packet(dest_ip):
	ethernet_header = Ether()
	ip_header = IPv6(dst=dest_ip)
	options_header = IPv6ExtHdrDestOpt()
	sendp(ethernet_header / ip_header / options_header)
	
	
if len(sys.argv) < 2:
	print('Use: python3 script.py <target_ipv6_address>')
	exit(-1)

send_ipv6_option_packet(sys.argv[1])
  • بعد تعيين نقطة توقف على tcpip!Ipv6pProcessOptions وتشغيل السكربت، اتضح أن كل ما هو مطلوب للوصول إلى الدالة الضعيفة هو إرسال حزمة IPv6 تحتوي على بنية خيارات فارغة. ثم حاولت إضافة بعض الخيارات غير الصالحة إلى البنية لمعرفة ما إذا كان بإمكاني الوصول إلى استدعاء IppSendErrorList().

أشارت مراجعة سريعة للكود إلى أن أي تنسيق غير صالح تقريبًا للخيارات قد يؤدي إلى تشغيل استدعاء IppSendErrorList. لذا، قررت استخدام خيار الحزمة العملاقة Jumbo Packet بطول غير صالح (أقل من 65535 بايت).

options_header = IPv6ExtHdrDestOpt(options=[Jumbo(jumboplen=0x1337)])

  • إذًا، ما الذي يفعله IppSendErrorList() فعليًا؟ حسنًا، الكود بسيط جدًا. image دالة IppSendErrorList بأكملها.

  • يتكرر الكود عبر قائمة مرتبطة ويستدعي IppSendError() على كل عنصر في القائمة. مرة أخرى، اصطفت النجوم وكانت الأمور سهلة حتى الآن. إذا كان IppSendErrorList يستدعي ببساطة IppSendError لكل عنصر في قائمة، وكان التصحيح يستبدل الاستدعاء إلى IppSendErrorList بـ IppSendError، فإن المشكلة تحدث عند استدعاء IppSendError على عنصر في القائمة ليس هو الأول.

إنه يعدّ قائمة، ويتحقق منها 52,567 مرة

  • هنا تحولت الأمور من الواضح إلى الصعب بشكل غير طبيعي، على الرغم من أنني أعتقد أن جزءًا كبيرًا من ذلك كان بسبب انشغال إحدى خليتّي الدماغ المتاحتين بمحاربة عدوى كوفيد سيئة. خسرت بضعة أيام بين محاولة فهم أجزاء من الكود، والنوم، ثم نسيان ما كنت قد اكتشفته. تطلبت العملية بأكملها أكثر من أسبوع من الهندسة العكسية لأجزاء من tcpip.sys لمعرفة ما كان يحدث. لكن مشاركة مدونة Axel كانت مفيدة للغاية.

  • بالنظر إلى الدوال والبنية التي قام Axel بهندستها عكسيًا، وإلى أي الدوال الأخرى يتم تمريرها، يتضح أن الوسيط الوحيد الذي يُمرَّر إلى Ipv6pProcessOptions() هو نفس بنية packet_t المعرّفة في المقالة. بشكل أساسي، المؤشر الذي يُمرَّر إلى Ipv6pProcessOptions، والذي يتكرر عبره IppSendErrorList، هو قائمة مرتبطة من الحزم.

  • لذا، قمت بتعيين نقطة توقف على Ipv6pProcessOptions() وفحصت القائمة.

image

إدخال list->Next يكون NULL.

  • في كل مرة يتم فيها الوصول إلى نقطة التوقف الخاصة بي، كانت القائمة تحتوي على حزمة واحدة فقط. قضيت وقتًا أطول مما أود الاعتراف به في محاولة معرفة السبب وكيفية جعل القائمة قائمة فعلًا. كان أول ما فكرت فيه هو تجزئة IPv6: يتيح IPv6 للمرسلين تقسيم الحزم الكبيرة إلى حزم أصغر منفصلة، ومن المنطقي الاحتفاظ بها معًا في قائمة.

  • بعد هندسة عكسية مكثفة، تأكدت من أن افتراضاتي كانت صحيحة، على الرغم من أن قائمة الشظايا لا علاقة لها بالقائمة التي نتعامل معها هنا.

  • في الواقع، انتهى بي الأمر بالعثور على الإجابة بالصدفة تمامًا. في بعض الأحيان، كانت القائمة تمتلئ، لكن السبب كان غير واضح. بعد الكثير من الدوران في دوائر، أدركت أنه عندما يتم تشغيل نقطة التوقف الخاصة بي في النواة، فإنها توقف النواة بأكملها، مما يؤدي إلى تراكم الحزم في محول الشبكة. عندما تستأنف النواة عملها، يتم تمرير هذه الحزم إلى أسفل المكدس إلى tcpip.sys في قائمة أنيقة ومرتبة. حدث هذا فقط إذا تم إرسال الحزم بينما كانت النواة متوقفة، ولكن لم تتم معالجتها قبل الوصول إلى نقطة التوقف التالية.

  • هذا السلوك على الأرجح تحسين للأداء؛ حيث تعالج النواة الحزم بشكل فردي عند معدل نقل منخفض، لكن عند الأحجام الأعلى، يتم تنظيم الحزم في قوائم ومعالجتها على دفعات. على الأرجح تُفصل القوائم بناءً على عوامل مثل البروتوكول وعنوان المصدر لتسريع المعالجة، لذا يجب أن تحتوي قائمتنا على حزم IPv6 التي أرسلناها فقط.

  • الآن بعد أن عرفنا أن الحزم تتجمع في قوائم أثناء معدل النقل المرتفع، يتضح ما هو الخيار الأسهل. من المفارقات أن إثبات المفهوم لحجب الخدمة (DoS PoC) الخاص بنا سيضطر إلى استخدام DoS لتشغيل حالة DoS. إذا أغرقنا النظام بدفعات من حزم IPv6، يجب أن نتمكن من الحصول على قائمة كبيرة وجميلة تُمرَّر إلى IppSendErrorList().

تنزيل الأداة