Python-digital-forensics-important-artifacts-in-microsoft-windows

提供:Dev Guides
移動先:案内検索

Windows-IIIの重要なアーティファクト

この章では、Windowsでのフォレンジック分析中に調査者が取得できるさらなる成果物について説明します。

イベントログ

Windowsイベントログファイルは、名前のとおり、ユーザーがコンピューターにログオンしたとき、プログラムでエラーが発生したとき、システムの変更、RDPアクセス、アプリケーション固有のイベントなどの重要なイベントを格納する特別なファイルです。 サイバー調査員は、システムのアクセスに関する多くの有用な履歴情報を提供するため、イベントログ情報に常に関心を持っています。 次のPythonスクリプトでは、従来のWindowsイベントログ形式と現在のWindowsイベントログ形式の両方を処理します。

Pythonスクリプトの場合、サードパーティのモジュール、つまり* pytsk3、pyewf、unicodecsv、pyevt、およびpyevt * xをインストールする必要があります。 イベントログから情報を抽出するには、以下に示す手順に従ってください-

  • まず、入力引数に一致するすべてのイベントログを検索します。
  • 次に、ファイル署名の検証を実行します。
  • 次に、見つかった各イベントログを適切なライブラリで処理します。
  • 最後に、出力をスプレッドシートに書き込みます。

Pythonコード

この目的のためにPythonコードを使用する方法を見てみましょう-

まず、次のPythonライブラリをインポートします-

from __future__ import print_function
import argparse
import unicodecsv as csv
import os
import pytsk3
import pyewf
import pyevt
import pyevtx
import sys
from utility.pytskutil import TSKUtil

次に、コマンドラインハンドラーの引数を指定します。 ここでは、3つの引数を受け入れることに注意してください。1つ目は証拠ファイルへのパス、2つ目は証拠ファイルのタイプ、3つ目は処理するイベントログの名前です。

if __name__ == "__main__":
   parser = argparse.ArgumentParser('Information from Event Logs')
   parser.add_argument("EVIDENCE_FILE", help = "Evidence file path")
   parser.add_argument("TYPE", help = "Type of Evidence",choices = ("raw", "ewf"))
   parser.add_argument(
      "LOG_NAME",help = "Event Log Name (SecEvent.Evt, SysEvent.Evt, ""etc.)")

   parser.add_argument(
      "-d", help = "Event log directory to scan",default = "/WINDOWS/SYSTEM32/WINEVT")

   parser.add_argument(
      "-f", help = "Enable fuzzy search for either evt or"" evtx extension", action = "store_true")
   args = parser.parse_args()

   if os.path.exists(args.EVIDENCE_FILE) and \ os.path.isfile(args.EVIDENCE_FILE):
      main(args.EVIDENCE_FILE, args.TYPE, args.LOG_NAME, args.d, args.f)
   else:
      print("[-] Supplied input file {} does not exist or is not a ""file".format(args.EVIDENCE_FILE))
   sys.exit(1)

次に、イベントログと対話して、 TSKUtil オブジェクトを作成することにより、ユーザーが指定したパスの存在を照会します。 それは次のように* main()*メソッドの助けを借りて行うことができます-

def main(evidence, image_type, log, win_event, fuzzy):
   tsk_util = TSKUtil(evidence, image_type)
   event_dir = tsk_util.query_directory(win_event)

   if event_dir is not None:
      if fuzzy is True:
         event_log = tsk_util.recurse_files(log, path=win_event)
   else:
      event_log = tsk_util.recurse_files(log, path=win_event, logic="equal")

   if event_log is not None:
      event_data = []
      for hit in event_log:
         event_file = hit[2]
         temp_evt = write_file(event_file)

今、私たちは現在のディレクトリにコンテンツ全体を書き込むメソッドを定義することによって署名検証を実行する必要があります-

def write_file(event_file):
   with open(event_file.info.name.name, "w") as outfile:
      outfile.write(event_file.read_random(0, event_file.info.meta.size))
   return event_file.info.name.name
      if pyevt.check_file_signature(temp_evt):
         evt_log = pyevt.open(temp_evt)
         print("[+] Identified {} records in {}".format(
            evt_log.number_of_records, temp_evt))

         for i, record in enumerate(evt_log.records):
            strings = ""
            for s in record.strings:
               if s is not None:
                  strings += s + "\n"
            event_data.append([
               i, hit[0], record.computer_name,
               record.user_security_identifier,
               record.creation_time, record.written_time,
               record.event_category, record.source_name,
               record.event_identifier, record.event_type,
               strings, "",
               os.path.join(win_event, hit[1].lstrip("//"))
            ])
      elif pyevtx.check_file_signature(temp_evt):
         evtx_log = pyevtx.open(temp_evt)
         print("[+] Identified {} records in {}".format(
            evtx_log.number_of_records, temp_evt))
         for i, record in enumerate(evtx_log.records):
            strings = ""
            for s in record.strings:
               if s is not None:
               strings += s + "\n"
         event_data.append([
            i, hit[0], record.computer_name,
            record.user_security_identifier, "",
            record.written_time, record.event_level,
            record.source_name, record.event_identifier,
            "", strings, record.xml_string,
            os.path.join(win_event, hit[1].lstrip("//"))
      ])
      else:
         print("[-] {} not a valid event log. Removing temp" file...".format(temp_evt))
         os.remove(temp_evt)
      continue
      write_output(event_data)
   else:
      print("[-] {} Event log not found in {} directory".format(log, win_event))
      sys.exit(3)
else:
   print("[-] Win XP Event Log Directory {} not found".format(win_event))
   sys.exit(2

最後に、次のようにスプレッドシートに出力を書き込む方法を定義します-

def write_output(data):
   output_name = "parsed_event_logs.csv"
   print("[+] Writing {} to current working directory: {}".format(
      output_name, os.getcwd()))

   with open(output_name, "wb") as outfile:
      writer = csv.writer(outfile)
      writer.writerow([
         "Index", "File name", "Computer Name", "SID",
         "Event Create Date", "Event Written Date",
         "Event Category/Level", "Event Source", "Event ID",
         "Event Type", "Data", "XML Data", "File Path"
      ])
      writer.writerows(data)

上記のスクリプトを正常に実行すると、スプレッドシートでイベントログの情報を取得します。

インターネットの歴史

インターネット履歴は、法医学アナリストにとって非常に役立ちます。ほとんどのサイバー犯罪はインターネット上でのみ発生するためです。 Windowsのフォレンジックについて説明しているように、Internet Explorerからインターネット履歴を抽出する方法を見てみましょう。InternetExplorerはデフォルトでWindowsに付属しています。

Internet Explorerでは、インターネット履歴は index.dat ファイルに保存されます。 index.dat ファイルから情報を抽出するPythonスクリプトを見てみましょう。

以下の手順に従って、 index.dat ファイルから情報を抽出できます-

  • 最初に、システム内で index.dat ファイルを検索します。
  • 次に、ファイルを反復処理して、そのファイルから情報を抽出します。
  • 次に、これらすべての情報をCSVレポートに書き込みます。

Pythonコード

この目的のためにPythonコードを使用する方法を見てみましょう-

まず、次のPythonライブラリをインポートします-

from __future__ import print_function
import argparse

from datetime import datetime, timedelta
import os
import pytsk3
import pyewf
import pymsiecf
import sys
import unicodecsv as csv

from utility.pytskutil import TSKUtil

次に、コマンドラインハンドラーの引数を指定します。 ここでは、2つの引数を受け入れることに注意してください。1つ目は証拠ファイルへのパス、2つ目は証拠ファイルのタイプです-

if __name__ == "__main__":
parser = argparse.ArgumentParser('getting information from internet history')
   parser.add_argument("EVIDENCE_FILE", help = "Evidence file path")
   parser.add_argument("TYPE", help = "Type of Evidence",choices = ("raw", "ewf"))
   parser.add_argument("-d", help = "Index.dat directory to scan",default = "/USERS")
   args = parser.parse_args()

   if os.path.exists(args.EVIDENCE_FILE) and os.path.isfile(args.EVIDENCE_FILE):
      main(args.EVIDENCE_FILE, args.TYPE, args.d)
   else:
      print("[-] Supplied input file {} does not exist or is not a ""file".format(args.EVIDENCE_FILE))
      sys.exit(1)

次に、 TSKUtil のオブジェクトを作成して証拠ファイルを解釈し、ファイルシステムを反復処理してindex.datファイルを見つけます。 それは次のように* main()*関数を定義することで実行できます-

def main(evidence, image_type, path):
   tsk_util = TSKUtil(evidence, image_type)
   index_dir = tsk_util.query_directory(path)

   if index_dir is not None:
      index_files = tsk_util.recurse_files("index.dat", path = path,logic = "equal")

      if index_files is not None:
         print("[+] Identified {} potential index.dat files".format(len(index_files)))
         index_data = []

         for hit in index_files:
            index_file = hit[2]
            temp_index = write_file(index_file)

今、index.datファイルの情報を現在の作業ディレクトリにコピーし、後でサードパーティのモジュールで処理できるようにする機能を定義します-

def write_file(index_file):
   with open(index_file.info.name.name, "w") as outfile:
   outfile.write(index_file.read_random(0, index_file.info.meta.size))
return index_file.info.name.name

さて、組み込み関数、すなわち* check_file_signature()*の助けを借りて署名検証を実行するために次のコードを使用します-

if pymsiecf.check_file_signature(temp_index):
   index_dat = pymsiecf.open(temp_index)
   print("[+] Identified {} records in {}".format(
   index_dat.number_of_items, temp_index))

   for i, record in enumerate(index_dat.items):
   try:
      data = record.data
   if data is not None:
      data = data.rstrip("\x00")
   except AttributeError:

   if isinstance(record, pymsiecf.redirected):
      index_data.append([
         i, temp_index, "", "", "", "", "",record.location, "", "", record.offset,os.path.join(path, hit[1].lstrip("//"))])

   elif isinstance(record, pymsiecf.leak):
      index_data.append([
         i, temp_index, record.filename, "","", "", "", "", "", "", record.offset,os.path.join(path, hit[1].lstrip("//"))])
   continue

   index_data.append([
      i, temp_index, record.filename,
      record.type, record.primary_time,
      record.secondary_time,
      record.last_checked_time, record.location,
      record.number_of_hits, data, record.offset,
      os.path.join(path, hit[1].lstrip("//"))
   ])
   else:
      print("[-] {} not a valid index.dat file. Removing "
      "temp file..".format(temp_index))
      os.remove("index.dat")
      continue
      os.remove("index.dat")
      write_output(index_data)
   else:
      print("[-] Index.dat files not found in {} directory".format(path))
   sys.exit(3)
   else:
      print("[-] Directory {} not found".format(win_event))
   sys.exit(2)

次に、以下に示すように、CSVファイルで出力を印刷するメソッドを定義します-

def write_output(data):
   output_name = "Internet_Indexdat_Summary_Report.csv"
   print("[+] Writing {} with {} parsed index.dat files to current "
   "working directory: {}".format(output_name, len(data),os.getcwd()))

   with open(output_name, "wb") as outfile:
      writer = csv.writer(outfile)
      writer.writerow(["Index", "File Name", "Record Name",
      "Record Type", "Primary Date", "Secondary Date",
      "Last Checked Date", "Location", "No. of Hits",
      "Record Data", "Record Offset", "File Path"])
      writer.writerows(data)

上記のスクリプトを実行した後、CSVファイルのindex.datファイルから情報を取得します。

ボリュームシャドウコピー

シャドウコピーは、Windowsに含まれるコンピューターファイルのバックアップコピーまたはスナップショットを手動または自動で取得するためのテクノロジです。 ボリュームスナップショットサービスまたはボリュームシャドウサービス(VSS)とも呼ばれます。

これらのVSSファイルの助けを借りて、法医学の専門家は、システムが時間の経過とともにどのように変化したか、コンピューターに存在したファイルに関する履歴情報を得ることができます。 シャドウコピーテクノロジでは、シャドウコピーを作成および保存するために、ファイルシステムがNTFSである必要があります。

このセクションでは、フォレンジック画像に存在するシャドウコピーのボリュームへのアクセスに役立つPythonスクリプトを確認します。

Pythonスクリプトの場合、サードパーティのモジュール、つまり pytsk3、pyewf、unicodecsv、pyvshadow および vss をインストールする必要があります。 以下の手順に従って、VSSファイルから情報を抽出できます。

  • 最初に、RAWイメージのボリュームにアクセスし、すべてのNTFSパーティションを特定します。
  • 次に、シャドウコピーを繰り返し処理して情報を抽出します。
  • ここで、最後にスナップショット内のデータのファイルリストを作成する必要があります。

Pythonコード

この目的のためにPythonコードを使用する方法を見てみましょう-

まず、次のPythonライブラリをインポートします-

from __future__ import print_function
import argparse
from datetime import datetime, timedelta

import os
import pytsk3
import pyewf
import pyvshadow
import sys
import unicodecsv as csv

from utility import vss
from utility.pytskutil import TSKUtil
from utility import pytskutil

次に、コマンドラインハンドラーの引数を指定します。 ここでは、2つの引数を受け入れます。1つ目は証拠ファイルへのパス、2つ目は出力ファイルです。

if __name__ == "__main__":
   parser = argparse.ArgumentParser('Parsing Shadow Copies')
   parser.add_argument("EVIDENCE_FILE", help = "Evidence file path")
   parser.add_argument("OUTPUT_CSV", help = "Output CSV with VSS file listing")
   args = parser.parse_args()

ここで、入力ファイルのパスの存在を検証し、ディレクトリを出力ファイルから分離します。

directory = os.path.dirname(args.OUTPUT_CSV)
if not os.path.exists(directory) and directory != "":
   os.makedirs(directory)
if os.path.exists(args.EVIDENCE_FILE) and \ os.path.isfile(args.EVIDENCE_FILE):
   main(args.EVIDENCE_FILE, args.OUTPUT_CSV)
else:
   print("[-] Supplied input file {} does not exist or is not a "
   "file".format(args.EVIDENCE_FILE))

   sys.exit(1)

次に、 TSKUtil オブジェクトを作成して、証拠ファイルのボリュームを操作します。 それは次のように* main()*メソッドの助けを借りて行うことができます-

def main(evidence, output):
   tsk_util = TSKUtil(evidence, "raw")
   img_vol = tsk_util.return_vol()

if img_vol is not None:
   for part in img_vol:
      if tsk_util.detect_ntfs(img_vol, part):
         print("Exploring NTFS Partition for VSS")
         explore_vss(evidence, part.start * img_vol.info.block_size,output)
      else:
         print("[-] Must be a physical preservation to be compatible ""with this script")
         sys.exit(2)

今、次のように解析されたボリュームシャドウファイルを探索するためのメソッドを定義します-

def explore_vss(evidence, part_offset, output):
   vss_volume = pyvshadow.volume()
   vss_handle = vss.VShadowVolume(evidence, part_offset)
   vss_count = vss.GetVssStoreCount(evidence, part_offset)

   if vss_count > 0:
      vss_volume.open_file_object(vss_handle)
      vss_data = []

      for x in range(vss_count):
         print("Gathering data for VSC {} of {}".format(x, vss_count))
         vss_store = vss_volume.get_store(x)
         image = vss.VShadowImgInfo(vss_store)
         vss_data.append(pytskutil.openVSSFS(image, x))
write_csv(vss_data, output)

最後に、スプレッドシートに結果を書き込む方法を次のように定義します-

def write_csv(data, output):
   if data == []:
      print("[-] No output results to write")
      sys.exit(3)
   print("[+] Writing output to {}".format(output))
   if os.path.exists(output):
      append = True
with open(output, "ab") as csvfile:
      csv_writer = csv.writer(csvfile)
      headers = ["VSS", "File", "File Ext", "File Type", "Create Date",
         "Modify Date", "Change Date", "Size", "File Path"]
      if not append:
         csv_writer.writerow(headers)
      for result_list in data:
         csv_writer.writerows(result_list)

このPythonスクリプトを正常に実行すると、VSSにある情報をスプレッドシートに取得します。