Python Digital Network Forensics-I

บทนี้จะอธิบายพื้นฐานที่เกี่ยวข้องในการดำเนินการนิติเครือข่ายโดยใช้ Python

การทำความเข้าใจนิติเครือข่าย

นิติเครือข่ายเป็นสาขาหนึ่งของนิติดิจิทัลที่เกี่ยวข้องกับการตรวจสอบและวิเคราะห์การรับส่งข้อมูลเครือข่ายคอมพิวเตอร์ทั้งในพื้นที่และ WAN (เครือข่ายบริเวณกว้าง) เพื่อวัตถุประสงค์ในการรวบรวมข้อมูลการรวบรวมหลักฐานหรือการตรวจจับการบุกรุก นิติเครือข่ายมีบทบาทสำคัญในการตรวจสอบอาชญากรรมดิจิทัลเช่นการขโมยทรัพย์สินทางปัญญาหรือการรั่วไหลของข้อมูล ภาพของการสื่อสารบนเครือข่ายช่วยให้ผู้ตรวจสอบสามารถแก้คำถามที่สำคัญได้ดังต่อไปนี้ -

  • เข้าเว็บไซต์อะไรบ้าง

  • มีการอัปโหลดเนื้อหาประเภทใดในเครือข่ายของเรา

  • มีการดาวน์โหลดเนื้อหาประเภทใดจากเครือข่ายของเรา

  • มีการเข้าถึงเซิร์ฟเวอร์ใดบ้าง

  • มีใครส่งข้อมูลที่ละเอียดอ่อนออกไปนอกไฟร์วอลล์ของ บริษัท หรือไม่

Internet Evidence Finder (IEF)

IEF เป็นเครื่องมือทางนิติวิทยาศาสตร์ดิจิทัลในการค้นหาวิเคราะห์และนำเสนอหลักฐานดิจิทัลที่พบในสื่อดิจิทัลต่างๆเช่นคอมพิวเตอร์สมาร์ทโฟนแท็บเล็ตเป็นต้นเป็นที่นิยมและใช้โดยผู้เชี่ยวชาญด้านนิติเวชหลายพันคน

การใช้ IEF

เนื่องจากความนิยม IEF จึงถูกใช้โดยผู้เชี่ยวชาญด้านนิติเวชในระดับมาก การใช้ IEF บางส่วนมีดังนี้ -

  • เนื่องจากความสามารถในการค้นหาที่มีประสิทธิภาพจึงใช้เพื่อค้นหาไฟล์หรือสื่อข้อมูลหลาย ๆ ไฟล์พร้อมกัน

  • นอกจากนี้ยังใช้เพื่อกู้คืนข้อมูลที่ถูกลบจากพื้นที่ว่างที่ไม่ได้จัดสรรของ RAM ผ่านเทคนิคการแกะสลักใหม่

  • หากผู้ตรวจสอบต้องการสร้างหน้าเว็บใหม่ในรูปแบบเดิมในวันที่เปิดก็สามารถใช้ IEF ได้

  • นอกจากนี้ยังใช้เพื่อค้นหาโลจิคัลดิสก์หรือฟิสิคัลวอลุ่ม

การทิ้งรายงานจาก IEF เป็น CSV โดยใช้ Python

IEF จัดเก็บข้อมูลในฐานข้อมูล SQLite และตามสคริปต์ Python จะระบุตารางผลลัพธ์แบบไดนามิกภายในฐานข้อมูล IEF และถ่ายโอนข้อมูลไปยังไฟล์ CSV ที่เกี่ยวข้อง

ขั้นตอนนี้ทำได้ตามขั้นตอนที่แสดงด้านล่าง

  • ก่อนอื่นให้สร้างฐานข้อมูลผลลัพธ์ IEF ซึ่งจะเป็นไฟล์ฐานข้อมูล SQLite ที่ลงท้ายด้วยนามสกุล. db

  • จากนั้นค้นหาฐานข้อมูลนั้นเพื่อระบุตารางทั้งหมด

  • สุดท้ายเขียนตารางผลลัพธ์นี้ลงในไฟล์ 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 ไม่จำเป็นต้องรองรับ เราสามารถดึงข้อมูลแคชผลิตภัณฑ์ bi สำหรับข้อมูลจากผู้ให้บริการอีเมลเช่น Yahoo, Google ฯลฯ โดยใช้ฐานข้อมูลผลลัพธ์ IEF

ต่อไปนี้เป็นสคริปต์ Python สำหรับเข้าถึงข้อมูลแคชจาก Yahoo mail ซึ่งเข้าถึงได้จาก Google Chrome โดยใช้ฐานข้อมูล IEF โปรดทราบว่าขั้นตอนต่างๆจะมากหรือน้อยเหมือนกับที่ทำตามในสคริปต์ 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"]])

ตอนนี้สำหรับ บริษัท ชื่อและบันทึกจะใช้วิธีการรับดังที่แสดงด้านล่าง -

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)

ด้วยความช่วยเหลือของสคริปต์ข้างต้นเราสามารถประมวลผลข้อมูลแคชจาก Yahoo mail โดยใช้ฐานข้อมูล IEF