Python Digital Network Forensics-I

Questo capitolo spiegherà i fondamenti coinvolti nell'esecuzione di analisi di rete utilizzando Python.

Capire la Network Forensics

Network forensics è una branca della digital forensics che si occupa del monitoraggio e dell'analisi del traffico di rete di computer, sia locale che WAN (wide area network), ai fini della raccolta di informazioni, raccolta di prove o rilevamento di intrusioni. L'analisi forense della rete svolge un ruolo fondamentale nell'indagine sui crimini digitali come il furto di proprietà intellettuale o la fuga di informazioni. Un'immagine delle comunicazioni di rete aiuta un investigatore a risolvere alcune domande cruciali come segue:

  • Quali siti web sono stati consultati?

  • Che tipo di contenuto è stato caricato sulla nostra rete?

  • Che tipo di contenuto è stato scaricato dalla nostra rete?

  • A quali server si accede?

  • Qualcuno sta inviando informazioni sensibili al di fuori dei firewall aziendali?

Internet Evidence Finder (IEF)

IEF è uno strumento forense digitale per trovare, analizzare e presentare prove digitali trovate su diversi media digitali come computer, smartphone, tablet, ecc. È molto popolare e utilizzato da migliaia di professionisti forensi.

Uso di IEF

A causa della sua popolarità, IEF è utilizzato in larga misura dai professionisti forensi. Alcuni degli usi di IEF sono i seguenti:

  • Grazie alle sue potenti capacità di ricerca, viene utilizzato per cercare più file o supporti dati contemporaneamente.

  • Viene anche utilizzato per recuperare i dati cancellati dallo spazio non allocato della RAM attraverso nuove tecniche di intaglio.

  • Se gli investigatori vogliono ricostruire le pagine web nel loro formato originale alla data in cui sono state aperte, possono usare IEF.

  • Viene anche utilizzato per cercare volumi di dischi logici o fisici.

Dumping report da IEF a CSV utilizzando Python

IEF memorizza i dati in un database SQLite e il seguente script Python identificherà dinamicamente le tabelle dei risultati all'interno del database IEF e le scaricherà nei rispettivi file CSV.

Questo processo viene eseguito nei passaggi mostrati di seguito

  • Innanzitutto, genera il database dei risultati IEF che sarà un file di database SQLite che termina con l'estensione .db.

  • Quindi, interroga quel database per identificare tutte le tabelle.

  • Infine, scrivi queste tabelle dei risultati in un singolo file CSV.

Codice Python

Vediamo come utilizzare il codice Python per questo scopo -

Per lo script Python, importa le librerie necessarie come segue:

from __future__ import print_function

import argparse
import csv
import os
import sqlite3
import sys

Ora, dobbiamo fornire il percorso al file di database IEF -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('IEF to CSV')
   parser.add_argument("IEF_DATABASE", help="Input IEF database")
   parser.add_argument("OUTPUT_DIR", help="Output DIR")
   args = parser.parse_args()

Ora, confermeremo l'esistenza del database IEF come segue:

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

Ora, come abbiamo fatto negli script precedenti, effettua la connessione con il database SQLite come segue per eseguire le query tramite il cursore:

def main(database, out_directory):
   print("[+] Connecting to SQLite database")
   conn = sqlite3.connect(database)
   c = conn.cursor()

Le seguenti righe di codice recupereranno i nomi delle tabelle dal database:

print("List of all tables to extract")
c.execute("select * from sqlite_master where type = 'table'")
tables = [x[2] for x in c.fetchall() if not x[2].startswith('_') and not x[2].endswith('_DATA')]

Ora selezioneremo tutti i dati dalla tabella e utilizzando fetchall() sull'oggetto cursore memorizzeremo l'elenco delle tuple contenenti i dati della tabella nella sua interezza in una variabile -

print("Dumping {} tables to CSV files in {}".format(len(tables), out_directory))

for table in tables:
c.execute("pragma table_info('{}')".format(table))
table_columns = [x[1] for x in c.fetchall()]

c.execute("select * from '{}'".format(table))
table_data = c.fetchall()

Ora, usando CSV_Writer() metodo scriveremo il contenuto nel file CSV -

csv_name = table + '.csv'
csv_path = os.path.join(out_directory, csv_name)
print('[+] Writing {} table to {} CSV file'.format(table,csv_name))

with open(csv_path, "w", newline = "") as csvfile:
   csv_writer = csv.writer(csvfile)
   csv_writer.writerow(table_columns)
   csv_writer.writerows(table_data)

Lo script sopra recupererà tutti i dati dalle tabelle del database IEF e scriverà il contenuto nel file CSV di nostra scelta.

Lavorare con i dati memorizzati nella cache

Dal database dei risultati di IEF, possiamo recuperare più informazioni che non sono necessariamente supportate da IEF stesso. Possiamo recuperare i dati memorizzati nella cache, un prodotto bi per informazioni, da provider di servizi di posta elettronica come Yahoo, Google, ecc. Utilizzando il database dei risultati IEF.

Di seguito è riportato lo script Python per accedere alle informazioni sui dati memorizzati nella cache da Yahoo Mail, accessibile su Google Chrome, utilizzando il database IEF. Nota che i passaggi sarebbero più o meno gli stessi seguiti nell'ultimo script Python.

Innanzitutto, importa le librerie necessarie per Python come segue:

from __future__ import print_function
import argparse
import csv
import os
import sqlite3
import sys
import json

Ora, fornisci il percorso del file di database IEF insieme a due argomenti posizionali accettati dal gestore della riga di comando come fatto nell'ultimo script -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('IEF to CSV')
   parser.add_argument("IEF_DATABASE", help="Input IEF database")
   parser.add_argument("OUTPUT_DIR", help="Output DIR")
   args = parser.parse_args()

Ora, conferma l'esistenza del database IEF come segue:

directory = os.path.dirname(args.OUTPUT_CSV)

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

Ora, effettua la connessione con il database SQLite come segue per eseguire le query tramite il cursore:

def main(database, out_csv):
   print("[+] Connecting to SQLite database")
   conn = sqlite3.connect(database)
   c = conn.cursor()

Puoi utilizzare le seguenti righe di codice per recuperare le istanze del record della cache dei contatti di Yahoo Mail:

print("Querying IEF database for Yahoo Contact Fragments from " "the Chrome Cache Records Table")
   try:
      c.execute("select * from 'Chrome Cache Records' where URL like " "'https://data.mail.yahoo.com" "/classicab/v2/contacts/?format=json%'")
   except sqlite3.OperationalError:
      print("Received an error querying the database --    database may be" "corrupt or not have a Chrome Cache Records table")
      sys.exit(2)

Ora, l'elenco delle tuple restituite dalla query precedente per essere salvato in una variabile come segue:

contact_cache = c.fetchall()
contact_data = process_contacts(contact_cache)
write_csv(contact_data, out_csv)

Nota che qui useremo due metodi vale a dire process_contacts() per impostare l'elenco dei risultati e scorrere ogni record della cache dei contatti e json.loads() per memorizzare i dati JSON estratti dalla tabella in una variabile per ulteriori manipolazioni -

def process_contacts(contact_cache):
   print("[+] Processing {} cache files matching Yahoo contact cache " " data".format(len(contact_cache)))
   results = []
   
   for contact in contact_cache:
      url = contact[0]
      first_visit = contact[1]
      last_visit = contact[2]
      last_sync = contact[3]
      loc = contact[8]
	   contact_json = json.loads(contact[7].decode())
      total_contacts = contact_json["total"]
      total_count = contact_json["count"]
      
      if "contacts" not in contact_json:
         continue
      for c in contact_json["contacts"]:
         name, anni, bday, emails, phones, links = ("", "", "", "", "", "")
            if "name" in c:
            name = c["name"]["givenName"] + " " + \ c["name"]["middleName"] + " " + c["name"]["familyName"]
            
            if "anniversary" in c:
            anni = c["anniversary"]["month"] + \"/" + c["anniversary"]["day"] + "/" + \c["anniversary"]["year"]
            
            if "birthday" in c:
            bday = c["birthday"]["month"] + "/" + \c["birthday"]["day"] + "/" + c["birthday"]["year"]
            
            if "emails" in c:
               emails = ', '.join([x["ep"] for x in c["emails"]])
            
            if "phones" in c:
               phones = ', '.join([x["ep"] for x in c["phones"]])
            
            if "links" in c:
              links = ', '.join([x["ep"] for x in c["links"]])

Ora per azienda, titolo e note, viene utilizzato il metodo get come mostrato di seguito:

company = c.get("company", "")
title = c.get("jobTitle", "")
notes = c.get("notes", "")

Ora, aggiungiamo l'elenco dei metadati e degli elementi di dati estratti all'elenco dei risultati come segue:

results.append([url, first_visit, last_visit, last_sync, loc, name, bday,anni, emails, phones, links, company, title, notes,total_contacts, total_count])
return results

Ora, usando CSV_Writer() metodo, scriveremo il contenuto nel file CSV -

def write_csv(data, output):
   print("[+] Writing {} contacts to {}".format(len(data), output))
   with open(output, "w", newline="") as csvfile:
      csv_writer = csv.writer(csvfile)
      csv_writer.writerow([
         "URL", "First Visit (UTC)", "Last Visit (UTC)",
         "Last Sync (UTC)", "Location", "Contact Name", "Bday",
         "Anniversary", "Emails", "Phones", "Links", "Company", "Title",
         "Notes", "Total Contacts", "Count of Contacts in Cache"])
      csv_writer.writerows(data)

Con l'aiuto dello script precedente, possiamo elaborare i dati memorizzati nella cache da Yahoo mail utilizzando il database IEF.