Python-forensics-quick-guide
Pythonフォレンジック-はじめに
Pythonは、プロの開発者と初心者プログラマの両方が簡単に理解できる、簡単で読みやすいコードを備えた汎用プログラミング言語です。 Pythonは、あらゆるスタックフレームワークで使用できる多くの便利なライブラリで構成されています。 多くの研究所は、予測のための基本モデルを構築し、実験を実行するためにPythonに依存しています。 また、重要な運用システムの制御にも役立ちます。
Pythonには、デジタル調査をサポートし、調査中の証拠の整合性を保護する組み込み機能があります。 このチュートリアルでは、Pythonをデジタルまたは計算フォレンジックに適用する基本的な概念を説明します。
計算科学捜査とは何ですか?
計算科学捜査は新しい研究領域です。 デジタル手法を使用したフォレンジック問題の解決を扱います。 計算科学を使用してデジタル証拠を研究します。
計算フォレンジックには、主にツールマーク、指紋、靴跡、文書などのパターン証拠に基づいて調査されたオブジェクト、物質、およびプロセスを含む幅広い対象が含まれ、生理学的および行動パターン、DNA、およびデジタル証拠も含まれます犯罪現場。
次の図は、計算科学捜査の対象となる幅広い対象を示しています。
計算科学捜査は、いくつかのアルゴリズムの助けを借りて実装されています。 これらのアルゴリズムは、信号および画像処理、コンピュータービジョン、グラフィックスに使用されます。 データマイニング、機械学習、ロボット工学も含まれます。
計算科学捜査には、さまざまなデジタル手法が含まれます。 フォレンジックのすべてのデジタルメソッドを簡単にする最適なソリューションは、Pythonなどの汎用プログラミング言語を使用することです。
Pythonフォレンジック-Pythonのインストール
計算科学捜査のすべての活動にPythonが必要なので、Pythonを一歩ずつ進めて、インストール方法を理解しましょう。
- ステップ2 *-パッケージ/インストーラーをダウンロードした後、exeファイルをクリックしてインストールプロセスを開始します。
インストールが完了すると、次の画面が表示されます。
- ステップ3 *-次のステップは、システムにPythonの環境変数を設定することです。
- ステップ4 *-環境変数を設定したら、コマンドプロンプトでコマンド「python」を入力して、インストールが成功したかどうかを確認します。
インストールが成功した場合、コンソールに次の出力が表示されます。
Pythonフォレンジック-Pythonの概要
Pythonで記述されたコードは、CやPascalなどの他の従来のプログラミング言語で記述されたコードと非常によく似ています。 また、Pythonの構文はCから大きく借用されているとも言われています。 これには、C言語に似た多くのPythonキーワードが含まれます。
Pythonには、フォレンジックのためにデータを正確に抽出するために使用できる条件ステートメントとループステートメントが含まれています。 フロー制御の場合、 if/else 、 while 、および「反復可能な」オブジェクトをループする高レベルの for ステートメントを提供します。
if a < b:
max = b
else:
max = a
Pythonが他のプログラミング言語と異なる主な領域は、*動的タイピング*の使用です。 オブジェクトを参照する変数名を使用します。 これらの変数を宣言する必要はありません。
データ型
Pythonには、文字列、ブール値、数値などの一連の組み込みデータ型が含まれています。 不変タイプもあります。これは、実行中に変更できない値を意味します。
Pythonには、不変配列である tuples 、 lists 、およびハッシュテーブルである dictionaries を含む複合組み込みデータ型もあります。 それらはすべて、証拠を収集しながら値を格納するためにデジタルフォレンジックで使用されます。
サードパーティのモジュールとパッケージ
Pythonは、プログラムの編成に使用される*サードパーティモジュール*(単一のソースファイルにグループ化された関連コード)とも呼ばれるモジュールやパッケージのグループをサポートします。
Pythonには、広範な標準ライブラリが含まれています。これは、計算科学捜査で人気がある主な理由の1つです。
Pythonコードのライフサイクル
- 最初に、Pythonコードを実行すると、インタープリターは構文エラーのコードをチェックします。 インタプリタが構文エラーを発見した場合、エラーメッセージとしてすぐに表示されます。
- 構文エラーがない場合、コードはコンパイルされて bytecode が生成され、PVM(Python Virtual Machine)に送信されます。
- PVMは、ランタイムエラーまたは論理エラーがないかバイトコードをチェックします。 PVMがランタイムエラーを検出した場合、エラーメッセージとして直ちに報告されます。
- バイトコードにエラーがない場合、コードが処理され、出力が得られます。
次の図は、Pythonコードが最初に解釈されてバイトコードが生成される方法と、バイトコードがPVMによって処理されて出力が生成される方法をグラフィカルに示しています。
Pythonフォレンジック-基本的なフォレンジックアプリケーション
法医学ガイドラインに従ってアプリケーションを作成するには、その命名規則とパターンを理解し、それに従うことが重要です。
命名規則
Pythonフォレンジックアプリケーションの開発中に、従うべき規則と規則を次の表で説明します。
Constants | Uppercase with underscore separation | HIGH_TEMPERATURE |
Local variable name | Lowercase with bumpy caps (underscores are optional) | currentTemperature |
Global variable name | Prefix gl lowercase with bumpy caps (underscores are optional) | gl_maximumRecordedTemperature |
Functions name | Uppercase with bumpy caps (underscores optional) with active voice | ConvertFarenheitToCentigrade(…) |
Object name | Prefix ob_ lowercase with bumpy caps | ob_myTempRecorder |
Module | An underscore followed by lowercase with bumpy caps | _tempRecorder |
Class names | Prefix class_ then bumpy caps and keep brief | class_TempSystem |
計算科学捜査における命名規則の重要性を理解するシナリオを考えてみましょう。 通常、データの暗号化に使用されるハッシュアルゴリズムがあるとします。 一方向ハッシュアルゴリズムは、バイナリデータのストリームとして入力を受け取ります。これは、パスワード、ファイル、バイナリデータ、または任意のデジタルデータです。 ハッシュアルゴリズムは、入力で受信したデータに関して*メッセージダイジェスト*(md)を生成します。
特定のメッセージダイジェストを生成する新しいバイナリ入力を作成することは事実上不可能です。 バイナリ入力データの1ビットでも、変更された場合、以前のものとは異なる一意のメッセージが生成されます。
例
上記の規則に従う次のサンプルプログラムをご覧ください。
import sys, string, md5 # necessary libraries
print "Please enter your full name"
line = sys.stdin.readline()
line = line.rstrip()
md5_object = md5.new()
md5_object.update(line)
print md5_object.hexdigest() # Prints the output as per the hashing algorithm i.e. md5
exit
上記のプログラムは、次の出力を生成します。
このプログラムでは、Pythonスクリプトは入力(フルネーム)を受け入れ、md5ハッシュアルゴリズムに従ってそれを変換します。 必要に応じて、データを暗号化し、情報を保護します。 フォレンジックガイドラインに従って、証拠の名前またはその他の証拠をこのパターンで保護できます。
Pythonフォレンジック-ハッシュ関数
- ハッシュ関数*は、指定された長さの固定値に大量のデータをマッピングする関数として定義されます。 この関数は、同じ入力が同じ出力になり、実際にハッシュ和として定義されることを保証します。 ハッシュ合計には、特定の情報を持つ特性が含まれます。
この機能を元に戻すことは事実上不可能です。 したがって、ブルートフォース攻撃のようなサードパーティの攻撃は事実上不可能です。 また、この種のアルゴリズムは*一方向暗号アルゴリズム*と呼ばれます。
理想的な暗号化ハッシュ関数には4つの主要な特性があります-
- 任意の入力のハッシュ値を簡単に計算できる必要があります。
- ハッシュから元の入力を生成することは実行不可能でなければなりません。
- ハッシュを変更せずに入力を変更することは実行不可能でなければなりません。
- 同じハッシュを持つ2つの異なる入力を見つけることは実行不可能でなければなりません。
例
16進形式の文字を使用してパスワードを照合するのに役立つ次の例を検討してください。
import uuid
import hashlib
def hash_password(password):
# userid is used to generate a random number
salt = uuid.uuid4().hex #salt is stored in hexadecimal value
return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt
def check_password(hashed_password, user_password):
# hexdigest is used as an algorithm for storing passwords
password, salt = hashed_password.split(':')
return password == hashlib.sha256(salt.encode()
+ user_password.encode()).hexdigest()
new_pass = raw_input('Please enter required password ')
hashed_password = hash_password(new_pass)
print('The string to store in the db is: ' + hashed_password)
old_pass = raw_input('Re-enter new password ')
if check_password(hashed_password, old_pass):
print('Yuppie!! You entered the right password')
else:
print('Oops! I am sorry but the password does not match')
フローチャート
私たちは次のフローチャートの助けを借りてこのプログラムのロジックを説明しました-
出力
私たちのコードは次の出力を生成します-
2回入力されたパスワードは、ハッシュ関数と一致します。 これにより、2回入力されたパスワードが正確になり、有用なデータを収集して暗号化された形式で保存するのに役立ちます。
Pythonフォレンジック-暗号化のクラッキング
この章では、分析および証拠の取得中に取得したテキストデータのクラッキングについて学習します。
暗号化のプレーンテキストは、メッセージなどの通常の読み取り可能なテキストです。 一方、暗号テキストは、プレーンテキストを入力した後に取得された暗号化アルゴリズムの出力です。
プレーンテキストメッセージを暗号テキストに変換する単純なアルゴリズムは、敵からプレーンテキストを秘密にするためにJulius Caesarによって発明された* Caesar暗号*です。 この暗号化では、メッセージ内のすべての文字をアルファベット順で3桁シフトします。
以下はデモの図です。
a→D
b→E
c→F
w → Z
x → A
y → B
z → C
=== Example
A message entered when you run a Python script gives all the possibilities of characters, which is used for pattern evidence.
The types of pattern evidences used are as follows −
* Tire Tracks and Marks
* Impressions
* Fingerprints
Every biometric data comprises of vector data, which we need to crack to gather full-proof evidence.
The following Python code shows how you can produce a cipher text from plain text −
[source,prettyprint,notranslate]
----
インポートシステム
def decrypt(k、cipher):plaintext = '' in cipher in:p =(ord(each)-k)%126 if p <32:p + = 95 plaintext + = chr(p)print plaintext
def main(argv):if(len(sys.argv)!= 1):sys.exit( 'Usage:cracking.py')cipher = raw_input( 'Enter message:')for i in range(1,95、 1):__name__ == "__main__"の場合、decrypt(i、cipher):main(sys.argv [1:])
----
=== Output
Now, check the output of this code. When we enter a simple text "Radhika", the program will produce the following cipher text.
image:/python_forensics/cracking_encryption_output.jpg[Cracking Encryption Output]
Pythonフォレンジック-仮想化
- 仮想化*は、サーバー、ワークステーション、ネットワーク、ストレージなどのITシステムをエミュレートするプロセスです。 これは、オペレーティングシステム、サーバー、ストレージデバイス、またはネットワークプロセスの実際のバージョンではなく、仮想バージョンの作成に他なりません。
仮想ハードウェアのエミュレーションに役立つ主要コンポーネントは、*ハイパーバイザー*として定義されています。
次の図は、使用されるシステム仮想化の2つの主要なタイプを説明しています。
仮想化は、多くの方法で計算科学捜査で使用されています。 分析者は、各調査でワークステーションを検証済みの状態で使用できるようになります。 特に、仮想マシン上のセカンダリドライブとしてドライブのddイメージをアタッチすることにより、データの回復が可能です。 同じマシンを回復ソフトウェアとして使用して、証拠を収集できます。
次の例は、Pythonプログラミング言語の助けを借りて仮想マシンの作成を理解するのに役立ちます。
- ステップ1 *-仮想マシンに「dummy1」という名前を付けます。
すべての仮想マシンには、バイト単位で表される最小容量の512 MBのメモリが必要です。
vm_memory = 512 *1024* 1024
- ステップ2 *-計算されたデフォルトのクラスターに仮想マシンを接続する必要があります。
vm_cluster = api.clusters.get(name = "Default")
- ステップ3 *-仮想マシンは仮想ハードディスクドライブから起動する必要があります。
vm_os = params.OperatingSystem(boot = [params.Boot(dev = "hd")])
すべてのオプションは、vmsコレクションのaddメソッドを仮想マシンに使用する前に、仮想マシンパラメータオブジェクトに結合されます。
例
以下は、仮想マシンを追加するための完全なPythonスクリプトです。
from ovirtsdk.api import API #importing API library
from ovirtsdk.xml import params
try: #Api credentials is required for virtual machine
api = API(url = "https://HOST",
username = "Radhika",
password = "a@123",
ca_file = "ca.crt")
vm_name = "dummy1"
vm_memory = 512 *1024* 1024 #calculating the memory in bytes
vm_cluster = api.clusters.get(name = "Default")
vm_template = api.templates.get(name = "Blank")
#assigning the parameters to operating system
vm_os = params.OperatingSystem(boot = [params.Boot(dev = "hd")])
vm_params = params.VM(name = vm_name,
memory = vm_memory,
cluster = vm_cluster,
template = vm_template
os = vm_os)
try:
api.vms.add(vm = vm_params)
print "Virtual machine '%s' added." % vm_name #output if it is successful.
except Exception as ex:
print "Adding virtual machine '%s' failed: %s" % (vm_name, ex)
api.disconnect()
except Exception as ex:
print "Unexpected error: %s" % ex
出力
私たちのコードは次の出力を生成します-
Pythonフォレンジック-ネットワークフォレンジック
最新のネットワーク環境のシナリオでは、多くの困難により調査が困難になる場合があります。 これは、侵害サポートへの対応、インサイダーアクティビティの調査、脆弱性に関連する評価の実行、または規制順守の検証のいずれでも発生します。
ネットワークプログラミングの概念
次の定義は、ネットワークプログラミングで使用されます。
- クライアント-クライアントは、パーソナルコンピューターとワークステーションで実行されるネットワークプログラミングのクライアントサーバーアーキテクチャの一部です。
- サーバー-サーバーは、同じまたは他のコンピューター内の他のコンピュータープログラムにサービスを提供するクライアントサーバーアーキテクチャの一部です。
- * WebSockets-WebSocketsは、クライアントとサーバー間のプロトコルを提供し、永続的なTCP接続で実行されます。 これにより、双方向のメッセージをTCPソケット接続間で(同時に)送信できます。
WebSocketは、サーバーがクライアントに情報を送信することを可能にする他の多くのテクノロジーの後に登場します。 アップグレードヘッダーのハンドシェイク以外に、WebSocketsはHTTPから独立しています。
これらのプロトコルは、サードパーティのユーザーが送受信する情報を検証するために使用されます。 暗号化はメッセージの保護に使用される方法の1つであるため、メッセージが転送されたチャネルを保護することも重要です。
クライアントが*ハンドシェイク*に使用する次のPythonプログラムを検討してください。
例
# client.py
import socket
# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 8080
# connection to hostname on the port.
s.connect((host, port))
# Receive no more than 1024 bytes
tm = s.recv(1024)
print("The client is waiting for connection")
s.close()
出力
それは次の出力を生成します-
通信チャネルの要求を受け入れるサーバーには、次のスクリプトが含まれます。
# server.py
import socket
import time
# create a socket object
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 8080
# bind to the port
serversocket.bind((host, port))
# queue up to 5 requests
serversocket.listen(5)
while True:
# establish a connection
clientsocket,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
currentTime = time.ctime(time.time()) + "\r\n"
clientsocket.send(currentTime.encode('ascii'))
clientsocket.close()
Pythonプログラミングの助けを借りて作成されたクライアントとサーバーは、ホスト番号をリッスンします。 最初に、クライアントはホスト番号で送信されたデータに関してリクエストをサーバーに送信し、サーバーはリクエストを受け入れてすぐにレスポンスを送信します。 これにより、安全な通信チャネルを確保できます。
Pythonフォレンジック-Pythonモジュール
Pythonプログラムのモジュールは、コードの整理に役立ちます。 関連するコードを1つのモジュールにグループ化するのに役立ちます。これにより、理解と使用が容易になります。 バインドと参照に使用できる任意の名前の値が含まれます。 簡単に言えば、モジュールは、関数、クラス、変数を含むPythonコードで構成されるファイルです。
モジュール(ファイル)のPythonコードは .py 拡張子で保存され、必要に応じてコンパイルされます。
例
def print_hello_func( par ):
print "Hello : ", par
return
輸入明細書
Pythonソースファイルは、他のパッケージまたはサードパーティライブラリをインポートする import ステートメントを実行することにより、モジュールとして使用できます。 使用される構文は次のとおりです-
import module1[, module2[,... moduleN]
Pythonインタープリターがimportステートメントを検出すると、検索パスに存在する指定されたモジュールをインポートします。
例
次の例を考えてください。
#!/usr/bin/python
# Import module support
import support
# Now you can call defined function that module as follows
support.print_func("Radhika")
それは次の出力を生成します-
モジュールは、Pythonコードによってインポートされた回数に関係なく、一度だけロードされます。
From … importステートメント
*From* 属性は、特定の属性をモジュールから現在のネームスペースにインポートするのに役立ちます。 構文は次のとおりです。
from modname import name1[, name2[, ... nameN]]
例
モジュール fib から関数 fibonacci をインポートするには、次のステートメントを使用します。
from fib import fibonacci
モジュールの特定
モジュールがインポートされているとき、Pythonインタープリターは次のシーケンスを検索します-
- 現在のディレクトリ
- モジュールが存在しない場合、Pythonはシェル変数PYTHONPATHで各ディレクトリを検索します。
- シェル変数の場所が失敗した場合、Pythonはデフォルトパスをチェックします。
計算科学捜査では、Pythonモジュールとサードパーティモジュールを使用して、情報を取得し、より簡単に証拠を抽出します。 さらに章では、必要な出力を得るためのモジュールの実装に焦点を当てます。
Pythonフォレンジック-DshellとScapy
DShell
*Dshell* は、Pythonベースのネットワークフォレンジック分析ツールキットです。 このツールキットは、米国陸軍研究所によって開発されました。 このオープンソースツールキットのリリースは2014年でした。 このツールキットの主な焦点は、フォレンジック調査を簡単に行うことです。
ツールキットは、次の表にリストされている多数のデコーダーで構成されています。
Sr.No. | Decoder Name & Description |
---|---|
1 |
dns これは、DNS関連のクエリを抽出するために使用されます |
2 |
reservedips DNSの問題の解決策を特定する |
3 |
large-flows ネットフローのリスト |
4 |
rip-http HTTPトラフィックからファイルを抽出するために使用されます |
5 |
Protocols 非標準プロトコルの識別に使用 |
米国陸軍研究所は、次のリンクでGitHubのクローンリポジトリを維持しています-
https://github.com/USArmyResearchLab/Dshell
クローンは、このツールキットのインストールに使用されるスクリプト* install-ubuntu.py()*で構成されています。
インストールが成功すると、後で使用される実行可能ファイルと依存関係が自動的に構築されます。
依存関係は次のとおりです-
dependencies = {
"Crypto": "crypto",
"dpkt": "dpkt",
"IPy": "ipy",
"pcap": "pypcap"
}
このツールキットは、通常、インシデント中またはアラート中に記録されるpcap(パケットキャプチャ)ファイルに対して使用できます。 これらのpcapファイルは、LinuxプラットフォームのlibpcapまたはWindowsプラットフォームのWinPcapによって作成されます。
スカピー
Scapyは、ネットワークトラフィックの分析と操作に使用されるPythonベースのツールです。 以下はScapyツールキットのリンクです-
http://www.secdev.org/projects/scapy/
このツールキットは、パケット操作の分析に使用されます。 多数のプロトコルのパケットをデコードしてキャプチャすることができます。 Scapyは、ネットワークトラフィックに関する詳細な説明を調査者に提供する点でDshellツールキットとは異なります。 これらの説明はリアルタイムで記録されています。
Scapyには、サードパーティのツールまたはOSフィンガープリントを使用してプロットする機能があります。
次の例を考えてください。
import scapy, GeoIP #Imports scapy and GeoIP toolkit
from scapy import *
geoIp = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE) #locates the Geo IP address
def locatePackage(pkg):
src = pkg.getlayer(IP).src #gets source IP address
dst = pkg.getlayer(IP).dst #gets destination IP address
srcCountry = geoIp.country_code_by_addr(src) #gets Country details of source
dstCountry = geoIp.country_code_by_addr(dst) #gets country details of destination
print src+"("+srcCountry+") >> "+dst+"("+dstCountry+")\n"
このスクリプトは、互いに通信しているネットワークパケットで国の詳細の詳細な説明を提供します。
上記のスクリプトは、次の出力を生成します。
Pythonフォレンジック-検索
- 検索*は、確かにフォレンジック調査の柱の1つです。 現在、検索は証拠を実行している調査員と同じくらい良いです。
メッセージからキーワードを検索することは、私たちがキーワードの助けを借りて証拠を検索するときに、法医学において重要な役割を果たします。 特定のファイルで何を検索するかについての知識は、削除されたファイルにあるものとともに、経験と知識の両方が必要です。
Pythonには、 search 操作をサポートする標準ライブラリモジュールを備えたさまざまな組み込みメカニズムがあります。 基本的に、調査員は検索操作を使用して、「誰」、「何」、「どこ」、「いつ」などの質問に対する答えを見つけます。
例
次の例では、2つの文字列を宣言した後、find関数を使用して、最初の文字列に2番目の文字列が含まれているかどうかを確認しました。
# Searching a particular word from a message
str1 = "This is a string example for Computational forensics of gathering evidence!";
str2 = "string";
print str1.find(str2)
print str1.find(str2, 10)
print str1.find(str2, 40)
上記のスクリプトは、次の出力を生成します。
Pythonの「検索」機能は、メッセージまたは段落内のキーワードの検索に役立ちます。 これは、適切な証拠を収集する上で重要です。
Pythonフォレンジック-インデックス作成
- インデックス作成*は、実際に調査員がファイルを完全に見て、そこから潜在的な証拠を収集することを提供します。 証拠は、ファイル、ディスクイメージ、メモリスナップショット、またはネットワークトレースに含めることができます。
索引付けは、*キーワード検索*などの時間のかかるタスクの時間を短縮するのに役立ちます。 フォレンジック調査には、インデックスを使用してキーワードをすばやく特定する対話型検索フェーズも含まれます。
インデックスは、ソートされたリストにキーワードをリストするのにも役立ちます。
例
次の例は、Pythonで indexing を使用する方法を示しています。
aList = [123, 'sample', 'zara', 'indexing'];
print "Index for sample : ", aList.index('sample')
print "Index for indexing : ", aList.index('indexing')
str1 = "This is sample message for forensic investigation indexing";
str2 = "sample";
print "Index of the character keyword found is "
print str1.index(str2)
上記のスクリプトは、次の出力を生成します。
Pythonフォレンジック-Python Imaging Library
利用可能なリソースから貴重な情報を抽出することは、デジタルフォレンジックの重要な部分です。 利用可能なすべての情報にアクセスすることは、適切な証拠を取得するのに役立つため、調査プロセスにとって不可欠です。
データを含むリソースは、データベースなどの単純なデータ構造でも、JPEG画像などの複雑なデータ構造でもかまいません。 シンプルなデータ構造にはシンプルなデスクトップツールを使用して簡単にアクセスできますが、複雑なデータ構造から情報を抽出するには高度なプログラミングツールが必要です。
Pythonイメージングライブラリ
Python Imaging Library(PIL)は、Pythonインタープリターに画像処理機能を追加します。 このライブラリは多くのファイルフォーマットをサポートし、そして強力な画像処理とグラフィックス機能を提供します。 PILのソースファイルは、http://www.pythonware.com/products/pil/からダウンロードできます。
次の図は、PILの画像(複雑なデータ構造)からデータを抽出する完全なフロー図を示しています。
例
それでは、実際の動作を理解するためのプログラミング例を見てみましょう。
- ステップ1 *-情報を抽出する必要がある場所から次の画像があるとします。
- ステップ2 *-PILを使用してこの画像を開くと、さまざまなピクセル値を含む証拠の抽出に必要なポイントに最初に注意します。 ここに画像を開いてそのピクセル値を記録するコードがあります-
from PIL import Image
im = Image.open('Capture.jpeg', 'r')
pix_val = list(im.getdata())
pix_val_flat = [x for sets in pix_val for x in sets]
print pix_val_flat
- ステップ3 *-このコードは、画像のピクセル値を抽出した後、次の出力を生成します。
配信される出力は、RGBの組み合わせのピクセル値を表し、証拠に必要なデータのより良い全体像を提供します。 フェッチされたデータは配列の形式で表されます。
Pythonフォレンジック-モバイルフォレンジック
ハードディスクなどの標準的なコンピューターハードウェアのフォレンジック調査と分析は、安定した分野に発展し、非標準のハードウェアまたは一時的な証拠を分析する技術の支援を受けています。
スマートフォンはデジタル調査でますます使用されていますが、依然として非標準と見なされています。
法医学分析
フォレンジック調査では、スマートフォンからの着信やダイヤル番号などのデータを検索します。 テキストメッセージ、写真、またはその他の犯罪の証拠を含めることができます。 ほとんどのスマートフォンには、パスワードまたは英数字を使用した画面ロック機能があります。
ここでは、Pythonが画面ロックパスワードを解読してスマートフォンからデータを取得する方法を示す例を示します。
手動試験
Androidは、PIN番号または英数字パスワードによるパスワードロックをサポートしています。 両方のパスフレーズの制限は、4〜16桁の数字または文字である必要があります。 スマートフォンのパスワードは、Androidシステムの /data/system にある password.key という特別なファイルに保存されます。
Androidは、パスワードのソルトSHA1ハッシュサムとMD5ハッシュサムを保存します。 これらのパスワードは、次のコードで処理できます。
public byte[] passwordToHash(String password) {
if (password == null) {
return null;
}
String algo = null;
byte[] hashed = null;
try {
byte[] saltedPassword = (password + getSalt()).getBytes();
byte[] sha1 = MessageDigest.getInstance(algo = "SHA-1").digest(saltedPassword);
byte[] md5 = MessageDigest.getInstance(algo = "MD5").digest(saltedPassword);
hashed = (toHex(sha1) + toHex(md5)).getBytes();
} catch (NoSuchAlgorithmException e) {
Log.w(TAG, "Failed to encode string because of missing algorithm: " + algo);
}
return hashed;
}
ハッシュされたパスワードは* saltファイル*に保存されているため、辞書攻撃*を使用してパスワードを解読することはできません。 この *salt は、64ビットのランダムな整数の16進表現の文字列です。 Rooted Smartphone または JTAG Adapter を使用すると、 salt に簡単にアクセスできます。
根ざしたスマートフォン
ファイル /data/system/password.key のダンプは、SQLiteデータベースの lockscreen.password_salt キーの下に保存されます。 settings.db の下に、パスワードが保存され、次のスクリーンショットで値が明確に表示されます。
JTAGアダプター
JTAG(ジョイントテストアクショングループ)アダプターと呼ばれる特別なハードウェアを使用して、 salt にアクセスできます。 同様に、 Riff-Box または JIG-Adapter も同じ機能に使用できます。
Riff-boxから取得した情報を使用して、暗号化されたデータの位置、つまり salt を見つけることができます。 以下はルールです-
- 関連する文字列「lockscreen.password_salt」を検索します。
- バイトは、ソルトの実際の幅、つまり*長さ*を表します。
- これは、スマートフォンの保存されたパスワード/ピンを取得するために実際に検索される長さです。
これらのルールセットは、適切なソルトデータの取得に役立ちます。
Pythonフォレンジック-ネットワークタイムプロトコル
時刻を同期するために最も広く使用されているプロトコルであり、実践として広く受け入れられているのは、Network Time Protocol(NTP)によって行われます。
NTPは、ユーザーデータグラムプロトコル(UDP)を使用します。UDPは、最小時間を使用して、指定されたタイムソースと同期したいサーバーとクライアント間でパケットを通信します。
ネットワークタイムプロトコルの機能は次のとおりです-
- デフォルトのサーバーポートは123です。
- このプロトコルは、国立研究所に同期された多くのアクセス可能なタイムサーバーで構成されています。
- NTPプロトコル標準はIETFによって管理され、提案された標準は「Network Time Protocol Version 4:Protocol and Algorithms Specification」というタイトルのRFC 5905です[NTP RFC]
- オペレーティングシステム、プログラム、およびアプリケーションは、NTPを使用して適切な方法で時刻を同期します。
この章では、サードパーティのPythonライブラリntplibから実行可能なPythonでのNTPの使用に焦点を当てます。 このライブラリは、結果を自分のローカルシステムクロックと比較する重い作業を効率的に処理します。
NTPライブラリのインストール
*ntplib* は、次の図に示すようにhttps://pypi.python.org/pypi/ntplib/からダウンロードできます。
このライブラリは、NTPプロトコルフィールドを変換できるメソッドの助けを借りて、NTPサーバーへのシンプルなインターフェイスを提供します。 これは、うるう秒などの他のキー値にアクセスするのに役立ちます。
次のPythonプログラムは、NTPの使用法を理解するのに役立ちます。
import ntplib
import time
NIST = 'nist1-macon.macon.ga.us'
ntp = ntplib.NTPClient()
ntpResponse = ntp.request(NIST)
if (ntpResponse):
now = time.time()
diff = now-ntpResponse.tx_time
print diff;
上記のプログラムは、次の出力を生成します。
時間の差は、上記のプログラムで計算されます。 これらの計算は、法医学調査に役立ちます。 取得したネットワークデータは、ハードドライブで検出されたデータの分析とは根本的に異なります。
タイムゾーンの違いや正確なタイムゾーンの取得は、このプロトコルでメッセージをキャプチャするための証拠を収集するのに役立ちます。
Pythonフォレンジック-マルチプロセッシングサポート
通常、法医学の専門家は、一般的な犯罪におけるデジタル証拠の山を分析するためにデジタルソリューションを適用することは難しいと感じています。 ほとんどのデジタル調査ツールはシングルスレッドであり、一度に1つのコマンドしか実行できません。
この章では、Pythonのマルチプロセッシング機能に焦点を当てます。これは、一般的なフォレンジックの課題に関連する可能性があります。
マルチプロセッシング
マルチプロセッシングは、複数のプロセスをサポートするコンピューターシステムの能力として定義されます。 マルチプロセッシングをサポートするオペレーティングシステムにより、複数のプログラムを同時に実行できます。
- 対称*や*非対称処理*など、さまざまなタイプのマルチプロセッシングがあります。 次の図は、通常の法医学調査で使用される対称型マルチプロセッシングシステムを示しています。
例
次のコードは、Pythonプログラミングの内部でさまざまなプロセスがどのようにリストされるかを示しています。
import random
import multiprocessing
def list_append(count, id, out_list):
#appends the count of number of processes which takes place at a time
for i in range(count):
out_list.append(random.random())
if __name__ == "__main__":
size = 999
procs = 2
# Create a list of jobs and then iterate through
# the number of processes appending each process to
# the job list
jobs = []
for i in range(0, procs):
out_list = list() #list of processes
process1 = multiprocessing.Process(
target = list_append, args = (size, i, out_list))
# appends the list of processes
jobs.append(process)
# Calculate the random number of processes
for j in jobs:
j.start() #initiate the process
# After the processes have finished execution
for j in jobs:
j.join()
print "List processing complete."
ここで、関数* list_append()*は、システム内の一連のプロセスをリストするのに役立ちます。
出力
私たちのコードは次の出力を生成します-
Pythonフォレンジック-メモリとフォレンジック
この章では、 Android および Linux プラットフォームに適用可能なPythonベースのフォレンジックフレームワークである Volatility を使用して、揮発性メモリの調査に焦点を当てます。
揮発性メモリ
揮発性メモリは、システムの電源が切れたり中断されたりすると内容が消去されるストレージの一種です。 RAMは、揮発性メモリの最良の例です。 つまり、ハードドライブなどの不揮発性メモリに保存されていないドキュメントで作業しており、コンピューターの電源が切れると、すべてのデータが失われます。
一般的に、揮発性メモリの法医学は、他の法医学調査と同じパターンに従います-
- 調査対象の選択
- 法医学データの取得
- 法医学分析
Androidで使用される基本的な*揮発性プラグイン*は、分析のために* RAMダンプ*を収集します。 分析のためにRAMダンプを収集したら、RAM内のマルウェアを探し始めることが重要です。
YARAルール
YARAは堅牢な言語を提供する人気のあるツールで、Perlベースの正規表現と互換性があり、疑わしいファイル/ディレクトリを調べて文字列を照合するために使用されます。
このセクションでは、パターンマッチングの実装に基づいてYARAを使用し、それらをユーティリティパワーと組み合わせます。 完全なプロセスは、法医学分析に有益です。
例
次のコードを見てください。 このコードは、コードの抽出に役立ちます。
import operator
import os
import sys
sys.path.insert(0, os.getcwd())
import plyara.interp as interp
# Plyara is a script that lexes and parses a file consisting of one more Yara
# rules into a python dictionary representation.
if __name__ == '__main__':
file_to_analyze = sys.argv[1]
rulesDict = interp.parseString(open(file_to_analyze).read())
authors = {}
imps = {}
meta_keys = {}
max_strings = []
max_string_len = 0
tags = {}
rule_count = 0
for rule in rulesDict:
rule_count += 1
# Imports
if 'imports' in rule:
for imp in rule['imports']:
imp = imp.replace('"','')
if imp in imps:
imps[imp] += 1
else:
imps[imp] = 1
# Tags
if 'tags' in rule:
for tag in rule['tags']:
if tag in tags:
tags[tag] += 1
else:
tags[tag] = 1
# Metadata
if 'metadata' in rule:
for key in rule['metadata']:
if key in meta_keys:
meta_keys[key] += 1
else:
meta_keys[key] = 1
if key in ['Author', 'author']:
if rule['metadata'][key] in authors:
authors[rule['metadata'][key]] += 1
else:
authors[rule['metadata'][key]] = 1
#Strings
if 'strings' in rule:
for strr in rule['strings']:
if len(strr['value']) > max_string_len:
max_string_len = len(strr['value'])
max_strings = [(rule['rule_name'], strr['name'], strr['value'])]
elif len(strr['value']) == max_string_len:
max_strings.append((rule['rule_name'], strr['key'], strr['value']))
print("\nThe number of rules implemented" + str(rule_count))
ordered_meta_keys = sorted(meta_keys.items(), key = operator.itemgetter(1),
reverse = True)
ordered_authors = sorted(authors.items(), key = operator.itemgetter(1),
reverse = True)
ordered_imps = sorted(imps.items(), key = operator.itemgetter(1), reverse = True)
ordered_tags = sorted(tags.items(), key = operator.itemgetter(1), reverse = True)
上記のコードは次の出力を生成します。
実装されたYARAルールの数は、疑わしいファイルのより良い画像を提供するのに役立ちます。 間接的に、疑わしいファイルのリストは、法医学のための適切な情報を収集するのに役立ちます。
githubのソースコードは次のとおりです。https://github.com/radhikascs/Python_yara
LinuxでのPythonフォレンジック
デジタル調査の主な関心事は、重要な証拠またはデータを暗号化またはその他の形式で保護することです。 基本的な例はパスワードの保存です。 したがって、これらの貴重なデータを保護するには、デジタルフォレンジックの実装にLinuxオペレーティングシステムの使用法を理解する必要があります。
すべてのローカルユーザーの情報は、主に次の2つのファイルに保存されます-
- /etc/passwd * etc/shadow
最初のパスワードは必須であり、すべてのパスワードが保存されます。 2番目のファイルはオプションであり、ハッシュされたパスワードを含むローカルユーザーに関する情報を保存します。
パスワード情報をすべてのユーザーが読み取り可能なファイルに保存するというセキュリティ問題に関して問題が発生します。 したがって、ハッシュされたパスワードは /etc/passwd に保存され、コンテンツは特別な値「 x 」に置き換えられます。
対応するハッシュは /etc/shadow で検索する必要があります。 /etc/passwd の設定は、 /etc/shadow の詳細を上書きする場合があります。
Linuxの両方のテキストファイルには1行に1つのエントリが含まれており、エントリはコロンで区切られた複数のフィールドで構成されています。
*/etc/passwd* の形式は次のとおりです-
Sr.No. | Field Name & Description |
---|---|
1 |
Username このフィールドは、人間が読める形式の属性で構成されています |
2 |
Password hash Posix crypt関数に従ってエンコードされた形式のパスワードで構成されます |
ハッシュパスワードが*空*として保存されている場合、対応するユーザーはシステムにログインするためにパスワードを必要としません。 このフィールドに感嘆符などのハッシュアルゴリズムで生成できない値が含まれている場合、ユーザーはパスワードを使用してログオンできません。
ロックされたパスワードを持つユーザーは、他の認証メカニズム(SSHキーなど)を使用して引き続きログオンできます。 前述のように、特別な値「 x 」は、パスワードハッシュをシャドウファイルで見つける必要があることを意味します。
- パスワードハッシュ*には次のものが含まれます-
- 暗号化されたソルト-*暗号化されたソルト*は、画面ロック、ピン、およびパスワードの維持に役立ちます。
- *数値ユーザーID *-このフィールドはユーザーのIDを示します。 Linuxカーネルは、このユーザーIDをシステムに割り当てます。
- *数値グループID *-このフィールドは、ユーザーのプライマリグループを指します。
- ホームディレクトリ-新しいプロセスは、このディレクトリの参照で開始されます。
- コマンドシェル-このオプションのフィールドは、システムへのログインに成功した後に起動されるデフォルトのシェルを示します。
デジタルフォレンジックには、証拠の追跡に関連する情報の収集が含まれます。 したがって、ユーザーIDはレコードの維持に役立ちます。
Pythonを使用すると、分析のインジケーターについてこの情報をすべて自動的に分析し、最近のシステムアクティビティを再構築できます。 Linux Shellを実装すると、追跡が簡単かつ簡単になります。
LinuxでのPythonプログラミング
例
import sys
import hashlib
import getpass
def main(argv):
print '\nUser & Password Storage Program in Linux for forensic detection v.01\n'
if raw_input('The file ' + sys.argv[1] + ' will be erased or overwrite if
it exists .\nDo you wish to continue (Y/n): ') not in ('Y','y') :
sys.exit('\nChanges were not recorded\n')
user_name = raw_input('Please Enter a User Name: ')
password = hashlib.sha224(getpass.getpass('Please Enter a Password:')).hexdigest()
# Passwords which are hashed
try:
file_conn = open(sys.argv[1],'w')
file_conn.write(user_name + '\n')
file_conn.write(password + '\n')
file_conn.close()
except:
sys.exit('There was a problem writing the passwords to file!')
if __name__ == "__main__":
main(sys.argv[1:])
出力
パスワードは、次のスクリーンショットに示すように、16進形式で pass_db.txt に保存されます。 テキストファイルは、コンピューターフォレンジックでさらに使用するために保存されます。
Pythonフォレンジック-侵害の指標
侵害のインジケータ(IOC)は、「システムまたはネットワーク上の潜在的に悪意のあるアクティビティを識別する、システムログエントリまたはファイルで見つかったデータを含むフォレンジックデータの断片」として定義されます。
IOCを監視することにより、組織は攻撃を検出し、そのような侵害の発生を防ぐために迅速に行動するか、攻撃を初期段階で停止することで損害を制限できます。
いくつかのユースケースがあります。これにより、以下のようなフォレンジックアーティファクトのクエリが可能になります-
- MD5で特定のファイルを探す
- 実際にメモリに保存されている特定のエンティティを検索する
- Windowsレジストリに保存されている特定のエントリまたはエントリのセット
上記のすべての組み合わせにより、アーティファクトの検索結果が向上します。 前述のように、Windowsレジストリは、IOCの生成と保守に最適なプラットフォームを提供し、計算科学捜査に直接役立ちます。
方法論
- ファイルシステム内の場所、特に今のところWindowsレジストリを探します。
- フォレンジックツールによって設計されたアーティファクトのセットを検索します。
- 有害な活動の兆候を探します。
調査ライフサイクル
調査ライフサイクルはIOCに従い、レジストリ内の特定のエントリを検索します。
- ステージ1:初期証拠-ホストまたはネットワークで侵害の証拠が検出されます。 レスポンダーは、具体的なフォレンジックインジケーターである正確なソリューションを調査して特定します。
- ステージ2:ホストおよびネットワークのIOCの作成-収集されたデータに続いて、IOCが作成されます。これはWindowsレジストリで簡単に可能です。 OpenIOCの柔軟性により、インディケーターを作成する方法の順列の数に制限はありません。
- ステージ3:エンタープライズにIOCを展開-指定されたIOCが作成されると、調査員はWindowsレジスタのAPIを使用してこれらのテクノロジーを展開します。
- ステージ4:容疑者の特定-IOCの展開は、通常の方法で容疑者を特定するのに役立ちます。 追加のシステムも特定されます。
- ステージ5:証拠の収集と分析-容疑者に対する証拠が収集され、それに応じて分析されます。
- ステージ6:新しいIOCの調整と作成-調査チームは、企業で見つかった証拠とデータ、および追加のインテリジェンスに基づいて新しいIOCを作成し、引き続きサイクルを調整できます。
次の図は、調査ライフサイクルのフェーズを示しています-
Pythonフォレンジック-クラウドの実装
- クラウドコンピューティング*は、インターネット経由でユーザーに提供されるホストサービスのコレクションとして定義できます。 組織は、仮想マシン(VM)、ストレージ、またはユーティリティとしてのアプリケーションを含むリソースを消費したり、計算したりすることができます。
Pythonプログラミング言語でアプリケーションを構築することの最も重要な利点の1つは、*クラウド*を含むあらゆるプラットフォームにアプリケーションを仮想的に展開できることです。 Pythonはクラウドサーバーで実行でき、デスクトップ、タブレット、スマートフォンなどの便利なデバイスでも起動できることを意味します。
興味深い視点の1つは、* Rainbowテーブル*を生成してクラウドベースを作成することです。 これは、アプリケーションのシングルおよびマルチプロセッシングバージョンの統合に役立ちます。これには、いくつかの考慮事項が必要です。
パイクラウド
Pi Cloudはクラウドコンピューティングプラットフォームであり、Pythonプログラミング言語とAmazon Web Servicesのコンピューティングパワーを統合します。
- レインボーテーブル*でPiクラウドを実装する例を見てみましょう。
レインボーテーブル
- レインボーテーブル*は、特定のハッシュアルゴリズムに固有の暗号化されたパスワードのすべての可能なプレーンテキスト順列のリストとして定義されます。
- レインボーテーブルは、ハッシュされたパスワードのリストを作成する標準パターンに従います。
- テキストファイルは、暗号化されるパスワードの文字またはプレーンテキストを含むパスワードを生成するために使用されます。
- このファイルは、保存されるメイン関数を呼び出すPiクラウドによって使用されます。
- ハッシュ化されたパスワードの出力もテキストファイルに保存されます。
このアルゴリズムを使用して、データベースにパスワードを保存したり、クラウドシステムにバックアップストレージを保持したりできます。
次の組み込みプログラムは、テキストファイルに暗号化されたパスワードのリストを作成します。
例
import os
import random
import hashlib
import string
import enchant #Rainbow tables with enchant
import cloud #importing pi-cloud
def randomword(length):
return ''.join(random.choice(string.lowercase) for i in range(length))
print('Author- Radhika Subramanian')
def mainroutine():
engdict = enchant.Dict("en_US")
fileb = open("password.txt","a+")
# Capture the values from the text file named password
while True:
randomword0 = randomword(6)
if engdict.check(randomword0) == True:
randomkey0 = randomword0+str(random.randint(0,99))
elif engdict.check(randomword0) == False:
englist = engdict.suggest(randomword0)
if len(englist) > 0:
randomkey0 = englist[0]+str(random.randint(0,99))
else:
randomkey0 = randomword0+str(random.randint(0,99))
randomword3 = randomword(5)
if engdict.check(randomword3) == True:
randomkey3 = randomword3+str(random.randint(0,99))
elif engdict.check(randomword3) == False:
englist = engdict.suggest(randomword3)
if len(englist) > 0:
randomkey3 = englist[0]+str(random.randint(0,99))
else:
randomkey3 = randomword3+str(random.randint(0,99))
if 'randomkey0' and 'randomkey3' and 'randomkey1' in locals():
whasher0 = hashlib.new("md5")
whasher0.update(randomkey0)
whasher3 = hashlib.new("md5")
whasher3.update(randomkey3)
whasher1 = hashlib.new("md5")
whasher1.update(randomkey1)
print(randomkey0+" + "+str(whasher0.hexdigest())+"\n")
print(randomkey3+" + "+str(whasher3.hexdigest())+"\n")
print(randomkey1+" + "+str(whasher1.hexdigest())+"\n")
fileb.write(randomkey0+" + "+str(whasher0.hexdigest())+"\n")
fileb.write(randomkey3+" + "+str(whasher3.hexdigest())+"\n")
fileb.write(randomkey1+" + "+str(whasher1.hexdigest())+"\n")
jid = cloud.call(randomword) #square(3) evaluated on PiCloud
cloud.result(jid)
print('Value added to cloud')
print('Password added')
mainroutine()
出力
このコードは、次の出力を生成します-
パスワードは、次のスクリーンショットに示すように、表示されるテキストファイルに保存されます。