
إثبات المفهوم (PoC) وتحليل لثغرة تجاوز سعة المخزن المؤقت للمكدس المحلية في dataSIMS Avionics ARINC 664-1 الإصدار v4.5.3، مع تفصيل الحمولة وسكربت إعادة الإنتاج وتصحيحات سجلات CVE.
تجاوز محلي لسعة مخزن مؤقت قائم على المكدس في dataSIMS Avionics ARINC 4.5.3 (Data Device Corporation)
مرحبًا، أنا Kağan Çapar. في فبراير 2020 اكتشفت تجاوز سعة مخزن مؤقت محلي قائم على المكدس في برنامج dataSIMS لناقل بيانات الطيران (avionics databus) الخاص بشركة DDC، ونشرت إثبات المفهوم على Exploit-DB في فبراير 2021. وبعد ما يقرب من خمس سنوات، في يناير 2026، خصصت له VulnCheck رقم CVE-2021-47881 كرقم CVE بأثر رجعي — وعلمت بالتعيين بعد وقوعه، دون أن أُبلَّغ به.
هذا المستودع هو السجل الأرشيفي لذلك الاكتشاف: إثبات المفهوم الأصلي محفوظ كما نُشر، ونسخة منقولة إلى Python 3 مطابقة بايتًا ببايت، وتشريح مشروح للحمولة، وتصويبات لمشكلتين في سجل CVE المنشور.
النطاق، مقدمًا. هذا سجل، وليس تحليلًا للسبب الجذري. dataSIMS هو برنامج تجاري مغلق المصدر، ولا يوجد تصحيح من البائع، ولم أُعد اختبار هذا الاكتشاف على إصدار حالي. ما يمكن التحقق منه هنا تم التحقق منه وعرضه؛ وكل ما عداه مشروح في القيود. إذا جئت إلى هنا متوقعًا عمق CVE-2026-5201، فاقرأ تلك الملاحظة أولًا.
| CVE | CVE-2021-47881 |
| CWE | CWE-121 — تجاوز سعة المخزن المؤقت القائم على المكدس |
| CVSS v4.0 | 6.7 متوسط — AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N (VulnCheck) |
| CVSS v3.1 | 8.4 مرتفع — AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (VulnCheck) |
| المنتج المتأثر | dataSIMS Avionics ARINC 664-1، الإصدار 4.5.3 |
| البائع | Data Device Corporation |
| CNA | VulnCheck |
| اكتُشفت | 2020-02-17 |
| نُشر إثبات المفهوم | 2021-02-19 — EDB-49577 |
| نُشر CVE | 2026-01-23 (NVD) |
| تصحيح البائع | لا يوجد تصحيح منشور |
| اختُبر على | Windows 10 Enterprise x64 |
المكوّن المتأثر هو وحدة ARINC 664-1 في dataSIMS 4.5.3. تعيد هذه الوحدة قراءة ملف نتائج يحمل — رغم أنه يخص هذه الوحدة — اسم milstd1553result.txt؛ والاسم أثر من البائع موروث من سلالة MIL-STD-1553 الخاصة بالحزمة، وليس مؤشرًا على الوحدة المتأثرة. إن تزويد نسخة طويلة بشكل مفرط من هذا الملف بصيغة يصوغها المهاجم يتسبب في تجاوز سعة مخزن مؤقت ثابت الحجم على المكدس أثناء مسار إعادة القراءة، ويستبدل عنوان الإرجاع المحفوظ. ويقع التعطل مع السيطرة الكاملة على EIP:
EIP 42424242 <- 'BBBB' from the payload
ECX 42424242
C0000005 <- STATUS_ACCESS_VIOLATION
إثبات المفهوم المنشور حجمه 1040 بايت ويتوقف عند استبدال EIP. لا يحقق تنفيذًا برمجيًا، ولم يكن مقصودًا منه ذلك أبدًا — انظر قابلية الاستغلال.
تخطيط حقول إثبات المفهوم، وقد تحققت منه بتشغيل النسخة المنقولة (py poc/poc_py3.py --layout):
إزاحة EIP هي 1007. وهو رقم لا تحصل عليه من !mona findmsp أو pattern_offset.rb — بل هو مجموع خمسة حقول ضُبطت يدويًا. بُني إثبات المفهوم الأصلي بتوسيع نطاق التعطل حتى تحرّك عنوان الإرجاع، وليس بتحديد الإزاحة تحليليًا. أذكر هذا شفافيةً، لا تجميلًا: إعادة كتابة نظيفة كانت ستحدد المسافة الحقيقية إلى عنوان الإرجاع المحفوظ وتستغني عن align وimp وimp2 بالكامل، لأن أيًا منها لا يحمل معنى. imp/imp2 مجرد سلاسل حشو، وليست imports.
buf هو مقطع msfvenom من نوع shikata_ga_nai بطول 29 بايت. فُكك باستخدام ndisasm -b32:
00000000 DAC1 fcmovb st1 ; junk FPU op (sgn signature)
00000002 D97424F4 fnstenv [esp-0xc] ; GetPC
00000006 58 pop eax ; eax = &stub
00000007 BB0B7E9762 mov ebx,0x62977e0b ; XOR key
0000000C 33C9 xor ecx,ecx
0000000E B101 mov cl,0x1 ; <-- ONE 4-byte block
00000010 315819 xor [eax+0x19],ebx ; decode block at +0x19
00000013 83E8FC sub eax,-4 ; eax += 4
00000016 035815 add ebx,[eax+0x15] ; key schedule
00000019 E9 db 0xe9 ; <-- encoded block, not code
0000001A 8B db 0x8b
0000001B 7C9C jl 0xffffffb9
أمران ينتجان من هذا، وكلاهما يعني أن الحمولة لا يمكن أن تعمل أبدًا:
mov cl,0x1 — حلقة فك التشفير مكوَّنة لكتلة واحدة من 4 بايتات. لا توجد حمولة حقيقية خلفها، فقط تلك البايتات الأربعة.\xe2\xf4 (loop) غير موجودة. مقطع sgn الكامل ينهي حلقة فك التشفير بتعليمة loop قبل الجسم المُرمَّز. هنا يسقط التنفيذ مباشرة من add ebx,[eax+0x15] إلى E9 8B 7C 9C — التي ما تزال في تلك اللحظة مُرمَّزة، وهي ليست تسلسل تعليمات صالحًا على أي حال.إذًا المقطع مجرد عنصر نائب (placeholder) يحتل ذيل الحمولة. وهذا يطابق الطريقة التي وُصف بها إثبات المفهوم على Exploit-DB، وهو القراءة الصادقة: هذا عرض للسيطرة على EIP، وليس استغلالًا يعمل.
بتقييم هذا بالطريقة التي يقيّمه بها وسيط (broker) أو بائع، لا بالطريقة التي يقيّمه بها متجه CVSS v3.1:
milstd1553result.txt ملف ينتجه التطبيق نفسه، في موقع يتحكم به المستخدم نفسه بالفعل. المهاجم القادر على إعادة كتابته يستطيع عمومًا تشغيل برمجيات بصلاحيات ذلك المستخدم أصلًا. وهذا يجعله خلل متانة أكثر بكثير من كونه خللًا أمنيًا.EIP في بناء x86 من حقبة 2020 لا تعني الكثير وحدها. تحويلها إلى تنفيذ يتطلب سيناريو DEP/ASLR — وحدة بدون /DYNAMICBASE، أو سلسلة ROP، أو استبدال جزئي. لم يُنفَّذ أي من ذلك، ولم أتحقق من وسائل التخفيف التي يأتي بها الإصدار الحالي.UI:A في CVSS v4.0 تعكس الواقع؛ أما UI:N في v3.1 فلا تعكسه.إذا أراد أحدهم جعل هذا الأمر مثيرًا للاهتمام حقًا، فالأسطح المجدية ليست في هذا الملف إطلاقًا: برنامج تشغيل النواة (kernel driver) الذي توفره DDC لبطاقات 1553/664 الخاصة بمنافذ PCIe (معالجة IOCTL → LPE)، وأي تحليل لحزم ARINC 664/AFDX موجه للشبكة، وصيغ ملفات الإدخال التي تستهلكها الحزمة من مصادر غير موثوقة. تلك تعبر حدودًا حقيقية. وهذا لا يعبرها.
يحمل سجل CVE عيبين يستحقان الذكر بوضوح، لأنه منشور باسمي.
تسمية المنتج في السجل — "dataSIMS Avionics ARINC 664-1 الإصدار 4.5.3" — صحيحة. المكوّن المتأثر هو وحدة ARINC 664، كما ذُكر في عنواني الأصلي على Exploit-DB.
العيب هو مرجع البائع الذي أرفقته الـ CNA. يستشهد NVD بصفحة BU-69414، وهي صفحة منتج برمجيات MIL-STD-1553 لدى DDC — وهي حزمة ناقل بيانات مختلفة عن تلك التي يتأثر بها هذا الاكتشاف. ARINC 664 هو AFDX (Ethernet محوَّل بنمط محدد، الجزء السابع من معيار ARINC 664)؛ أما MIL-STD-1553 فهو ناقل أمر/استجابة مزدوج التكرار بسرعة 1 ميجابت/ثانية. وهما معياران لا صلة بينهما.
السبب الأرجح للاستشهاد الخاطئ هو اسم ملف النتائج. تسمّي dataSIMS ملف نتائج وحدة ARINC 664 باسم milstd1553result.txt — وهو بقايا من سلالة MIL-STD-1553 الخاصة بالحزمة. أي قارئ لوصف CVE يبحث عن صفحة منتج مطابقة لدى البائع سيتبع هذا النص مباشرة إلى خط منتجات 1553، وهو ما يبدو أنه حدث. اسم الملف ليس دليلًا على الوحدة المتأثرة، والسجل الذي يشير إلى صفحة منتج 1553 يوجّه المدافعين إلى مراجعة المكوّن الخطأ.
كلا المتجهين صادران عن VulnCheck، وهما يتعارضان على الأمرين المهمين:
| v3.1 (8.4 مرتفع) | v4.0 (6.7 متوسط) | |
|---|---|---|
| تفاعل المستخدم | UI:N — لا يوجد | UI:A — مطلوب |
| الأثر | C:H/I:H/A:H — سرية وسلامة وتوافر كاملة | VC:N/VI:N/VA:H — التوافر فقط |
لا يمكن أن يكونا صحيحين معًا. متجه v4.0 هو القابل للدفاع عنه: إثبات المفهوم يبرهن على تعطل، لا على كشف للمعلومات أو فقدان سلامة. درجة 8.4 في v3.1 تبالغ في تقدير الاكتشاف، وأفضل قول ذلك هنا على الاستفادة منه.
لا يتطلب أي شيء هنا البرنامج المستهدف — إثبات المفهوم يكتب الملف المعطوب فقط. تفعيل التجاوز يتطلب dataSIMS 4.5.3، وهو برنامج تجاري مرخّص لا يوزعه هذا المستودع.
# print the field map, write nothing
py poc/poc_py3.py --layout
# write the 1040-byte payload
py poc/poc_py3.py -o milstd1553result.txt
ثم حمّل الملف باستخدام الإصدار المتأثر تحت مصحح أخطاء (debugger) ولاحظ استبدال EIP. poc/49577.py هو المصدر الأصلي بلغة Python 2، مؤرشَف كما هو؛ ولن يعمل على Python 3.
تنتج النسخة المنقولة ملفًا مطابقًا بايتًا ببايت بحجم 1040 بايت (sha256 530efb5e…). ثلاثة أمور تطلبت التغيير، وأمر واحد يبدو كخلل وليس كذلك:
print len(win32) عبارة (statement) في Python 2، وSyntaxError في Python 3.str مع شيل كود (shellcode) من النوع bytes. سمحت Python 2 بذلك لأن str كانت بايتات؛ أما Python 3 فترفع TypeError.open(..., "w") إلى "wb". في الوضع النصي، كانت Python 3 سترمّز كل بايت ≥ 0x80 في المقطع بترميز UTF-8 — 0xda → 0xc3 0x9a — مما يُفسد الحمولة بصمت ويغيّر طولها.imp2 = "\x61\x72\x61\x63\x61\x67\x131\x7a" ليس سلوكًا غريبًا مرتبطًا بالإصدار. \x يأخذ رقمين سداسي عشر بالضبط في كل من Python 2 و3، لذا هو يليه الحرف . الحقل 9 بايتات في كليهما. الأمر فقط يبدو سيئًا عند القراءة.مذكورة صراحةً حتى لا يضطر أحد إلى التخمين حول ما تم وما لم يتم:
EIP هو النتيجة كلها.Kağan Çapar — GitHub · Exploit-DB · LinkedIn · X
الشروحات: الإنجليزية · التركية
| الحقل | الإزاحة | الطول | المحتوى |
|---|
junk | 0 / 0x000 | 600 | حشو 0x41 |
align | 600 / 0x258 | 8 | "22221111" |
prop | 608 / 0x260 | 380 | حشو 0x43 |
imp | 988 / 0x3dc | 10 | "bzhrturlu2" |
imp2 | 998 / 0x3e6 | 9 | "aracag" 0x13 "1z" |
overwrite | 1007 / 0x3ef | 4 | 0x42 × 4 → عنوان الإرجاع المحفوظ |
buf | 1011 / 0x3f3 | 29 | مقطع فك تشفير shikata_ga_nai |
| الإجمالي | 1040 | sha256 530efb5efef917082e40dcf379f5e0a526375724af18aba6f0270f794f96d066 |
\x1310x131| التاريخ | الحدث |
|---|
| 2020-02-17 | اكتشاف الثغرة |
| 2021-02-19 | نشر إثبات المفهوم — EDB-49577 |
| 2026-01-22 | نشر نشرة VulnCheck |
| 2026-01-23 | نشر CVE-2021-47881 في NVD |
| 2026-06-17 | آخر تعديل على سجل NVD |