Investigasi Menggunakan Email
Bab sebelumnya membahas tentang pentingnya dan proses forensik jaringan dan konsep yang terlibat. Di bab ini, mari kita pelajari tentang peran email dalam forensik digital dan penyelidikannya menggunakan Python.
Peran Email dalam Investigasi
Email memainkan peran yang sangat penting dalam komunikasi bisnis dan telah muncul sebagai salah satu aplikasi terpenting di internet. Mereka adalah mode yang nyaman untuk mengirim pesan dan juga dokumen, tidak hanya dari komputer tetapi juga dari gadget elektronik lainnya seperti ponsel dan tablet.
Sisi negatif dari email adalah penjahat dapat membocorkan informasi penting tentang perusahaan mereka. Karenanya, peran email dalam forensik digital telah meningkat dalam beberapa tahun terakhir. Dalam forensik digital, email dianggap sebagai bukti penting dan Analisis Header Email menjadi penting untuk mengumpulkan bukti selama proses forensik.
Seorang penyelidik memiliki tujuan berikut saat melakukan forensik email -
- Untuk mengidentifikasi penjahat utama
- Untuk mengumpulkan bukti yang diperlukan
- Untuk mempresentasikan temuan
- Untuk membangun kasus ini
Tantangan dalam Forensik Email
Forensik email memainkan peran yang sangat penting dalam penyelidikan karena sebagian besar komunikasi di era sekarang bergantung pada email. Namun, penyidik forensik email mungkin menghadapi tantangan berikut selama penyelidikan -
Email Palsu
Tantangan terbesar dalam email forensik adalah penggunaan email palsu yang dibuat dengan memanipulasi dan membuat skrip header dll. Dalam kategori ini, penjahat juga menggunakan email sementara yang merupakan layanan yang memungkinkan pengguna terdaftar untuk menerima email di alamat sementara yang kadaluwarsa. setelah jangka waktu tertentu.
Spoofing
Tantangan lain dalam forensik email adalah spoofing di mana penjahat biasa menampilkan email sebagai milik orang lain. Dalam hal ini mesin akan menerima alamat IP palsu dan asli.
Mengirim email ulang tanpa nama
Di sini, server Email menghapus informasi pengenal dari pesan email sebelum meneruskannya lebih jauh. Ini mengarah ke tantangan besar lainnya untuk investigasi email.
Teknik yang Digunakan dalam Investigasi Forensik Email
Forensik email adalah studi tentang sumber dan isi email sebagai bukti untuk mengidentifikasi pengirim dan penerima pesan yang sebenarnya bersama dengan beberapa informasi lain seperti tanggal / waktu pengiriman dan maksud pengirim. Ini melibatkan penyelidikan metadata, pemindaian port, serta pencarian kata kunci.
Beberapa teknik umum yang dapat digunakan untuk penyelidikan forensik email adalah
- Analisis Header
- Investigasi server
- Investigasi Perangkat Jaringan
- Sidik Jari Mailer Pengirim
- Pengenal Tertanam Perangkat Lunak
Pada bagian berikut, kita akan belajar bagaimana mengambil informasi menggunakan Python untuk keperluan investigasi email.
Ekstraksi Informasi dari file EML
File EML pada dasarnya adalah email dalam format file yang banyak digunakan untuk menyimpan pesan email. Mereka adalah file teks terstruktur yang kompatibel di beberapa klien email seperti Microsoft Outlook, Outlook Express, dan Windows Live Mail.
File EML menyimpan header email, konten isi, data lampiran sebagai teks biasa. Ini menggunakan base64 untuk menyandikan data biner dan pengkodean Quoted-Printable (QP) untuk menyimpan informasi konten. Skrip Python yang dapat digunakan untuk mengekstrak informasi dari file EML diberikan di bawah ini -
Pertama, impor pustaka Python berikut seperti yang ditunjukkan di bawah ini -
from __future__ import print_function
from argparse import ArgumentParser, FileType
from email import message_from_file
import os
import quopri
import base64
Di perpustakaan di atas, quopridigunakan untuk memecahkan kode nilai yang dikodekan QP dari file EML. Setiap data yang dikodekan base64 dapat didekodekan dengan bantuanbase64 Perpustakaan.
Selanjutnya, mari kita berikan argumen untuk penangan baris perintah. Perhatikan bahwa di sini hanya akan menerima satu argumen yang akan menjadi jalur ke file EML seperti yang ditunjukkan di bawah ini -
if __name__ == '__main__':
parser = ArgumentParser('Extracting information from EML file')
parser.add_argument("EML_FILE",help="Path to EML File", type=FileType('r'))
args = parser.parse_args()
main(args.EML_FILE)
Sekarang, kita perlu mendefinisikan main() fungsi di mana kita akan menggunakan metode bernama message_from_file()dari perpustakaan email untuk membaca file seperti objek. Di sini kita akan mengakses header, isi isi, lampiran, dan informasi muatan lainnya dengan menggunakan variabel yang dihasilkan bernamaemlfile seperti yang ditunjukkan pada kode yang diberikan di bawah ini -
def main(input_file):
emlfile = message_from_file(input_file)
for key, value in emlfile._headers:
print("{}: {}".format(key, value))
print("\nBody\n")
if emlfile.is_multipart():
for part in emlfile.get_payload():
process_payload(part)
else:
process_payload(emlfile[1])
Sekarang, kita perlu mendefinisikan process_payload() metode di mana kami akan mengekstrak konten tubuh pesan dengan menggunakan get_payload()metode. Kami akan memecahkan kode data yang dikodekan QP dengan menggunakanquopri.decodestring()fungsi. Kami juga akan memeriksa jenis konten MIME sehingga dapat menangani penyimpanan email dengan benar. Perhatikan kode yang diberikan di bawah ini -
def process_payload(payload):
print(payload.get_content_type() + "\n" + "=" * len(payload.get_content_type()))
body = quopri.decodestring(payload.get_payload())
if payload.get_charset():
body = body.decode(payload.get_charset())
else:
try:
body = body.decode()
except UnicodeDecodeError:
body = body.decode('cp1252')
if payload.get_content_type() == "text/html":
outfile = os.path.basename(args.EML_FILE.name) + ".html"
open(outfile, 'w').write(body)
elif payload.get_content_type().startswith('application'):
outfile = open(payload.get_filename(), 'wb')
body = base64.b64decode(payload.get_payload())
outfile.write(body)
outfile.close()
print("Exported: {}\n".format(outfile.name))
else:
print(body)
Setelah menjalankan skrip di atas, kita akan mendapatkan informasi header beserta berbagai muatan di konsol.
Menganalisis File MSG menggunakan Python
Pesan email datang dalam berbagai format. MSG adalah salah satu jenis format yang digunakan oleh Microsoft Outlook dan Exchange. File dengan ekstensi MSG dapat berisi teks ASCII biasa untuk tajuk dan badan pesan utama serta hyperlink dan lampiran.
Di bagian ini, kita akan mempelajari cara mengekstrak informasi dari file MSG menggunakan API Outlook. Perhatikan bahwa skrip Python berikut hanya akan berfungsi di Windows. Untuk ini, kita perlu menginstal pustaka Python pihak ketiga bernamapywin32 sebagai berikut -
pip install pywin32
Sekarang, impor pustaka berikut menggunakan perintah yang ditunjukkan -
from __future__ import print_function
from argparse import ArgumentParser
import os
import win32com.client
import pywintypes
Sekarang, mari kita berikan argumen untuk penangan baris perintah. Di sini akan menerima dua argumen, satu akan menjadi jalur ke file MSG dan lainnya akan menjadi folder keluaran yang diinginkan sebagai berikut -
if __name__ == '__main__':
parser = ArgumentParser(‘Extracting information from MSG file’)
parser.add_argument("MSG_FILE", help="Path to MSG file")
parser.add_argument("OUTPUT_DIR", help="Path to output folder")
args = parser.parse_args()
out_dir = args.OUTPUT_DIR
if not os.path.exists(out_dir):
os.makedirs(out_dir)
main(args.MSG_FILE, args.OUTPUT_DIR)
Sekarang, kita perlu mendefinisikan main() fungsi yang akan kami panggil win32com perpustakaan untuk menyiapkan Outlook API yang selanjutnya memungkinkan akses ke file MAPI namespace.
def main(msg_file, output_dir):
mapi = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
msg = mapi.OpenSharedItem(os.path.abspath(args.MSG_FILE))
display_msg_attribs(msg)
display_msg_recipients(msg)
extract_msg_body(msg, output_dir)
extract_attachments(msg, output_dir)
Sekarang, tentukan fungsi berbeda yang kita gunakan dalam skrip ini. Kode yang diberikan di bawah ini menunjukkan definisidisplay_msg_attribs() fungsi yang memungkinkan kita menampilkan berbagai atribut pesan seperti subject, to, BCC, CC, Size, SenderName, sent, dll.
def display_msg_attribs(msg):
attribs = [
'Application', 'AutoForwarded', 'BCC', 'CC', 'Class',
'ConversationID', 'ConversationTopic', 'CreationTime',
'ExpiryTime', 'Importance', 'InternetCodePage', 'IsMarkedAsTask',
'LastModificationTime', 'Links','ReceivedTime', 'ReminderSet',
'ReminderTime', 'ReplyRecipientNames', 'Saved', 'Sender',
'SenderEmailAddress', 'SenderEmailType', 'SenderName', 'Sent',
'SentOn', 'SentOnBehalfOfName', 'Size', 'Subject',
'TaskCompletedDate', 'TaskDueDate', 'To', 'UnRead'
]
print("\nMessage Attributes")
for entry in attribs:
print("{}: {}".format(entry, getattr(msg, entry, 'N/A')))
Sekarang, tentukan display_msg_recipeints() fungsi yang mengulangi pesan dan menampilkan detail penerima.
def display_msg_recipients(msg):
recipient_attrib = ['Address', 'AutoResponse', 'Name', 'Resolved', 'Sendable']
i = 1
while True:
try:
recipient = msg.Recipients(i)
except pywintypes.com_error:
break
print("\nRecipient {}".format(i))
print("=" * 15)
for entry in recipient_attrib:
print("{}: {}".format(entry, getattr(recipient, entry, 'N/A')))
i += 1
Selanjutnya, kami mendefinisikan extract_msg_body() fungsi yang mengekstrak konten tubuh, HTML serta teks biasa, dari pesan.
def extract_msg_body(msg, out_dir):
html_data = msg.HTMLBody.encode('cp1252')
outfile = os.path.join(out_dir, os.path.basename(args.MSG_FILE))
open(outfile + ".body.html", 'wb').write(html_data)
print("Exported: {}".format(outfile + ".body.html"))
body_data = msg.Body.encode('cp1252')
open(outfile + ".body.txt", 'wb').write(body_data)
print("Exported: {}".format(outfile + ".body.txt"))
Selanjutnya, kita akan mendefinisikan extract_attachments() fungsi yang mengekspor data lampiran ke direktori keluaran yang diinginkan.
def extract_attachments(msg, out_dir):
attachment_attribs = ['DisplayName', 'FileName', 'PathName', 'Position', 'Size']
i = 1 # Attachments start at 1
while True:
try:
attachment = msg.Attachments(i)
except pywintypes.com_error:
break
Setelah semua fungsi ditentukan, kami akan mencetak semua atribut ke konsol dengan baris kode berikut -
print("\nAttachment {}".format(i))
print("=" * 15)
for entry in attachment_attribs:
print('{}: {}'.format(entry, getattr(attachment, entry,"N/A")))
outfile = os.path.join(os.path.abspath(out_dir),os.path.split(args.MSG_FILE)[-1])
if not os.path.exists(outfile):
os.makedirs(outfile)
outfile = os.path.join(outfile, attachment.FileName)
attachment.SaveAsFile(outfile)
print("Exported: {}".format(outfile))
i += 1
Setelah menjalankan script di atas, kita akan mendapatkan atribut message dan lampirannya di jendela konsol bersama dengan beberapa file di direktori keluaran.
Menyusun file MBOX dari Google Takeout menggunakan Python
File MBOX adalah file teks dengan format khusus yang memisahkan pesan yang disimpan di dalamnya. Mereka sering kali ditemukan terkait dengan sistem UNIX, Thunderbolt, dan Google Takeouts.
Di bagian ini, Anda akan melihat skrip Python, di mana kami akan menyusun file MBOX yang didapat dari Google Takeouts. Tetapi sebelumnya kita harus tahu bagaimana kita dapat menghasilkan file MBOX ini dengan menggunakan akun Google atau akun Gmail kita.
Mendapatkan Kotak Surat Akun Google ke dalam Format MBX
Mendapatkan kotak surat akun Google berarti mengambil cadangan akun Gmail kami. Pencadangan dapat dilakukan untuk berbagai alasan pribadi atau profesional. Perhatikan bahwa Google menyediakan pencadangan data Gmail. Untuk mendapatkan kotak surat akun Google kami ke dalam format MBOX, Anda harus mengikuti langkah-langkah yang diberikan di bawah ini -
Buka My account dasbor.
Buka bagian Info pribadi & privasi dan pilih Kontrol tautan konten Anda.
Anda dapat membuat arsip baru atau mengelola arsip yang sudah ada. Jika kita mengklik,CREATE ARCHIVE tautan, lalu kita akan mendapatkan beberapa kotak centang untuk setiap produk Google yang ingin kita sertakan.
Setelah memilih produk, kita akan mendapatkan kebebasan untuk memilih jenis file dan ukuran maksimum untuk arsip kita bersama dengan metode pengiriman untuk memilih dari daftar.
Terakhir, kita akan mendapatkan backup ini dalam format MBOX.
Kode Python
Sekarang, file MBOX yang dibahas di atas dapat disusun menggunakan Python seperti yang ditunjukkan di bawah ini -
Pertama, perlu mengimpor pustaka Python sebagai berikut -
from __future__ import print_function
from argparse import ArgumentParser
import mailbox
import os
import time
import csv
from tqdm import tqdm
import base64
Semua pustaka telah digunakan dan dijelaskan dalam skrip sebelumnya, kecuali mailbox perpustakaan yang digunakan untuk mengurai file MBOX.
Sekarang, berikan argumen untuk penangan baris perintah. Di sini ia akan menerima dua argumen - satu akan menjadi jalur ke file MBOX, dan yang lainnya akan menjadi folder keluaran yang diinginkan.
if __name__ == '__main__':
parser = ArgumentParser('Parsing MBOX files')
parser.add_argument("MBOX", help="Path to mbox file")
parser.add_argument(
"OUTPUT_DIR",help = "Path to output directory to write report ""and exported content")
args = parser.parse_args()
main(args.MBOX, args.OUTPUT_DIR)
Sekarang, akan menentukan main() fungsi dan panggilan mbox kelas perpustakaan kotak surat dengan bantuan yang kita dapat mengurai file MBOX dengan memberikan jalurnya -
def main(mbox_file, output_dir):
print("Reading mbox file")
mbox = mailbox.mbox(mbox_file, factory=custom_reader)
print("{} messages to parse".format(len(mbox)))
Sekarang, tentukan metode pembaca untuk mailbox perpustakaan sebagai berikut -
def custom_reader(data_stream):
data = data_stream.read()
try:
content = data.decode("ascii")
except (UnicodeDecodeError, UnicodeEncodeError) as e:
content = data.decode("cp1252", errors="replace")
return mailbox.mboxMessage(content)
Sekarang, buat beberapa variabel untuk diproses lebih lanjut sebagai berikut -
parsed_data = []
attachments_dir = os.path.join(output_dir, "attachments")
if not os.path.exists(attachments_dir):
os.makedirs(attachments_dir)
columns = [
"Date", "From", "To", "Subject", "X-Gmail-Labels", "Return-Path", "Received",
"Content-Type", "Message-ID","X-GM-THRID", "num_attachments_exported", "export_path"]
Selanjutnya, gunakan tqdm untuk menghasilkan bilah kemajuan dan melacak proses iterasi sebagai berikut -
for message in tqdm(mbox):
msg_data = dict()
header_data = dict(message._headers)
for hdr in columns:
msg_data[hdr] = header_data.get(hdr, "N/A")
Sekarang, periksa apakah pesan cuaca memiliki muatan atau tidak. Jika sudah maka akan kita definisikanwrite_payload() metode sebagai berikut -
if len(message.get_payload()):
export_path = write_payload(message, attachments_dir)
msg_data['num_attachments_exported'] = len(export_path)
msg_data['export_path'] = ", ".join(export_path)
Sekarang, data perlu ditambahkan. Kemudian kami akan meneleponcreate_report() metode sebagai berikut -
parsed_data.append(msg_data)
create_report(
parsed_data, os.path.join(output_dir, "mbox_report.csv"), columns)
def write_payload(msg, out_dir):
pyld = msg.get_payload()
export_path = []
if msg.is_multipart():
for entry in pyld:
export_path += write_payload(entry, out_dir)
else:
content_type = msg.get_content_type()
if "application/" in content_type.lower():
content = base64.b64decode(msg.get_payload())
export_path.append(export_content(msg, out_dir, content))
elif "image/" in content_type.lower():
content = base64.b64decode(msg.get_payload())
export_path.append(export_content(msg, out_dir, content))
elif "video/" in content_type.lower():
content = base64.b64decode(msg.get_payload())
export_path.append(export_content(msg, out_dir, content))
elif "audio/" in content_type.lower():
content = base64.b64decode(msg.get_payload())
export_path.append(export_content(msg, out_dir, content))
elif "text/csv" in content_type.lower():
content = base64.b64decode(msg.get_payload())
export_path.append(export_content(msg, out_dir, content))
elif "info/" in content_type.lower():
export_path.append(export_content(msg, out_dir,
msg.get_payload()))
elif "text/calendar" in content_type.lower():
export_path.append(export_content(msg, out_dir,
msg.get_payload()))
elif "text/rtf" in content_type.lower():
export_path.append(export_content(msg, out_dir,
msg.get_payload()))
else:
if "name=" in msg.get('Content-Disposition', "N/A"):
content = base64.b64decode(msg.get_payload())
export_path.append(export_content(msg, out_dir, content))
elif "name=" in msg.get('Content-Type', "N/A"):
content = base64.b64decode(msg.get_payload())
export_path.append(export_content(msg, out_dir, content))
return export_path
Perhatikan bahwa pernyataan if-else di atas mudah dipahami. Sekarang, kita perlu mendefinisikan metode yang akan mengekstrak nama file dari filemsg objek sebagai berikut -
def export_content(msg, out_dir, content_data):
file_name = get_filename(msg)
file_ext = "FILE"
if "." in file_name: file_ext = file_name.rsplit(".", 1)[-1]
file_name = "{}_{:.4f}.{}".format(file_name.rsplit(".", 1)[0], time.time(), file_ext)
file_name = os.path.join(out_dir, file_name)
Sekarang, dengan bantuan baris kode berikut, Anda sebenarnya dapat mengekspor file -
if isinstance(content_data, str):
open(file_name, 'w').write(content_data)
else:
open(file_name, 'wb').write(content_data)
return file_name
Sekarang, mari kita tentukan fungsi untuk mengekstrak nama file dari message untuk merepresentasikan nama file ini secara akurat sebagai berikut -
def get_filename(msg):
if 'name=' in msg.get("Content-Disposition", "N/A"):
fname_data = msg["Content-Disposition"].replace("\r\n", " ")
fname = [x for x in fname_data.split("; ") if 'name=' in x]
file_name = fname[0].split("=", 1)[-1]
elif 'name=' in msg.get("Content-Type", "N/A"):
fname_data = msg["Content-Type"].replace("\r\n", " ")
fname = [x for x in fname_data.split("; ") if 'name=' in x]
file_name = fname[0].split("=", 1)[-1]
else:
file_name = "NO_FILENAME"
fchars = [x for x in file_name if x.isalnum() or x.isspace() or x == "."]
return "".join(fchars)
Sekarang, kita dapat menulis file CSV dengan mendefinisikan create_report() berfungsi sebagai berikut -
def create_report(output_data, output_file, columns):
with open(output_file, 'w', newline="") as outfile:
csvfile = csv.DictWriter(outfile, columns)
csvfile.writeheader()
csvfile.writerows(output_data)
Setelah Anda menjalankan skrip yang diberikan di atas, kami akan mendapatkan laporan CSV dan direktori yang penuh dengan lampiran.