انتقل إلى المحتوى

سجل معاملات NTFS ‏($LogFile)

ما هو ولماذا يهم

NTFS هو نظام الملفات الذي يستخدمه Windows عادةً لوحدة تخزين النظام. وللتعافي من الأعطال، يسجّل التغييرات التي ينوي إجراءها على البيانات الوصفية لنظام الملفات في ملف مخفي على وحدة التخزين اسمه $LogFile. ويمكن لكل تحديث أن يحمل بايتات redo (الحالة الجديدة) وبايتات undo (الحالة السابقة اللازمة للتراجع عن التغيير). وهذا منفصل عن سجلات أحداث Windows، وعن ملفات .LOG1 الخاصة بسجل Windows، وعن دفتر يومية USN.

بالنسبة إلى المحقق، تكون الحالة السابقة مفيدة بشكل خاص. فقد يحتفظ سجل undo باسم ملف قبل إعادة تسميته، أو بإدخال مجلد محذوف، أو بطوابع زمنية من قبل تحديث للبيانات الوصفية. كما تحتوي بعض السجلات على بايتات كتبها NTFS إلى دفتر يومية USN، بما في ذلك سجلات لم تعد موجودة في $J المجمّع. ومع ذلك، تتعلق معاملات كثيرة بنشاط روتيني لنظام التشغيل، ولا تصف هجومًا.

مثال: يذكر إدخال فهرس مُزال report.txt؛ ويذكر إدخال مضاف لاحقًا report.txt.encrypted. ويمكن لمطابقة مرجع الملف الكامل، والمجلد الأم، وسلسلة المعاملات، والآثار الرقمية الأخرى أن تدعم استنتاج إعادة التسمية. ولا يحدد هذان الاسمان وحدهما برنامج الفدية، ولا مشغّله، ولا الوقت الدقيق للتشفير.

الموقع والجمع

C:\$LogFile
D:\$LogFile

لكل وحدة تخزين NTFS سجلها الخاص. احصل عليه بأداة تقرأ البيانات الوصفية لـ NTFS أو تصدّرها من صورة جنائية أو لقطة (snapshot)؛ فقد لا يتمكن النسخ العادي للملفات في Windows من الوصول إليه. اجمع $MFT و$Extend\$UsnJrnl:$J الخاصين بوحدة التخزين نفسها في أقرب وقت ممكن. واحتفظ بالملفات الأصلية وتجزئاتها. فقد يحتوي اكتساب لاحق على مقطع مختلف من النشاط.

$LogFile سجل دائري: تكتب السجلات الجديدة فوق القديمة. ويعتمد الاحتفاظ على حجم السجل وعبء العمل، وقد لا يتجاوز دقائق أو ساعات. وغياب اسم ملف أو عملية ليس دليلًا على أنها لم تحدث قط.

ما الذي يثبته السجل، والتحذيرات

  • يسجّل التحديث البيانات الوصفية التي سجّلها NTFS لأغراض الاسترداد. ولا يثبت إدخال redo منفرد أن إجراءً كاملًا على مستوى أعلى قد اكتمل أو أن شخصًا بعينه قد بدأه. اربط السجلات ذات الصلة، واكتمال المعاملة، ونظام الملفات الناتج، والأدلة المستقلة.
  • لا يوجد طابع زمني عام للمعاملة. تصف الطوابع الزمنية المضمّنة البيانات الوصفية للملف، وقد تكون أحيانًا قديمة أو منسوخة أو معدّلة من قِبل المهاجم. لا تضع CreatedOn في الجدول الزمني للحادث على أنه وقت إعادة تسمية أو تغيير طابع زمني. وقد توفر سجلات USN طابعًا زمنيًا منفصلًا.
  • ترتّب أرقام LSN (أرقام تسلسل السجل) السجلات داخل سجل وحدة تخزين واحدة. وهي ليست أوقاتًا بالساعة ويجب عدم مقارنتها عبر المضيفات أو وحدات التخزين. وقد تبقى سجلات من دورات أقدم للمخزن الدائري جنبًا إلى جنب مع النشاط الأحدث.
  • تُعاد استخدام خانة جدول المعاملات. جمّع باستخدام TransactionFirstLsn وTransactionId وهوية العميل والمصدر بدلًا من TransactionId وحده. وقد تشير السلاسل إلى خارج البيانات المحتفظ بها.
  • تحتوي مراجع الملفات على رقم إدخال ورقم تسلسل. وإلا فإن إعادة استخدام إدخال MFT قد تجعل ملفات غير مرتبطة تبدو وكأنها الملف نفسه.
  • تصف المسارات التي يوفرها $MFT حالة MFT المجمّع، لا مسارًا تاريخيًا معاد بناؤه. يطابق Juntei أرقام التسلسل ويترك المكونات غير المعروفة صريحة. فقد يكون المجلد الأم قد أُعيدت تسميته بعد المعاملة، وقد توفر الروابط الصلبة (hard links) أكثر من اسم حالي.
  • يعني TargetInferred أن ربط السمة المفتوحة (open attribute) جاء من مقطع مختلف من السجل. تعامل مع ذلك الربط بعناية إضافية. وقد يُفك ترميز إدخالات الفهرس غير المحلولة بالاعتماد على تخطيطها وحده؛ فتحقق من أسمائها بالبايتات الخام وبمصادر أخرى.
  • تُتخطى الصفحة الممزقة (torn page)؛ وتبقى السجلات المقروءة المحيطة بها متاحة. ويعلّم Truncated سجلًا يفتقد تتمته. راجع تشخيصات المحلل قبل اعتبار الإخراج كاملًا. والمُدخل ذو الطول الصفري خطأ؛ أما السجل غير المكتوب المكوّن بالكامل من FF فلا يحتوي على صفوف بشكل مشروع.
  • لا يعيد المحلل تطبيق المعاملات لإعادة بناء MFT تاريخي. ولا يسترد محتويات عشوائية لملفات غير مقيمة (non-resident) ولا ينفّذ أي بيانات مجمّعة. ولا تُدعم صفحات DAX المحمية بـ CRC. ويغطي التحقق على أدلة حقيقية بشكل أساسي صفحات السجل بحجم 4 KiB.

التحليل باستخدام Juntei

# Single log, current paths from an adjacent $MFT when present
juntei parse-ntfs logfile -f '$LogFile' -o logfile.csv

# Explicit MFT from the SAME volume
juntei parse-ntfs logfile -f '$LogFile' -m '$MFT' -t jsonl -o logfile.jsonl

# Multiple collected logs; SourceFile distinguishes every input
juntei parse-ntfs logfile -d evidence -o collected-logs.csv

# Preserve the underlying payloads for low-level validation
juntei parse-ntfs logfile -f '$LogFile' --raw-data -t jsonl -o logfile-raw.jsonl

# Automatic per-computer output
juntei auto-parse -d evidence -o parsed

راجع مرجع الأوامر لجميع الخيارات. يقبل الاكتشاف في المجلدات $LogFile وLogFile وصيغتيهما .bin، وأسماء مثل C_$LogFile أو C_$LogFile.bin، دون مراعاة حالة الأحرف. أما الملف المفرد الممرَّر بـ -f فيمكن أن يحمل أي اسم.

يراعي الإقران التلقائي مع MFT بادئة وحدة التخزين في ملف التصدير: يستخدم C_$LogFile الملف C_$MFT، ويجرّب D_$LogFile.bin أولًا D_$MFT.bin، ثم D_$MFT. ولا تستخدم السجلات ذات البادئة أبدًا $MFT العادي بديلًا احتياطيًا. ويقبل LogFile بلا بادئة أيضًا MFT أو $MFT. استخدم -m مع -f لتحديد MFT مطابق صراحةً عندما يكون لملف التصدير مخطط تسمية آخر.

الإخراج سجل واحد لكل LSN، بما في ذلك سجلات التحديث ونقاط التحقق (checkpoint) والعملاء غير المعروفين. وJSON دفق من الكائنات المنسقة للقراءة؛ أما JSONL فكائن واحد في كل سطر. ولـ CSV أسماء الحقول نفسها؛ وتكون المصفوفات والحقول المنظّمة JSON مضغوطًا داخل خلية CSV. والقيم المفردة غير المعروفة فارغة في CSV وnull في JSON. وتعني المصفوفات الفارغة أنه لم يُفك ترميز أي عناصر، لا أنه ثبت عدم وجود أي منها.

يُحتفظ بسجل كامل واحد وسجلاته المحللة في الذاكرة في كل مرة. ويضيف تحليل مسارات MFT ذاكرة وعملًا. وقد يزيد --raw-data حجم الإخراج زيادة كبيرة. وفي auto-parse، استخدم -T للحد من عمليات المحلل المتزامنة على جهاز ذي ذاكرة محدودة.

إذا تعذّرت قراءة MFT المجاور، يحذّر Juntei ويصدّر السجل دون مسارات؛ ويبقى MftSource حينئذٍ null. ولا يؤدي فشل الإثراء هذا إلى تجاهل الأدلة الأساسية المقروءة. كما تنتج حالات MFT المفقودة أو الملتبسة تحذيرًا وعددًا في Logs without a matching MFT في الملخص؛ ولا تُحتسب حالات فشل في التحليل.

حقول الإخراج

هوية السجل وسلامته ومصدره

الحقل المعنى والتفسير
SourceFile، FileOffset مسار المُدخل وإزاحة البايت التي قُرئت عندها ترويسة هذا السجل؛ استخدمهما للتحقق من البايتات.
LSN رقم تسلسل السجل. القيم الكبيرة أعداد صحيحة، لا طوابع زمنية.
PreviousLSN، UndoNextLSN روابط إلى السجلات السابقة وسجلات التراجع. يعني الصفر عدم وجود رابط؛ وقد تشير الروابط غير الصفرية إلى خارج البيانات المحتفظ بها.
TransactionID، TransactionFirstLSN خانة جدول المعاملات وأقدم LSN مرتبط بهذه المعاملة؛ والخانة وحدها ليست فريدة.
RecordType ClientRecord (تحديث)، أو ClientRestart (نقطة تحقق)، أو Other.
ClientIndex، ClientSequence هوية عميل السجل؛ وهو عادةً NTFS. وهذه ليست حساب مستخدم ولا معرّف عملية.
Flags، SpansPages علامات السجل الخام وما إذا كانت بيانات العميل تمتد إلى صفحة أخرى. والامتداد عبر الصفحات أمر طبيعي.
Truncated True إذا وجد المحلل تتمة مفقودة لهذا LSN. ولا يلخّص كل التلف في الملف بأكمله.
ClusterSize، ClusterSizeSource عدد البايتات لكل عنقود (cluster) المستخدم لإزاحات الهدف؛ والمصدر هو Caller أو Checkpoint أو Inferred. قدّم القيمة الحقيقية باستخدام --cluster-size إن كانت معروفة.
LogVersion الإصدار من أحدث صفحة إعادة تشغيل (restart page) مقروءة، وعادةً 1.1 أو 2.0؛ ويكون null إذا لم تبقَ أي صفحة إعادة تشغيل مقروءة.
MFT-Source ملف MFT المستخدم لإثراء المسار الحالي، إن وُجد. ويجب أن ينتمي إلى وحدة التخزين نفسها.

في JSON/JSONL الخاص بـ auto-parse، يُضاف Comp وArtifact كما في المحللات الأخرى. ويحتوي سجل .txt الخاص بالمهمة على التشخيصات؛ وتبيّن ملفات البيان ما إذا كانت المهمة قد نجحت أو فشلت أو تُخطّيت. ويمكن أن ينتج التلف القابل للإنقاذ مهمةً ناجحة مع عدد غير صفري في Parse problems في سجلها.

العمليات والهدف

الحقل المعنى والتفسير
RedoOperation، UndoOperation أسماء عمليات NTFS، أو قيمة ست عشرية للرمز غير المعروف. يصف redo التحديث المقصود؛ ويصف undo عكسه.
TargetEntryNumber، TargetSequenceNumber لعملية على سجل ملف: رقم سجل MFT المتأثر، دون استنتاج رقم تسلسل. وإلا: مرجع الملف المالك للسمة المفتوحة المحلولة. ويستهدف تحديث فهرس المجلد المضمّن (inline) المجلدَ، لا العنصر الفرعي الذي يصفه إدخاله.
TargetAttributeType، TargetAttributeName النوع الرقمي واسم السمة المفتوحة التي تستخدمها العملية. ولعمليات سجلات الملفات يكون هذا عادةً $DATA الخاص بـ $MFT. الأنواع الشائعة: 16 ($STANDARD_INFORMATION)، و48 ($FILE_NAME)، و128 ($DATA)، و144 ($INDEX_ROOT)، و160 ($INDEX_ALLOCATION)، و176 ($BITMAP).
TargetPath مسار MFT الحالي عندما يكون المرجع الكامل للهدف معروفًا، أو مكونات غير معروفة. ويكون فارغًا لعمليات سجلات الملفات التي يكون جيلها التاريخي غير معروف؛ إذ يجب ألا يُحلَّل رقم السجل وحده إلى شاغله الحالي.
OpenAttributeEntryNumber، OpenAttributeSequenceNumber، OpenAttributePath الملف المالك للسمة المفتوحة التي تكتب العملية عبرها، مع مسار MFT الحالي له. ولعمليات سجلات الملفات تحفظ هذه الحقول سياق $MFT منفصلًا عن السجل المتأثر.
TargetAttribute الإزاحة في جدول السمات المفتوحة في السجل؛ وهذا يختلف عن نوع السمة أو معرّف MFT الخاص بها.
TargetInferred True إذا كان ربط الهدف آتيًا من مقطع آخر من السجل. ويبقى الهدف null غير محلول حتى لو كانت هذه العلامة false.
TargetVCN، Lcns العنقود الافتراضي في الهدف وأرقام العناقيد الفعلية؛ مفيدة للتحقق منخفض المستوى لا للتوقيت.
RecordOffset، AttributeOffset إزاحتا السمة/الإدخال والتحديث داخلها.
ClusterBlockOffset، TargetBlockSize الإزاحة وحجم الهدف بوحدات من 512 بايت.
OffsetInTarget إزاحة البايت المحسوبة في سجل الملف المتأثر أو الدفق غير المقيم. تعتمد على حجمي العنقود وسجل MFT.
RedoLength، UndoLength أطوال البيانات المعلنة. يمكن لعملية التصفير أن تعلن طولًا دون أن تحمل ذلك العدد من بايتات الحمولة.
RedoBytesAvailable، UndoBytesAvailable بايتات الحمولة المتاحة فعلًا لفك الترميز. قارنها بالأطوال المعلنة وبدلالات العملية.

أعمدة مريحة للبيانات الوصفية للملفات

تعرض هذه الأعمدة اسم ملف مفضّلًا واحدًا ليس بصيغة DOS من جانب redo، مع الرجوع إلى undo عند غيابه. وإذا لم يحمل أي من الجانبين اسم ملف، فإن حقول تحديث الطوابع الزمنية تفضّل طوابع redo الزمنية، ثم undo. كما تعرض تحديثات إدخالات المجلدات أوقاتها وحجمها وعلاماتها مباشرةً، مفضّلةً redo على undo. وتعرض سمات $DATA التي فُك ترميزها حجمها حتى عند عدم وجود اسم ملف. ويأخذ حجم $DATA غير المسمى لسجل ملف فُك ترميزه الأولوية على حجم اسم الملف الذي قد يكون قديمًا. وهي أداة مساعدة للتصفح؛ استخدم حقول الجانبين المنفصلة لمقارنة كاملة بين ما قبل وما بعد.

الحقل المعنى والتفسير
MetadataSide Redo أو Undo، ويحدد الجانب الذي يوفر الأعمدة المريحة لاسم الملف/الطابع الزمني.
EntryNumber، SequenceNumber الملف الموصوف ببيانات وصفية لاسم ملف/سجل ملف/سمة فُك ترميزها، أو بتحديث جزئي لطابع زمني في $STANDARD_INFORMATION، مع رقم التسلسل عند معرفته. ويكونان فارغين لتحديث إدخال مجلد لا يحدد العنصر الفرعي، ولتحديثات الحجم/قائمة المقاطع (run-list) الخام. استخدم TargetEntryNumber للسجل المتأثر.
Filename الاسم المفضّل بعد فك ترميزه؛ وتبقى كل الأسماء في مصفوفات الجانبين، بما في ذلك أسماء DOS المستعارة والروابط الصلبة.
ParentEntryNumber، ParentSequenceNumber، ParentPath مرجع المجلد الأم ومسار MFT الحالي؛ وليس إعادة بناء للمسار التاريخي.
CreatedOn، ContentModifiedOn، RecordModifiedOn، LastAccessedOn أوقات البيانات الوصفية بتوقيت UTC، بدقة 100 نانوثانية. وهذه ليست طوابع زمنية للمعاملات. وتبقى الأوقات المفقودة/غير الصالحة فارغة/null.
FileSize، FileAttributes الحجم وعلامات Windows الرقمية من البيانات الوصفية المحددة؛ وقد تكون قيم إدخالات المجلدات قديمة. ويمكن لسمات $DATA وسجلات الملفات التي فُك ترميزها أن توفر حجمًا أكثر مباشرة.
AttrType النوع الرقمي لسجل سمة فُك ترميزه؛ و48 لتحديث بيانات وصفية لإدخال مجلد فُك ترميزه. وهو منفصل عن السمة المفتوحة التي تستهدفها العملية.

البيانات الوصفية والحمولات الكاملة لـ redo/undo

الحقل المعنى والتفسير
RedoFileNames، UndoFileNames مصفوفات بكل $FILE_NAME فُك ترميزه في ذلك الجانب، مع الحفاظ على التمييز بين الأسماء المضافة/الجديدة والمُزالة/القديمة.
RedoTimes، UndoTimes طوابع $STANDARD_INFORMATION الزمنية التي كتبها كل جانب؛ وتترك التحديثات الجزئية الطوابع الزمنية غير المتغيرة غائبة بدلًا من تخمينها.
RedoDecoded، UndoDecoded معلومات منظّمة عن سجل ملف أو سمة أو إدخال فهرس أو إدخال مجلد، يحددها Kind. وقد تعني القيمة null عملية غير مدعومة أو بايتات غير كافية.
JournalWriteOffset، JournalWriteLength الإزاحة وعدد البايتات لبيانات redo التي تكتب $DATA:$J. ويحدد هذا مصدرًا محتملًا لسجلات USN كانت ستضيع لولاه؛ ولا يصدّر دفتر يومية معاد بناؤه.
Checkpoint إصدار نقطة التحقق، وLSN البداية، وحجم العنقود، وLSN/طول تفريغات جدول السمات المفتوحة، وأسماء السمات، والصفحات المتسخة (dirty pages)، وجدول المعاملات.
OtherRecordType نوع سجل العميل الخام لجسم غير معروف أو يتعذر فك ترميزه.
RedoData، UndoData، OtherData حمولات ست عشرية لا تُعرض إلا مع --raw-data؛ وإلا فهي null/فارغة. احتفظ بها للتحقق من البنى غير المدعومة أو التالفة.

يتضمن كل كائن لاسم ملف مرجعي الملف والمجلد الأم (Raw، EntryNumber، SequenceNumber)، وName، وNameEscaped، وNamespace، وParentPath الحالي، وأربعة طوابع زمنية، وSize، وAllocatedSize، وAttr، وReparseValue. ويحدد NameEscaped قيم UTF-16 غير الصالحة الممثلة بتسلسلات هروب. ويمكن أن تكون قيمة reparse وسمَ reparse أو حجم سمات موسعة.

تحتفظ كائنات الطوابع الزمنية بكل من Utc والعدد الصحيح Filetime؛ ويمكن أن يكون للقيمة الحارسة (sentinel) أو غير الصالحة تمثيل UTC بقيمة null مع الاحتفاظ بعددها الصحيح الأصلي. وتحتوي RedoTimes وUndoTimes على Created وModified وChanged وAccessed؛ وقيم الأعضاء المفقودين null.

تتضمن كائنات FileRecord التي فُك ترميزها الرقمَ، والتسلسل، وعدد الروابط الصلبة، والعلامات، والمرجع الأساسي، وما إذا كانت الترويسة وحدها هي الباقية، والسمات الموجودة. وتحتفظ كل سمة فُك ترميزها بالنوع، والاسم، وحالة الإقامة، والعلامات، والمعرّف، والحجم، والحجم المخصص. ويضيف $STANDARD_INFORMATION الأوقات الأربعة، والسمات، ومعرّفات المالك/الأمان، والحصة (quota)، وUSN؛ وتحتاج هذه المعرّفات إلى تحليل منفصل، وليست دليلًا على المستخدم الذي غيّر الملف. وتتضمن إدخالات الفهرس العلامات، وطول المفتاح، واسم ملف اختياريًا. وتحتفظ تحديثات إدخالات المجلدات بالأوقات الأربعة، والأحجام، والسمات، وقيمة reparse حتى عندما لا يكون الاسم نفسه قد سُجّل.

سير عمل التحقيق

  1. راجع التشخيصات بحثًا عن صفحات إعادة التشغيل المفقودة والصفحات الممزقة والسجلات المقتطعة.
  2. ابحث في كل من RedoFileNames وUndoFileNames عن اسم ملف أو امتداد مريب.
  3. طابق رقمي الإدخال والتسلسل، ثم افحص سلسلة LSN الخاصة بالمعاملة وعملياتها.
  4. قارن الطوابع الزمنية في redo وundo بحثًا عن تغييرات. فالنسخ الروتيني والاستخراج والاستعادة قد تغيّر الطوابع الزمنية أيضًا؛ والاختلاف خيط للتحقيق، لا حكم تلقائي بالتلاعب بالطوابع الزمنية (timestomping).
  5. اربط النتائج بـ دفتر يومية USN و$MFT و$I30. واستخدم سجلات الأحداث وPrefetch وآثار نشاط المستخدم لإثبات التنفيذ أو الإسناد.

على سبيل المثال، ابحث عن كل السجلات التي تحمل اسم ملف مشفّر في أي من الجانبين:

jq 'select(any(.RedoFileNames[]?, .UndoFileNames[]?;
  .Name | endswith(".encrypted"))) |
  {Lsn, TransactionId, TransactionFirstLsn, RedoOperation, UndoOperation,
   RedoFileNames, UndoFileNames}' logfile.jsonl

هذا بحث عن أسماء الملفات، وليس كاشفًا كاملًا لبرامج الفدية. ولفحص حمولات دفتر اليومية، صدّر باستخدام --raw-data واختر السجلات التي تحتوي على JournalWriteOffset غير null؛ إذ تمثّل القيمة الست عشرية في RedoData البايتات المكتوبة عند تلك الإزاحة. وتحليل سجلات USN المضمّنة هذه وإزالة تكرارها خطوة منفصلة. ولا يدمجها Juntei بعدُ مع إخراج parse-ntfs usn-journal.

مزيد من التفاصيل