Artefatos importantes no Windows III

Este capítulo explicará sobre outros artefatos que um investigador pode obter durante a análise forense no Windows.

Logs de eventos

Os arquivos de log de eventos do Windows, como sugestões de nomes, são arquivos especiais que armazenam eventos significativos, como quando o usuário faz logon no computador, quando o programa encontra um erro, sobre mudanças no sistema, acesso RDP, eventos específicos do aplicativo etc. informações de registro porque fornecem muitas informações históricas úteis sobre o acesso do sistema. No script Python a seguir, processaremos os formatos de log de eventos do Windows herdados e atuais.

Para o script Python, precisamos instalar módulos de terceiros, a saber pytsk3, pyewf, unicodecsv, pyevt and pyevtx. Podemos seguir as etapas abaixo para extrair informações dos logs de eventos -

  • Primeiro, pesquise todos os logs de eventos que correspondem ao argumento de entrada.

  • Em seguida, execute a verificação da assinatura do arquivo.

  • Agora, processe cada log de eventos encontrado com a biblioteca apropriada.

  • Por último, escreva a saída na planilha.

Código Python

Vamos ver como usar o código Python para esse propósito -

Primeiro, importe as seguintes bibliotecas Python -

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

Agora, forneça os argumentos para o manipulador de linha de comando. Observe que aqui ele aceitará três argumentos - o primeiro é o caminho para o arquivo de evidência, o segundo é o tipo de arquivo de evidência e o terceiro é o nome do log de eventos a ser processado.

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)

Agora, interaja com os logs de eventos para consultar a existência do caminho fornecido pelo usuário, criando nosso TSKUtilobjeto. Isso pode ser feito com a ajuda demain() método da seguinte forma -

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)

Agora, precisamos realizar a verificação da assinatura seguida pela definição de um método que gravará todo o conteúdo no diretório atual -

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

Por último, defina um método para escrever a saída na planilha da seguinte maneira -

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)

Depois de executar com sucesso o script acima, obteremos as informações de registro de eventos na planilha.

História da Internet

O histórico da Internet é muito útil para analistas forenses; já que a maioria dos crimes cibernéticos ocorre apenas na Internet. Vamos ver como extrair o histórico da Internet do Internet Explorer, conforme discutimos sobre a análise forense do Windows, e o Internet Explorer vem por padrão com o Windows.

No Internet Explorer, o histórico da Internet é salvo em index.datArquivo. Vejamos um script Python, que extrairá as informações deindex.dat Arquivo.

Podemos seguir as etapas abaixo para extrair informações de index.dat arquivos -

  • Primeiro, procure index.dat arquivos dentro do sistema.

  • Em seguida, extraia as informações desse arquivo iterando por meio deles.

  • Agora, escreva todas essas informações em um relatório CSV.

Código Python

Vamos ver como usar o código Python para esse propósito -

Primeiro, importe as seguintes bibliotecas Python -

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

Agora, forneça argumentos para o manipulador de linha de comando. Observe que aqui ele aceitará dois argumentos - o primeiro seria o caminho para o arquivo de evidência e o segundo seria o tipo de arquivo de evidência -

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)

Agora, interprete o arquivo de evidência criando um objeto de TSKUtile iterar através do sistema de arquivos para localizar arquivos index.dat. Isso pode ser feito definindo omain() funcionar da seguinte forma -

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)

Agora, defina uma função com a ajuda da qual podemos copiar as informações do arquivo index.dat para o diretório de trabalho atual e, posteriormente, eles podem ser processados ​​por um módulo de terceiros -

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

Agora, use o seguinte código para realizar a validação da assinatura com a ajuda da função integrada, a saber 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)

Agora, defina um método que irá imprimir a saída em arquivo CSV, conforme mostrado abaixo -

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)

Após executar o script acima, obteremos as informações do arquivo index.dat no arquivo CSV.

Cópias de sombra de volume

Uma cópia de sombra é a tecnologia incluída no Windows para fazer cópias de backup ou instantâneos de arquivos de computador manualmente ou automaticamente. Também é chamado de serviço de instantâneo de volume ou serviço de sombra de volume (VSS).

Com a ajuda desses arquivos VSS, os especialistas forenses podem obter algumas informações históricas sobre como o sistema mudou ao longo do tempo e quais arquivos existiam no computador. A tecnologia de cópia de sombra requer que o sistema de arquivos seja NTFS para criar e armazenar cópias de sombra.

Nesta seção, veremos um script Python, que ajuda a acessar qualquer volume de cópias de sombra presentes na imagem forense.

Para o script Python, precisamos instalar módulos de terceiros, a saber pytsk3, pyewf, unicodecsv, pyvshadow e vss. Podemos seguir as etapas abaixo para extrair informações dos arquivos VSS

  • Primeiro, acesse o volume da imagem bruta e identifique todas as partições NTFS.

  • Em seguida, extraia as informações dessas cópias de sombra iterando por meio delas.

  • Agora, finalmente, precisamos criar uma lista de arquivos de dados dentro dos instantâneos.

Código Python

Vamos ver como usar o código Python para esse propósito -

Primeiro, importe as seguintes bibliotecas Python -

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

Agora, forneça argumentos para o manipulador de linha de comando. Aqui, ele aceitará dois argumentos - o primeiro é o caminho para o arquivo de evidência e o segundo é o arquivo de saída.

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()

Agora, valide a existência do caminho do arquivo de entrada e também separe o diretório do arquivo de saída.

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)

Agora, interaja com o volume do arquivo de evidência criando o TSKUtilobjeto. Isso pode ser feito com a ajuda demain() método da seguinte forma -

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)

Agora, defina um método para explorar o arquivo de sombra de volume analisado da seguinte maneira -

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)

Por último, defina o método para escrever o resultado na planilha da seguinte maneira -

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)

Depois de executar com êxito este script Python, obteremos as informações residentes no VSS em uma planilha.