Python 디지털 네트워크 포렌식 -I

이 장에서는 Python을 사용하여 네트워크 포렌식을 수행하는 데 관련된 기본 사항을 설명합니다.

네트워크 포렌식 이해

네트워크 포렌식은 정보 수집, 증거 수집 또는 침입 탐지를 위해 로컬 및 WAN (광역 네트워크)의 컴퓨터 네트워크 트래픽을 모니터링하고 분석하는 디지털 포렌식의 한 분야입니다. 네트워크 포렌식은 지적 재산의 도난이나 정보 유출과 같은 디지털 범죄를 조사하는 데 중요한 역할을합니다. 네트워크 통신 그림은 조사자가 다음과 같은 몇 가지 중요한 질문을 해결하는 데 도움이됩니다.

  • 어떤 웹 사이트에 액세스 했습니까?

  • 네트워크에 어떤 종류의 콘텐츠가 업로드 되었습니까?

  • 네트워크에서 어떤 종류의 콘텐츠를 다운로드 했습니까?

  • 어떤 서버에 액세스하고 있습니까?

  • 누군가 회사 방화벽 외부로 민감한 정보를 보내고 있습니까?

Internet Evidence Finder (IEF)

IEF는 컴퓨터, 스마트 폰, 태블릿 등과 같은 다양한 디지털 미디어에서 발견 된 디지털 증거를 찾고, 분석하고, 제시하는 디지털 포렌식 도구입니다. 수천 명의 포렌식 전문가가 매우 유명하고 사용합니다.

IEF 사용

인기로 인해 IEF는 법의학 전문가가 많이 사용합니다. IEF의 일부 용도는 다음과 같습니다.

  • 강력한 검색 기능으로 인해 여러 파일 또는 데이터 미디어를 동시에 검색하는 데 사용됩니다.

  • 또한 새로운 조각 기술을 통해 RAM의 할당되지 않은 공간에서 삭제 된 데이터를 복구하는 데 사용됩니다.

  • 조사관이 웹 페이지를 연 날짜에 원래 형식으로 다시 만들고 싶다면 IEF를 사용할 수 있습니다.

  • 논리 또는 물리 디스크 볼륨을 검색하는데도 사용됩니다.

Python을 사용하여 IEF에서 CSV로 보고서 덤프

IEF는 SQLite 데이터베이스에 데이터를 저장하고 다음 Python 스크립트는 IEF 데이터베이스 내에서 결과 테이블을 동적으로 식별하고 각 CSV 파일에 덤프합니다.

이 프로세스는 아래 표시된 단계에서 수행됩니다.

  • 먼저 .db 확장자로 끝나는 SQLite 데이터베이스 파일이 될 IEF 결과 데이터베이스를 생성합니다.

  • 그런 다음 해당 데이터베이스를 쿼리하여 모든 테이블을 식별합니다.

  • 마지막으로이 결과 테이블을 개별 CSV 파일에 기록합니다.

파이썬 코드

이 목적으로 파이썬 코드를 사용하는 방법을 살펴 보겠습니다.

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에서 액세스 한 Yahoo 메일에서 캐시 된 데이터 정보에 액세스하기위한 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()

당신은 야후 메일 연락처 캐시 레코드의 인스턴스를 가져 오기 위해 다음 코드 줄을 사용할 수 있습니다-

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 메일에서 캐시 된 데이터를 처리 할 수 ​​있습니다.