Python数字网络取证-I

本章将解释使用Python执行网络取证所涉及的基本原理.

了解网络取证

网络取证是数字取证的一个分支它用于监控和分析本地和广域网(广域网)的计算机网络流量,用于信息收集,证据收集或入侵检测.网络取证在调查诸如盗窃知识产权或信息泄露等数字犯罪方面发挥着关键作用.网络通信的图片有助于调查人员解决一些关键问题,如下所示;

  • 访问了哪些网站?

  • 我们的网络上传了哪些内容?

  • 什么样的内容已从我们的网络下载?

  • 正在访问哪些服务器?

  • 是有人在公司防火墙外发送敏感信息吗?

Internet Evidence Finder(IEF)

IEF是一种数字取证工具,用于查找,分析和呈现在计算机,智能手机,平板电脑等不同数字媒体上发现的数字证据.它非常受欢迎,并被成千上万的法医专业人员使用.

使用IEF

由于受欢迎程度,IEF在很大程度上被法医专业人士使用. IEF的一些用法如下:<

  • 由于其强大的搜索功能,它用于搜索多个文件或数据媒体同时发生.

  • 它还用于通过新的雕刻技术从未分配的RAM空间中恢复已删除的数据.

  • 如果调查人员希望在打开日期以原始格式重建网页,那么他们就可以使用IEF.

  • 它还用于搜索逻辑或物理磁盘卷.

使用Python将报告从IEF转储到CSV

IEF将数据存储在SQLite数据库中,以下Python脚本将动态识别IEF数据库中的结果表并将其转储到相应的CSV文件中.

此过程已完成在下面显示的步骤中

  • 首先,生成IEF结果数据库,该数据库将是以.db扩展名结尾的SQLite数据库文件.

  • 然后,查询该数据库以识别所有表.

  • 最后,将此结果表写入个人CSV文件.

Python代码

让我们看看如何将Python代码用于此目的 :

对于Python脚本,导入必要的库,如下所示;

from __future__ import print_function

import argparse
import csv
import os
import sqlite3
import sys

现在,我们需要提供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()

现在,我们将确认IEF数据库是否存在ows :

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)

现在,正如我们在早期脚本中所做的那样,按照以下方式与SQLite数据库建立连接,通过游标 : 执行查询;

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

以下代码行将从数据库中获取表的名称 :

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

现在,我们将从表中选择所有数据并使用 fetchall()方法我们将把游标包含表格数据的元组列表存储在一个变量 :

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

现在,通过使用 CSV_Writer()方法,我们将编写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)

上面的脚本将从IEF数据库的表中获取所有数据,并将内容写入我们选择的CSV文件.

使用缓存数据

从IEF结果数据库中,我们可以获取IEF本身不一定支持的更多信息.我们可以使用IEF结果数据库从Yahoo,Google等电子邮件服务提供商那里获取缓存数据,这是一种信息的双向产品.

以下是用于访问缓存的Python脚本来自Yahoo邮件的数据信息,通过使用IEF数据库在Google Chrome上访问.请注意,这些步骤与上一个Python脚本中的步骤大致相同.

首先,为Python导入必要的库,如下所示;

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

现在,提供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()

现在,确认IEF数据库的存在如下 :

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)

现在,按如下方式与SQLite数据库建立连接,通过游标和减号执行查询;

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

您可以使用以下代码行来获取Yahoo的实例邮件联系人缓存记录 :

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)

现在,从上面的查询返回的元组列表将保存到变量中,如下所示 :

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

注意,这里我们将使用两种方法即 process_contacts()用于设置结果列表以及遍历每个联系人缓存记录和 json.loads()以将从表中提取的JSON数据存储到变量用于进一步操作 : 去;

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

现在对于公司,标题和注释,使用get方法如下所示 :

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

现在,让我们将元数据列表和提取的数据元素附加到结果中列表如下 :

 
 results.append([url,first_visit,last_visit,last_sync,loc,name,bday,anni,email,phones,links,company,title,notes,total_contacts,total_count])
返回结果

现在,通过使用 CSV_Writer()方法,我们将内容写入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)

借助上述脚本,我们可以通过u处理来自Yahoo邮箱的缓存数据唱IEF数据库.