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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
virtualbox_e1000_0day — هروب من الضيف إلى المضيف في VirtualBox E1000 | Kitploit
أدوات/GitHubGitHub/mortenoir1/virtualbox_e1000_0day
تحليل الثغرات الأمنيةالاستغلالاختبار الاختراقأمن الأجهزةاستغلال الملفات الثنائية
GitHubmortenoir1/virtualbox_e1000_0day

virtualbox_e1000_0day

هروب من الضيف إلى المضيف في VirtualBox E1000

عرض المستودع
1.4k19622منذ 7 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

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

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

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

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

لماذا

أحب VirtualBox ولا علاقة لذلك بنشري ثغرة يوم-صفر (0day). السبب هو خلافي مع الحالة الراهنة لأمن المعلومات، خاصة البحث الأمني والمكافآت مقابل اكتشاف الثغرات (bug bounty):

  1. الانتظار نصف عام حتى تُصحَّح ثغرة يُعتبر أمرًا مقبولًا.
  2. في مجال المكافآت مقابل اكتشاف الثغرات، هذه أمور تُعتبر مقبولة:
    1. الانتظار أكثر من شهر حتى يتم التحقق من ثغرة مقدَّمة واتخاذ قرار بالشراء أو عدم الشراء.
    2. تغيير القرار في أي لحظة. اليوم تكتشف أن برنامج المكافآت سيشتري ثغرات في برنامج ما، وبعد أسبوع تأتي بثغرات واستغلالات (exploits) لتتلقى رد "لسنا مهتمين".
    3. عدم وجود قائمة دقيقة بالبرمجيات التي يهتم برنامج المكافآت بشراء ثغرات فيها. هذا مريح لبرامج المكافآت، ومُربك للباحثين.
    4. عدم وجود حدود سفلى وعليا دقيقة لأسعار الثغرات. هناك عوامل كثيرة تؤثر على السعر، لكن الباحثين يحتاجون إلى معرفة ما يستحق العمل عليه وما لا يستحق.
  3. تضخيم الذات والهراء التسويقي: تسمية الثغرات وإنشاء مواقع ويب لها؛ عقد ألف مؤتمر في السنة؛ المبالغة في أهمية دور الفرد كباحث أمني؛ اعتبار النفس "منقذًا للعالم". انزل إلى الأرض يا صاحب السمو.

لقد سئمت من الأمرين الأولين، لذا قراري هو الإفصاح الكامل. يا أهل أمن المعلومات، تقدمُوا.

معلومات عامة

البرنامج المعرض للثغرة: VirtualBox 5.2.20 والإصدارات الأقدم.

نظام التشغيل المضيف: أي نظام، فالخطأ في قاعدة أكواد مشتركة.

نظام التشغيل الضيف: أي نظام.

إعدادات الآلة الافتراضية: افتراضية (الشرط الوحيد هو أن تكون بطاقة الشبكة من نوع Intel PRO/1000 MT Desktop (82540EM) والوضع NAT).

كيف تحمي نفسك

حتى صدور إصدار VirtualBox المُصحَّح، يمكنك تغيير بطاقة الشبكة لآلاتك الافتراضية إلى PCnet (أيٍّ من النوعين) أو إلى Paravirtualized Network. إذا لم تستطع، غيّر الوضع من NAT إلى وضع آخر. الطريقة الأولى أكثر أمانًا.

مقدمة

جهاز الشبكة الافتراضي الافتراضي في VirtualBox هو Intel PRO/1000 MT Desktop (82540EM) ووضع الشبكة الافتراضي هو NAT. سنشير إليه باسم E1000.

يحتوي E1000 على ثغرة تسمح لمهاجم يملك صلاحيات root/administrator داخل الضيف بالهروب إلى ring3 على المضيف. بعدها يمكن للمهاجم استخدام تقنيات موجودة لرفع الصلاحيات إلى ring 0 عبر /dev/vboxdrv.

تفاصيل الثغرة

E1000 101

لإرسال حزم الشبكة، يقوم الضيف بما يفعله أي حاسوب عادي: يضبط بطاقة الشبكة ويزوّدها بحزم الشبكة. الحزم هي إطارات طبقة ربط البيانات (data link layer) وترويسات أخرى أعلى مستوى. الحزم المزوَّدة للمهايئ تُغلَّف في واصفات إرسال Tx descriptors (Tx تعني إرسال). واصف الإرسال هو بنية بيانات موصوفة في ورقة بيانات 82540EM (317453006EN.PDF, Revision 4.0). يخزّن معلومات وصفية مثل حجم الحزمة، ووسم VLAN، وعلامات تمكين تجزئة TCP/IP، وما إلى ذلك.

توفر ورقة بيانات 82540EM ثلاثة أنواع من واصفات الإرسال: تراثية (legacy)، سياقية (context)، وبيانات (data). النوع التراثي مهمل على ما أعتقد. النوعان الآخران يُستخدمان معًا. الشيء الوحيد الذي يهمنا هو أن واصفات السياق تضبط أقصى حجم للحزمة وتفعّل تجزئة TCP/IP، وأن واصفات البيانات تحمل العناوين الفيزيائية لحزم الشبكة وأحجامها. يجب أن يكون حجم الحزمة في واصف البيانات أصغر من أقصى حجم للحزمة في واصف السياق. عادةً تُزوَّد واصفات السياق لبطاقة الشبكة قبل واصفات البيانات.

لتزويد بطاقة الشبكة بواصفات الإرسال، يكتب الضيف واصفات الإرسال إلى Tx Ring. هذه حلقة عازلة (ring buffer) تقع في الذاكرة الفيزيائية عند عنوان محدد مسبقًا. عندما تُكتب جميع الواصفات إلى Tx Ring، يحدّث الضيف سجل E1000 MMIO TDT (Transmit Descriptor Tail) ليُعلِم المضيف بوجود واصفات جديدة يجب معالجتها.

المدخلات

اعتبر المصفوفة التالية من واصفات الإرسال:``` [context_1, data_2, data_3, context_4, data_5]

لنقم بتعيين حقول هيكلها كما يلي (أسماء الحقول افتراضية لتكون قابلة للقراءة البشرية لكنها ترتبط مباشرة بمواصفات 82540EM):```
context_1.header_length = 0
context_1.maximum_segment_size = 0x3010
context_1.tcp_segmentation_enabled = true

data_2.data_length = 0x10
data_2.end_of_packet = false
data_2.tcp_segmentation_enabled = true

data_3.data_length = 0
data_3.end_of_packet = true
data_3.tcp_segmentation_enabled = true

context_4.header_length = 0
context_4.maximum_segment_size = 0xF
context_4.tcp_segmentation_enabled = true

data_5.data_length = 0x4188
data_5.end_of_packet = true
data_5.tcp_segmentation_enabled = true

سنتعلم لماذا يجب أن تكون بهذه الطريقة في تحليلنا خطوة بخطوة.

تحليل السبب الجذري

معالجة [context_1, data_2, data_3]

لنفترض أن الواصفات المذكورة أعلاه تُكتب إلى Tx Ring بالترتيب المحدد ويتم تحديث سجل TDT بواسطة الضيف. الآن سينفّذ المضيف دالة e1kXmitPending في الملف src/VBox/Devices/Network/DevE1000.cpp (معظم التعليقات تمت وستتم إزالتها من أجل سهولة القراءة):```c static int e1kXmitPending(PE1KSTATE pThis, bool fOnWorkerThread) { ... while (!pThis->fLocked && e1kTxDLazyLoad(pThis)) { while (e1kLocateTxPacket(pThis)) { fIncomplete = false; rc = e1kXmitAllocBuf(pThis, pThis->fGSO); if (RT_FAILURE(rc)) goto out; rc = e1kXmitPacket(pThis, fOnWorkerThread); if (RT_FAILURE(rc)) goto out; }

ستقوم `e1kTxDLazyLoad` بقراءة جميع واصفات Tx الخمسة من حلقة الإرسال Tx Ring. ثم يتم استدعاء `e1kLocateTxPacket` لأول مرة. تتكرر هذه الدالة عبر جميع الواصفات لإعداد حالة أولية لكنها لا تعالجها فعليًا. في حالتنا، سيتعامل الاستدعاء الأول لـ `e1kLocateTxPacket` مع واصفات `context_1` و`data_2` و`data_3`. أما الواصفان المتبقيان، `context_4` و`data_5`، فسيتم التعامل معهما في التكرار الثاني من حلقة while (سنغطي التكرار الثاني في القسم التالي). هذا التقسيم الثنائي للمصفوفة ضروري لتفعيل الثغرة، لذا دعنا نكتشف السبب.

تبدو `e1kLocateTxPacket` بهذا الشكل:```c
static bool e1kLocateTxPacket(PE1KSTATE pThis)
{
...
    for (int i = pThis->iTxDCurrent; i < pThis->nTxDFetched; ++i)
    {
        E1KTXDESC *pDesc = &pThis->aTxDescriptors[i];
        switch (e1kGetDescType(pDesc))
        {
            case E1K_DTYP_CONTEXT:
                e1kUpdateTxContext(pThis, pDesc);
                continue;
            case E1K_DTYP_LEGACY:
                ...
                break;
            case E1K_DTYP_DATA:
                if (!pDesc->data.u64BufAddr || !pDesc->data.cmd.u20DTALEN)
                    break;
                ...
                break;
            default:
                AssertMsgFailed(("Impossible descriptor type!"));
        }

الوصف الأول (context_1) هو من نوع E1K_DTYP_CONTEXT لذا يتم استدعاء الدالة e1kUpdateTxContext. تقوم هذه الدالة بتحديث سياق تجزئة TCP إذا كان تجزئة TCP مفعّلاً للوصف. هذا صحيح بالنسبة إلى context_1 لذا سيتم تحديث سياق تجزئة TCP. (ما هو تحديث سياق تجزئة TCP بالضبط ليس مهمًا، وسنستخدم هذا فقط للإشارة إلى الكود أدناه).

الوصف الثاني (data_2) هو من نوع E1K_DTYP_DATA لذا سيتم تنفيذ عدة إجراءات غير ضرورية للنقاش.

الوصف الثالث (data_3) هو أيضًا من نوع E1K_DTYP_DATA ولكن بما أن data_3.data_length == 0 لا يتم تنفيذ أي إجراء.

في الوقت الحالي تتم معالجة الأوصاف الثلاثة مبدئيًا ويبقى الاثنان. الآن الشيء: بعد عبارة switch يوجد فحص لمعرفة ما إذا كان حقل end_of_packet الخاص بالوصف قد تم تعيينه. هذا صحيح بالنسبة لوصف data_3 (data_3.end_of_packet == true). يقوم الكود ببعض الإجراءات ويعيد من الدالة:```c if (pDesc->legacy.cmd.fEOP) { ... return true; }

إذا كانت `data_3.end_of_packet` خاطئة، فسيتم معالجة الواصفَين المتبقيين `context_4` و`data_5`، وسيتم تجاوز الثغرة. ستجد أدناه سببًا في أن تلك العودة من الدالة تؤدي إلى الخطأ.
تنزيل الأداة