สิ่งประดิษฐ์ที่สำคัญใน Windows-I

บทนี้จะอธิบายแนวคิดต่างๆที่เกี่ยวข้องกับการพิสูจน์หลักฐานของ Microsoft Windows และสิ่งประดิษฐ์ที่สำคัญที่ผู้ตรวจสอบสามารถได้รับจากกระบวนการตรวจสอบ

บทนำ

สิ่งประดิษฐ์คือวัตถุหรือพื้นที่ภายในระบบคอมพิวเตอร์ที่มีข้อมูลสำคัญที่เกี่ยวข้องกับกิจกรรมที่ดำเนินการโดยผู้ใช้คอมพิวเตอร์ ประเภทและตำแหน่งของข้อมูลนี้ขึ้นอยู่กับระบบปฏิบัติการ ในระหว่างการวิเคราะห์ทางนิติวิทยาศาสตร์สิ่งประดิษฐ์เหล่านี้มีบทบาทสำคัญมากในการอนุมัติหรือไม่อนุมัติการสังเกตของผู้ตรวจสอบ

ความสำคัญของ Windows Artifacts สำหรับนิติเวช

สิ่งประดิษฐ์ของ Windows มีความสำคัญเนื่องจากสาเหตุต่อไปนี้ -

  • ประมาณ 90% ของการเข้าชมในโลกมาจากคอมพิวเตอร์ที่ใช้ Windows เป็นระบบปฏิบัติการ นั่นคือเหตุผลที่ผู้ตรวจสอบทางนิติวิทยาศาสตร์ดิจิทัลสิ่งประดิษฐ์ของ Windows เป็นสิ่งที่จำเป็นมาก

  • ระบบปฏิบัติการ Windows จัดเก็บหลักฐานประเภทต่างๆที่เกี่ยวข้องกับกิจกรรมของผู้ใช้ในระบบคอมพิวเตอร์ นี่เป็นอีกเหตุผลหนึ่งที่แสดงให้เห็นถึงความสำคัญของสิ่งประดิษฐ์ของ Windows สำหรับการพิสูจน์หลักฐานทางดิจิทัล

  • หลายครั้งที่ผู้ตรวจสอบวนเวียนอยู่กับการสืบสวนในพื้นที่เก่าและดั้งเดิมเช่นข้อมูลที่คัดลอกโดยผู้ใช้ สิ่งประดิษฐ์ของ Windows สามารถนำไปสู่การตรวจสอบไปสู่พื้นที่ที่ไม่ใช่แบบดั้งเดิมเช่นข้อมูลที่ระบบสร้างขึ้นหรือสิ่งประดิษฐ์

  • Windows มีสิ่งประดิษฐ์มากมายซึ่งเป็นประโยชน์สำหรับผู้ตรวจสอบตลอดจน บริษัท และบุคคลที่ทำการสืบสวนอย่างไม่เป็นทางการ

  • การเพิ่มขึ้นของอาชญากรรมไซเบอร์ในช่วงไม่กี่ปีที่ผ่านมาเป็นอีกสาเหตุหนึ่งที่สิ่งประดิษฐ์ของ Windows มีความสำคัญ

Windows Artifacts และสคริปต์ Python

ในส่วนนี้เราจะพูดถึงสิ่งประดิษฐ์ของ Windows และสคริปต์ Python เพื่อดึงข้อมูลจากสิ่งเหล่านี้

ถังขยะรีไซเคิล

เป็นหนึ่งในสิ่งประดิษฐ์ของ Windows ที่สำคัญสำหรับการตรวจสอบทางนิติวิทยาศาสตร์ ถังรีไซเคิลของ Windows มีไฟล์ที่ผู้ใช้ลบ แต่ระบบยังไม่ได้ลบออก แม้ว่าผู้ใช้จะลบไฟล์ออกจากระบบอย่างสมบูรณ์ แต่ก็ทำหน้าที่เป็นแหล่งข้อมูลสำคัญในการตรวจสอบ เนื่องจากผู้ตรวจสอบสามารถดึงข้อมูลที่มีค่าเช่นเส้นทางไฟล์ต้นฉบับตลอดจนเวลาที่ส่งไปยังถังรีไซเคิลจากไฟล์ที่ถูกลบ

โปรดทราบว่าการจัดเก็บหลักฐานถังรีไซเคิลขึ้นอยู่กับรุ่นของ Windows ในสคริปต์ Python ต่อไปนี้เราจะจัดการกับ Windows 7 ที่สร้างไฟล์สองไฟล์:$R ไฟล์ที่มีเนื้อหาจริงของไฟล์รีไซเคิลและ $I ไฟล์ที่มีชื่อไฟล์ต้นฉบับพา ธ ขนาดไฟล์เมื่อไฟล์ถูกลบ

สำหรับสคริปต์ Python เราจำเป็นต้องติดตั้งโมดูลของบุคคลที่สามคือ pytsk3, pyewf และ unicodecsv. เราสามารถใช้pipเพื่อติดตั้ง เราสามารถทำตามขั้นตอนต่อไปนี้เพื่อดึงข้อมูลจากถังรีไซเคิล -

  • ขั้นแรกเราต้องใช้วิธีการเรียกซ้ำเพื่อสแกนผ่านไฟล์ $Recycle.bin และเลือกไฟล์ทั้งหมดที่ขึ้นต้นด้วย $I.

  • ต่อไปเราจะอ่านเนื้อหาของไฟล์และแยกวิเคราะห์โครงสร้างข้อมูลเมตาที่มีอยู่

  • ตอนนี้เราจะค้นหาไฟล์ $ R ที่เกี่ยวข้อง

  • ในที่สุดเราจะเขียนผลลัพธ์ลงในไฟล์ CSV เพื่อตรวจสอบ

ให้เราดูวิธีใช้รหัส Python เพื่อจุดประสงค์นี้ -

ขั้นแรกเราต้องนำเข้าไลบรารี Python ต่อไปนี้ -

from __future__ import print_function
from argparse import ArgumentParser

import datetime
import os
import struct

from utility.pytskutil import TSKUtil
import unicodecsv as csv

ต่อไปเราต้องจัดเตรียมอาร์กิวเมนต์สำหรับตัวจัดการบรรทัดคำสั่ง โปรดทราบว่าที่นี่จะยอมรับสามอาร์กิวเมนต์ - อันดับแรกคือพา ธ ไปยังไฟล์หลักฐานอันดับที่สองคือประเภทของไฟล์หลักฐานและที่สามคือพา ธ เอาต์พุตที่ต้องการไปยังรายงาน CSV ดังที่แสดงด้านล่าง -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Recycle Bin evidences')
   parser.add_argument('EVIDENCE_FILE', help = "Path to evidence file")
   parser.add_argument('IMAGE_TYPE', help = "Evidence file format",
   choices = ('ewf', 'raw'))
   parser.add_argument('CSV_REPORT', help = "Path to CSV report")
   args = parser.parse_args()
   main(args.EVIDENCE_FILE, args.IMAGE_TYPE, args.CSV_REPORT)

ตอนนี้กำหนด main()ฟังก์ชันที่จะจัดการการประมวลผลทั้งหมด มันจะค้นหา$I ไฟล์ดังนี้ -

def main(evidence, image_type, report_file):
   tsk_util = TSKUtil(evidence, image_type)
   dollar_i_files = tsk_util.recurse_files("$I", path = '/$Recycle.bin',logic = "startswith")
   
   if dollar_i_files is not None:
      processed_files = process_dollar_i(tsk_util, dollar_i_files)
      write_csv(report_file,['file_path', 'file_size', 'deleted_time','dollar_i_file', 'dollar_r_file', 'is_directory'],processed_files)
   else:
      print("No $I files found")

ทีนี้ถ้าเราพบ $I จากนั้นไฟล์จะต้องถูกส่งไปที่ process_dollar_i() ซึ่งจะยอมรับ tsk_util เช่นเดียวกับรายการของ $I ไฟล์ดังที่แสดงด้านล่าง -

def process_dollar_i(tsk_util, dollar_i_files):
   processed_files = []
   
   for dollar_i in dollar_i_files:
      file_attribs = read_dollar_i(dollar_i[2])
      if file_attribs is None:
         continue
      file_attribs['dollar_i_file'] = os.path.join('/$Recycle.bin', dollar_i[1][1:])

ตอนนี้ค้นหาไฟล์ $ R ดังนี้ -

recycle_file_path = os.path.join('/$Recycle.bin',dollar_i[1].rsplit("/", 1)[0][1:])
dollar_r_files = tsk_util.recurse_files(
   "$R" + dollar_i[0][2:],path = recycle_file_path, logic = "startswith")
   
   if dollar_r_files is None:
      dollar_r_dir = os.path.join(recycle_file_path,"$R" + dollar_i[0][2:])
      dollar_r_dirs = tsk_util.query_directory(dollar_r_dir)
   
   if dollar_r_dirs is None:
      file_attribs['dollar_r_file'] = "Not Found"
      file_attribs['is_directory'] = 'Unknown'
   
   else:
      file_attribs['dollar_r_file'] = dollar_r_dir
      file_attribs['is_directory'] = True
   
   else:
      dollar_r = [os.path.join(recycle_file_path, r[1][1:])for r in dollar_r_files]
      file_attribs['dollar_r_file'] = ";".join(dollar_r)
      file_attribs['is_directory'] = False
      processed_files.append(file_attribs)
   return processed_files

ตอนนี้กำหนด read_dollar_i() วิธีการอ่านไฟล์ $Iไฟล์หรืออีกนัยหนึ่งคือแยกวิเคราะห์ข้อมูลเมตา เราจะใช้read_random()วิธีการอ่านแปดไบต์แรกของลายเซ็น สิ่งนี้จะคืนค่าไม่มีหากลายเซ็นไม่ตรงกัน หลังจากนั้นเราจะต้องอ่านและแกะค่าจาก$I ไฟล์หากเป็นไฟล์ที่ถูกต้อง

def read_dollar_i(file_obj):
   if file_obj.read_random(0, 8) != '\x01\x00\x00\x00\x00\x00\x00\x00':
      return None
   raw_file_size = struct.unpack('<q', file_obj.read_random(8, 8))
   raw_deleted_time = struct.unpack('<q',   file_obj.read_random(16, 8))
   raw_file_path = file_obj.read_random(24, 520)

ตอนนี้หลังจากแตกไฟล์เหล่านี้แล้วเราจำเป็นต้องตีความจำนวนเต็มให้เป็นค่าที่มนุษย์อ่านได้โดยใช้ sizeof_fmt() ฟังก์ชันดังแสดงด้านล่าง -

file_size = sizeof_fmt(raw_file_size[0])
deleted_time = parse_windows_filetime(raw_deleted_time[0])

file_path = raw_file_path.decode("utf16").strip("\x00")
return {'file_size': file_size, 'file_path': file_path,'deleted_time': deleted_time}

ตอนนี้เราต้องกำหนด sizeof_fmt() ฟังก์ชันดังต่อไปนี้ -

def sizeof_fmt(num, suffix = 'B'):
   for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
      if abs(num) < 1024.0:
         return "%3.1f%s%s" % (num, unit, suffix)
      num /= 1024.0
   return "%.1f%s%s" % (num, 'Yi', suffix)

ตอนนี้กำหนดฟังก์ชันสำหรับจำนวนเต็มที่ตีความเป็นวันที่และเวลาที่จัดรูปแบบดังนี้ -

def parse_windows_filetime(date_value):
   microseconds = float(date_value) / 10
   ts = datetime.datetime(1601, 1, 1) + datetime.timedelta(
      microseconds = microseconds)
   return ts.strftime('%Y-%m-%d %H:%M:%S.%f')

ตอนนี้เราจะกำหนด write_csv() วิธีการเขียนผลลัพธ์ที่ประมวลผลเป็นไฟล์ CSV ดังนี้ -

def write_csv(outfile, fieldnames, data):
   with open(outfile, 'wb') as open_outfile:
      csvfile = csv.DictWriter(open_outfile, fieldnames)
      csvfile.writeheader()
      csvfile.writerows(data)

เมื่อคุณเรียกใช้สคริปต์ข้างต้นเราจะได้รับข้อมูลจากไฟล์ $ I และ $ R

บันทึกย่อช่วยเตือน

Windows Sticky Notes เข้ามาแทนที่นิสัยการเขียนด้วยปากกาและกระดาษในโลกแห่งความเป็นจริง บันทึกย่อเหล่านี้ใช้เพื่อลอยบนเดสก์ท็อปพร้อมตัวเลือกต่างๆสำหรับสีแบบอักษรและอื่น ๆ ใน Windows 7 ไฟล์ Sticky Notes จะถูกเก็บเป็นไฟล์ OLE ดังนั้นในสคริปต์ Python ต่อไปนี้เราจะตรวจสอบไฟล์ OLE นี้เพื่อแยกข้อมูลเมตาจาก Sticky Notes

สำหรับสคริปต์ Python นี้เราจำเป็นต้องติดตั้งโมดูลของบุคคลที่สามคือ olefile, pytsk3, pyewfและ unicodecsv เราสามารถใช้คำสั่งpip เพื่อติดตั้ง

เราสามารถทำตามขั้นตอนที่กล่าวถึงด้านล่างเพื่อดึงข้อมูลจากไฟล์ Sticky note คือ StickyNote.sn -

  • อันดับแรกเปิดไฟล์หลักฐานและค้นหาไฟล์ StickyNote.snt ทั้งหมด

  • จากนั้นแยกวิเคราะห์ข้อมูลเมตาและเนื้อหาจากสตรีม OLE และเขียนเนื้อหา RTF ลงในไฟล์

  • สุดท้ายสร้างรายงาน CSV ของข้อมูลเมตานี้

รหัส Python

ให้เราดูวิธีใช้รหัส Python เพื่อจุดประสงค์นี้ -

ขั้นแรกให้นำเข้าไลบรารี Python ต่อไปนี้ -

from __future__ import print_function
from argparse import ArgumentParser

import unicodecsv as csv
import os
import StringIO

from utility.pytskutil import TSKUtil
import olefile

จากนั้นกำหนดตัวแปรส่วนกลางที่จะใช้กับสคริปต์นี้ -

REPORT_COLS = ['note_id', 'created', 'modified', 'note_text', 'note_file']

ต่อไปเราต้องจัดเตรียมอาร์กิวเมนต์สำหรับตัวจัดการบรรทัดคำสั่ง โปรดทราบว่าที่นี่จะยอมรับสามอาร์กิวเมนต์ - อันดับแรกคือพา ธ ไปยังไฟล์หลักฐานที่สองคือประเภทของไฟล์หลักฐานและที่สามคือพา ธ เอาต์พุตที่ต้องการดังนี้ -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Evidence from Sticky Notes')
   parser.add_argument('EVIDENCE_FILE', help="Path to evidence file")
   parser.add_argument('IMAGE_TYPE', help="Evidence file format",choices=('ewf', 'raw'))
   parser.add_argument('REPORT_FOLDER', help="Path to report folder")
   args = parser.parse_args()
   main(args.EVIDENCE_FILE, args.IMAGE_TYPE, args.REPORT_FOLDER)

ตอนนี้เราจะกำหนด main() ซึ่งจะคล้ายกับสคริปต์ก่อนหน้าตามที่แสดงด้านล่าง -

def main(evidence, image_type, report_folder):
   tsk_util = TSKUtil(evidence, image_type)
   note_files = tsk_util.recurse_files('StickyNotes.snt', '/Users','equals')

ตอนนี้ให้เราทำซ้ำผ่านไฟล์ผลลัพธ์ แล้วเราจะโทรparse_snt_file() เพื่อประมวลผลไฟล์จากนั้นเราจะเขียนไฟล์ RTF ด้วยไฟล์ write_note_rtf() วิธีการดังนี้ -

report_details = []
for note_file in note_files:
   user_dir = note_file[1].split("/")[1]
   file_like_obj = create_file_like_obj(note_file[2])
   note_data = parse_snt_file(file_like_obj)
   
   if note_data is None:
      continue
   write_note_rtf(note_data, os.path.join(report_folder, user_dir))
   report_details += prep_note_report(note_data, REPORT_COLS,"/Users" + note_file[1])
   write_csv(os.path.join(report_folder, 'sticky_notes.csv'), REPORT_COLS,report_details)

ต่อไปเราต้องกำหนดฟังก์ชันต่างๆที่ใช้ในสคริปต์นี้

ก่อนอื่นเราจะกำหนด create_file_like_obj() ฟังก์ชั่นสำหรับอ่านขนาดของไฟล์โดยใช้ pytskไฟล์วัตถุ จากนั้นเราจะกำหนดparse_snt_file() ฟังก์ชันที่จะรับอ็อบเจ็กต์ที่มีลักษณะคล้ายไฟล์เป็นอินพุตและใช้เพื่ออ่านและตีความไฟล์โน้ต

def parse_snt_file(snt_file):
   
   if not olefile.isOleFile(snt_file):
      print("This is not an OLE file")
      return None
   ole = olefile.OleFileIO(snt_file)
   note = {}
   
   for stream in ole.listdir():
      if stream[0].count("-") == 3:
         if stream[0] not in note:
            note[stream[0]] = {"created": ole.getctime(stream[0]),"modified": ole.getmtime(stream[0])}
         content = None
         if stream[1] == '0':
            content = ole.openstream(stream).read()
         elif stream[1] == '3':
            content = ole.openstream(stream).read().decode("utf-16")
         if content:
            note[stream[0]][stream[1]] = content
	return note

ตอนนี้สร้างไฟล์ RTF โดยกำหนดไฟล์ write_note_rtf() ฟังก์ชันดังต่อไปนี้

def write_note_rtf(note_data, report_folder):
   if not os.path.exists(report_folder):
      os.makedirs(report_folder)
   
   for note_id, stream_data in note_data.items():
      fname = os.path.join(report_folder, note_id + ".rtf")
      with open(fname, 'w') as open_file:
         open_file.write(stream_data['0'])

ตอนนี้เราจะแปลพจนานุกรมที่ซ้อนกันเป็นรายการพจนานุกรมแบบรวมที่เหมาะสมกว่าสำหรับสเปรดชีต CSV จะทำได้โดยการกำหนดprep_note_report()ฟังก์ชัน สุดท้ายนี้เราจะกำหนดwrite_csv() ฟังก์ชัน

def prep_note_report(note_data, report_cols, note_file):
   report_details = []
   
   for note_id, stream_data in note_data.items():
      report_details.append({
         "note_id": note_id,
         "created": stream_data['created'],
         "modified": stream_data['modified'],
         "note_text": stream_data['3'].strip("\x00"),
         "note_file": note_file
      })
   return report_details
def write_csv(outfile, fieldnames, data):
   with open(outfile, 'wb') as open_outfile:
      csvfile = csv.DictWriter(open_outfile, fieldnames)
      csvfile.writeheader()
      csvfile.writerows(data)

หลังจากเรียกใช้สคริปต์ด้านบนเราจะได้รับข้อมูลเมตาจากไฟล์ Sticky Notes

ไฟล์รีจิสทรี

ไฟล์รีจิสทรีของ Windows มีรายละเอียดที่สำคัญมากมายซึ่งเปรียบเสมือนขุมทรัพย์ของข้อมูลสำหรับนักวิเคราะห์ทางนิติวิทยาศาสตร์ เป็นฐานข้อมูลแบบลำดับชั้นที่มีรายละเอียดที่เกี่ยวข้องกับการกำหนดค่าระบบปฏิบัติการกิจกรรมของผู้ใช้การติดตั้งซอฟต์แวร์เป็นต้นในสคริปต์ Python ต่อไปนี้เราจะเข้าถึงข้อมูลพื้นฐานทั่วไปจากSYSTEM และ SOFTWARE ลมพิษ

สำหรับสคริปต์ Python นี้เราจำเป็นต้องติดตั้งโมดูลของบุคคลที่สามคือ pytsk3, pyewf และ registry. เราสามารถใช้pip เพื่อติดตั้ง

เราสามารถทำตามขั้นตอนด้านล่างเพื่อดึงข้อมูลจากรีจิสทรีของ Windows -

  • ขั้นแรกค้นหากลุ่มรีจิสทรีเพื่อดำเนินการตามชื่อและตามเส้นทาง

  • จากนั้นเราจะเปิดไฟล์เหล่านี้โดยใช้โมดูล StringIO และ Registry

  • ในที่สุดเราต้องประมวลผลแต่ละรังและพิมพ์ค่าที่แยกวิเคราะห์ไปยังคอนโซลเพื่อตีความ

รหัส Python

ให้เราดูวิธีใช้รหัส Python เพื่อจุดประสงค์นี้ -

ขั้นแรกให้นำเข้าไลบรารี Python ต่อไปนี้ -

from __future__ import print_function
from argparse import ArgumentParser

import datetime
import StringIO
import struct

from utility.pytskutil import TSKUtil
from Registry import Registry

ตอนนี้ให้อาร์กิวเมนต์สำหรับตัวจัดการบรรทัดคำสั่ง ที่นี่จะยอมรับสองข้อโต้แย้ง - ประการแรกคือเส้นทางไปยังไฟล์หลักฐานที่สองคือประเภทของไฟล์หลักฐานดังที่แสดงด้านล่าง -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Evidence from Windows Registry')
   parser.add_argument('EVIDENCE_FILE', help = "Path to evidence file")
   parser.add_argument('IMAGE_TYPE', help = "Evidence file format",
   choices = ('ewf', 'raw'))
   args = parser.parse_args()
   main(args.EVIDENCE_FILE, args.IMAGE_TYPE)

ตอนนี้เราจะกำหนด main() ฟังก์ชันสำหรับการค้นหา SYSTEM และ SOFTWARE ลมพิษภายใน /Windows/System32/config โฟลเดอร์ดังนี้ -

def main(evidence, image_type):
   tsk_util = TSKUtil(evidence, image_type)
   tsk_system_hive = tsk_util.recurse_files('system', '/Windows/system32/config', 'equals')
   tsk_software_hive = tsk_util.recurse_files('software', '/Windows/system32/config', 'equals')
   system_hive = open_file_as_reg(tsk_system_hive[0][2])
   software_hive = open_file_as_reg(tsk_software_hive[0][2])
   process_system_hive(system_hive)
   process_software_hive(software_hive)

ตอนนี้กำหนดฟังก์ชันสำหรับเปิดไฟล์รีจิสทรี เพื่อจุดประสงค์นี้เราต้องรวบรวมขนาดของไฟล์จากpytsk metadata ดังนี้ -

def open_file_as_reg(reg_file):
   file_size = reg_file.info.meta.size
   file_content = reg_file.read_random(0, file_size)
   file_like_obj = StringIO.StringIO(file_content)
   return Registry.Registry(file_like_obj)

ตอนนี้ด้วยความช่วยเหลือของวิธีการต่อไปนี้เราสามารถดำเนินการได้ SYSTEM> รัง -

def process_system_hive(hive):
   root = hive.root()
   current_control_set = root.find_key("Select").value("Current").value()
   control_set = root.find_key("ControlSet{:03d}".format(current_control_set))
   raw_shutdown_time = struct.unpack(
      '<Q', control_set.find_key("Control").find_key("Windows").value("ShutdownTime").value())
   
   shutdown_time = parse_windows_filetime(raw_shutdown_time[0])
   print("Last Shutdown Time: {}".format(shutdown_time))
   
   time_zone = control_set.find_key("Control").find_key("TimeZoneInformation")
      .value("TimeZoneKeyName").value()
   
   print("Machine Time Zone: {}".format(time_zone))
   computer_name = control_set.find_key("Control").find_key("ComputerName").find_key("ComputerName")
      .value("ComputerName").value()
   
   print("Machine Name: {}".format(computer_name))
   last_access = control_set.find_key("Control").find_key("FileSystem")
      .value("NtfsDisableLastAccessUpdate").value()
   last_access = "Disabled" if last_access == 1 else "enabled"
   print("Last Access Updates: {}".format(last_access))

ตอนนี้เราจำเป็นต้องกำหนดฟังก์ชันสำหรับจำนวนเต็มที่ตีความเป็นวันที่และเวลาที่จัดรูปแบบดังนี้ -

def parse_windows_filetime(date_value):
   microseconds = float(date_value) / 10
   ts = datetime.datetime(1601, 1, 1) + datetime.timedelta(microseconds = microseconds)
   return ts.strftime('%Y-%m-%d %H:%M:%S.%f')

def parse_unix_epoch(date_value):
   ts = datetime.datetime.fromtimestamp(date_value)
   return ts.strftime('%Y-%m-%d %H:%M:%S.%f')

ตอนนี้ด้วยความช่วยเหลือของวิธีการต่อไปนี้เราสามารถดำเนินการได้ SOFTWARE รัง -

def process_software_hive(hive):
   root = hive.root()
   nt_curr_ver = root.find_key("Microsoft").find_key("Windows NT")
      .find_key("CurrentVersion")
   
   print("Product name: {}".format(nt_curr_ver.value("ProductName").value()))
   print("CSD Version: {}".format(nt_curr_ver.value("CSDVersion").value()))
   print("Current Build: {}".format(nt_curr_ver.value("CurrentBuild").value()))
   print("Registered Owner: {}".format(nt_curr_ver.value("RegisteredOwner").value()))
   print("Registered Org: 
      {}".format(nt_curr_ver.value("RegisteredOrganization").value()))
   
   raw_install_date = nt_curr_ver.value("InstallDate").value()
   install_date = parse_unix_epoch(raw_install_date)
   print("Installation Date: {}".format(install_date))

หลังจากเรียกใช้สคริปต์ข้างต้นเราจะได้รับข้อมูลเมตาที่เก็บไว้ในไฟล์ Windows Registry