فهارس المجلدات ($I30)¶
ما هو $I30¶
يحتفظ كل مجلد في NTFS بفهرس للملفات الموجودة فيه، يُسمى $I30. ويحتفظ المجلد الصغير به في
سجل $MFT الخاص به ($INDEX_ROOT)؛ أما المجلد الأكبر فيملك أيضًا سجلات INDX، حجم كل منها عادةً 4,096 بايت، في
دفق $INDEX_ALLOCATION:$I30. ويحمل كل إدخال في الفهرس نسخة من $FILE_NAME الخاص بالملف: اسمه،
ومرجع MFT، والمجلد الأب، وأربعة طوابع زمنية، وحجمين، كما كانت في آخر مرة حدّث فيها NTFS
الإدخال.
عندما يُحذف ملف أو يُعاد تسميته فيخرج من مجلد، يزيل NTFS إدخاله وينقل الإدخالات
التي تليه. وتبقى البايتات القديمة في المساحة الراكدة (slack) لسجل INDX، بعد الإدخالات المستخدمة، إلى أن
تكتب فوقها إدخالات لاحقة. ويمكن أن تحتفظ المساحة الراكدة في الفهرس باسم ملف وأوقاته وحجمه حتى لو
أُعيد استخدام سجل $MFT الخاص به ودارت سجلات دفتر يومية USN الخاصة به.
أفضل استنتاج: الاسم الموجود في المساحة الراكدة للفهرس كان، في
وقت ما، في فهرس هذا المجلد بأوقات $FILE_NAME وأحجامه المذكورة. ولا يوضح إدخال المساحة الراكدة
متى أُزيل، ولا ما إذا كان قد حُذف أو أُعيد تسميته أو نُقل بسبب إعادة الموازنة.
الموقع والجمع¶
$I30 هو بيانات وصفية لـ NTFS: اجمعه بأداة جنائية تدعم الوصول الخام ويمكنها تصدير دفق
$I30 الخاص بمجلد (كثيرًا ما تُسمى الملفات المصدّرة $I30). ويمكن لـ Juntei أيضًا البحث في صورة قرص أو
مساحة غير مخصصة عن سجلات INDX. واجمع أيضًا $MFT و$J من وحدة التخزين نفسها، لمعرفة ماهية
إدخالات المساحة الراكدة.
تحذيرات للمحلل¶
- المساحة الراكدة في الفهرس جزئية وغير مرتبة. تُكتب الإدخالات فوق بعضها مع تغيّر المجلد؛ و غياب اسم ما لا يثبت شيئًا.
- كثير من إدخالات المساحة الراكدة نسخ من إدخالات لا تزال مستخدمة، تُركت عند نقل الإدخالات.
ويميّزها
CopyOfEntryInUse. وقد يوجد الاسم المحذوف نفسه أيضًا في المساحة الراكدة عدة مرات. - الأوقات في إدخال الفهرس هي أوقات
$FILE_NAMEكما كانت عند آخر تحديث للإدخال. وقد تختلف عن كل من أوقات$STANDARD_INFORMATIONو$FILE_NAMEفي سجل$MFTالخاص بالملف. AllocatedSizeوRealSizeهما أيضًا كما كانا عند آخر تحديث للإدخال، وقد يكونان قديمين.- قد يكون
FileEntry(أوParentEntry) الخاص بإدخال في المساحة الراكدة مفقودًا عندما تكتب بايتات لاحقة فوقه. وعند وجوده، ربما يكون سجل MFT الذي يشير إليه قد أُعيد استخدامه منذ ذلك الحين: قارن رقم التسلسل. - يقرأ
parse-ntfs i30سجلات INDX. ولا يوجد فهرس المجلد الصغير إلا في سجل$MFTالخاص به ($INDEX_ROOT)؛ وتوجد ملفاته في$MFT.
التحليل باستخدام Juntei¶
Usage: juntei parse-ntfs i30 <INPUT> [OPTIONS]
Input:
-d, --directory <DIR> Recursively find $I30 files (with $I30 in their name, or starting with an INDX record)
-f, --file <FILE> Parse one $I30 stream, or any file holding INDX records (a disk image, unallocated space)
Filtering:
--slack-only Only the entries found in slack
--no-copies Leave out the slack entries that copy an entry in use
Output:
-o, --output <FILE> Save every entry
-t, --output-type <TYPE> csv, json, or jsonl
juntei parse-ntfs i30 -f 'Users_$I30'
juntei parse-ntfs i30 -d evidence/ -o i30.csv
juntei parse-ntfs i30 -f 'Users_$I30' --slack-only --no-copies -t jsonl
juntei parse-ntfs i30 -f disk.raw -o carved-i30.csv
يسرد الملخص سجلات INDX (وعدد ما كُتب منها جزئيًا)، والإدخالات المستخدمة والموجودة في المساحة الراكدة، وأسماء إدخالات المساحة الراكدة التي ليست نسخًا مطابقة لإدخالات مستخدمة. وهذه الأسماء مرشحة لأن تكون ملفات محذوفة أو أُعيدت تسميتها، وليست حكمًا قاطعًا بحد ذاتها.
حقول إخراج CSV¶
| الحقل | التفسير |
|---|---|
SourcePath |
ملف الإدخال؛ يميّز بين المضيفين والمجلدات. |
RecordOffset، EntryOffset |
إزاحتا البايت لسجل INDX وللإدخال في ملف الإدخال. ضروريتان للتحقق وللسجلات الموجودة في صور الأقراص. |
RecordVCN، RecordLSN |
موضع السجل في دفق الفهرس ورقم تسلسل $LogFile الخاص به. |
FromSlack |
True للإدخال الموجود بعد الإدخالات المستخدمة. |
CopyOfEntryInUse |
إدخال في المساحة الراكدة له الاسم ومساحة الأسماء والملف (عند معرفته) والأب والأوقات نفسها لإدخال مستخدم في فهرس المجلد نفسه. وعادةً ما يكون بقايا نقل الإدخالات، لا ملفًا محذوفًا. |
Filename |
الاسم في المجلد. |
Namespace |
win32 أو dos (الاسم المختصر 8.3) أو win32_and_dos أو posix. |
FileEntry، FileSequence |
مرجع MFT الخاص بالملف. فارغ لإدخال في المساحة الراكدة كُتب فوق ترويسته. |
ParentEntry، ParentSequence |
مرجع MFT الخاص بالمجلد. فارغ عندما تُكتب بايتات أخرى فوقه. |
CreatedUTC، ModifiedUTC، MFT-ModifiedUTC، AccessedUTC |
أوقات $FILE_NAME، بدقة 100 نانوثانية، كما كانت عند آخر تحديث للإدخال. |
AllocatedSize، RealSize |
الأحجام التي نسخها NTFS إلى الإدخال؛ راجع التحذيرات أعلاه. |
FileAttributes |
أسماء السمات مدمجة بالرمز | (hidden|archive)؛ وis_directory للمجلد الفرعي. وتُحفظ البتات التي لا يسميها هذا الإصدار من Juntei بالنظام السداسي عشري (0x00800000). |
ReparseValue |
وسم إعادة التوجيه (reparse tag) أو حجم السمات الموسعة من $FILE_NAME. |
Problems |
تلف في السجل، مثل قطاعات كُتبت جزئيًا. ولا تزال الإدخالات من سجل تالف تستحق المراجعة، بحذر. |
تحتوي JSON/JSONL على الحقول نفسها بصيغة snake_case، مع problems على هيئة قائمة وnull للقيم
غير المعروفة.
كيف تُكتشف إدخالات المساحة الراكدة¶
تُفحص المساحة الراكدة عند كل حد من 8 بايتات، حيث تبدأ الإدخالات، بحثًا عن إدخالات كاملة، وعن
سمات $FILE_NAME التي كُتب فوق ترويسة إدخالها، وفي بداية المساحة الراكدة، عن
$FILE_NAME كتبت نهاية الإدخالات المستخدمة فوق مرجع الأب الخاص به. ويجب أن يبدو المرشح
مثل ما يكتبه Windows: اسم UTF-16 صالح بلا أحرف تحكم أو فواصل مسارات، وأربعة
أوقات بين 1980 و2100، ومساحة أسماء معروفة، وأعلام سمات معروفة. ومرجع الأب الذي يتجاوز
32 بت هو بايتات كُتبت فوقه، ويُترك فارغًا.
تُطبَّق مصفوفة تسلسل التحديث (update sequence array) لكل سجل. والقطاع الذي لا ينتهي بقيمة تسلسل التحديث
قد كُتب جزئيًا؛ ويقرأ Juntei السجل كما هو ويسمّي القطاعات في Problems.
استراتيجية التحقيق¶
- ابدأ بالأسماء غير المنسوخة في المساحة الراكدة الواردة في الملخص، ثم صفِّ باستخدام
--slack-only --no-copies. - ابحث عن
FileEntryفي$MFT. يعنيFileSequenceالمماثل الملف نفسه؛ أما القيمة الأعلى فتعني أن السجل حُرّر منذ ذلك الحين، وربما أُعيد استخدامه. - ابحث عن الاسم في دفتر يومية USN لمعرفة متى حُذف أو أُعيدت تسميته.
- قارن أوقات
$FILE_NAMEبأوقات$STANDARD_INFORMATIONفي$MFTللكشف عن التلاعب بالطوابع الزمنية (timestomping). - اربط ذلك بـ Prefetch وLNK وJump Lists وسجلات الأحداث لمعرفة كيفية استخدام الملف.
مزيد من التفاصيل¶
- Microsoft: جدول الملفات الرئيسي
- libfsntfs: توثيق تنسيق NTFS
- dfir_ntfs
- INDXRipper
- ys-ntfs-parser (الوحدة
i30في حزمةmftالخاصة به)