ข้ามไปที่เนื้อหา

ดัชนีไดเรกทอรี ($I30)

$I30 คืออะไร

ไดเรกทอรี NTFS ทุกไดเรกทอรีเก็บดัชนีของไฟล์ที่อยู่ภายในไว้ โดยมีชื่อว่า $I30 ไดเรกทอรีขนาดเล็กจะเก็บดัชนีนี้ไว้ใน เรคคอร์ด $MFT ของตน ($INDEX_ROOT) ส่วนไดเรกทอรีขนาดใหญ่จะมีเรคคอร์ด INDX เพิ่มเติม ซึ่งโดยปกติมีขนาด 4,096 ไบต์ต่อเรคคอร์ด อยู่ใน สตรีม $INDEX_ALLOCATION:$I30 แต่ละรายการดัชนีเก็บสำเนาของ $FILE_NAME ของไฟล์ ได้แก่ ชื่อ MFT reference ไดเรกทอรีแม่ timestamp สี่ค่า และขนาดสองค่า ตามสถานะ ณ ครั้งล่าสุดที่ NTFS อัปเดตรายการนั้น

เมื่อไฟล์ถูกลบหรือถูกเปลี่ยนชื่อออกจากไดเรกทอรี NTFS จะลบรายการของไฟล์นั้นและย้ายรายการที่อยู่ ถัดไปขึ้นมา ไบต์เดิมจะยังคงอยู่ใน slack ของเรคคอร์ด INDX ถัดจากรายการที่ใช้งานอยู่ จนกว่า รายการที่เขียนภายหลังจะเขียนทับ index slack อาจเก็บชื่อ เวลา และขนาดของไฟล์ที่ เรคคอร์ด $MFT ถูกนำกลับมาใช้ใหม่แล้ว และเรคคอร์ด USN Journal ถูกวนทับไปแล้วได้

ข้อสรุปที่ดีที่สุด: ชื่อที่พบใน index slack เคยอยู่ในดัชนีของ ไดเรกทอรีนี้ ณ ช่วงเวลาหนึ่ง พร้อมเวลาและขนาดของ $FILE_NAME ตามที่ระบุ รายการใน slack ไม่ได้บอกว่าถูกลบออกเมื่อใด หรือถูกลบ เปลี่ยนชื่อ หรือย้ายจากการปรับสมดุล (rebalancing)

ตำแหน่งและการเก็บรวบรวม

C:\<directory>:$I30:$INDEX_ALLOCATION

$I30 เป็นเมทาดาทาของ NTFS ให้เก็บรวบรวมด้วยเครื่องมือนิติวิทยาศาสตร์ที่อ่านข้อมูลดิบได้และสามารถส่งออกสตรีม $I30 ของไดเรกทอรีได้ (ไฟล์ที่ส่งออกมักมีชื่อว่า $I30) Juntei ยังสามารถค้นหาเรคคอร์ด INDX ในดิสก์อิมเมจ หรือพื้นที่ที่ไม่ได้จัดสรร (unallocated space) ได้ด้วย ให้เก็บรวบรวม $MFT และ $J ของวอลุ่มเดียวกันด้วย เพื่อระบุว่า รายการใน slack นั้นคืออะไร

ข้อควรระวังสำหรับนักวิเคราะห์

  • index slack เป็น ข้อมูลบางส่วนและไม่มีลำดับ รายการจะถูกเขียนทับเมื่อไดเรกทอรีเปลี่ยนแปลง การ ไม่พบชื่อไม่ได้พิสูจน์อะไร
  • รายการใน slack จำนวนมากเป็นสำเนาของรายการที่ยังใช้งานอยู่ ซึ่งหลงเหลือจากการย้ายรายการ CopyOfEntryInUse จะทำเครื่องหมายรายการเหล่านี้ นอกจากนี้ชื่อที่ถูกลบชื่อเดียวกันอาจปรากฏใน slack หลายครั้ง
  • เวลาในรายการดัชนีคือเวลาของ $FILE_NAME ณ การอัปเดตครั้งล่าสุดของรายการ ซึ่งอาจแตกต่าง จากทั้งเวลาของ $STANDARD_INFORMATION และ $FILE_NAME ในเรคคอร์ด $MFT ของไฟล์
  • AllocatedSize และ RealSize ก็เป็นค่า ณ การอัปเดตครั้งล่าสุดของรายการเช่นกัน และอาจล้าสมัยแล้ว
  • FileEntry (หรือ ParentEntry) ของรายการใน slack อาจหายไปเมื่อไบต์ที่เขียนภายหลังเขียนทับ หากมีอยู่ เรคคอร์ด MFT ที่ระบุอาจถูกนำกลับมาใช้ใหม่แล้ว: ให้เปรียบเทียบ sequence number
  • 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 (และจำนวนเรคคอร์ดที่ถูกเขียนเพียงบางส่วน) รายการที่ใช้งานอยู่และรายการใน slack และชื่อของรายการใน slack ที่ไม่ใช่สำเนาที่ตรงกันทุกประการของรายการที่ใช้งานอยู่ ชื่อเหล่านั้น เป็นเพียงผู้ที่อาจเป็นไฟล์ที่ถูกลบหรือถูกเปลี่ยนชื่อ ไม่ใช่ข้อสรุปในตัวเอง

ฟิลด์เอาต์พุต CSV

ฟิลด์ การตีความ
SourcePath ไฟล์อินพุต ใช้แยกแยะโฮสต์และไดเรกทอรี
RecordOffset, EntryOffset byte offset ของเรคคอร์ด INDX และของรายการในอินพุต จำเป็นสำหรับการตรวจสอบความถูกต้องและสำหรับเรคคอร์ดที่พบในดิสก์อิมเมจ
RecordVCN, RecordLSN ตำแหน่งของเรคคอร์ดในสตรีมดัชนีและ sequence number ของ $LogFile
FromSlack True สำหรับรายการที่พบถัดจากรายการที่ใช้งานอยู่
CopyOfEntryInUse รายการใน slack ที่มีชื่อ namespace ไฟล์ (หากทราบ) ไดเรกทอรีแม่ และเวลาเหมือนกับรายการที่ใช้งานอยู่ในดัชนีไดเรกทอรีเดียวกัน โดยปกติเป็นสิ่งที่หลงเหลือจากการย้ายรายการ ไม่ใช่ไฟล์ที่ถูกลบ
Filename ชื่อในไดเรกทอรี
Namespace win32, dos (ชื่อสั้นแบบ 8.3), win32_and_dos หรือ posix
FileEntry, FileSequence MFT reference ของไฟล์ ว่างสำหรับรายการใน slack ที่ส่วนหัวถูกเขียนทับ
ParentEntry, ParentSequence MFT reference ของไดเรกทอรี ว่างเมื่อไบต์อื่นเขียนทับ
CreatedUTC, ModifiedUTC, MFT-ModifiedUTC, AccessedUTC เวลาของ $FILE_NAME ละเอียดถึง 100 ns ณ การอัปเดตครั้งล่าสุดของรายการ
AllocatedSize, RealSize ขนาดที่ NTFS คัดลอกมาไว้ในรายการ ดูข้อควรระวังด้านบน
FileAttributes ชื่อแอตทริบิวต์ที่เชื่อมด้วย | (hidden|archive) และ is_directory สำหรับไดเรกทอรีย่อย บิตที่ Juntei เวอร์ชันนี้ไม่ได้ตั้งชื่อจะถูกเก็บไว้เป็นเลขฐานสิบหก (0x00800000)
ReparseValue reparse tag หรือขนาด extended attribute จาก $FILE_NAME
Problems ความเสียหายในเรคคอร์ด เช่น เซกเตอร์ที่ถูกเขียนเพียงบางส่วน รายการจากเรคคอร์ดที่เสียหายยังควรตรวจทานอยู่ แต่ต้องใช้ความระมัดระวัง

JSON/JSONL มีฟิลด์เดียวกันในรูปแบบ snake_case โดย problems เป็นลิสต์ และใช้ null สำหรับค่าที่ ไม่ทราบ

วิธีค้นหารายการใน slack

slack จะถูกสแกนทุกขอบเขต 8 ไบต์ ซึ่งเป็นจุดที่รายการเริ่มต้น เพื่อหารายการที่สมบูรณ์ หาแอตทริบิวต์ $FILE_NAME ที่ส่วนหัวของรายการถูกเขียนทับ และที่จุดเริ่มต้นของ slack จะหา $FILE_NAME ที่ parent reference ถูกส่วนท้ายของรายการที่ใช้งานอยู่เขียนทับ ข้อมูลที่เป็นผู้สมัครต้องดู เหมือนสิ่งที่ Windows เขียน ได้แก่ ชื่อ UTF-16 ที่ถูกต้องโดยไม่มีอักขระควบคุมหรือตัวคั่นพาธ เวลาสี่ค่า อยู่ระหว่างปี 1980 ถึง 2100 namespace ที่รู้จัก และแฟล็กแอตทริบิวต์ที่รู้จัก parent reference ที่เกิน 32 บิตถือเป็นไบต์ที่ถูกเขียนทับและจะปล่อยว่างไว้

update sequence array ของแต่ละเรคคอร์ดจะถูกนำมาใช้ เซกเตอร์ที่ไม่ได้ลงท้ายด้วยค่า update sequence ถือว่าถูกเขียนเพียงบางส่วน Juntei จะอ่านเรคคอร์ดตามสภาพที่เป็นอยู่และระบุเซกเตอร์เหล่านั้นใน Problems

กลยุทธ์การตรวจสอบ

  1. เริ่มจากชื่อใน slack ที่ไม่ใช่สำเนาในข้อมูลสรุป จากนั้นกรองด้วย --slack-only --no-copies
  2. ค้นหา FileEntry ใน $MFT หาก FileSequence เท่ากันหมายถึงเป็นไฟล์เดียวกัน หาก สูงกว่าหมายความว่าเรคคอร์ดถูกปล่อยว่างไปแล้วตั้งแต่นั้น และอาจถูกนำกลับมาใช้ใหม่
  3. ค้นหาชื่อใน USN Journal เพื่อดูว่าไฟล์ถูกลบหรือเปลี่ยนชื่อเมื่อใด
  4. เปรียบเทียบเวลาของ $FILE_NAME กับเวลาของ $STANDARD_INFORMATION ใน $MFT เพื่อตรวจหา timestomping
  5. เชื่อมโยงกับ Prefetch, LNK, Jump Lists และ event log เพื่อดูว่าไฟล์ถูกใช้งานอย่างไร

รายละเอียดเพิ่มเติม