Python Digital Network Forensics-I

Ce chapitre expliquera les principes de base impliqués dans la réalisation d'investigations réseau à l'aide de Python.

Comprendre la criminalistique réseau

La criminalistique réseau est une branche de la criminalistique numérique qui traite de la surveillance et de l'analyse du trafic du réseau informatique, à la fois local et WAN (réseau étendu), à des fins de collecte d'informations, de collecte de preuves ou de détection d'intrusions. La criminalistique des réseaux joue un rôle essentiel dans les enquêtes sur les crimes numériques tels que le vol de propriété intellectuelle ou la fuite d'informations. Une image des communications réseau aide un enquêteur à résoudre certaines questions cruciales comme suit -

  • Quels sites Web ont été consultés?

  • Quel type de contenu a été téléchargé sur notre réseau?

  • Quel type de contenu a été téléchargé depuis notre réseau?

  • À quels serveurs accède-t-on?

  • Quelqu'un envoie-t-il des informations sensibles en dehors des pare-feu de l'entreprise?

Internet Evidence Finder (IEF)

IEF est un outil médico-légal numérique pour trouver, analyser et présenter des preuves numériques trouvées sur différents supports numériques comme l'ordinateur, les smartphones, les tablettes, etc. Il est très populaire et utilisé par des milliers de professionnels de la médecine légale.

Utilisation d'IEF

En raison de sa popularité, IEF est utilisé dans une large mesure par les professionnels de la médecine légale. Certaines des utilisations de l'IEF sont les suivantes -

  • En raison de ses puissantes capacités de recherche, il est utilisé pour rechercher simultanément plusieurs fichiers ou supports de données.

  • Il est également utilisé pour récupérer des données supprimées de l'espace non alloué de la RAM grâce à de nouvelles techniques de sculpture.

  • Si les enquêteurs souhaitent reconstruire des pages Web dans leur format d'origine à la date à laquelle elles ont été ouvertes, ils peuvent utiliser IEF.

  • Il est également utilisé pour rechercher des volumes de disque logiques ou physiques.

Dumping des rapports d'IEF vers CSV à l'aide de Python

IEF stocke les données dans une base de données SQLite et le script Python suivant identifiera dynamiquement les tables de résultats dans la base de données IEF et les videra dans les fichiers CSV respectifs.

Ce processus se fait selon les étapes ci-dessous

  • Tout d'abord, générez la base de données de résultats IEF qui sera un fichier de base de données SQLite se terminant par l'extension .db.

  • Ensuite, interrogez cette base de données pour identifier toutes les tables.

  • Enfin, écrivez ces tableaux de résultats dans un fichier CSV individuel.

Code Python

Voyons comment utiliser le code Python à cette fin -

Pour le script Python, importez les bibliothèques nécessaires comme suit -

from __future__ import print_function

import argparse
import csv
import os
import sqlite3
import sys

Maintenant, nous devons fournir le chemin d'accès au fichier de base de données 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()

Maintenant, nous allons confirmer l'existence de la base de données IEF comme suit -

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)

Maintenant, comme nous l'avons fait dans les scripts précédents, établissez la connexion avec la base de données SQLite comme suit pour exécuter les requêtes via le curseur -

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

Les lignes de code suivantes chercheront les noms des tables de la base de données -

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

Maintenant, nous allons sélectionner toutes les données du tableau et en utilisant fetchall() méthode sur l'objet curseur, nous allons stocker la liste des tuples contenant les données de la table dans son intégralité dans une variable -

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

Maintenant, en utilisant CSV_Writer() méthode nous allons écrire le contenu dans un fichier 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)

Le script ci-dessus récupérera toutes les données des tables de la base de données IEF et écrira le contenu dans le fichier CSV de notre choix.

Travailler avec des données mises en cache

À partir de la base de données de résultats IEF, nous pouvons récupérer plus d'informations qui ne sont pas nécessairement prises en charge par IEF lui-même. Nous pouvons récupérer les données en cache, un produit bi pour information, auprès d'un fournisseur de services de messagerie comme Yahoo, Google, etc. en utilisant la base de données de résultats IEF.

Ce qui suit est le script Python pour accéder aux informations de données mises en cache à partir de Yahoo mail, accessible sur Google Chrome, à l'aide de la base de données IEF. Notez que les étapes seraient plus ou moins les mêmes que celles suivies dans le dernier script Python.

Tout d'abord, importez les bibliothèques nécessaires pour Python comme suit -

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

Maintenant, fournissez le chemin d'accès au fichier de base de données IEF avec deux arguments de position acceptés par le gestionnaire de ligne de commande comme cela a été fait dans le dernier 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()

Maintenant, confirmez l'existence de la base de données IEF comme suit -

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)

Maintenant, établissez la connexion avec la base de données SQLite comme suit pour exécuter les requêtes via le curseur -

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

Vous pouvez utiliser les lignes de code suivantes pour récupérer les instances de l'enregistrement de cache de contacts 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)

Maintenant, la liste des tuples renvoyés par la requête ci-dessus à enregistrer dans une variable comme suit -

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

Notez qu'ici nous utiliserons deux méthodes à savoir process_contacts() pour configurer la liste de résultats ainsi que pour parcourir chaque enregistrement de cache de contact et json.loads() pour stocker les données JSON extraites de la table dans une variable pour une manipulation ultérieure -

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

Maintenant, pour la société, le titre et les notes, la méthode get est utilisée comme indiqué ci-dessous -

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

Maintenant, ajoutons la liste des métadonnées et des éléments de données extraits à la liste de résultats comme suit -

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

Maintenant, en utilisant CSV_Writer() méthode, nous écrirons le contenu dans un fichier 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)

Avec l'aide du script ci-dessus, nous pouvons traiter les données en cache de Yahoo mail en utilisant la base de données IEF.