Ważne artefakty w systemie Windows-III

W tym rozdziale wyjaśniono dalsze artefakty, które badacz może uzyskać podczas analizy kryminalistycznej w systemie Windows.

Dzienniki zdarzeń

Pliki dziennika zdarzeń systemu Windows, jak sugeruje nazwa, są specjalnymi plikami, które przechowują ważne zdarzenia, takie jak logowanie użytkownika na komputerze, wystąpienie błędu programu, zmiany systemu, dostęp RDP, zdarzenia dotyczące aplikacji itp. Cyberprzestępcy są zawsze zainteresowani zdarzeniem. informacje dziennika, ponieważ zawiera wiele przydatnych informacji historycznych o dostępie do systemu. W poniższym skrypcie w języku Python będziemy przetwarzać zarówno starsze, jak i obecne formaty dziennika zdarzeń systemu Windows.

W przypadku skryptu Python musimy zainstalować moduły stron trzecich, a mianowicie pytsk3, pyewf, unicodecsv, pyevt and pyevtx. Możemy wykonać poniższe kroki, aby wyodrębnić informacje z dzienników zdarzeń -

  • Najpierw wyszukaj wszystkie dzienniki zdarzeń, które pasują do argumentu wejściowego.

  • Następnie przeprowadź weryfikację podpisu pliku.

  • Teraz przetwórz każdy znaleziony dziennik zdarzeń za pomocą odpowiedniej biblioteki.

  • Na koniec zapisz dane wyjściowe do arkusza kalkulacyjnego.

Kod w Pythonie

Zobaczmy, jak w tym celu wykorzystać kod Pythona -

Najpierw zaimportuj następujące biblioteki Pythona -

from __future__ import print_function
import argparse
import unicodecsv as csv
import os
import pytsk3
import pyewf
import pyevt
import pyevtx
import sys
from utility.pytskutil import TSKUtil

Teraz podaj argumenty obsługi wiersza poleceń. Zauważ, że w tym przypadku przyjmie trzy argumenty - pierwszy to ścieżka do pliku dowodowego, drugi to typ pliku dowodowego, a trzeci to nazwa dziennika zdarzeń do przetworzenia.

if __name__ == "__main__":
   parser = argparse.ArgumentParser('Information from Event Logs')
   parser.add_argument("EVIDENCE_FILE", help = "Evidence file path")
   parser.add_argument("TYPE", help = "Type of Evidence",choices = ("raw", "ewf"))
   parser.add_argument(
      "LOG_NAME",help = "Event Log Name (SecEvent.Evt, SysEvent.Evt, ""etc.)")
   
   parser.add_argument(
      "-d", help = "Event log directory to scan",default = "/WINDOWS/SYSTEM32/WINEVT")
   
   parser.add_argument(
      "-f", help = "Enable fuzzy search for either evt or"" evtx extension", action = "store_true")
   args = parser.parse_args()
   
   if os.path.exists(args.EVIDENCE_FILE) and \ os.path.isfile(args.EVIDENCE_FILE):
      main(args.EVIDENCE_FILE, args.TYPE, args.LOG_NAME, args.d, args.f)
   else:
      print("[-] Supplied input file {} does not exist or is not a ""file".format(args.EVIDENCE_FILE))
   sys.exit(1)

Teraz wejdź w interakcję z dziennikami zdarzeń, aby zapytać o istnienie ścieżki podanej przez użytkownika, tworząc naszą TSKUtilobiekt. Można to zrobić za pomocąmain() metoda w następujący sposób -

def main(evidence, image_type, log, win_event, fuzzy):
   tsk_util = TSKUtil(evidence, image_type)
   event_dir = tsk_util.query_directory(win_event)
   
   if event_dir is not None:
      if fuzzy is True:
         event_log = tsk_util.recurse_files(log, path=win_event)
   else:
      event_log = tsk_util.recurse_files(log, path=win_event, logic="equal")
   
   if event_log is not None:
      event_data = []
      for hit in event_log:
         event_file = hit[2]
         temp_evt = write_file(event_file)

Teraz musimy przeprowadzić weryfikację podpisu, a następnie zdefiniować metodę, która zapisze całą zawartość do bieżącego katalogu -

def write_file(event_file):
   with open(event_file.info.name.name, "w") as outfile:
      outfile.write(event_file.read_random(0, event_file.info.meta.size))
   return event_file.info.name.name
      if pyevt.check_file_signature(temp_evt):
         evt_log = pyevt.open(temp_evt)
         print("[+] Identified {} records in {}".format(
            evt_log.number_of_records, temp_evt))
         
         for i, record in enumerate(evt_log.records):
            strings = ""
            for s in record.strings:
               if s is not None:
                  strings += s + "\n"
            event_data.append([
               i, hit[0], record.computer_name,
               record.user_security_identifier,
               record.creation_time, record.written_time,
               record.event_category, record.source_name,
               record.event_identifier, record.event_type,
               strings, "",
               os.path.join(win_event, hit[1].lstrip("//"))
            ])
      elif pyevtx.check_file_signature(temp_evt):
         evtx_log = pyevtx.open(temp_evt)
         print("[+] Identified {} records in {}".format(
            evtx_log.number_of_records, temp_evt))
         for i, record in enumerate(evtx_log.records):
            strings = ""
            for s in record.strings:
			   if s is not None:
               strings += s + "\n"
         event_data.append([
            i, hit[0], record.computer_name,
            record.user_security_identifier, "",
            record.written_time, record.event_level,
            record.source_name, record.event_identifier,
            "", strings, record.xml_string,
            os.path.join(win_event, hit[1].lstrip("//"))
      ])
      else:
         print("[-] {} not a valid event log. Removing temp" file...".format(temp_evt))
         os.remove(temp_evt)
      continue
      write_output(event_data)
   else:
      print("[-] {} Event log not found in {} directory".format(log, win_event))
      sys.exit(3)
else:
   print("[-] Win XP Event Log Directory {} not found".format(win_event))
   sys.exit(2

Na koniec zdefiniuj metodę zapisywania danych wyjściowych do arkusza kalkulacyjnego w następujący sposób -

def write_output(data):
   output_name = "parsed_event_logs.csv"
   print("[+] Writing {} to current working directory: {}".format(
      output_name, os.getcwd()))
   
   with open(output_name, "wb") as outfile:
      writer = csv.writer(outfile)
      writer.writerow([
         "Index", "File name", "Computer Name", "SID",
         "Event Create Date", "Event Written Date",
         "Event Category/Level", "Event Source", "Event ID",
         "Event Type", "Data", "XML Data", "File Path"
      ])
      writer.writerows(data)

Po pomyślnym uruchomieniu powyższego skryptu uzyskamy informacje o dzienniku zdarzeń w arkuszu kalkulacyjnym.

Historia Internetu

Historia Internetu jest bardzo przydatna dla analityków kryminalistycznych; ponieważ większość cyberprzestępstw ma miejsce wyłącznie w internecie. Zobaczmy, jak wyodrębnić historię internetową z Internet Explorera, omawiając kryminalistykę systemu Windows, a Internet Explorer jest domyślnie dostępny w systemie Windows.

W przeglądarce Internet Explorer historia internetowa jest zapisywana w formacie index.datplik. Przyjrzyjmy się skryptowi w Pythonie, który wyodrębni informacje zindex.dat plik.

Możemy wykonać poniższe kroki, aby wyodrębnić informacje z index.dat pliki -

  • Najpierw wyszukaj index.dat pliki w systemie.

  • Następnie wyodrębnij informacje z tego pliku, przechodząc przez nie.

  • Teraz zapisz wszystkie te informacje w raporcie CSV.

Kod w Pythonie

Zobaczmy, jak w tym celu wykorzystać kod Pythona -

Najpierw zaimportuj następujące biblioteki Pythona -

from __future__ import print_function
import argparse

from datetime import datetime, timedelta
import os
import pytsk3
import pyewf
import pymsiecf
import sys
import unicodecsv as csv

from utility.pytskutil import TSKUtil

Teraz podaj argumenty do obsługi wiersza poleceń. Zwróć uwagę, że w tym przypadku przyjmie dwa argumenty - pierwszy będzie ścieżką do pliku dowodowego, a drugi typem pliku dowodowego -

if __name__ == "__main__":
parser = argparse.ArgumentParser('getting information from internet history')
   parser.add_argument("EVIDENCE_FILE", help = "Evidence file path")
   parser.add_argument("TYPE", help = "Type of Evidence",choices = ("raw", "ewf"))
   parser.add_argument("-d", help = "Index.dat directory to scan",default = "/USERS")
   args = parser.parse_args()
   
   if os.path.exists(args.EVIDENCE_FILE) and os.path.isfile(args.EVIDENCE_FILE):
      main(args.EVIDENCE_FILE, args.TYPE, args.d)
   else:
      print("[-] Supplied input file {} does not exist or is not a ""file".format(args.EVIDENCE_FILE))
      sys.exit(1)

Teraz zinterpretuj plik dowodowy, tworząc obiekt TSKUtili wykonaj iterację w systemie plików, aby znaleźć pliki index.dat. Można to zrobić, definiując plikmain() działają w następujący sposób -

def main(evidence, image_type, path):
   tsk_util = TSKUtil(evidence, image_type)
   index_dir = tsk_util.query_directory(path)
   
   if index_dir is not None:
      index_files = tsk_util.recurse_files("index.dat", path = path,logic = "equal")
      
      if index_files is not None:
         print("[+] Identified {} potential index.dat files".format(len(index_files)))
         index_data = []
         
         for hit in index_files:
            index_file = hit[2]
            temp_index = write_file(index_file)

Teraz zdefiniuj funkcję, za pomocą której możemy skopiować informacje z pliku index.dat do bieżącego katalogu roboczego, a później mogą być przetwarzane przez zewnętrzny moduł -

def write_file(index_file):
   with open(index_file.info.name.name, "w") as outfile:
   outfile.write(index_file.read_random(0, index_file.info.meta.size))
return index_file.info.name.name

Teraz użyj następującego kodu, aby przeprowadzić walidację podpisu za pomocą wbudowanej funkcji, a mianowicie check_file_signature() -

if pymsiecf.check_file_signature(temp_index):
   index_dat = pymsiecf.open(temp_index)
   print("[+] Identified {} records in {}".format(
   index_dat.number_of_items, temp_index))

   for i, record in enumerate(index_dat.items):
   try:
      data = record.data
   if data is not None:
      data = data.rstrip("\x00")
   except AttributeError:
   
   if isinstance(record, pymsiecf.redirected):
      index_data.append([
         i, temp_index, "", "", "", "", "",record.location, "", "", record.offset,os.path.join(path, hit[1].lstrip("//"))])
   
   elif isinstance(record, pymsiecf.leak):
      index_data.append([
         i, temp_index, record.filename, "","", "", "", "", "", "", record.offset,os.path.join(path, hit[1].lstrip("//"))])
   continue
   
   index_data.append([
      i, temp_index, record.filename,
      record.type, record.primary_time,
      record.secondary_time,
      record.last_checked_time, record.location,
      record.number_of_hits, data, record.offset,
      os.path.join(path, hit[1].lstrip("//"))
   ])
   else:
      print("[-] {} not a valid index.dat file. Removing "
      "temp file..".format(temp_index))
      os.remove("index.dat")
      continue
      os.remove("index.dat")
      write_output(index_data)
   else:
      print("[-] Index.dat files not found in {} directory".format(path))
   sys.exit(3)
   else:
      print("[-] Directory {} not found".format(win_event))
   sys.exit(2)

Teraz zdefiniuj metodę, która wydrukuje wynik w pliku CSV, jak pokazano poniżej -

def write_output(data):
   output_name = "Internet_Indexdat_Summary_Report.csv"
   print("[+] Writing {} with {} parsed index.dat files to current "
   "working directory: {}".format(output_name, len(data),os.getcwd()))
   
   with open(output_name, "wb") as outfile:
      writer = csv.writer(outfile)
      writer.writerow(["Index", "File Name", "Record Name",
      "Record Type", "Primary Date", "Secondary Date",
      "Last Checked Date", "Location", "No. of Hits",
      "Record Data", "Record Offset", "File Path"])
      writer.writerows(data)

Po uruchomieniu powyższego skryptu uzyskamy informacje z pliku index.dat w pliku CSV.

Kopie woluminów w tle

Kopia w tle to technologia zawarta w systemie Windows do ręcznego lub automatycznego wykonywania kopii zapasowych lub migawek plików komputerowych. Nazywa się to również usługą migawki woluminu lub usługą woluminu w tle (VSS).

Z pomocą tych plików VSS eksperci medycyny sądowej mogą uzyskać pewne historyczne informacje o tym, jak system zmieniał się w czasie i jakie pliki istniały na komputerze. Technologia kopiowania w tle wymaga systemu plików NTFS do tworzenia i przechowywania kopii w tle.

W tej sekcji zobaczymy skrypt w Pythonie, który pomaga uzyskać dostęp do dowolnej ilości kopii w tle obecnych w obrazie śledczym.

W przypadku skryptu Python musimy zainstalować moduły stron trzecich, a mianowicie pytsk3, pyewf, unicodecsv, pyvshadow i vss. Możemy wykonać kroki podane poniżej, aby wyodrębnić informacje z plików VSS

  • Najpierw uzyskaj dostęp do woluminu surowego obrazu i zidentyfikuj wszystkie partycje NTFS.

  • Następnie wyodrębnij informacje z kopii w tle, przechodząc przez nie.

  • Teraz musimy w końcu utworzyć listę plików danych w migawkach.

Kod w Pythonie

Zobaczmy, jak w tym celu wykorzystać kod Pythona -

Najpierw zaimportuj następujące biblioteki Pythona -

from __future__ import print_function
import argparse
from datetime import datetime, timedelta

import os
import pytsk3
import pyewf
import pyvshadow
import sys
import unicodecsv as csv

from utility import vss
from utility.pytskutil import TSKUtil
from utility import pytskutil

Teraz podaj argumenty do obsługi wiersza poleceń. Tutaj przyjmie dwa argumenty - pierwszy to ścieżka do pliku dowodowego, a drugi to plik wyjściowy.

if __name__ == "__main__":
   parser = argparse.ArgumentParser('Parsing Shadow Copies')
   parser.add_argument("EVIDENCE_FILE", help = "Evidence file path")
   parser.add_argument("OUTPUT_CSV", help = "Output CSV with VSS file listing")
   args = parser.parse_args()

Teraz sprawdź istnienie ścieżki pliku wejściowego, a także oddziel katalog od pliku wyjściowego.

directory = os.path.dirname(args.OUTPUT_CSV)
if not os.path.exists(directory) and directory != "":
   os.makedirs(directory)
if os.path.exists(args.EVIDENCE_FILE) and \ os.path.isfile(args.EVIDENCE_FILE):
   main(args.EVIDENCE_FILE, args.OUTPUT_CSV)
else:
   print("[-] Supplied input file {} does not exist or is not a "
   "file".format(args.EVIDENCE_FILE))
   
   sys.exit(1)

Teraz wejdź w interakcję z woluminem pliku dowodowego, tworząc plik TSKUtilobiekt. Można to zrobić za pomocąmain() metoda w następujący sposób -

def main(evidence, output):
   tsk_util = TSKUtil(evidence, "raw")
   img_vol = tsk_util.return_vol()

if img_vol is not None:
   for part in img_vol:
      if tsk_util.detect_ntfs(img_vol, part):
         print("Exploring NTFS Partition for VSS")
         explore_vss(evidence, part.start * img_vol.info.block_size,output)
      else:
         print("[-] Must be a physical preservation to be compatible ""with this script")
         sys.exit(2)

Teraz zdefiniuj metodę eksploracji przeanalizowanego pliku cienia woluminu w następujący sposób -

def explore_vss(evidence, part_offset, output):
   vss_volume = pyvshadow.volume()
   vss_handle = vss.VShadowVolume(evidence, part_offset)
   vss_count = vss.GetVssStoreCount(evidence, part_offset)
   
   if vss_count > 0:
      vss_volume.open_file_object(vss_handle)
      vss_data = []
      
      for x in range(vss_count):
         print("Gathering data for VSC {} of {}".format(x, vss_count))
         vss_store = vss_volume.get_store(x)
         image = vss.VShadowImgInfo(vss_store)
         vss_data.append(pytskutil.openVSSFS(image, x))
write_csv(vss_data, output)

Na koniec zdefiniuj metodę zapisu wyniku w arkuszu kalkulacyjnym w następujący sposób -

def write_csv(data, output):
   if data == []:
      print("[-] No output results to write")
      sys.exit(3)
   print("[+] Writing output to {}".format(output))
   if os.path.exists(output):
      append = True
with open(output, "ab") as csvfile:
      csv_writer = csv.writer(csvfile)
      headers = ["VSS", "File", "File Ext", "File Type", "Create Date",
         "Modify Date", "Change Date", "Size", "File Path"]
      if not append:
         csv_writer.writerow(headers)
      for result_list in data:
         csv_writer.writerows(result_list)

Po pomyślnym uruchomieniu tego skryptu w Pythonie otrzymamy informacje znajdujące się w VSS do arkusza kalkulacyjnego.