Python Digital Network Forensics-I

In diesem Kapitel werden die Grundlagen für die Durchführung der Netzwerkforensik mit Python erläutert.

Grundlegendes zur Netzwerkforensik

Die Netzwerkforensik ist ein Zweig der digitalen Forensik, der sich mit der Überwachung und Analyse des lokalen und des WAN-Netzwerks (Wide Area Network) zum Zwecke der Informationserfassung, Beweiserfassung oder Erkennung von Eindringlingen befasst. Netzwerkforensik spielt eine entscheidende Rolle bei der Untersuchung digitaler Verbrechen wie Diebstahl von geistigem Eigentum oder Informationsverlust. Ein Bild der Netzwerkkommunikation hilft einem Ermittler, einige wichtige Fragen wie folgt zu lösen:

  • Auf welche Websites wurde zugegriffen?

  • Welche Art von Inhalten wurde in unser Netzwerk hochgeladen?

  • Welche Art von Inhalten wurde von unserem Netzwerk heruntergeladen?

  • Auf welche Server wird zugegriffen?

  • Sendet jemand vertrauliche Informationen außerhalb der Firewalls des Unternehmens?

Internet Evidence Finder (IEF)

IEF ist ein digitales forensisches Tool zum Auffinden, Analysieren und Präsentieren digitaler Beweise, die auf verschiedenen digitalen Medien wie Computern, Smartphones, Tablets usw. gefunden wurden. Es ist sehr beliebt und wird von Tausenden von Forensikern verwendet.

Verwendung von IEF

Aufgrund seiner Beliebtheit wird IEF in großem Umfang von Forensikern eingesetzt. Einige der Verwendungszwecke von IEF sind wie folgt:

  • Aufgrund seiner leistungsstarken Suchfunktionen werden mehrere Dateien oder Datenmedien gleichzeitig durchsucht.

  • Es wird auch verwendet, um gelöschte Daten aus dem nicht zugewiesenen RAM-Speicher durch neue Carving-Techniken wiederherzustellen.

  • Wenn Ermittler Webseiten zum Zeitpunkt ihrer Eröffnung in ihrem ursprünglichen Format neu erstellen möchten, können sie IEF verwenden.

  • Es wird auch zum Durchsuchen logischer oder physischer Datenträger verwendet.

Dumping von Berichten von IEF zu CSV mit Python

IEF speichert Daten in einer SQLite-Datenbank. Das folgende Python-Skript identifiziert die Ergebnistabellen in der IEF-Datenbank dynamisch und speichert sie in den entsprechenden CSV-Dateien.

Dieser Vorgang wird in den unten gezeigten Schritten ausgeführt

  • Generieren Sie zunächst eine IEF-Ergebnisdatenbank, bei der es sich um eine SQLite-Datenbankdatei handelt, die mit der Erweiterung .db endet.

  • Fragen Sie dann diese Datenbank ab, um alle Tabellen zu identifizieren.

  • Zuletzt schreiben Sie diese Ergebnistabellen in eine einzelne CSV-Datei.

Python-Code

Lassen Sie uns sehen, wie Python-Code für diesen Zweck verwendet wird -

Importieren Sie für Python-Skripte die erforderlichen Bibliotheken wie folgt:

from __future__ import print_function

import argparse
import csv
import os
import sqlite3
import sys

Jetzt müssen wir den Pfad zur IEF-Datenbankdatei angeben -

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

Nun werden wir die Existenz der IEF-Datenbank wie folgt bestätigen:

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)

Stellen Sie nun wie in früheren Skripten die Verbindung zur SQLite-Datenbank wie folgt her, um die Abfragen über den Cursor auszuführen:

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

Die folgenden Codezeilen rufen die Namen der Tabellen aus der Datenbank ab -

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')]

Jetzt werden wir alle Daten aus der Tabelle auswählen und verwenden fetchall() Methode auf dem Cursor-Objekt speichern wir die Liste der Tupel, die die Daten der Tabelle in ihrer Gesamtheit enthalten, in einer Variablen -

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

Jetzt mit CSV_Writer() Methode werden wir den Inhalt in CSV-Datei schreiben -

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)

Das obige Skript ruft alle Daten aus Tabellen der IEF-Datenbank ab und schreibt den Inhalt in die CSV-Datei unserer Wahl.

Arbeiten mit zwischengespeicherten Daten

Aus der IEF-Ergebnisdatenbank können wir weitere Informationen abrufen, die nicht unbedingt von IEF selbst unterstützt werden. Mithilfe der IEF-Ergebnisdatenbank können wir die zwischengespeicherten Daten, ein Bi-Produkt zur Information, von E-Mail-Dienstanbietern wie Yahoo, Google usw. abrufen.

Das folgende Python-Skript ermöglicht den Zugriff auf die zwischengespeicherten Dateninformationen aus Yahoo Mail, auf die über Google Chrome zugegriffen wird, mithilfe der IEF-Datenbank. Beachten Sie, dass die Schritte mehr oder weniger den im letzten Python-Skript beschriebenen entsprechen.

Importieren Sie zunächst die erforderlichen Bibliotheken für Python wie folgt:

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

Geben Sie nun den Pfad zur IEF-Datenbankdatei zusammen mit zwei Positionsargumenten an, die vom Befehlszeilenhandler akzeptiert werden, wie im letzten Skript ausgeführt.

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

Bestätigen Sie nun die Existenz der IEF-Datenbank wie folgt:

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)

Stellen Sie nun die Verbindung mit der SQLite-Datenbank wie folgt her, um die Abfragen über den Cursor auszuführen:

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

Sie können die folgenden Codezeilen verwenden, um die Instanzen des Yahoo Mail-Kontaktcache-Datensatzes abzurufen:

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)

Nun wird die Liste der von der obigen Abfrage zurückgegebenen Tupel wie folgt in einer Variablen gespeichert:

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

Beachten Sie, dass wir hier nämlich zwei Methoden verwenden werden process_contacts() zum Einrichten der Ergebnisliste sowie zum Durchlaufen jedes Kontakt-Cache-Datensatzes und json.loads() um die aus der Tabelle extrahierten JSON-Daten zur weiteren Bearbeitung in einer Variablen zu speichern -

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"]])

Für Firma, Titel und Notizen wird nun die get-Methode wie unten gezeigt verwendet -

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

Fügen wir nun die Liste der Metadaten und extrahierten Datenelemente wie folgt an die Ergebnisliste an:

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

Jetzt mit CSV_Writer() Methode werden wir den Inhalt in CSV-Datei schreiben -

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)

Mit Hilfe des obigen Skripts können wir die zwischengespeicherten Daten aus Yahoo Mail mithilfe der IEF-Datenbank verarbeiten.