Python数字网络取证-I
本章将解释使用 Python 执行网络取证所涉及的基础知识。
了解网络取证
网络取证是数字取证的一个分支,它处理本地和 WAN(广域网)计算机网络流量的监控和分析,以达到信息收集、证据收集或入侵检测的目的。网络取证在调查数字犯罪(例如盗窃知识产权或信息泄露)方面发挥着至关重要的作用。网络通信的图片可以帮助调查人员解决以下一些关键问题 -
访问过哪些网站?
我们的网络上上传了哪些类型的内容?
从我们的网络下载了哪些内容?
正在访问哪些服务器?
有人在公司防火墙之外发送敏感信息吗?
互联网证据查找器 (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 数据库的存在,如下 -
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等电子邮件服务提供商处获取缓存数据,这是信息的双产品。
以下是使用 IEF 数据库从 Google Chrome 上访问雅虎邮件的缓存数据信息的 Python 脚本。请注意,这些步骤或多或少与上一个 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 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)
现在,从上面的查询返回的元组列表将保存到变量中,如下所示 -
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, emails, phones, links, company, title, notes,total_contacts, total_count]) return results
现在,通过使用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)
借助上述脚本,我们可以使用 IEF 数据库处理来自 Yahoo 邮件的缓存数据。