Artefactos importantes en Windows-III

Este capítulo explicará otros artefactos que un investigador puede obtener durante el análisis forense en Windows.

Registros de eventos

Los archivos de registro de eventos de Windows, como sugerencias de nombre, son archivos especiales que almacenan eventos importantes como cuando el usuario inicia sesión en la computadora, cuando un programa encuentra un error, sobre cambios en el sistema, acceso RDP, eventos específicos de la aplicación, etc. Los investigadores cibernéticos siempre están interesados ​​en eventos información de registro porque proporciona mucha información histórica útil sobre el acceso al sistema. En la siguiente secuencia de comandos de Python, procesaremos los formatos de registro de eventos de Windows actuales y heredados.

Para el script Python, necesitamos instalar módulos de terceros, a saber pytsk3, pyewf, unicodecsv, pyevt and pyevtX. Podemos seguir los pasos que se indican a continuación para extraer información de los registros de eventos:

  • Primero, busque todos los registros de eventos que coincidan con el argumento de entrada.

  • Luego, realice la verificación de la firma del archivo.

  • Ahora, procese cada registro de eventos que encuentre con la biblioteca adecuada.

  • Por último, escriba la salida en una hoja de cálculo.

Código Python

Veamos cómo usar el código Python para este propósito:

Primero, importe las siguientes bibliotecas de 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

Ahora, proporcione los argumentos para el controlador de línea de comandos. Tenga en cuenta que aquí aceptará tres argumentos: el primero es la ruta al archivo de evidencia, el segundo es el tipo de archivo de evidencia y el tercero es el nombre del registro de eventos a procesar.

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)

Ahora, interactúe con los registros de eventos para consultar la existencia de la ruta proporcionada por el usuario creando nuestro TSKUtilobjeto. Se puede hacer con la ayuda demain() método de la siguiente manera -

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)

Ahora, necesitamos realizar la verificación de la firma y luego definir un método que escribirá todo el contenido en el directorio actual:

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 un método para escribir la salida en una hoja de cálculo de la siguiente manera:

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)

Una vez que ejecute con éxito el script anterior, obtendremos la información del registro de eventos en la hoja de cálculo.

Historia de Internet

El historial de Internet es muy útil para los analistas forenses; ya que la mayoría de los delitos cibernéticos ocurren solo a través de Internet. Veamos cómo extraer el historial de Internet de Internet Explorer, ya que discutimos sobre el análisis forense de Windows, e Internet Explorer viene por defecto con Windows.

En Internet Explorer, el historial de Internet se guarda en index.datarchivo. Veamos un script de Python, que extraerá la información deindex.dat archivo.

Podemos seguir los pasos que se indican a continuación para extraer información de index.dat archivos -

  • Primero, busque index.dat archivos dentro del sistema.

  • Luego, extraiga la información de ese archivo iterando a través de ellos.

  • Ahora, escriba toda esta información en un informe CSV.

Código Python

Veamos cómo usar el código Python para este propósito:

Primero, importe las siguientes bibliotecas de 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

Ahora, proporcione argumentos para el controlador de línea de comandos. Tenga en cuenta que aquí aceptará dos argumentos: el primero sería la ruta al archivo de pruebas y el segundo sería el tipo de archivo de pruebas.

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)

Ahora, interprete el archivo de evidencia creando un objeto de TSKUtile iterar a través del sistema de archivos para encontrar archivos index.dat. Se puede hacer definiendo elmain() funciona de la siguiente manera:

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)

Ahora, defina una función con la ayuda de la cual podamos copiar la información del archivo index.dat al directorio de trabajo actual y luego pueden ser procesados ​​por un módulo de terceros:

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

Ahora, use el siguiente código para realizar la validación de la firma con la ayuda de la función incorporada 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)

Ahora, defina un método que imprima la salida en un archivo CSV, como se muestra a continuación:

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)

Después de ejecutar el script anterior, obtendremos la información del archivo index.dat en el archivo CSV.

Copias de sombra de volumen

Una instantánea es la tecnología incluida en Windows para realizar copias de seguridad o instantáneas de archivos de computadora de forma manual o automática. También se denomina servicio de instantáneas de volumen o servicio de sombra de volumen (VSS).

Con la ayuda de estos archivos VSS, los expertos forenses pueden tener información histórica sobre cómo cambió el sistema con el tiempo y qué archivos existían en la computadora. La tecnología de instantáneas requiere que el sistema de archivos sea NTFS para crear y almacenar instantáneas.

En esta sección, veremos un script de Python, que ayuda a acceder a cualquier volumen de instantáneas presentes en la imagen forense.

Para el script de Python, necesitamos instalar módulos de terceros, a saber pytsk3, pyewf, unicodecsv, pyvshadow y vss. Podemos seguir los pasos que se indican a continuación para extraer información de los archivos VSS

  • Primero, acceda al volumen de la imagen sin procesar e identifique todas las particiones NTFS.

  • Luego, extraiga la información de esas instantáneas repitiéndolas.

  • Ahora, por fin necesitamos crear una lista de archivos de datos dentro de las instantáneas.

Código Python

Veamos cómo usar el código Python para este propósito:

Primero, importe las siguientes bibliotecas de 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

Ahora, proporcione argumentos para el controlador de línea de comandos. Aquí aceptará dos argumentos: el primero es la ruta al archivo de evidencia y el segundo es el archivo de salida.

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

Ahora, valide la existencia de la ruta del archivo de entrada y también separe el directorio del archivo de salida.

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)

Ahora, interactúe con el volumen del archivo de evidencia creando el TSKUtilobjeto. Se puede hacer con la ayuda demain() método de la siguiente manera -

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)

Ahora, defina un método para explorar el archivo de sombra de volumen analizado de la siguiente manera:

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 el método para escribir el resultado en una hoja de cálculo de la siguiente manera:

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)

Una vez que ejecute con éxito este script de Python, obtendremos la información que reside en VSS en una hoja de cálculo.