Python Digital Network Forensics-I
Chương này sẽ giải thích các nguyên tắc cơ bản liên quan đến việc thực hiện pháp y mạng bằng Python.
Hiểu về pháp y mạng
Pháp y mạng là một nhánh của pháp y kỹ thuật số đề cập đến việc giám sát và phân tích lưu lượng mạng máy tính, cả cục bộ và WAN (mạng diện rộng), nhằm mục đích thu thập thông tin, thu thập bằng chứng hoặc phát hiện xâm nhập. Pháp y mạng đóng một vai trò quan trọng trong việc điều tra tội phạm kỹ thuật số như trộm cắp tài sản trí tuệ hoặc rò rỉ thông tin. Hình ảnh về truyền thông mạng giúp điều tra viên giải quyết một số câu hỏi quan trọng như sau:
Những trang web nào đã được truy cập?
Loại nội dung nào đã được tải lên trên mạng của chúng tôi?
Loại nội dung nào đã được tải xuống từ mạng của chúng tôi?
Những máy chủ nào đang được truy cập?
Có ai đó đang gửi thông tin nhạy cảm bên ngoài tường lửa của công ty không?
Công cụ tìm bằng chứng Internet (IEF)
IEF là một công cụ pháp y kỹ thuật số để tìm, phân tích và trình bày bằng chứng kỹ thuật số được tìm thấy trên các phương tiện kỹ thuật số khác nhau như máy tính, điện thoại thông minh, máy tính bảng, v.v. Nó rất phổ biến và được sử dụng bởi hàng nghìn chuyên gia pháp y.
Sử dụng IEF
Do tính phổ biến của nó, IEF được các chuyên gia pháp y sử dụng ở mức độ lớn. Một số công dụng của IEF như sau:
Do khả năng tìm kiếm mạnh mẽ, nó được sử dụng để tìm kiếm đồng thời nhiều tệp hoặc phương tiện dữ liệu.
Nó cũng được sử dụng để khôi phục dữ liệu đã xóa từ không gian chưa được phân bổ của RAM thông qua các kỹ thuật khắc mới.
Nếu các nhà điều tra muốn xây dựng lại các trang web ở định dạng ban đầu của chúng vào ngày chúng được mở, thì họ có thể sử dụng IEF.
Nó cũng được sử dụng để tìm kiếm khối lượng đĩa logic hoặc vật lý.
Bán báo cáo từ IEF sang CSV bằng Python
IEF lưu trữ dữ liệu trong cơ sở dữ liệu SQLite và sau tập lệnh Python sẽ tự động xác định các bảng kết quả trong cơ sở dữ liệu IEF và kết xuất chúng vào các tệp CSV tương ứng.
Quá trình này được thực hiện theo các bước hiển thị bên dưới
Đầu tiên, tạo cơ sở dữ liệu kết quả IEF sẽ là tệp cơ sở dữ liệu SQLite kết thúc bằng phần mở rộng .db.
Sau đó, truy vấn cơ sở dữ liệu đó để xác định tất cả các bảng.
Cuối cùng, ghi bảng kết quả này vào một tệp CSV riêng lẻ.
Mã Python
Hãy để chúng tôi xem cách sử dụng mã Python cho mục đích này -
Đối với tập lệnh Python, hãy nhập các thư viện cần thiết như sau:
from __future__ import print_function
import argparse
import csv
import os
import sqlite3
import sys
Bây giờ, chúng ta cần cung cấp đường dẫn đến tệp cơ sở dữ liệu 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()
Bây giờ, chúng tôi sẽ xác nhận sự tồn tại của cơ sở dữ liệu IEF như sau:
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)
Bây giờ, như chúng ta đã làm trong các tập lệnh trước đó, hãy tạo kết nối với cơ sở dữ liệu SQLite như sau để thực thi các truy vấn thông qua con trỏ:
def main(database, out_directory):
print("[+] Connecting to SQLite database")
conn = sqlite3.connect(database)
c = conn.cursor()
Các dòng mã sau đây sẽ lấy tên của các bảng từ cơ sở dữ liệu:
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')]
Bây giờ, chúng tôi sẽ chọn tất cả dữ liệu từ bảng và bằng cách sử dụng fetchall() trên đối tượng con trỏ, chúng tôi sẽ lưu trữ danh sách các bộ giá trị chứa toàn bộ dữ liệu của bảng trong một biến -
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()
Bây giờ, bằng cách sử dụng CSV_Writer() chúng tôi sẽ viết nội dung trong tệp 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)
Tập lệnh trên sẽ tìm nạp tất cả dữ liệu từ các bảng của cơ sở dữ liệu IEF và ghi nội dung vào tệp CSV mà chúng tôi chọn.
Làm việc với dữ liệu được lưu trong bộ nhớ đệm
Từ cơ sở dữ liệu kết quả của IEF, chúng tôi có thể tìm nạp thêm thông tin không nhất thiết phải được hỗ trợ bởi chính IEF. Chúng tôi có thể tìm nạp dữ liệu đã lưu trong bộ nhớ cache, một sản phẩm bi để biết thông tin, từ nhà cung cấp dịch vụ email như Yahoo, Google, v.v. bằng cách sử dụng cơ sở dữ liệu kết quả IEF.
Sau đây là tập lệnh Python để truy cập thông tin dữ liệu được lưu trong bộ nhớ cache từ Yahoo mail, được truy cập trên Google Chrome, bằng cách sử dụng cơ sở dữ liệu IEF. Lưu ý rằng các bước sẽ giống hoặc ít hơn như sau trong tập lệnh Python cuối cùng.
Đầu tiên, nhập các thư viện cần thiết cho Python như sau:
from __future__ import print_function
import argparse
import csv
import os
import sqlite3
import sys
import json
Bây giờ, cung cấp đường dẫn đến tệp cơ sở dữ liệu IEF cùng với hai đối số vị trí được trình xử lý dòng lệnh chấp nhận như được thực hiện trong tập lệnh cuối cùng -
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()
Bây giờ, xác nhận sự tồn tại của cơ sở dữ liệu IEF như sau:
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)
Bây giờ, tạo kết nối với cơ sở dữ liệu SQLite như sau để thực hiện các truy vấn thông qua con trỏ -
def main(database, out_csv):
print("[+] Connecting to SQLite database")
conn = sqlite3.connect(database)
c = conn.cursor()
Bạn có thể sử dụng các dòng mã sau để tìm nạp các phiên bản của bản ghi bộ nhớ cache liên hệ 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)
Bây giờ, danh sách các bộ giá trị được trả về từ truy vấn trên sẽ được lưu vào một biến như sau:
contact_cache = c.fetchall()
contact_data = process_contacts(contact_cache)
write_csv(contact_data, out_csv)
Lưu ý rằng ở đây chúng tôi sẽ sử dụng hai phương pháp cụ thể là process_contacts() để thiết lập danh sách kết quả cũng như lặp qua từng bản ghi bộ nhớ đệm liên hệ và json.loads() để lưu trữ dữ liệu JSON được trích xuất từ bảng thành một biến để thao tác thêm -
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"]])
Bây giờ đối với công ty, tiêu đề và ghi chú, phương thức get được sử dụng như hình dưới đây:
company = c.get("company", "")
title = c.get("jobTitle", "")
notes = c.get("notes", "")
Bây giờ, chúng ta hãy nối danh sách siêu dữ liệu và các phần tử dữ liệu được trích xuất vào danh sách kết quả như sau:
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
Bây giờ, bằng cách sử dụng CSV_Writer() , chúng tôi sẽ viết nội dung trong tệp 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)
Với sự trợ giúp của script trên, chúng ta có thể xử lý dữ liệu đã lưu trong bộ đệm từ Yahoo mail bằng cách sử dụng cơ sở dữ liệu IEF.