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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
freebsd-dirent-info-leak-bugs — CVE-2020-25578 و CVE-2020-25579: بعض ثغرات تسريب المعلومات في FreeBSD التي وجدتها في عام 2020. | Kitploit
أدوات/GitHubGitHub/farazsth98/freebsd-dirent-info-leak-bugs
تحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالاستغلالجمع المعلوماتتحليل الملفات الثنائية
GitHubfarazsth98/freebsd-dirent-info-leak-bugs

freebsd-dirent-info-leak-bugs

CVE-2020-25578 و CVE-2020-25579: بعض ثغرات تسريب المعلومات في FreeBSD التي وجدتها في عام 2020.

عرض المستودع

الأكثر شعبية

عرض الكل →

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

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

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

عرض جميع الأدوات →
مشاركة
72منذ 5 سنواتلم تتم المراجعة بعد

كيف وجدت الثغرات؟

  1. قررت بشكل عشوائي تدقيق أنظمة الملفات في FreeBSD
  2. أجريت بعض البحث ووجدت أن نظام الملفات الافتراضي المستخدم هو مزيج من FFS و UFS
  3. أمضيت بعض الوقت في تدقيق ufs_create ولم أجد أي ثغرات
  4. اذهب هنا وانظر في تاريخ الالتزامات لوظائف نظام ملفات UFS
  5. لاحظت هذا الالتزام حول تسريب المعلومات من خلال بايتات الحشو في كائنات struct dirent المخصصة على المكدس
  6. حللت التصحيح ووجدت أن التصحيح لـ msdosfs_readdir غير مكتمل. قاموا بتصحيح مثيل واحد من الثغرة، لكن ليس الثاني.
  7. كتبت دليلاً على المفهوم (PoC) لتأكيد أنني أستطيع تسريب 3 بايتات من الحشو. ثم بدأت في البحث عن متغيرات.
  8. وجدت المتغيرات في mqueuefs و autofs و smbfs و tmpfs التي تسمح لي بتسريب مؤشر كامل بحجم 8 بايت. كتبت دليلاً على المفهوم لتأكيد ذلك.

الثغرة الأصلية

كما ذكر أعلاه، الثغرة الأصلية التي وجدتها كانت في msdosfs_readdir أثناء تحليلي للتصحيح الخاص بالالتزام المرتبط أعلاه.

التدفق الأساسي لاستدعاء readdir في FreeBSD هو كما يلي:

root@kitploit:~
#include <dirent.h>

int main(void) {
    struct dirent *dp;
    DIR *dirp;

    dirp = opendir("./somedir");
    dp = readdir(dirp);
}

اعتمادًا على نظام الملفات الذي يوجد فيه somedir، قد يتم استدعاء أي من وظائف *_readdir العديدة في نواة FreeBSD.

التصحيح أعلاه يضيف دالة تسمى dirent_terminate والتي يُقصد استدعاؤها قبل إرجاع كائن struct dirent إلى مساحة المستخدم (غالبًا باستخدام دالة uiomove). ستقوم هذه الدالة بإفراغ بايتات الحشو بالإضافة إلى أي بايتات متبقية في حقل d_name من الهيكل. تعريف struct dirent موجود هنا.

بالنظر إلى التصحيح، في السطر 1562، يمكنك رؤية dirent_terminate تُستدعى مع المتغير dirbuf كوسيطة. بعد ذلك، يتم استدعاء uiomove لنسخ محتويات dirbuf إلى مساحة المستخدم. ومع ذلك، لاحظ أن هذه السطور من الكود تقع ضمن كتلة جملة if هذه. التعليق أعلاه هذه الجملة يوضح أن هذا الفرع يُتخذ فقط إذا تم استدعاء readdir على جذر نظام ملفات MSDOS، لذلك يمكننا ببساطة تجاوز جملة if هذه عن طريق استدعاء readdir في أي دليل فرعي بعد جذر نظام الملفات.

في الأسفل، نرى استدعاء آخر لـ uiomove في السطر 1691. ومع ذلك، عند قراءة الكود بعناية، سترى أن dirent_terminate لم تُستدعَ في هذه الحالة، مما يعني أن بايتات الحشو ستبقى غير مهيأة. لسوء الحظ، تم إفراغ حقل d_name في بداية هذه الدالة (هنا)، لذا لا يمكننا الحصول على تسريب أكبر.

دليل المفهوم (PoC)

أولاً، لم يكن لدي قرص USB، لذلك كان علي إيجاد طريقة لتركيب نظام ملفات MSDOS. ما يلي يعمل:

root@kitploit:~
$ dd if=/dev/zero of=test.img bs=512 count=256000
$ sudo mdconfig -a -t vnode -f test.img
$ sudo newfs_msdos -s 131072000 /dev/md1 # mdconfig أعاد md1
$ mkdir ./temp
$ sudo mount -t msdosfs /dev/md1 ./temp
$ mkdir ./temp/test_dir

يمكن العثور على دليل المفهوم في original_poc.c. ما عليك سوى ترجمته باستخدام clang وتشغيله من نفس الدليل الذي توجد به الأوامر أعلاه، وسترى البايتات المسربة مطبوعة.

المتغيرات

بدأت في البحث عن متغيرات لهذه الثغرة. أعتقد أنني قمت بالبحث عن uiomove\(&.*, والذي أعاد حوالي 15-20 نتيجة، وراجعتها جميعًا يدويًا. لسوء الحظ، لا توجد أي من المتغيرات بشكل افتراضي في FreeBSD (يجب تمكين أنظمة الملفات يدويًا / ترجمتها في النواة). الوظائف التي تحتوي على المتغيرات هي كما يلي:

  1. mqfs_readdir
  2. tmpfs_dir_getdotdent
  3. tmpfs_dir_getdotdotdent
  4. smbfs_readvdir
  5. autofs_readdir_one

الثغرة هي نفسها تمامًا في كل هذه الوظائف، لذا سأغطي mqfs_readdir فقط.

  1. أولاً، يتم تخصيص struct dirent entry على المكدس
  2. بعد ذلك، يتم استدعاء dirent_terminate لإفراغ بايتات الحشو + حقول d_name من الهيكل
  3. أخيرًا، يتم استدعاء vfs_read_dirent. هذه الدالة ستستدعي uiomove لنسخ الهيكل إلى مساحة المستخدم

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

دليل المفهوم (PoC)

سيعمل هذا الدليل نفسه لجميع المتغيرات، ما عليك سوى تشغيله على نظام ملفات مختلف. بالنسبة لـ mqueuefs، افعل ما يلي (يلزم تمكين / ترجمة mqueuefs في النواة أولاً):

root@kitploit:~
$ mkdir ./temp
$ sudo mount -t mqueuefs null ./temp

يمكن العثور على دليل المفهوم نفسه في variants_poc.c. ما عليك سوى ترجمته باستخدام clang وتشغيله من نفس الدليل الذي توجد به الأوامر أعلاه. سترى مؤشرات النواة مطبوعة (من المفترض مؤشر مكدس واحد ومؤشر قسم كود / كومة واحد، لم أتحقق من ذلك).

تنزيل الأداة