Python Digital Forensics - Panduan Cepat

Bab ini akan memberi Anda pengantar tentang apa itu forensik digital, dan ulasan historisnya. Anda juga akan memahami di mana Anda dapat menerapkan forensik digital dalam kehidupan nyata dan keterbatasannya.

Apa itu Digital Forensik?

Forensik digital dapat didefinisikan sebagai cabang ilmu forensik yang menganalisis, memeriksa, mengidentifikasi dan memulihkan bukti digital yang berada pada perangkat elektronik. Ini biasanya digunakan untuk hukum pidana dan investigasi pribadi.

Misalnya, Anda dapat mengandalkan bukti ekstrak forensik digital jika seseorang mencuri beberapa data di perangkat elektronik.

Ulasan Sejarah Singkat Forensik Digital

Sejarah kejahatan komputer dan tinjauan sejarah forensik digital dijelaskan di bagian ini seperti yang diberikan di bawah ini -

1970-an-1980-an: Kejahatan Komputer Pertama

Sebelum dekade ini, tidak ada kejahatan komputer yang diakui. Namun, jika itu seharusnya terjadi, maka hukum yang ada menanganinya. Kemudian, pada tahun 1978 kejahatan komputer pertama diakui di Florida Computer Crime Act, yang mencakup undang-undang yang melarang modifikasi atau penghapusan data pada sistem komputer yang tidak sah. Namun seiring berjalannya waktu, seiring dengan kemajuan teknologi, cakupan kejahatan komputer yang dilakukan juga semakin meningkat. Untuk menangani kejahatan yang berkaitan dengan hak cipta, privasi dan pornografi anak, berbagai undang-undang lain disahkan.

1980-an-1990-an: Dekade Pembangunan

Dekade ini adalah dekade perkembangan forensik digital, semua karena investigasi pertama (1986) di mana Cliff Stoll melacak peretas bernama Markus Hess. Dalam kurun waktu ini berkembang dua macam disiplin ilmu forensik digital - pertama dengan bantuan alat dan teknik ad-hoc yang dikembangkan oleh para praktisi yang menganggapnya sebagai hobi, sedangkan yang kedua dikembangkan oleh komunitas ilmiah. Pada tahun 1992, istilah tersebut“Computer Forensics”digunakan dalam literatur akademis.

2000s-2010s: Dekade Standardisasi

Setelah perkembangan forensik digital ke tingkat tertentu, perlu dibuat beberapa standar khusus yang dapat diikuti saat melakukan investigasi. Karenanya, berbagai badan dan badan ilmiah telah menerbitkan pedoman forensik digital. Pada tahun 2002, Kelompok Kerja Ilmiah tentang Bukti Digital (SWGDE) menerbitkan sebuah makalah berjudul "Praktik terbaik untuk Forensik Komputer". Bulu lain di topi adalah perjanjian internasional yang dipimpin Eropa yaitu“The Convention on Cybercrime”ditandatangani oleh 43 negara dan diratifikasi oleh 16 negara. Bahkan setelah standar tersebut, masih ada kebutuhan untuk menyelesaikan beberapa masalah yang telah diidentifikasi oleh peneliti.

Proses Forensik Digital

Sejak kejahatan komputer pertama kali pada tahun 1978, ada peningkatan besar dalam aktivitas kriminal digital. Karena kenaikan ini, diperlukan cara yang terstruktur untuk menghadapinya. Pada tahun 1984, proses formal telah diperkenalkan dan setelah itu sejumlah besar proses investigasi forensik komputer yang baru dan lebih baik telah dikembangkan.

Proses investigasi forensik komputer melibatkan tiga fase utama seperti yang dijelaskan di bawah -

Tahap 1: Akuisisi atau Pencitraan Pameran

Tahap pertama forensik digital melibatkan penyelamatan keadaan sistem digital sehingga dapat dianalisis nanti. Ini sangat mirip dengan mengambil foto, sampel darah, dll. Dari TKP. Misalnya, ini melibatkan pengambilan gambar dari area yang dialokasikan dan tidak terisi dari hard disk atau RAM.

Tahap 2: Analisis

Input dari fase ini adalah data yang diperoleh pada fase akuisisi. Di sini, data tersebut diperiksa untuk mengidentifikasi barang bukti. Fase ini memberikan tiga jenis alat bukti sebagai berikut -

  • Inculpatory evidences - Bukti-bukti ini mendukung sejarah tertentu.

  • Exculpatory evidences - Bukti-bukti ini bertentangan dengan sejarah tertentu.

  • Evidence of tampering- Bukti-bukti ini menunjukkan bahwa sistem dirancang untuk menghindari identifikasi. Ini termasuk memeriksa file dan konten direktori untuk memulihkan file yang dihapus.

Tahap 3: Presentasi atau Pelaporan

Seperti namanya, fase ini menyajikan kesimpulan dan bukti-bukti terkait dari penyelidikan.

Aplikasi Forensik Digital

Forensik digital berkaitan dengan pengumpulan, analisis, dan pelestarian bukti-bukti yang terkandung dalam perangkat digital apa pun. Penggunaan forensik digital tergantung pada aplikasinya. Seperti yang disebutkan sebelumnya, ini digunakan terutama dalam dua aplikasi berikut -

Hukum Kriminal

Dalam hukum pidana, bukti dikumpulkan untuk mendukung atau menentang hipotesis di pengadilan. Prosedur forensik sangat mirip dengan yang digunakan dalam investigasi kriminal tetapi dengan persyaratan dan batasan hukum yang berbeda.

Investigasi Pribadi

Terutama dunia korporat menggunakan forensik digital untuk penyelidikan pribadi. Ini digunakan ketika perusahaan curiga bahwa karyawan mungkin melakukan aktivitas ilegal di komputer mereka yang bertentangan dengan kebijakan perusahaan. Forensik digital menyediakan salah satu rute terbaik bagi perusahaan atau orang untuk diambil ketika menyelidiki seseorang untuk kesalahan digital.

Cabang dari Digital Forensik

Kejahatan digital tidak terbatas pada komputer saja, namun peretas dan penjahat menggunakan perangkat digital kecil seperti tablet, ponsel pintar, dll. Dalam skala yang sangat besar juga. Beberapa perangkat memiliki memori volatile, sementara yang lain memiliki memori non-volatile. Karenanya tergantung pada jenis perangkat, forensik digital memiliki cabang berikut -

Forensik Komputer

Cabang forensik digital ini berhubungan dengan komputer, sistem tertanam, dan memori statis seperti drive USB. Berbagai macam informasi dari log ke file aktual di drive dapat diselidiki di forensik komputer.

Forensik Seluler

Ini berkaitan dengan penyelidikan data dari perangkat seluler. Cabang ini berbeda dengan forensik komputer dalam artian bahwa perangkat seluler memiliki sistem komunikasi bawaan yang berguna untuk memberikan informasi yang berguna terkait lokasi.

Forensik Jaringan

Ini berkaitan dengan pemantauan dan analisis lalu lintas jaringan komputer, baik lokal maupun WAN (jaringan area luas) untuk tujuan pengumpulan informasi, pengumpulan bukti, atau deteksi intrusi.

Forensik Database

Cabang forensik digital ini berkaitan dengan studi forensik database dan metadatanya.

Keterampilan yang Diperlukan untuk Investigasi Forensik Digital

Pemeriksa forensik digital membantu melacak peretas, memulihkan data yang dicuri, mengikuti serangan komputer kembali ke sumbernya, dan membantu jenis penyelidikan lain yang melibatkan komputer. Beberapa keterampilan utama yang dibutuhkan untuk menjadi pemeriksa forensik digital seperti yang dibahas di bawah ini -

Kemampuan Berpikir Luar Biasa

Seorang penyelidik forensik digital harus menjadi pemikir yang luar biasa dan harus mampu menerapkan alat dan metodologi yang berbeda pada tugas tertentu untuk mendapatkan hasil. Ia harus dapat menemukan pola yang berbeda dan membuat korelasi di antara mereka.

Keterampilan teknis

Seorang pemeriksa forensik digital harus memiliki keterampilan teknologi yang baik karena bidang ini membutuhkan pengetahuan tentang jaringan, bagaimana sistem digital berinteraksi.

Bergairah tentang Keamanan Cyber

Karena bidang forensik digital adalah tentang menyelesaikan kejahatan dunia maya dan ini adalah tugas yang membosankan, dibutuhkan banyak semangat bagi seseorang untuk menjadi penyelidik forensik digital yang andal.

Kemampuan berkomunikasi

Keterampilan komunikasi yang baik adalah suatu keharusan untuk berkoordinasi dengan berbagai tim dan untuk mengekstrak data atau informasi yang hilang.

Terampil dalam Pembuatan Laporan

Setelah implementasi akuisisi dan analisis berhasil, pemeriksa forensik digital harus menyebutkan semua temuan laporan akhir dan presentasi. Oleh karena itu, ia harus memiliki keterampilan yang baik dalam membuat laporan dan memperhatikan detail.

Batasan

Investigasi forensik digital menawarkan batasan tertentu seperti yang dibahas di sini -

Perlu menghasilkan bukti yang meyakinkan

Salah satu kemunduran utama investigasi forensik digital adalah pemeriksa harus memenuhi standar yang diperlukan untuk pembuktian di pengadilan, karena datanya dapat dengan mudah dirusak. Di sisi lain, penyidik ​​forensik komputer harus memiliki pengetahuan yang lengkap tentang persyaratan hukum, penanganan barang bukti dan tata cara dokumentasi untuk menyajikan alat bukti yang meyakinkan di pengadilan.

Alat Investigasi

Efektivitas investigasi digital sepenuhnya terletak pada keahlian pemeriksa forensik digital dan pemilihan alat investigasi yang tepat. Jika alat yang digunakan tidak sesuai dengan standar yang ditentukan maka di pengadilan, alat bukti dapat disangkal oleh hakim.

Kurangnya pengetahuan teknis di antara penonton

Batasan lain adalah bahwa beberapa individu tidak sepenuhnya akrab dengan forensik komputer; Oleh karena itu, banyak orang yang tidak memahami bidang ini. Penyidik ​​harus memastikan untuk mengkomunikasikan temuan mereka dengan pengadilan sedemikian rupa untuk membantu semua orang memahami hasil.

Biaya

Menghasilkan bukti digital dan melestarikannya sangat mahal. Oleh karena itu, proses ini mungkin tidak dipilih oleh banyak orang yang tidak mampu membayar biayanya.

Pada bab sebelumnya, kita mempelajari dasar-dasar forensik digital, kelebihan dan kekurangannya. Bab ini akan membuat Anda nyaman dengan Python, alat penting yang kami gunakan dalam penyelidikan forensik digital ini.

Mengapa Python untuk Digital Forensics?

Python adalah bahasa pemrograman yang populer dan digunakan sebagai alat untuk keamanan dunia maya, pengujian penetrasi, serta investigasi forensik digital. Saat Anda memilih Python sebagai alat forensik digital, Anda tidak memerlukan perangkat lunak pihak ketiga lainnya untuk menyelesaikan tugas tersebut.

Beberapa fitur unik dari bahasa pemrograman Python yang membuatnya cocok untuk proyek forensik digital diberikan di bawah ini -

  • Simplicity of Syntax - Sintaks Python sederhana dibandingkan dengan bahasa lain, yang membuatnya lebih mudah untuk dipelajari dan digunakan untuk forensik digital.

  • Comprehensive inbuilt modules - Modul inbuilt komprehensif Python adalah bantuan yang sangat baik untuk melakukan investigasi forensik digital lengkap.

  • Help and Support - Menjadi bahasa pemrograman open source, Python menikmati dukungan luar biasa dari komunitas pengembang dan pengguna.

Fitur Python

Python, sebagai bahasa skrip tingkat tinggi, ditafsirkan, interaktif dan berorientasi objek, menyediakan fitur-fitur berikut -

  • Easy to Learn - Python adalah bahasa yang ramah pengembang dan mudah dipelajari, karena memiliki lebih sedikit kata kunci dan struktur paling sederhana.

  • Expressive and Easy to read- Bahasa Python bersifat ekspresif; karenanya kodenya lebih mudah dipahami dan dibaca.

  • Cross-platform Compatible - Python adalah bahasa yang kompatibel dengan lintas platform yang artinya dapat berjalan secara efisien di berbagai platform seperti UNIX, Windows, dan Macintosh.

  • Interactive Mode Programming - Kita dapat melakukan pengujian interaktif dan debugging kode karena Python mendukung mode interaktif untuk pemrograman.

  • Provides Various Modules and Functions - Python memiliki pustaka standar yang besar yang memungkinkan kita untuk menggunakan kumpulan modul dan fungsi yang kaya untuk skrip kita.

  • Supports Dynamic Type Checking - Python mendukung pemeriksaan tipe dinamis dan menyediakan tipe data dinamis tingkat tinggi.

  • GUI Programming - Python mendukung pemrograman GUI untuk mengembangkan antarmuka pengguna grafis.

  • Integration with other programming languages - Python dapat dengan mudah diintegrasikan dengan bahasa pemrograman lain seperti C, C ++, JAVA dll.

Menginstal Python

Distribusi Python tersedia untuk berbagai platform seperti Windows, UNIX, Linux, dan Mac. Kami hanya perlu mengunduh kode biner sesuai platform kami. Jika kode biner untuk platform apa pun tidak tersedia, kita harus memiliki kompiler C agar kode sumber dapat dikompilasi secara manual.

Bagian ini akan membuat Anda terbiasa dengan instalasi Python pada berbagai platform−

Instalasi Python di Unix dan Linux

Anda dapat mengikuti langkah-langkah yang ditunjukkan di bawah ini untuk menginstal Python di mesin Unix / Linux.

Step 1- Buka browser web. Ketik dan masukkan www.python.org/downloads/

Step 2 - Unduh kode sumber zip yang tersedia untuk Unix / Linux.

Step 3 - Ekstrak file zip yang diunduh.

Step 4 - Jika Anda ingin menyesuaikan beberapa opsi, Anda dapat mengedit file Modules/Setup file.

Step 5 - Gunakan perintah berikut untuk menyelesaikan instalasi -

run ./configure script
make
make install

Setelah Anda berhasil menyelesaikan langkah-langkah yang diberikan di atas, Python akan diinstal di lokasi standarnya /usr/local/bin dan perpustakaannya di /usr/local/lib/pythonXX dimana XX adalah versi Python.

Instalasi Python di Windows

Kami dapat mengikuti langkah-langkah sederhana berikut untuk menginstal Python di mesin Windows.

Step 1- Buka browser web. Ketik dan masukkan www.python.org/downloads/

Step 2 - Unduh penginstal Windows python-XYZ.msi file, di mana XYZ adalah versi yang perlu kita instal.

Step 3 - Sekarang jalankan file MSI itu setelah menyimpan file penginstal ke mesin lokal Anda.

Step 4 - Jalankan file yang diunduh yang akan memunculkan wizard instalasi Python.

Instalasi Python di Macintosh

Untuk menginstal Python 3 di Mac OS X, kita harus menggunakan penginstal paket bernama Homebrew.

Anda dapat menggunakan perintah berikut untuk menginstal Homebrew, jika Anda tidak memilikinya di sistem Anda -

$ ruby -e "$(curl -fsSL
https://raw.githubusercontent.com/Homebrew/install/master/install)"

Jika Anda perlu memperbarui manajer paket, maka itu dapat dilakukan dengan bantuan perintah berikut -

$ brew update

Sekarang, gunakan perintah berikut untuk menginstal Python3 di sistem Anda -

$ brew install python3

Mengatur PATH

Kita perlu mengatur jalur untuk instalasi Python dan ini berbeda dengan platform seperti UNIX, WINDOWS, atau MAC.

Pengaturan jalur di Unix / Linux

Anda dapat menggunakan opsi berikut untuk mengatur jalur di Unix / Linux -

  • If using csh shell - Tipe setenv PATH "$PATH:/usr/local/bin/python" lalu tekan Enter.

  • If using bash shell (Linux) - Ketik export ATH="$PATH:/usr/local/bin/python" lalu tekan Enter.

  • If using sh or ksh shell - Tipe PATH="$PATH:/usr/local/bin/python" lalu tekan Enter.

Path Setting di Windows

Tipe path %path%;C:\Python pada prompt perintah dan kemudian tekan Enter.

Menjalankan Python

Anda dapat memilih salah satu dari tiga metode berikut untuk memulai penerjemah Python -

Metode 1: Menggunakan Interpreter Interaktif

Sistem yang menyediakan penafsir baris perintah atau shell dapat dengan mudah digunakan untuk memulai Python. Misalnya, Unix, DOS, dll. Anda dapat mengikuti langkah-langkah yang diberikan di bawah ini untuk memulai pengkodean dalam interpreter interaktif -

Step 1 - Masuk python di baris perintah.

Step 2 - Mulai coding segera di interpreter interaktif menggunakan perintah yang ditunjukkan di bawah ini -

$python # Unix/Linux
or
python% # Unix/Linux
or
C:> python # Windows/DOS

Metode 2: Menggunakan Script dari Command-line

Kita juga dapat menjalankan skrip Python pada baris perintah dengan memanggil juru bahasa pada aplikasi kita. Anda dapat menggunakan perintah yang ditunjukkan di bawah ini -

$python script.py # Unix/Linux
or
python% script.py # Unix/Linux
or
C: >python script.py # Windows/DOS

Metode 3: Lingkungan Pembangunan Terpadu

Jika suatu sistem memiliki aplikasi GUI yang mendukung Python, maka Python dapat dijalankan dari lingkungan GUI tersebut. Beberapa IDE untuk berbagai platform diberikan di bawah ini -

  • Unix IDE - UNIX memiliki IDLE IDE untuk Python.

  • Windows IDE - Windows memiliki PythonWin, antarmuka Windows pertama untuk Python bersama dengan GUI.

  • Macintosh IDE - Macintosh memiliki IDLE IDE yang tersedia dari situs web utama, dapat diunduh sebagai file MacBinary atau BinHex.

Sekarang setelah Anda merasa nyaman dengan instalasi dan menjalankan perintah Python di sistem lokal Anda, mari kita beralih ke konsep forensik secara detail. Bab ini akan menjelaskan berbagai konsep yang terlibat dalam menangani artefak di forensik digital Python.

Kebutuhan Pembuatan Laporan

Proses forensik digital mencakup pelaporan sebagai tahap ketiga. Ini adalah salah satu bagian terpenting dari proses forensik digital. Pembuatan laporan diperlukan karena alasan berikut -

  • Ini adalah dokumen di mana pemeriksa forensik digital menguraikan proses investigasi dan temuannya.

  • Laporan forensik digital yang baik dapat direferensikan oleh pemeriksa lain untuk mencapai hasil yang sama dengan memberikan repositori yang sama.

  • Ini adalah dokumen teknis dan ilmiah yang berisi fakta yang ditemukan dalam bukti digital 1 dan 0.

Panduan Umum Pembuatan Laporan

Laporan ditulis untuk memberikan informasi kepada pembaca dan harus dimulai dengan dasar yang kokoh. penyidik ​​dapat menghadapi kesulitan dalam menyajikan temuan mereka secara efisien jika laporan dibuat tanpa pedoman atau standar umum. Beberapa pedoman umum yang harus diikuti saat membuat laporan forensik digital diberikan di bawah ini -

  • Summary - Laporan harus memuat rangkuman informasi yang singkat sehingga pembaca dapat mengetahui tujuan laporan tersebut.

  • Tools used - Kami harus menyebutkan alat-alat yang selama ini digunakan untuk menjalankan proses forensik digital, termasuk tujuannya.

  • Repository - Misalkan kita menginvestigasi komputer seseorang kemudian ringkasan bukti dan analisis materi yang relevan seperti email, riwayat pencarian internal dll, kemudian harus dimasukkan dalam laporan agar kasus tersebut dapat disajikan dengan jelas.

  • Recommendations for counsel - Laporan harus memiliki rekomendasi bagi penasehat untuk melanjutkan atau menghentikan investigasi berdasarkan temuan dalam laporan.

Membuat Jenis Laporan yang Berbeda

Pada bagian di atas, kami mengetahui tentang pentingnya report dalam forensik digital bersama dengan pedoman untuk membuatnya. Beberapa format dalam Python untuk membuat berbagai jenis laporan dibahas di bawah -

Laporan CSV

Salah satu format keluaran laporan yang paling umum adalah laporan spreadsheet CSV. Anda dapat membuat CSV untuk membuat laporan data yang diproses menggunakan kode Python seperti yang ditunjukkan di bawah ini -

Pertama, impor perpustakaan yang berguna untuk menulis spreadsheet -

from __future__ import print_function
import csv
import os
import sys

Sekarang, panggil metode berikut -

Write_csv(TEST_DATA_LIST, ["Name", "Age", "City", "Job description"], os.getcwd())

Kami menggunakan variabel global berikut untuk mewakili tipe data sampel -

TEST_DATA_LIST = [["Ram", 32, Bhopal, Manager], 
   ["Raman", 42, Indore, Engg.],
   ["Mohan", 25, Chandigarh, HR], 
   ["Parkash", 45, Delhi, IT]]

Selanjutnya, mari kita tentukan metode untuk melanjutkan operasi lebih lanjut. Kami membuka file dalam mode "w" dan mengatur argumen kata kunci baris baru ke string kosong.

def Write_csv(data, header, output_directory, name = None):
   if name is None:
      name = "report1.csv"
   print("[+] Writing {} to {}".format(name, output_directory))
   
   with open(os.path.join(output_directory, name), "w", newline = "") as \ csvfile:
      writer = csv.writer(csvfile)
      writer.writerow(header)
      writer.writerow(data)

Jika Anda menjalankan skrip di atas, Anda akan mendapatkan detail berikut yang disimpan dalam file report1.csv.

Nama Usia Kota Penunjukan
Ram 32 Bhopal Managerh
Raman 42 Indore Engg
Mohan 25 Chandigarh HR
Parkash 45 Delhi ITU

Laporan Excel

Format keluaran umum lainnya dari laporan adalah laporan spreadsheet Excel (.xlsx). Kita dapat membuat tabel dan juga memplot grafik dengan menggunakan Excel. Kami dapat membuat laporan data yang diproses dalam format Excel menggunakan kode Python seperti yang ditunjukkan di bawah-

Pertama, impor modul XlsxWriter untuk membuat spreadsheet -

import xlsxwriter

Sekarang, buat objek buku kerja. Untuk ini, kita perlu menggunakan konstruktor Workbook ().

workbook = xlsxwriter.Workbook('report2.xlsx')

Sekarang, buat lembar kerja baru dengan menggunakan modul add_worksheet ().

worksheet = workbook.add_worksheet()

Selanjutnya, tulis data berikut ke dalam lembar kerja -

report2 = (['Ram', 32, ‘Bhopal’],['Mohan',25, ‘Chandigarh’] ,['Parkash',45, ‘Delhi’])

row = 0
col = 0

Anda dapat mengulang data ini dan menuliskannya sebagai berikut -

for item, cost in (a):
   worksheet.write(row, col, item)
   worksheet.write(row, col+1, cost)
   row + = 1

Sekarang, mari kita tutup file Excel ini dengan menggunakan metode close ().

workbook.close()

Script di atas akan membuat file Excel bernama report2.xlsx yang memiliki data berikut -

Ram 32 Bhopal
Mohan 25 Chandigarh
Parkash 45 Delhi

Media Akuisisi Investigasi

Penting bagi penyidik ​​untuk memiliki catatan investigasi terperinci untuk mengingat secara akurat temuan atau mengumpulkan semua bagian investigasi. Tangkapan layar sangat berguna untuk melacak langkah-langkah yang diambil untuk penyelidikan tertentu. Dengan bantuan kode Python berikut, kita dapat mengambil tangkapan layar dan menyimpannya di hard disk untuk digunakan nanti.

Pertama, instal modul Python bernama pyscreenshot dengan menggunakan perintah berikut -

Pip install pyscreenshot

Sekarang, impor modul yang diperlukan seperti yang ditunjukkan -

import pyscreenshot as ImageGrab

Gunakan baris kode berikut untuk mendapatkan tangkapan layar -

image = ImageGrab.grab()

Gunakan baris kode berikut untuk menyimpan tangkapan layar ke lokasi tertentu -

image.save('d:/image123.png')

Sekarang, jika Anda ingin menampilkan tangkapan layar sebagai grafik, Anda dapat menggunakan kode Python berikut -

import numpy as np
import matplotlib.pyplot as plt
import pyscreenshot as ImageGrab
imageg = ImageGrab.grab()
plt.imshow(image, cmap='gray', interpolation='bilinear')
plt.show()

Bab ini akan menjelaskan forensik digital Python pada perangkat seluler dan konsep yang terlibat.

pengantar

Forensik perangkat seluler adalah cabang forensik digital yang berhubungan dengan akuisisi dan analisis perangkat seluler untuk memulihkan bukti digital dari minat investigasi. Cabang ini berbeda dengan forensik komputer karena perangkat seluler memiliki sistem komunikasi bawaan yang berguna untuk memberikan informasi berguna terkait lokasi.

Meskipun penggunaan smartphone meningkat dalam forensik digital dari hari ke hari, tetap saja itu dianggap tidak standar karena heterogenitasnya. Di sisi lain, perangkat keras komputer, seperti hard disk, dianggap standar dan juga dikembangkan sebagai disiplin yang stabil. Dalam industri forensik digital, ada banyak perdebatan tentang teknik yang digunakan untuk perangkat non-standar, yang memiliki bukti sementara, seperti smartphone.

Artefak Diekstraksi dari Perangkat Seluler

Perangkat seluler modern memiliki banyak informasi digital dibandingkan dengan ponsel lama yang hanya memiliki log panggilan atau pesan SMS. Dengan demikian, perangkat seluler dapat memberikan banyak wawasan kepada penyelidik tentang penggunanya. Beberapa artefak yang dapat diekstraksi dari perangkat seluler adalah seperti yang disebutkan di bawah ini -

  • Messages - Ini adalah artefak berguna yang dapat mengungkapkan keadaan pikiran pemiliknya dan bahkan dapat memberikan beberapa informasi yang tidak diketahui sebelumnya kepada penyelidik.

  • Location History- Data riwayat lokasi adalah artefak berguna yang dapat digunakan oleh penyelidik untuk memvalidasi tentang lokasi tertentu seseorang.

  • Applications Installed - Dengan mengakses jenis aplikasi yang diinstal, penyelidik mendapatkan beberapa wawasan tentang kebiasaan dan pemikiran pengguna ponsel.

Sumber Bukti dan Pemrosesan dengan Python

Ponsel cerdas memiliki basis data SQLite dan file PLIST sebagai sumber utama bukti. Pada bagian ini kita akan memproses sumber-sumber bukti dengan menggunakan python.

Menganalisis file PLIST

PLIST (Daftar Properti) adalah format yang fleksibel dan nyaman untuk menyimpan data aplikasi terutama pada perangkat iPhone. Ini menggunakan ekstensi.plist. Jenis file yang digunakan untuk menyimpan informasi tentang bundel dan aplikasi. Ini bisa dalam dua format:XML dan binary. Kode Python berikut akan membuka dan membaca file PLIST. Perhatikan bahwa sebelum melanjutkan ke ini, kita harus membuatnya sendiriInfo.plist mengajukan.

Pertama, instal pustaka pihak ketiga bernama biplist dengan perintah berikut -

Pip install biplist

Sekarang, impor beberapa pustaka yang berguna untuk memproses file plist -

import biplist
import os
import sys

Sekarang, gunakan perintah berikut di bawah metode utama dapat digunakan untuk membaca file plist menjadi variabel -

def main(plist):
   try:
      data = biplist.readPlist(plist)
   except (biplist.InvalidPlistException,biplist.NotBinaryPlistException) as e:
print("[-] Invalid PLIST file - unable to be opened by biplist")
sys.exit(1)

Sekarang, kita dapat membaca data di konsol atau langsung mencetaknya, dari variabel ini.

Database SQLite

SQLite berfungsi sebagai tempat penyimpanan data utama di perangkat seluler. SQLite pustaka dalam proses yang mengimplementasikan mesin database SQL transaksional, tanpa server, tanpa konfigurasi, dan mandiri. Ini adalah database, yang tidak terkonfigurasi, Anda tidak perlu mengkonfigurasinya di sistem Anda, tidak seperti database lain.

Jika Anda seorang pemula atau tidak terbiasa dengan database SQLite, Anda dapat mengikuti tautan www.tutorialspoint.com/sqlite/index.htm Selain itu, Anda dapat mengikuti tautan www.tutorialspoint.com/sqlite/sqlite_python.htm jika Anda ingin membahas detail SQLite dengan Python.

Selama forensik seluler, kita dapat berinteraksi dengan sms.db file dari perangkat seluler dan dapat mengekstrak informasi berharga dari messagemeja. Python memiliki pustaka bawaan bernamasqlite3untuk menghubungkan dengan database SQLite. Anda dapat mengimpor yang sama dengan perintah berikut -

import sqlite3

Sekarang, dengan bantuan perintah berikut, kita dapat terhubung dengan database, misalnya sms.db dalam kasus perangkat seluler -

Conn = sqlite3.connect(‘sms.db’)
C = conn.cursor()

Di sini, C adalah objek kursor dengan bantuan yang bisa kita gunakan untuk berinteraksi dengan database.

Sekarang, misalkan jika kita ingin menjalankan perintah tertentu, katakan untuk mendapatkan detail dari abc table, itu dapat dilakukan dengan bantuan perintah berikut -

c.execute(“Select * from abc”)
c.close()

Hasil dari perintah di atas akan disimpan di file cursorobyek. Demikian pula yang bisa kita gunakanfetchall() metode untuk membuang hasil ke dalam variabel yang dapat kita manipulasi.

Kita dapat menggunakan perintah berikut untuk mendapatkan data nama kolom dari tabel pesan sms.db -

c.execute(“pragma table_info(message)”)
table_data = c.fetchall()
columns = [x[1] for x in table_data

Perhatikan bahwa di sini kita menggunakan perintah SQLite PRAGMA yang merupakan perintah khusus yang akan digunakan untuk mengontrol berbagai variabel lingkungan dan bendera negara dalam lingkungan SQLite. Pada perintah di atas, filefetchall()metode mengembalikan tupel hasil. Setiap nama kolom disimpan di indeks pertama setiap tupel.

Sekarang, dengan bantuan perintah berikut kita dapat melakukan kueri tabel untuk semua datanya dan menyimpannya dalam variabel bernama data_msg -

c.execute(“Select * from message”)
data_msg = c.fetchall()

Perintah di atas akan menyimpan data dalam variabel dan selanjutnya kita juga dapat menulis data di atas dalam file CSV dengan menggunakan csv.writer() metode.

Cadangan iTunes

Forensik seluler iPhone dapat dilakukan pada cadangan yang dibuat oleh iTunes. Pemeriksa forensik mengandalkan analisis backup logis iPhone yang diperoleh melalui iTunes. Protokol AFC (koneksi file Apple) digunakan oleh iTunes untuk mengambil cadangan. Selain itu, proses pencadangan tidak mengubah apa pun di iPhone kecuali catatan kunci escrow.

Sekarang, muncul pertanyaan mengapa penting bagi ahli forensik digital untuk memahami teknik backup iTunes? Hal ini penting jika kita mendapatkan akses ke komputer tersangka daripada iPhone secara langsung karena ketika komputer digunakan untuk melakukan sinkronisasi dengan iPhone, maka sebagian besar informasi di iPhone kemungkinan besar akan dicadangkan di komputer.

Proses Pencadangan dan Lokasinya

Setiap kali produk Apple dicadangkan ke komputer, itu sinkron dengan iTunes dan akan ada folder tertentu dengan ID unik perangkat. Dalam format cadangan terbaru, file disimpan dalam subfolder yang berisi dua karakter heksadesimal pertama dari nama file. Dari file backup tersebut, terdapat beberapa file seperti info.plist yang berguna bersama dengan database bernama Manifest.db. Tabel berikut menunjukkan lokasi cadangan, yang bervariasi dengan sistem operasi cadangan iTunes -

OS Lokasi Cadangan
Win7 C: \ Users \ [nama pengguna] \ AppData \ Roaming \ AppleComputer \ MobileSync \ Backup \
MAC OS X ~ / Library / Application Suport / MobileSync / Backup /

Untuk memproses cadangan iTunes dengan Python, pertama-tama kita perlu mengidentifikasi semua cadangan di lokasi cadangan sesuai sistem operasi kita. Kemudian kita akan mengulangi setiap backup dan membaca database Manifest.db.

Sekarang, dengan bantuan kode Python berikut kita dapat melakukan hal yang sama -

Pertama, impor pustaka yang diperlukan sebagai berikut -

from __future__ import print_function
import argparse
import logging
import os

from shutil import copyfile
import sqlite3
import sys
logger = logging.getLogger(__name__)

Sekarang, berikan dua argumen posisi yaitu INPUT_DIR dan OUTPUT_DIR yang mewakili cadangan iTunes dan folder keluaran yang diinginkan -

if __name__ == "__main__":
   parser.add_argument("INPUT_DIR",help = "Location of folder containing iOS backups, ""e.g. ~\Library\Application Support\MobileSync\Backup folder")
   parser.add_argument("OUTPUT_DIR", help = "Output Directory")
   parser.add_argument("-l", help = "Log file path",default = __file__[:-2] + "log")
   parser.add_argument("-v", help = "Increase verbosity",action = "store_true") args = parser.parse_args()

Sekarang, atur log sebagai berikut -

if args.v:
   logger.setLevel(logging.DEBUG)
else:
   logger.setLevel(logging.INFO)

Sekarang, atur format pesan untuk log ini sebagai berikut -

msg_fmt = logging.Formatter("%(asctime)-15s %(funcName)-13s""%(levelname)-8s %(message)s")
strhndl = logging.StreamHandler(sys.stderr)
strhndl.setFormatter(fmt = msg_fmt)

fhndl = logging.FileHandler(args.l, mode = 'a')
fhndl.setFormatter(fmt = msg_fmt)

logger.addHandler(strhndl)
logger.addHandler(fhndl)
logger.info("Starting iBackup Visualizer")
logger.debug("Supplied arguments: {}".format(" ".join(sys.argv[1:])))
logger.debug("System: " + sys.platform)
logger.debug("Python Version: " + sys.version)

Baris kode berikut akan membuat folder yang diperlukan untuk direktori keluaran yang diinginkan dengan menggunakan os.makedirs() fungsi -

if not os.path.exists(args.OUTPUT_DIR):
   os.makedirs(args.OUTPUT_DIR)

Sekarang, teruskan direktori input dan output yang disediakan ke fungsi main () sebagai berikut -

if os.path.exists(args.INPUT_DIR) and os.path.isdir(args.INPUT_DIR):
   main(args.INPUT_DIR, args.OUTPUT_DIR)
else:
   logger.error("Supplied input directory does not exist or is not ""a directory")
   sys.exit(1)

Sekarang Tulis main() fungsi yang selanjutnya akan dipanggil backup_summary() berfungsi untuk mengidentifikasi semua cadangan yang ada di folder input -

def main(in_dir, out_dir):
   backups = backup_summary(in_dir)
def backup_summary(in_dir):
   logger.info("Identifying all iOS backups in {}".format(in_dir))
   root = os.listdir(in_dir)
   backups = {}
   
   for x in root:
      temp_dir = os.path.join(in_dir, x)
      if os.path.isdir(temp_dir) and len(x) == 40:
         num_files = 0
         size = 0
         
         for root, subdir, files in os.walk(temp_dir):
            num_files += len(files)
            size += sum(os.path.getsize(os.path.join(root, name))
               for name in files)
         backups[x] = [temp_dir, num_files, size]
   return backups

Sekarang, cetak ringkasan setiap cadangan ke konsol sebagai berikut -

print("Backup Summary")
print("=" * 20)

if len(backups) > 0:
   for i, b in enumerate(backups):
      print("Backup No.: {} \n""Backup Dev. Name: {} \n""# Files: {} \n""Backup Size (Bytes): {}\n".format(i, b, backups[b][1], backups[b][2]))

Sekarang, buang konten file Manifest.db ke variabel bernama db_items.

try:
   db_items = process_manifest(backups[b][0])
   except IOError:
      logger.warn("Non-iOS 10 backup encountered or " "invalid backup. Continuing to next backup.")
continue

Sekarang, mari kita tentukan fungsi yang akan mengambil jalur direktori cadangan -

def process_manifest(backup):
   manifest = os.path.join(backup, "Manifest.db")
   
   if not os.path.exists(manifest):
      logger.error("Manifest DB not found in {}".format(manifest))
      raise IOError

Sekarang, menggunakan SQLite3 kita akan terhubung ke database dengan kursor bernama c -

c = conn.cursor()
items = {}

for row in c.execute("SELECT * from Files;"):
   items[row[0]] = [row[2], row[1], row[3]]
return items

create_files(in_dir, out_dir, b, db_items)
   print("=" * 20)
else:
   logger.warning("No valid backups found. The input directory should be
      " "the parent-directory immediately above the SHA-1 hash " "iOS device backups")
      sys.exit(2)

Sekarang, tentukan create_files() metode sebagai berikut -

def create_files(in_dir, out_dir, b, db_items):
   msg = "Copying Files for backup {} to {}".format(b, os.path.join(out_dir, b))
   logger.info(msg)

Sekarang, lakukan iterasi melalui setiap kunci di file db_items kamus -

for x, key in enumerate(db_items):
   if db_items[key][0] is None or db_items[key][0] == "":
      continue
   else:
      dirpath = os.path.join(out_dir, b,
os.path.dirname(db_items[key][0]))
   filepath = os.path.join(out_dir, b, db_items[key][0])
   
   if not os.path.exists(dirpath):
      os.makedirs(dirpath)
      original_dir = b + "/" + key[0:2] + "/" + key
   path = os.path.join(in_dir, original_dir)
   
   if os.path.exists(filepath):
      filepath = filepath + "_{}".format(x)

Sekarang, gunakan shutil.copyfile() metode untuk menyalin file cadangan sebagai berikut -

try:
   copyfile(path, filepath)
   except IOError:
      logger.debug("File not found in backup: {}".format(path))
         files_not_found += 1
   if files_not_found > 0:
      logger.warning("{} files listed in the Manifest.db not" "found in
backup".format(files_not_found))
   copyfile(os.path.join(in_dir, b, "Info.plist"), os.path.join(out_dir, b,
"Info.plist"))
   copyfile(os.path.join(in_dir, b, "Manifest.db"), os.path.join(out_dir, b,
"Manifest.db"))
   copyfile(os.path.join(in_dir, b, "Manifest.plist"), os.path.join(out_dir, b,
"Manifest.plist"))
   copyfile(os.path.join(in_dir, b, "Status.plist"),os.path.join(out_dir, b,
"Status.plist"))

Dengan skrip Python di atas, kita bisa mendapatkan struktur file cadangan yang diperbarui di folder output kita. Kita bisa gunakanpycrypto pustaka python untuk mendekripsi cadangan.

Wifi

Perangkat seluler dapat digunakan untuk terhubung ke dunia luar dengan menghubungkan melalui jaringan Wi-Fi yang tersedia di mana-mana. Terkadang perangkat terhubung ke jaringan terbuka ini secara otomatis.

Dalam kasus iPhone, daftar koneksi Wi-Fi terbuka yang terhubung dengan perangkat disimpan dalam file PLIST bernama com.apple.wifi.plist. File ini akan berisi Wi-Fi SSID, BSSID dan waktu koneksi.

Kita perlu mengekstrak detail Wi-Fi dari laporan XML Cellebrite standar menggunakan Python. Untuk ini, kita perlu menggunakan API dari Wireless Geographic Logging Engine (WIGLE), platform populer yang dapat digunakan untuk menemukan lokasi perangkat menggunakan nama jaringan Wi-Fi.

Kita bisa menggunakan pustaka Python bernama requestsuntuk mengakses API dari WIGLE. Itu dapat diinstal sebagai berikut -

pip install requests

API dari WIGLE

Kami perlu mendaftar di situs WIGLE https://wigle.net/accountuntuk mendapatkan API gratis dari WIGLE. Skrip Python untuk mendapatkan informasi tentang perangkat pengguna dan koneksinya melalui API WIGEL dibahas di bawah ini -

Pertama, impor pustaka berikut untuk menangani berbagai hal -

from __future__ import print_function

import argparse
import csv
import os
import sys
import xml.etree.ElementTree as ET
import requests

Sekarang, berikan dua argumen posisi yaitu INPUT_FILE dan OUTPUT_CSV yang akan mewakili file input dengan alamat MAC Wi-Fi dan file CSV output yang diinginkan masing-masing -

if __name__ == "__main__":
   parser.add_argument("INPUT_FILE", help = "INPUT FILE with MAC Addresses")
   parser.add_argument("OUTPUT_CSV", help = "Output CSV File")
   parser.add_argument("-t", help = "Input type: Cellebrite XML report or TXT
file",choices = ('xml', 'txt'), default = "xml")
   parser.add_argument('--api', help = "Path to API key
   file",default = os.path.expanduser("~/.wigle_api"),
   type = argparse.FileType('r'))
   args = parser.parse_args()

Sekarang baris kode berikut akan memeriksa apakah file input ada dan merupakan file. Jika tidak, itu keluar dari skrip -

if not os.path.exists(args.INPUT_FILE) or \ not os.path.isfile(args.INPUT_FILE):
   print("[-] {} does not exist or is not a
file".format(args.INPUT_FILE))
   sys.exit(1)
directory = os.path.dirname(args.OUTPUT_CSV)
if directory != '' and not os.path.exists(directory):
   os.makedirs(directory)
api_key = args.api.readline().strip().split(":")

Sekarang, berikan argumen ke main sebagai berikut -

main(args.INPUT_FILE, args.OUTPUT_CSV, args.t, api_key)
def main(in_file, out_csv, type, api_key):
   if type == 'xml':
      wifi = parse_xml(in_file)
   else:
      wifi = parse_txt(in_file)
query_wigle(wifi, out_csv, api_key)

Sekarang, kita akan mengurai file XML sebagai berikut -

def parse_xml(xml_file):
   wifi = {}
   xmlns = "{http://pa.cellebrite.com/report/2.0}"
   print("[+] Opening {} report".format(xml_file))
   
   xml_tree = ET.parse(xml_file)
   print("[+] Parsing report for all connected WiFi addresses")
   
   root = xml_tree.getroot()

Sekarang, lakukan iterasi melalui elemen turunan dari root sebagai berikut -

for child in root.iter():
   if child.tag == xmlns + "model":
      if child.get("type") == "Location":
         for field in child.findall(xmlns + "field"):
            if field.get("name") == "TimeStamp":
               ts_value = field.find(xmlns + "value")
               try:
               ts = ts_value.text
               except AttributeError:
continue

Sekarang, kita akan memeriksa apakah string 'ssid' ada di teks nilai atau tidak -

if "SSID" in value.text:
   bssid, ssid = value.text.split("\t")
   bssid = bssid[7:]
   ssid = ssid[6:]

Sekarang, kita perlu menambahkan BSSID, SSID, dan timestamp ke kamus wifi sebagai berikut -

if bssid in wifi.keys():

wifi[bssid]["Timestamps"].append(ts)
   wifi[bssid]["SSID"].append(ssid)
else:
   wifi[bssid] = {"Timestamps": [ts], "SSID":
[ssid],"Wigle": {}}
return wifi

Pengurai teks yang jauh lebih sederhana daripada pengurai XML ditunjukkan di bawah ini -

def parse_txt(txt_file):
   wifi = {}
   print("[+] Extracting MAC addresses from {}".format(txt_file))
   
   with open(txt_file) as mac_file:
      for line in mac_file:
         wifi[line.strip()] = {"Timestamps": ["N/A"], "SSID":
["N/A"],"Wigle": {}}
return wifi

Sekarang, mari kita gunakan modul permintaan untuk membuat WIGLE APIpanggilan dan perlu beralih ke query_wigle() metode -

def query_wigle(wifi_dictionary, out_csv, api_key):
   print("[+] Querying Wigle.net through Python API for {} "
"APs".format(len(wifi_dictionary)))
   for mac in wifi_dictionary:

   wigle_results = query_mac_addr(mac, api_key)
def query_mac_addr(mac_addr, api_key):

   query_url = "https://api.wigle.net/api/v2/network/search?" \
"onlymine = false&freenet = false&paynet = false" \ "&netid = {}".format(mac_addr)
   req = requests.get(query_url, auth = (api_key[0], api_key[1]))
   return req.json()

Sebenarnya ada batasan per hari untuk panggilan WIGLE API, jika batas itu melebihi maka pasti akan muncul error sebagai berikut -

try:
   if wigle_results["resultCount"] == 0:
      wifi_dictionary[mac]["Wigle"]["results"] = []
         continue
   else:
      wifi_dictionary[mac]["Wigle"] = wigle_results
except KeyError:
   if wigle_results["error"] == "too many queries today":
      print("[-] Wigle daily query limit exceeded")
      wifi_dictionary[mac]["Wigle"]["results"] = []
      continue
   else:
      print("[-] Other error encountered for " "address {}: {}".format(mac,
wigle_results['error']))
   wifi_dictionary[mac]["Wigle"]["results"] = []
   continue
prep_output(out_csv, wifi_dictionary)

Sekarang, kami akan menggunakan prep_output() metode untuk meratakan kamus menjadi potongan-potongan yang mudah ditulis -

def prep_output(output, data):
   csv_data = {}
   google_map = https://www.google.com/maps/search/

Sekarang, akses semua data yang telah kami kumpulkan sejauh berikut -

for x, mac in enumerate(data):
   for y, ts in enumerate(data[mac]["Timestamps"]):
      for z, result in enumerate(data[mac]["Wigle"]["results"]):
         shortres = data[mac]["Wigle"]["results"][z]
         g_map_url = "{}{},{}".format(google_map, shortres["trilat"],shortres["trilong"])

Sekarang, kita dapat menulis output dalam file CSV seperti yang telah kita lakukan di skrip sebelumnya di bab ini dengan menggunakan write_csv() fungsi.

Dalam bab ini, kita akan mempelajari secara detail tentang menyelidiki metadata tersemat menggunakan forensik digital Python.

pengantar

Metadata tertanam adalah informasi tentang data yang disimpan dalam file yang sama yang memiliki objek yang dijelaskan oleh data tersebut. Dengan kata lain, ini adalah informasi tentang aset digital yang disimpan dalam file digital itu sendiri. Itu selalu dikaitkan dengan file dan tidak pernah dapat dipisahkan.

Dalam kasus forensik digital, kami tidak dapat mengekstrak semua informasi tentang file tertentu. Di sisi lain, metadata yang disematkan dapat memberi kami informasi yang penting untuk penyelidikan. Misalnya, metadata file teks mungkin berisi informasi tentang penulis, panjangnya, tanggal tertulis, dan bahkan ringkasan singkat tentang dokumen itu. Gambar digital mungkin menyertakan metadata seperti panjang gambar, kecepatan rana, dll.

Artefak yang Mengandung Atribut Metadata dan Ekstraksi mereka

Di bagian ini, kita akan belajar tentang berbagai artefak yang mengandung atribut metadata dan proses ekstraksinya menggunakan Python.

Audio dan Video

Ini adalah dua artefak yang sangat umum yang memiliki metadata tersemat. Metadata ini dapat diekstraksi untuk tujuan penyelidikan.

Anda dapat menggunakan skrip Python berikut untuk mengekstrak atribut atau metadata umum dari file audio atau MP3 dan video atau file MP4.

Perhatikan bahwa untuk skrip ini, kita perlu menginstal pustaka python pihak ketiga bernama mutagen yang memungkinkan kita mengekstrak metadata dari file audio dan video. Itu dapat diinstal dengan bantuan perintah berikut -

pip install mutagen

Beberapa pustaka berguna yang perlu kita impor untuk skrip Python ini adalah sebagai berikut -

from __future__ import print_function

import argparse
import json
import mutagen

Penangan baris perintah akan mengambil satu argumen yang mewakili jalur ke file MP3 atau MP4. Kemudian, kami akan menggunakanmutagen.file() metode untuk membuka pegangan ke file sebagai berikut -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Python Metadata Extractor')
   parser.add_argument("AV_FILE", help="File to extract metadata from")
   args = parser.parse_args()
   av_file = mutagen.File(args.AV_FILE)
   file_ext = args.AV_FILE.rsplit('.', 1)[-1]
   
   if file_ext.lower() == 'mp3':
      handle_id3(av_file)
   elif file_ext.lower() == 'mp4':
      handle_mp4(av_file)

Sekarang, kita perlu menggunakan dua pegangan, satu untuk mengekstrak data dari MP3 dan satu lagi untuk mengekstrak data dari file MP4. Kita dapat mendefinisikan pegangan ini sebagai berikut -

def handle_id3(id3_file):
   id3_frames = {'TIT2': 'Title', 'TPE1': 'Artist', 'TALB': 'Album','TXXX':
      'Custom', 'TCON': 'Content Type', 'TDRL': 'Date released','COMM': 'Comments',
         'TDRC': 'Recording Date'}
   print("{:15} | {:15} | {:38} | {}".format("Frame", "Description","Text","Value"))
   print("-" * 85)
   
   for frames in id3_file.tags.values():
      frame_name = id3_frames.get(frames.FrameID, frames.FrameID)
      desc = getattr(frames, 'desc', "N/A")
      text = getattr(frames, 'text', ["N/A"])[0]
      value = getattr(frames, 'value', "N/A")
      
      if "date" in frame_name.lower():
         text = str(text)
      print("{:15} | {:15} | {:38} | {}".format(
         frame_name, desc, text, value))
def handle_mp4(mp4_file):
   cp_sym = u"\u00A9"
   qt_tag = {
      cp_sym + 'nam': 'Title', cp_sym + 'art': 'Artist',
      cp_sym + 'alb': 'Album', cp_sym + 'gen': 'Genre',
      'cpil': 'Compilation', cp_sym + 'day': 'Creation Date',
      'cnID': 'Apple Store Content ID', 'atID': 'Album Title ID',
      'plID': 'Playlist ID', 'geID': 'Genre ID', 'pcst': 'Podcast',
      'purl': 'Podcast URL', 'egid': 'Episode Global ID',
      'cmID': 'Camera ID', 'sfID': 'Apple Store Country',
      'desc': 'Description', 'ldes': 'Long Description'}
genre_ids = json.load(open('apple_genres.json'))

Sekarang, kita perlu melakukan iterasi melalui file MP4 ini sebagai berikut -

print("{:22} | {}".format('Name', 'Value'))
print("-" * 40)

for name, value in mp4_file.tags.items():
   tag_name = qt_tag.get(name, name)
   
   if isinstance(value, list):
      value = "; ".join([str(x) for x in value])
   if name == 'geID':
      value = "{}: {}".format(
      value, genre_ids[str(value)].replace("|", " - "))
   print("{:22} | {}".format(tag_name, value))

Skrip di atas akan memberi kita informasi tambahan tentang file MP3 dan juga MP4.

Gambar-gambar

Gambar mungkin berisi jenis metadata yang berbeda tergantung pada format filenya. Namun, sebagian besar gambar menyematkan informasi GPS. Kami dapat mengekstrak informasi GPS ini dengan menggunakan pustaka Python pihak ketiga. Anda dapat menggunakan skrip Python berikut dapat digunakan untuk melakukan hal yang sama -

Pertama, unduh pustaka python pihak ketiga bernama Python Imaging Library (PIL) sebagai berikut -

pip install pillow

Ini akan membantu kami mengekstrak metadata dari gambar.

Kami juga dapat menulis detail GPS yang disematkan dalam gambar ke file KML, tetapi untuk ini kami perlu mengunduh pustaka Python pihak ketiga bernama simplekml sebagai berikut -

pip install simplekml

Dalam skrip ini, pertama-tama kita perlu mengimpor pustaka berikut -

from __future__ import print_function
import argparse

from PIL import Image
from PIL.ExifTags import TAGS

import simplekml
import sys

Sekarang, penangan baris perintah akan menerima satu argumen posisi yang pada dasarnya mewakili jalur file foto.

parser = argparse.ArgumentParser('Metadata from images')
parser.add_argument('PICTURE_FILE', help = "Path to picture")
args = parser.parse_args()

Sekarang, kita perlu menentukan URL yang akan mengisi informasi koordinat. URL-nya adalahgmaps dan open_maps. Kita juga membutuhkan fungsi untuk mengubah koordinat tupel derajat menit detik (DMS), yang disediakan oleh pustaka PIL, menjadi desimal. Itu dapat dilakukan sebagai berikut -

gmaps = "https://www.google.com/maps?q={},{}"
open_maps = "http://www.openstreetmap.org/?mlat={}&mlon={}"

def process_coords(coord):
   coord_deg = 0
   
   for count, values in enumerate(coord):
      coord_deg += (float(values[0]) / values[1]) / 60**count
   return coord_deg

Sekarang, kami akan menggunakan image.open() berfungsi untuk membuka file sebagai objek PIL.

img_file = Image.open(args.PICTURE_FILE)
exif_data = img_file._getexif()

if exif_data is None:
   print("No EXIF data found")
   sys.exit()
for name, value in exif_data.items():
   gps_tag = TAGS.get(name, name)
   if gps_tag is not 'GPSInfo':
      continue

Setelah menemukan GPSInfo tag, kami akan menyimpan referensi GPS dan memproses koordinat dengan process_coords() metode.

lat_ref = value[1] == u'N'
lat = process_coords(value[2])

if not lat_ref:
   lat = lat * -1
lon_ref = value[3] == u'E'
lon = process_coords(value[4])

if not lon_ref:
   lon = lon * -1

Sekarang, mulai kml objek dari simplekml perpustakaan sebagai berikut -

kml = simplekml.Kml()
kml.newpoint(name = args.PICTURE_FILE, coords = [(lon, lat)])
kml.save(args.PICTURE_FILE + ".kml")

Kami sekarang dapat mencetak koordinat dari informasi yang diproses sebagai berikut -

print("GPS Coordinates: {}, {}".format(lat, lon))
print("Google Maps URL: {}".format(gmaps.format(lat, lon)))
print("OpenStreetMap URL: {}".format(open_maps.format(lat, lon)))
print("KML File {} created".format(args.PICTURE_FILE + ".kml"))

Dokumen PDF

Dokumen PDF memiliki berbagai macam media termasuk gambar, teks, formulir, dll. Saat kami mengekstrak metadata yang disematkan dalam dokumen PDF, kami mungkin mendapatkan data yang dihasilkan dalam format yang disebut Platform Metadata yang Dapat Diperluas (XMP). Kita dapat mengekstrak metadata dengan bantuan kode Python berikut -

Pertama, instal pustaka Python pihak ketiga bernama PyPDF2untuk membaca metadata yang disimpan dalam format XMP. Itu dapat diinstal sebagai berikut -

pip install PyPDF2

Sekarang, impor pustaka berikut untuk mengekstrak metadata dari file PDF -

from __future__ import print_function
from argparse import ArgumentParser, FileType

import datetime
from PyPDF2 import PdfFileReader
import sys

Sekarang, penangan baris perintah akan menerima satu argumen posisi yang pada dasarnya mewakili jalur file dari file PDF.

parser = argparse.ArgumentParser('Metadata from PDF')
parser.add_argument('PDF_FILE', help='Path to PDF file',type=FileType('rb'))
args = parser.parse_args()

Sekarang kita bisa menggunakan getXmpMetadata() metode untuk menyediakan objek yang berisi metadata yang tersedia sebagai berikut -

pdf_file = PdfFileReader(args.PDF_FILE)
xmpm = pdf_file.getXmpMetadata()

if xmpm is None:
   print("No XMP metadata found in document.")
   sys.exit()

Kita bisa gunakan custom_print() metode untuk mengekstrak dan mencetak nilai yang relevan seperti judul, pencipta, kontributor dll sebagai berikut -

custom_print("Title: {}", xmpm.dc_title)
custom_print("Creator(s): {}", xmpm.dc_creator)
custom_print("Contributors: {}", xmpm.dc_contributor)
custom_print("Subject: {}", xmpm.dc_subject)
custom_print("Description: {}", xmpm.dc_description)
custom_print("Created: {}", xmpm.xmp_createDate)
custom_print("Modified: {}", xmpm.xmp_modifyDate)
custom_print("Event Dates: {}", xmpm.dc_date)

Kami juga bisa mendefinisikan custom_print() metode jika PDF dibuat menggunakan beberapa perangkat lunak sebagai berikut -

def custom_print(fmt_str, value):
   if isinstance(value, list):
      print(fmt_str.format(", ".join(value)))
   elif isinstance(value, dict):
      fmt_value = [":".join((k, v)) for k, v in value.items()]
      print(fmt_str.format(", ".join(value)))
   elif isinstance(value, str) or isinstance(value, bool):
      print(fmt_str.format(value))
   elif isinstance(value, bytes):
      print(fmt_str.format(value.decode()))
   elif isinstance(value, datetime.datetime):
      print(fmt_str.format(value.isoformat()))
   elif value is None:
      print(fmt_str.format("N/A"))
   else:
      print("warn: unhandled type {} found".format(type(value)))

Kami juga dapat mengekstrak properti khusus lainnya yang disimpan oleh perangkat lunak sebagai berikut -

if xmpm.custom_properties:
   print("Custom Properties:")
   
   for k, v in xmpm.custom_properties.items():
      print("\t{}: {}".format(k, v))

Skrip di atas akan membaca dokumen PDF dan akan mencetak metadata yang disimpan dalam format XMP termasuk beberapa properti khusus yang disimpan oleh perangkat lunak dengan bantuan PDF yang telah dibuat.

File Windows Executables

Terkadang kami mungkin menemukan file eksekusi yang mencurigakan atau tidak sah. Tetapi untuk tujuan penyelidikan, ini mungkin berguna karena metadata yang disematkan. Kita bisa mendapatkan informasi seperti lokasinya, tujuannya dan atribut lain seperti pabrikan, tanggal kompilasi, dll. Dengan bantuan mengikuti skrip Python kita bisa mendapatkan tanggal kompilasi, data yang berguna dari header dan simbol yang diimpor serta diekspor.

Untuk tujuan ini, instal pustaka Python pihak ketiga terlebih dahulu pefile. Itu dapat dilakukan sebagai berikut -

pip install pefile

Setelah Anda berhasil menginstal ini, impor pustaka berikut sebagai berikut -

from __future__ import print_function

import argparse
from datetime import datetime
from pefile import PE

Sekarang, penangan baris perintah akan menerima satu argumen posisi yang pada dasarnya mewakili jalur file dari file yang dapat dieksekusi. Anda juga dapat memilih gaya keluaran, apakah Anda membutuhkannya secara mendetail dan bertele-tele atau dengan cara yang disederhanakan. Untuk ini, Anda perlu memberikan argumen opsional seperti yang ditunjukkan di bawah ini -

parser = argparse.ArgumentParser('Metadata from executable file')
parser.add_argument("EXE_FILE", help = "Path to exe file")
parser.add_argument("-v", "--verbose", help = "Increase verbosity of output",
action = 'store_true', default = False)
args = parser.parse_args()

Sekarang, kita akan memuat file yang dapat dieksekusi dengan menggunakan kelas PE. Kami juga akan membuang data yang dapat dieksekusi ke objek kamus dengan menggunakandump_dict() metode.

pe = PE(args.EXE_FILE)
ped = pe.dump_dict()

Kita dapat mengekstrak metadata file dasar seperti kepengarangan yang disematkan, versi dan waktu kompilasi menggunakan kode yang ditunjukkan di bawah ini -

file_info = {}
for structure in pe.FileInfo:
   if structure.Key == b'StringFileInfo':
      for s_table in structure.StringTable:
         for key, value in s_table.entries.items():
            if value is None or len(value) == 0:
               value = "Unknown"
            file_info[key] = value
print("File Information: ")
print("==================")

for k, v in file_info.items():
   if isinstance(k, bytes):
      k = k.decode()
   if isinstance(v, bytes):
      v = v.decode()
   print("{}: {}".format(k, v))
comp_time = ped['FILE_HEADER']['TimeDateStamp']['Value']
comp_time = comp_time.split("[")[-1].strip("]")
time_stamp, timezone = comp_time.rsplit(" ", 1)
comp_time = datetime.strptime(time_stamp, "%a %b %d %H:%M:%S %Y")
print("Compiled on {} {}".format(comp_time, timezone.strip()))

Kami dapat mengekstrak data yang berguna dari header sebagai berikut -

for section in ped['PE Sections']:
   print("Section '{}' at {}: {}/{} {}".format(
      section['Name']['Value'], hex(section['VirtualAddress']['Value']),
      section['Misc_VirtualSize']['Value'],
      section['SizeOfRawData']['Value'], section['MD5'])
   )

Sekarang, ekstrak daftar impor dan ekspor dari file yang dapat dieksekusi seperti yang ditunjukkan di bawah ini -

if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
   print("\nImports: ")
   print("=========")
   
   for dir_entry in pe.DIRECTORY_ENTRY_IMPORT:
      dll = dir_entry.dll
      
      if not args.verbose:
         print(dll.decode(), end=", ")
         continue
      name_list = []
      
      for impts in dir_entry.imports:
         if getattr(impts, "name", b"Unknown") is None:
            name = b"Unknown"
         else:
            name = getattr(impts, "name", b"Unknown")
			name_list.append([name.decode(), hex(impts.address)])
      name_fmt = ["{} ({})".format(x[0], x[1]) for x in name_list]
      print('- {}: {}'.format(dll.decode(), ", ".join(name_fmt)))
   if not args.verbose:
      print()

Sekarang, cetak exports, names dan addresses menggunakan kode seperti yang ditunjukkan di bawah ini -

if hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'):
   print("\nExports: ")
   print("=========")
   
   for sym in pe.DIRECTORY_ENTRY_EXPORT.symbols:
      print('- {}: {}'.format(sym.name.decode(), hex(sym.address)))

Skrip di atas akan mengekstrak metadata dasar, informasi dari header dari file windows yang dapat dieksekusi.

Metadata Dokumen Office

Sebagian besar pekerjaan di komputer dilakukan dalam tiga aplikasi MS Office - Word, PowerPoint dan Excel. File-file ini memiliki metadata yang sangat besar, yang dapat mengungkapkan informasi menarik tentang penulis dan sejarahnya.

Perhatikan bahwa metadata dari format 2007 kata (.docx), excel (.xlsx) dan powerpoint (.pptx) disimpan dalam file XML. Kami dapat memproses file XML ini dengan Python dengan bantuan skrip Python berikut yang ditunjukkan di bawah ini -

Pertama, impor pustaka yang diperlukan seperti yang ditunjukkan di bawah ini -

from __future__ import print_function
from argparse import ArgumentParser
from datetime import datetime as dt
from xml.etree import ElementTree as etree

import zipfile
parser = argparse.ArgumentParser('Office Document Metadata’)
parser.add_argument("Office_File", help="Path to office file to read")
args = parser.parse_args()

Sekarang, periksa apakah file tersebut adalah file ZIP. Jika tidak, ajukan kesalahan. Sekarang, buka file dan ekstrak elemen kunci untuk diproses menggunakan kode berikut -

zipfile.is_zipfile(args.Office_File)
zfile = zipfile.ZipFile(args.Office_File)
core_xml = etree.fromstring(zfile.read('docProps/core.xml'))
app_xml = etree.fromstring(zfile.read('docProps/app.xml'))

Sekarang, buat kamus untuk memulai ekstraksi metadata -

core_mapping = {
   'title': 'Title',
   'subject': 'Subject',
   'creator': 'Author(s)',
   'keywords': 'Keywords',
   'description': 'Description',
   'lastModifiedBy': 'Last Modified By',
   'modified': 'Modified Date',
   'created': 'Created Date',
   'category': 'Category',
   'contentStatus': 'Status',
   'revision': 'Revision'
}

Menggunakan iterchildren() metode untuk mengakses setiap tag dalam file XML -

for element in core_xml.getchildren():
   for key, title in core_mapping.items():
      if key in element.tag:
         if 'date' in title.lower():
            text = dt.strptime(element.text, "%Y-%m-%dT%H:%M:%SZ")
         else:
            text = element.text
         print("{}: {}".format(title, text))

Demikian pula, lakukan ini untuk file app.xml yang berisi informasi statistik tentang konten dokumen -

app_mapping = {
   'TotalTime': 'Edit Time (minutes)',
   'Pages': 'Page Count',
   'Words': 'Word Count',
   'Characters': 'Character Count',
   'Lines': 'Line Count',
   'Paragraphs': 'Paragraph Count',
   'Company': 'Company',
   'HyperlinkBase': 'Hyperlink Base',
   'Slides': 'Slide count',
   'Notes': 'Note Count',
   'HiddenSlides': 'Hidden Slide Count',
}
for element in app_xml.getchildren():
   for key, title in app_mapping.items():
      if key in element.tag:
         if 'date' in title.lower():
            text = dt.strptime(element.text, "%Y-%m-%dT%H:%M:%SZ")
         else:
            text = element.text
         print("{}: {}".format(title, text))

Sekarang setelah menjalankan skrip di atas, kita bisa mendapatkan detail berbeda tentang dokumen tertentu. Perhatikan bahwa kami dapat menerapkan skrip ini hanya pada dokumen Office 2007 atau versi yang lebih baru.

Bab ini akan menjelaskan dasar-dasar yang terlibat dalam melakukan forensik jaringan menggunakan Python.

Memahami Forensik Jaringan

Forensik jaringan adalah cabang forensik digital yang menangani pemantauan dan analisis lalu lintas jaringan komputer, baik lokal maupun WAN (jaringan area luas), untuk keperluan pengumpulan informasi, pengumpulan bukti, atau deteksi intrusi. Forensik jaringan memainkan peran penting dalam menyelidiki kejahatan digital seperti pencurian kekayaan intelektual atau kebocoran informasi. Gambar komunikasi jaringan membantu penyidik ​​untuk memecahkan beberapa pertanyaan penting sebagai berikut -

  • Situs web apa yang telah diakses?

  • Jenis konten apa yang telah diunggah di jaringan kami?

  • Jenis konten apa yang telah diunduh dari jaringan kami?

  • Server apa yang sedang diakses?

  • Apakah seseorang mengirimkan informasi sensitif di luar firewall perusahaan?

Internet Evidence Finder (IEF)

IEF adalah alat forensik digital untuk menemukan, menganalisis dan menyajikan bukti digital yang ditemukan di berbagai media digital seperti komputer, smartphone, tablet, dll. IEF sangat populer dan digunakan oleh ribuan profesional forensik.

Penggunaan IEF

Karena popularitasnya, IEF banyak digunakan oleh para profesional forensik. Beberapa kegunaan IEF adalah sebagai berikut -

  • Karena kemampuan pencariannya yang kuat, ini digunakan untuk mencari banyak file atau media data secara bersamaan.

  • Ini juga digunakan untuk memulihkan data yang dihapus dari ruang RAM yang tidak terisi melalui teknik ukiran baru.

  • Jika peneliti ingin membangun kembali halaman web dalam format aslinya pada tanggal dibuka, maka mereka dapat menggunakan IEF.

  • Ini juga digunakan untuk mencari volume disk logis atau fisik.

Membuang Laporan dari IEF ke CSV menggunakan Python

IEF menyimpan data dalam database SQLite dan mengikuti skrip Python akan secara dinamis mengidentifikasi tabel hasil dalam database IEF dan membuangnya ke file CSV masing-masing.

Proses ini dilakukan dalam langkah-langkah yang ditunjukkan di bawah ini

  • Pertama, buat database hasil IEF yang akan menjadi file database SQLite yang diakhiri dengan ekstensi .db.

  • Kemudian, kueri database tersebut untuk mengidentifikasi semua tabel.

  • Terakhir, tulis tabel hasil ini ke file CSV individu.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Untuk skrip Python, impor pustaka yang diperlukan sebagai berikut -

from __future__ import print_function

import argparse
import csv
import os
import sqlite3
import sys

Sekarang, kita perlu menyediakan jalur ke file database 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()

Sekarang, kami akan mengkonfirmasi keberadaan database IEF sebagai berikut -

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)

Sekarang, seperti yang kita lakukan di skrip sebelumnya, buat koneksi dengan database SQLite sebagai berikut untuk mengeksekusi kueri melalui kursor -

def main(database, out_directory):
   print("[+] Connecting to SQLite database")
   conn = sqlite3.connect(database)
   c = conn.cursor()

Baris kode berikut akan mengambil nama tabel dari database -

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')]

Sekarang, kita akan memilih semua data dari tabel dan dengan menggunakan fetchall() metode pada objek kursor kita akan menyimpan daftar tupel yang berisi data tabel secara keseluruhan dalam variabel -

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()

Sekarang, dengan menggunakan CSV_Writer() metode kami akan menulis konten dalam file 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)

Script di atas akan mengambil semua data dari tabel database IEF dan menulis isinya ke file CSV pilihan kita.

Bekerja dengan Data Cache

Dari database hasil IEF, kita dapat memperoleh lebih banyak informasi yang belum tentu didukung oleh IEF itu sendiri. Kita dapat mengambil data yang di-cache, produk bi untuk informasi, dari penyedia layanan email seperti Yahoo, Google dll dengan menggunakan database hasil IEF.

Berikut ini adalah script Python untuk mengakses informasi data cache dari Yahoo mail, diakses di Google Chrome, dengan menggunakan database IEF. Perhatikan bahwa langkah-langkahnya kurang lebih sama dengan yang diikuti di skrip Python terakhir.

Pertama, impor pustaka yang diperlukan untuk Python sebagai berikut -

from __future__ import print_function
import argparse
import csv
import os
import sqlite3
import sys
import json

Sekarang, berikan jalur ke file database IEF bersama dengan dua argumen posisi yang diterima oleh penangan baris perintah seperti yang dilakukan di skrip terakhir -

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()

Sekarang, konfirmasikan keberadaan database IEF sebagai berikut -

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)

Sekarang, buat koneksi dengan database SQLite sebagai berikut untuk mengeksekusi kueri melalui kursor -

def main(database, out_csv):
   print("[+] Connecting to SQLite database")
   conn = sqlite3.connect(database)
   c = conn.cursor()

Anda dapat menggunakan baris kode berikut untuk mengambil contoh catatan cache kontak 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)

Sekarang, daftar tupel yang dikembalikan dari kueri di atas untuk disimpan ke dalam variabel sebagai berikut -

contact_cache = c.fetchall()
contact_data = process_contacts(contact_cache)
write_csv(contact_data, out_csv)

Perhatikan bahwa di sini kita akan menggunakan dua metode yaitu process_contacts() untuk menyiapkan daftar hasil serta melakukan iterasi melalui setiap catatan cache kontak dan json.loads() untuk menyimpan data JSON yang diekstrak dari tabel menjadi variabel untuk manipulasi lebih lanjut -

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"]])

Sekarang untuk perusahaan, judul dan catatan, metode get digunakan seperti yang ditunjukkan di bawah ini -

company = c.get("company", "")
title = c.get("jobTitle", "")
notes = c.get("notes", "")

Sekarang, mari kita tambahkan daftar metadata dan elemen data yang diekstrak ke daftar hasil sebagai berikut -

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

Sekarang, dengan menggunakan CSV_Writer() metode, kami akan menulis konten dalam file 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)

Dengan bantuan script di atas, kita dapat memproses data yang di-cache dari Yahoo mail dengan menggunakan database IEF.

Bab sebelumnya membahas beberapa konsep forensik jaringan menggunakan Python. Dalam bab ini, mari kita memahami forensik jaringan menggunakan Python pada level yang lebih dalam.

Pelestarian Halaman Web dengan Sup Cantik

World Wide Web (WWW) adalah sumber informasi yang unik. Namun, warisannya berisiko tinggi karena hilangnya konten pada tingkat yang mengkhawatirkan. Sejumlah warisan budaya dan institusi akademis, organisasi nirlaba dan bisnis swasta telah mengeksplorasi masalah yang terlibat dan berkontribusi pada pengembangan solusi teknis untuk pengarsipan web.

Pelestarian halaman web atau pengarsipan web adalah proses pengumpulan data dari World Wide Web, memastikan bahwa data disimpan dalam arsip dan membuatnya tersedia untuk peneliti, sejarawan, dan publik di masa mendatang. Sebelum melangkah lebih jauh ke pelestarian halaman web, mari kita bahas beberapa masalah penting terkait dengan pemeliharaan halaman web seperti yang diberikan di bawah ini -

  • Change in Web Resources - Sumber daya web terus berubah setiap hari yang merupakan tantangan bagi pelestarian halaman web.

  • Large Quantity of Resources - Masalah lain yang terkait dengan pelestarian halaman web adalah banyaknya sumber daya yang harus dipertahankan.

  • Integrity - Halaman web harus dilindungi dari perubahan, penghapusan, atau penghapusan yang tidak sah untuk melindungi integritasnya.

  • Dealing with multimedia data - Saat melindungi halaman web, kami juga perlu menangani data multimedia, dan ini dapat menyebabkan masalah saat melakukannya.

  • Providing access - Selain melestarikan, masalah penyediaan akses ke sumber daya web dan menangani masalah kepemilikan juga perlu diselesaikan.

Dalam bab ini, kita akan menggunakan pustaka Python bernama Beautiful Soup untuk pelestarian halaman web.

Apa itu Beautiful Soup?

Beautiful Soup adalah pustaka Python untuk menarik data dari file HTML dan XML. Ini bisa digunakan denganurlibkarena memerlukan masukan (dokumen atau url) untuk membuat objek sup, karena tidak dapat mengambil laman web itu sendiri. Anda dapat mempelajari secara detail tentang ini di www.crummy.com/software/BeautifulSoup/bs4/doc/

Perhatikan bahwa sebelum menggunakannya, kita harus menginstal pustaka pihak ketiga menggunakan perintah berikut -

pip install bs4

Selanjutnya, menggunakan pengelola paket Anaconda, kita dapat menginstal Beautiful Soup sebagai berikut -

conda install -c anaconda beautifulsoup4

Script Python untuk Menjaga Halaman Web

Skrip Python untuk melestarikan halaman web dengan menggunakan perpustakaan pihak ketiga yang disebut Beautiful Soup dibahas di sini -

Pertama, impor pustaka yang diperlukan sebagai berikut -

from __future__ import print_function
import argparse

from bs4 import BeautifulSoup, SoupStrainer
from datetime import datetime

import hashlib
import logging
import os
import ssl
import sys
from urllib.request import urlopen

import urllib.error
logger = logging.getLogger(__name__)

Perhatikan bahwa skrip ini akan mengambil dua argumen posisi, satu adalah URL yang akan dipertahankan dan lainnya adalah direktori keluaran yang diinginkan seperti yang ditunjukkan di bawah ini -

if __name__ == "__main__":
   parser = argparse.ArgumentParser('Web Page preservation')
   parser.add_argument("DOMAIN", help="Website Domain")
   parser.add_argument("OUTPUT_DIR", help="Preservation Output Directory")
   parser.add_argument("-l", help="Log file path",
   default=__file__[:-3] + ".log")
   args = parser.parse_args()

Sekarang, atur logging untuk skrip dengan menentukan file dan stream handler untuk berada dalam loop dan mendokumentasikan proses akuisisi seperti yang ditunjukkan -

logger.setLevel(logging.DEBUG)
msg_fmt = logging.Formatter("%(asctime)-15s %(funcName)-10s""%(levelname)-8s %(message)s")
strhndl = logging.StreamHandler(sys.stderr)
strhndl.setFormatter(fmt=msg_fmt)
fhndl = logging.FileHandler(args.l, mode='a')
fhndl.setFormatter(fmt=msg_fmt)

logger.addHandler(strhndl)
logger.addHandler(fhndl)
logger.info("Starting BS Preservation")
logger.debug("Supplied arguments: {}".format(sys.argv[1:]))
logger.debug("System " + sys.platform)
logger.debug("Version " + sys.version)

Sekarang, mari kita lakukan validasi input pada direktori output yang diinginkan sebagai berikut -

if not os.path.exists(args.OUTPUT_DIR):
   os.makedirs(args.OUTPUT_DIR)
main(args.DOMAIN, args.OUTPUT_DIR)

Sekarang, kita akan mendefinisikan file main() fungsi yang akan mengekstrak nama dasar situs web dengan menghapus elemen yang tidak perlu sebelum nama sebenarnya bersama dengan validasi tambahan pada URL masukan sebagai berikut -

def main(website, output_dir):
   base_name = website.replace("https://", "").replace("http://", "").replace("www.", "")
   link_queue = set()
   
   if "http://" not in website and "https://" not in website:
      logger.error("Exiting preservation - invalid user input: {}".format(website))
      sys.exit(1)
   logger.info("Accessing {} webpage".format(website))
   context = ssl._create_unverified_context()

Sekarang, kita perlu membuka koneksi dengan URL menggunakan metode urlopen (). Mari kita gunakan blok try-kecuali sebagai berikut -

try:
   index = urlopen(website, context=context).read().decode("utf-8")
except urllib.error.HTTPError as e:
   logger.error("Exiting preservation - unable to access page: {}".format(website))
   sys.exit(2)
logger.debug("Successfully accessed {}".format(website))

Baris kode berikutnya mencakup tiga fungsi seperti yang dijelaskan di bawah ini -

  • write_output() untuk menulis halaman web pertama ke direktori keluaran

  • find_links() berfungsi untuk mengidentifikasi link pada halaman web ini

  • recurse_pages() berfungsi untuk mengulang dan menemukan semua tautan di halaman web.

write_output(website, index, output_dir)
link_queue = find_links(base_name, index, link_queue)
logger.info("Found {} initial links on webpage".format(len(link_queue)))
recurse_pages(website, link_queue, context, output_dir)
logger.info("Completed preservation of {}".format(website))

Sekarang, mari kita definisikan write_output() metode sebagai berikut -

def write_output(name, data, output_dir, counter=0):
   name = name.replace("http://", "").replace("https://", "").rstrip("//")
   directory = os.path.join(output_dir, os.path.dirname(name))
   
   if not os.path.exists(directory) and os.path.dirname(name) != "":
      os.makedirs(directory)

Kami perlu mencatat beberapa detail tentang halaman web dan kemudian kami mencatat hash data dengan menggunakan hash_data() metode sebagai berikut -

logger.debug("Writing {} to {}".format(name, output_dir)) logger.debug("Data Hash: {}".format(hash_data(data)))
path = os.path.join(output_dir, name)
path = path + "_" + str(counter)
with open(path, "w") as outfile:
   outfile.write(data)
logger.debug("Output File Hash: {}".format(hash_file(path)))

Sekarang, definisikan hash_data() metode dengan bantuan yang kita baca UTF-8 data yang dikodekan dan kemudian menghasilkan SHA-256 hash sebagai berikut -

def hash_data(data):
   sha256 = hashlib.sha256()
   sha256.update(data.encode("utf-8"))
   return sha256.hexdigest()
def hash_file(file):
   sha256 = hashlib.sha256()
   with open(file, "rb") as in_file:
      sha256.update(in_file.read())
return sha256.hexdigest()

Sekarang, mari kita buat file Beautifulsoup objek dari data halaman web di bawah find_links() metode sebagai berikut -

def find_links(website, page, queue):
   for link in BeautifulSoup(page, "html.parser",parse_only = SoupStrainer("a", href = True)):
      if website in link.get("href"):
         if not os.path.basename(link.get("href")).startswith("#"):
            queue.add(link.get("href"))
   return queue

Sekarang, kita perlu mendefinisikan recurse_pages() metode dengan memberikan masukan dari URL situs web, antrian tautan saat ini, konteks SSL yang belum diverifikasi dan direktori keluaran sebagai berikut -

def recurse_pages(website, queue, context, output_dir):
   processed = []
   counter = 0
   
   while True:
      counter += 1
      if len(processed) == len(queue):
         break
      for link in queue.copy(): if link in processed:
         continue
	   processed.append(link)
      try:
      page = urlopen(link,      context=context).read().decode("utf-8")
      except urllib.error.HTTPError as e:
         msg = "Error accessing webpage: {}".format(link)
         logger.error(msg)
         continue

Sekarang, tulis output dari setiap halaman web yang diakses dalam file dengan mengirimkan nama tautan, data halaman, direktori output, dan penghitung sebagai berikut -

write_output(link, page, output_dir, counter)
queue = find_links(website, page, queue)
logger.info("Identified {} links throughout website".format(
   len(queue)))

Sekarang, ketika kita menjalankan skrip ini dengan memberikan URL situs web, direktori keluaran, dan jalur ke file log, kita akan mendapatkan detail tentang halaman web tersebut yang dapat digunakan untuk penggunaan di masa mendatang.

Berburu Virus

Pernahkah Anda bertanya-tanya bagaimana analis forensik, peneliti keamanan, dan responden insiden dapat memahami perbedaan antara perangkat lunak yang berguna dan perangkat lunak perusak? Jawabannya terletak pada pertanyaan itu sendiri, karena tanpa mempelajari tentang malware, yang dengan cepat dihasilkan oleh peretas, sangat tidak mungkin bagi peneliti dan spesialis untuk membedakan antara perangkat lunak yang berguna dan malware. Pada bagian ini, mari kita bahasVirusShare, alat untuk menyelesaikan tugas ini.

Memahami VirusShare

VirusShare adalah kumpulan sampel malware milik pribadi terbesar untuk memberikan sampel kode berbahaya langsung kepada peneliti keamanan, penanggap insiden, dan analis forensik. Ini berisi lebih dari 30 juta sampel.

Manfaat VirusShare adalah daftar hash malware yang tersedia secara gratis. Siapa pun dapat menggunakan hash ini untuk membuat kumpulan hash yang sangat komprehensif dan menggunakannya untuk mengidentifikasi file yang berpotensi berbahaya. Tetapi sebelum menggunakan VirusShare, kami menyarankan Anda untuk berkunjunghttps://virusshare.com untuk lebih jelasnya.

Membuat Daftar Hash yang Dibatasi Baris Baru dari VirusShare menggunakan Python

Daftar hash dari VirusShare dapat digunakan oleh berbagai alat forensik seperti X-way dan EnCase. Dalam skrip yang dibahas di bawah ini, kita akan mengotomatiskan daftar unduhan hash dari VirusShare untuk membuat daftar hash yang dipisahkan baris baru.

Untuk skrip ini, kita membutuhkan pustaka Python pihak ketiga tqdm yang dapat diunduh sebagai berikut -

pip install tqdm

Perhatikan bahwa dalam skrip ini, pertama-tama kita akan membaca halaman hash VirusShare dan secara dinamis mengidentifikasi daftar hash terbaru. Kemudian kami akan menginisialisasi bilah kemajuan dan mengunduh daftar hash dalam kisaran yang diinginkan.

Pertama, impor pustaka berikut -

from __future__ import print_function

import argparse
import os
import ssl
import sys
import tqdm

from urllib.request import urlopen
import urllib.error

Skrip ini akan mengambil satu argumen posisi, yang akan menjadi jalur yang diinginkan untuk set hash -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Hash set from VirusShare')
   parser.add_argument("OUTPUT_HASH", help = "Output Hashset")
   parser.add_argument("--start", type = int, help = "Optional starting location")
   args = parser.parse_args()

Sekarang, kami akan melakukan validasi input standar sebagai berikut -

directory = os.path.dirname(args.OUTPUT_HASH)
if not os.path.exists(directory):
   os.makedirs(directory)
if args.start:
   main(args.OUTPUT_HASH, start=args.start)
else:
   main(args.OUTPUT_HASH)

Sekarang kita perlu mendefinisikan main() berfungsi dengan **kwargs sebagai argumen karena ini akan membuat kamus yang dapat kita rujuk untuk mendukung argumen kunci yang disediakan seperti yang ditunjukkan di bawah ini -

def main(hashset, **kwargs):
   url = "https://virusshare.com/hashes.4n6"
   print("[+] Identifying hash set range from {}".format(url))
   context = ssl._create_unverified_context()

Sekarang, kita perlu membuka halaman hashes VirusShare dengan menggunakan urlib.request.urlopen()metode. Kami akan menggunakan blok coba-kecuali sebagai berikut -

try:
   index = urlopen(url, context = context).read().decode("utf-8")
except urllib.error.HTTPError as e:
   print("[-] Error accessing webpage - exiting..")
   sys.exit(1)

Sekarang, identifikasi daftar hash terbaru dari halaman yang diunduh. Anda dapat melakukan ini dengan mencari contoh terakhir dari HTMLhreftag ke daftar hash VirusShare. Itu dapat dilakukan dengan baris kode berikut -

tag = index.rfind(r'a href = "hashes/VirusShare_')
stop = int(index[tag + 27: tag + 27 + 5].lstrip("0"))

if "start" not in kwa<rgs:
   start = 0
else:
   start = kwargs["start"]

if start < 0 or start > stop:
   print("[-] Supplied start argument must be greater than or equal ""to zero but less than the latest hash list, ""currently: {}".format(stop))
sys.exit(2)
print("[+] Creating a hashset from hash lists {} to {}".format(start, stop))
hashes_downloaded = 0

Sekarang, kami akan menggunakan tqdm.trange() metode untuk membuat lingkaran dan bilah kemajuan sebagai berikut -

for x in tqdm.trange(start, stop + 1, unit_scale=True,desc="Progress"):
   url_hash = "https://virusshare.com/hashes/VirusShare_"\"{}.md5".format(str(x).zfill(5))
   try:
      hashes = urlopen(url_hash, context=context).read().decode("utf-8")
      hashes_list = hashes.split("\n")
   except urllib.error.HTTPError as e:
      print("[-] Error accessing webpage for hash list {}"" - continuing..".format(x))
   continue

Setelah melakukan langkah-langkah di atas dengan sukses, kami akan membuka file teks set hash dalam mode + untuk ditambahkan ke bagian bawah file teks.

with open(hashset, "a+") as hashfile:
   for line in hashes_list:
   if not line.startswith("#") and line != "":
      hashes_downloaded += 1
      hashfile.write(line + '\n')
   print("[+] Finished downloading {} hashes into {}".format(
      hashes_downloaded, hashset))

Setelah menjalankan script di atas, Anda akan mendapatkan daftar hash terbaru yang berisi nilai hash MD5 dalam format teks.

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-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 cara 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 payload 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.

Pada 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 file 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 sebelum itu kita harus tahu bagaimana kita bisa 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 klik,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 menyediakan 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 untuk 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.

Bab ini akan menjelaskan berbagai konsep yang terlibat dalam forensik Microsoft Windows dan artefak penting yang dapat diperoleh penyidik ​​dari proses penyelidikan.

pengantar

Artefak adalah benda atau area dalam sistem komputer yang memiliki informasi penting terkait dengan aktivitas yang dilakukan oleh pengguna komputer. Jenis dan lokasi informasi ini bergantung pada sistem operasi. Selama analisis forensik, artefak ini memainkan peran yang sangat penting dalam menyetujui atau tidak menyetujui observasi penyidik.

Pentingnya Artefak Windows untuk Forensik

Artefak Windows dianggap penting karena alasan berikut -

  • Sekitar 90% lalu lintas di dunia berasal dari komputer yang menggunakan Windows sebagai sistem operasinya. Itulah sebabnya bagi pemeriksa forensik digital, artefak Windows sangat penting.

  • Sistem operasi Windows menyimpan berbagai jenis bukti yang terkait dengan aktivitas pengguna di sistem komputer. Ini adalah alasan lain yang menunjukkan pentingnya artefak Windows untuk forensik digital.

  • Berkali-kali penyidik ​​berputar penyelidikan di sekitar area lama dan tradisional seperti data yang dikelompokkan pengguna. Artefak Windows dapat mengarahkan penyelidikan ke area non-tradisional seperti data yang dibuat sistem atau artefak.

  • Artefak yang berlimpah disediakan oleh Windows yang berguna bagi penyelidik serta perusahaan dan individu yang melakukan penyelidikan informal.

  • Meningkatnya kejahatan dunia maya dalam beberapa tahun terakhir adalah alasan lain pentingnya artefak Windows.

Artefak Windows dan Skrip Python mereka

Pada bagian ini, kita akan membahas tentang beberapa artefak Windows dan skrip Python untuk mengambil informasi darinya.

Tempat sampah

Ini adalah salah satu artefak Windows penting untuk penyelidikan forensik. Recycle bin Windows berisi file yang telah dihapus oleh pengguna, tetapi belum dihapus secara fisik oleh sistem. Meskipun pengguna benar-benar menghapus file dari sistem, ini berfungsi sebagai sumber investigasi yang penting. Ini karena pemeriksa dapat mengekstrak informasi berharga, seperti jalur file asli serta waktu pengirimannya ke Recycle Bin, dari file yang dihapus.

Perhatikan bahwa penyimpanan bukti Recycle Bin tergantung pada versi Windows. Dalam skrip Python berikut, kita akan berurusan dengan Windows 7 di mana ia membuat dua file:$R file yang berisi konten sebenarnya dari file daur ulang dan $I file yang berisi nama file asli, jalur, ukuran file saat file dihapus.

Untuk skrip Python kita perlu menginstal modul pihak ketiga yaitu pytsk3, pyewf dan unicodecsv. Kita bisa gunakanpipuntuk menginstalnya. Kami dapat mengikuti langkah-langkah berikut untuk mengekstrak informasi dari Recycle Bin -

  • Pertama, kita perlu menggunakan metode rekursif untuk memindai file $Recycle.bin folder dan pilih semua file yang dimulai dengan $I.

  • Selanjutnya, kita akan membaca konten file dan mengurai struktur metadata yang tersedia.

  • Sekarang, kita akan mencari file $ R yang terkait.

  • Terakhir, kami akan menulis hasilnya ke file CSV untuk ditinjau.

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, kita perlu mengimpor pustaka Python berikut -

from __future__ import print_function
from argparse import ArgumentParser

import datetime
import os
import struct

from utility.pytskutil import TSKUtil
import unicodecsv as csv

Selanjutnya, kita perlu memberikan argumen untuk penangan baris perintah. Perhatikan bahwa ini akan menerima tiga argumen - pertama adalah jalur ke file bukti, kedua adalah jenis file bukti dan ketiga adalah jalur keluaran yang diinginkan ke laporan CSV, seperti yang ditunjukkan di bawah ini -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Recycle Bin evidences')
   parser.add_argument('EVIDENCE_FILE', help = "Path to evidence file")
   parser.add_argument('IMAGE_TYPE', help = "Evidence file format",
   choices = ('ewf', 'raw'))
   parser.add_argument('CSV_REPORT', help = "Path to CSV report")
   args = parser.parse_args()
   main(args.EVIDENCE_FILE, args.IMAGE_TYPE, args.CSV_REPORT)

Sekarang, tentukan main()fungsi yang akan menangani semua pemrosesan. Ini akan mencari$I mengajukan sebagai berikut -

def main(evidence, image_type, report_file):
   tsk_util = TSKUtil(evidence, image_type)
   dollar_i_files = tsk_util.recurse_files("$I", path = '/$Recycle.bin',logic = "startswith") if dollar_i_files is not None: processed_files = process_dollar_i(tsk_util, dollar_i_files) write_csv(report_file,['file_path', 'file_size', 'deleted_time','dollar_i_file', 'dollar_r_file', 'is_directory'],processed_files) else: print("No $I files found")

Sekarang, jika kita temukan $I file, maka itu harus dikirim ke process_dollar_i() fungsi yang akan menerima tsk_util objek serta daftar $I file, seperti yang ditunjukkan di bawah ini -

def process_dollar_i(tsk_util, dollar_i_files):
   processed_files = []
   
   for dollar_i in dollar_i_files:
      file_attribs = read_dollar_i(dollar_i[2])
      if file_attribs is None:
         continue
      file_attribs['dollar_i_file'] = os.path.join('/$Recycle.bin', dollar_i[1][1:])

Sekarang, cari file $ R sebagai berikut -

recycle_file_path = os.path.join('/$Recycle.bin',dollar_i[1].rsplit("/", 1)[0][1:]) dollar_r_files = tsk_util.recurse_files( "$R" + dollar_i[0][2:],path = recycle_file_path, logic = "startswith")
   
   if dollar_r_files is None:
      dollar_r_dir = os.path.join(recycle_file_path,"$R" + dollar_i[0][2:])
      dollar_r_dirs = tsk_util.query_directory(dollar_r_dir)
   
   if dollar_r_dirs is None:
      file_attribs['dollar_r_file'] = "Not Found"
      file_attribs['is_directory'] = 'Unknown'
   
   else:
      file_attribs['dollar_r_file'] = dollar_r_dir
      file_attribs['is_directory'] = True
   
   else:
      dollar_r = [os.path.join(recycle_file_path, r[1][1:])for r in dollar_r_files]
      file_attribs['dollar_r_file'] = ";".join(dollar_r)
      file_attribs['is_directory'] = False
      processed_files.append(file_attribs)
   return processed_files

Sekarang, definisikan read_dollar_i() metode untuk membaca $Ifile, dengan kata lain, mengurai metadata. Kami akan menggunakanread_random()metode untuk membaca delapan byte pertama tanda tangan. Ini akan mengembalikan tidak ada jika tanda tangan tidak cocok. Setelah itu, kita harus membaca dan membongkar nilai dari$I file jika itu adalah file yang valid.

def read_dollar_i(file_obj):
   if file_obj.read_random(0, 8) != '\x01\x00\x00\x00\x00\x00\x00\x00':
      return None
   raw_file_size = struct.unpack('<q', file_obj.read_random(8, 8))
   raw_deleted_time = struct.unpack('<q',   file_obj.read_random(16, 8))
   raw_file_path = file_obj.read_random(24, 520)

Sekarang, setelah mengekstrak file-file ini kita perlu menafsirkan integer menjadi nilai yang dapat dibaca manusia dengan menggunakan sizeof_fmt() berfungsi seperti yang ditunjukkan di bawah ini -

file_size = sizeof_fmt(raw_file_size[0])
deleted_time = parse_windows_filetime(raw_deleted_time[0])

file_path = raw_file_path.decode("utf16").strip("\x00")
return {'file_size': file_size, 'file_path': file_path,'deleted_time': deleted_time}

Sekarang, kita perlu mendefinisikan sizeof_fmt() berfungsi sebagai berikut -

def sizeof_fmt(num, suffix = 'B'):
   for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
      if abs(num) < 1024.0:
         return "%3.1f%s%s" % (num, unit, suffix)
      num /= 1024.0
   return "%.1f%s%s" % (num, 'Yi', suffix)

Sekarang, tentukan fungsi untuk bilangan bulat yang ditafsirkan ke dalam format tanggal dan waktu sebagai berikut -

def parse_windows_filetime(date_value):
   microseconds = float(date_value) / 10
   ts = datetime.datetime(1601, 1, 1) + datetime.timedelta(
      microseconds = microseconds)
   return ts.strftime('%Y-%m-%d %H:%M:%S.%f')

Sekarang, kami akan mendefinisikan write_csv() metode untuk menulis hasil yang diproses menjadi file CSV sebagai berikut -

def write_csv(outfile, fieldnames, data):
   with open(outfile, 'wb') as open_outfile:
      csvfile = csv.DictWriter(open_outfile, fieldnames)
      csvfile.writeheader()
      csvfile.writerows(data)

Ketika Anda menjalankan script di atas, kita akan mendapatkan data dari file $ I dan $ R.

Catatan tempel

Windows Sticky Notes menggantikan kebiasaan menulis di dunia nyata dengan pena dan kertas. Catatan ini digunakan untuk mengapung di desktop dengan opsi berbeda untuk warna, font, dll. Di Windows 7 file Catatan Tempel disimpan sebagai file OLE maka dalam skrip Python berikut kami akan menyelidiki file OLE ini untuk mengekstrak metadata dari Catatan Tempel.

Untuk skrip Python ini, kita perlu menginstal modul pihak ketiga yaitu olefile, pytsk3, pyewfdan unicodecsv. Kita bisa menggunakan perintahpip untuk menginstalnya.

Kami dapat mengikuti langkah-langkah yang dibahas di bawah ini untuk mengekstraksi informasi dari file catatan tempel yaitu StickyNote.sn -

  • Pertama, buka file bukti dan temukan semua file StickyNote.snt.

  • Kemudian, parsing metadata dan konten dari aliran OLE dan tulis konten RTF ke file.

  • Terakhir, buat laporan CSV dari metadata ini.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, impor pustaka Python berikut -

from __future__ import print_function
from argparse import ArgumentParser

import unicodecsv as csv
import os
import StringIO

from utility.pytskutil import TSKUtil
import olefile

Selanjutnya, tentukan variabel global yang akan digunakan di seluruh skrip ini -

REPORT_COLS = ['note_id', 'created', 'modified', 'note_text', 'note_file']

Selanjutnya, kita perlu memberikan argumen untuk penangan baris perintah. Perhatikan bahwa di sini ia akan menerima tiga argumen - pertama adalah jalur ke file bukti, kedua adalah jenis file bukti dan ketiga adalah jalur keluaran yang diinginkan sebagai berikut -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Evidence from Sticky Notes')
   parser.add_argument('EVIDENCE_FILE', help="Path to evidence file")
   parser.add_argument('IMAGE_TYPE', help="Evidence file format",choices=('ewf', 'raw'))
   parser.add_argument('REPORT_FOLDER', help="Path to report folder")
   args = parser.parse_args()
   main(args.EVIDENCE_FILE, args.IMAGE_TYPE, args.REPORT_FOLDER)

Sekarang, kami akan mendefinisikan main() fungsi yang akan mirip dengan skrip sebelumnya seperti yang ditunjukkan di bawah ini -

def main(evidence, image_type, report_folder):
   tsk_util = TSKUtil(evidence, image_type)
   note_files = tsk_util.recurse_files('StickyNotes.snt', '/Users','equals')

Sekarang, mari kita ulangi file yang dihasilkan. Kemudian kami akan meneleponparse_snt_file() berfungsi untuk memproses file dan kemudian kita akan menulis file RTF dengan write_note_rtf() metode sebagai berikut -

report_details = []
for note_file in note_files:
   user_dir = note_file[1].split("/")[1]
   file_like_obj = create_file_like_obj(note_file[2])
   note_data = parse_snt_file(file_like_obj)
   
   if note_data is None:
      continue
   write_note_rtf(note_data, os.path.join(report_folder, user_dir))
   report_details += prep_note_report(note_data, REPORT_COLS,"/Users" + note_file[1])
   write_csv(os.path.join(report_folder, 'sticky_notes.csv'), REPORT_COLS,report_details)

Selanjutnya, kita perlu mendefinisikan berbagai fungsi yang digunakan dalam skrip ini.

Pertama-tama kami akan mendefinisikan create_file_like_obj() fungsi untuk membaca ukuran file dengan cara mengambil pytskobjek file. Kemudian kami akan mendefinisikanparse_snt_file() fungsi yang akan menerima objek seperti file sebagai inputnya dan digunakan untuk membaca dan menafsirkan file catatan tempel.

def parse_snt_file(snt_file):
   
   if not olefile.isOleFile(snt_file):
      print("This is not an OLE file")
      return None
   ole = olefile.OleFileIO(snt_file)
   note = {}
   
   for stream in ole.listdir():
      if stream[0].count("-") == 3:
         if stream[0] not in note:
            note[stream[0]] = {"created": ole.getctime(stream[0]),"modified": ole.getmtime(stream[0])}
         content = None
         if stream[1] == '0':
            content = ole.openstream(stream).read()
         elif stream[1] == '3':
            content = ole.openstream(stream).read().decode("utf-16")
         if content:
            note[stream[0]][stream[1]] = content
	return note

Sekarang, buat file RTF dengan mendefinisikan write_note_rtf() berfungsi sebagai berikut

def write_note_rtf(note_data, report_folder):
   if not os.path.exists(report_folder):
      os.makedirs(report_folder)
   
   for note_id, stream_data in note_data.items():
      fname = os.path.join(report_folder, note_id + ".rtf")
      with open(fname, 'w') as open_file:
         open_file.write(stream_data['0'])

Sekarang, kami akan menerjemahkan kamus bertingkat menjadi daftar datar kamus yang lebih sesuai untuk spreadsheet CSV. Itu akan dilakukan dengan mendefinisikanprep_note_report()fungsi. Terakhir, kami akan mendefinisikanwrite_csv() fungsi.

def prep_note_report(note_data, report_cols, note_file):
   report_details = []
   
   for note_id, stream_data in note_data.items():
      report_details.append({
         "note_id": note_id,
         "created": stream_data['created'],
         "modified": stream_data['modified'],
         "note_text": stream_data['3'].strip("\x00"),
         "note_file": note_file
      })
   return report_details
def write_csv(outfile, fieldnames, data):
   with open(outfile, 'wb') as open_outfile:
      csvfile = csv.DictWriter(open_outfile, fieldnames)
      csvfile.writeheader()
      csvfile.writerows(data)

Setelah menjalankan script di atas, kita akan mendapatkan metadata dari file Catatan Tempel.

File Registri

File registri Windows berisi banyak detail penting yang seperti harta karun informasi bagi seorang analis forensik. Ini adalah database hierarkis yang berisi detail terkait konfigurasi sistem operasi, aktivitas pengguna, instalasi perangkat lunak, dll. Dalam skrip Python berikut kita akan mengakses informasi dasar umum dariSYSTEM dan SOFTWARE gatal-gatal.

Untuk skrip Python ini, kita perlu menginstal modul pihak ketiga yaitu pytsk3, pyewf dan registry. Kita bisa gunakanpip untuk menginstalnya.

Kami dapat mengikuti langkah-langkah yang diberikan di bawah ini untuk mengekstrak informasi dari registri Windows -

  • Pertama, temukan kumpulan registri untuk diproses berdasarkan namanya serta jalur.

  • Kemudian kita membuka file tersebut dengan menggunakan modul StringIO dan Registry.

  • Akhirnya kita perlu memproses setiap sarang dan mencetak nilai parsing ke konsol untuk interpretasi.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, impor pustaka Python berikut -

from __future__ import print_function
from argparse import ArgumentParser

import datetime
import StringIO
import struct

from utility.pytskutil import TSKUtil
from Registry import Registry

Sekarang, berikan argumen untuk penangan baris perintah. Di sini ia akan menerima dua argumen - pertama adalah jalur ke file bukti, kedua adalah jenis file bukti, seperti yang ditunjukkan di bawah ini -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Evidence from Windows Registry')
   parser.add_argument('EVIDENCE_FILE', help = "Path to evidence file")
   parser.add_argument('IMAGE_TYPE', help = "Evidence file format",
   choices = ('ewf', 'raw'))
   args = parser.parse_args()
   main(args.EVIDENCE_FILE, args.IMAGE_TYPE)

Sekarang kita akan mendefinisikan main() fungsi untuk mencari SYSTEM dan SOFTWARE gatal-gatal di dalam /Windows/System32/config folder sebagai berikut -

def main(evidence, image_type):
   tsk_util = TSKUtil(evidence, image_type)
   tsk_system_hive = tsk_util.recurse_files('system', '/Windows/system32/config', 'equals')
   tsk_software_hive = tsk_util.recurse_files('software', '/Windows/system32/config', 'equals')
   system_hive = open_file_as_reg(tsk_system_hive[0][2])
   software_hive = open_file_as_reg(tsk_software_hive[0][2])
   process_system_hive(system_hive)
   process_software_hive(software_hive)

Sekarang, tentukan fungsi untuk membuka file registri. Untuk tujuan ini, kita perlu mengumpulkan ukuran file daripytsk metadata sebagai berikut -

def open_file_as_reg(reg_file):
   file_size = reg_file.info.meta.size
   file_content = reg_file.read_random(0, file_size)
   file_like_obj = StringIO.StringIO(file_content)
   return Registry.Registry(file_like_obj)

Sekarang, dengan bantuan metode berikut, kami dapat memproses SYSTEM> sarang -

def process_system_hive(hive):
   root = hive.root()
   current_control_set = root.find_key("Select").value("Current").value()
   control_set = root.find_key("ControlSet{:03d}".format(current_control_set))
   raw_shutdown_time = struct.unpack(
      '<Q', control_set.find_key("Control").find_key("Windows").value("ShutdownTime").value())
   
   shutdown_time = parse_windows_filetime(raw_shutdown_time[0])
   print("Last Shutdown Time: {}".format(shutdown_time))
   
   time_zone = control_set.find_key("Control").find_key("TimeZoneInformation")
      .value("TimeZoneKeyName").value()
   
   print("Machine Time Zone: {}".format(time_zone))
   computer_name = control_set.find_key("Control").find_key("ComputerName").find_key("ComputerName")
      .value("ComputerName").value()
   
   print("Machine Name: {}".format(computer_name))
   last_access = control_set.find_key("Control").find_key("FileSystem")
      .value("NtfsDisableLastAccessUpdate").value()
   last_access = "Disabled" if last_access == 1 else "enabled"
   print("Last Access Updates: {}".format(last_access))

Sekarang, kita perlu mendefinisikan fungsi untuk bilangan bulat yang diinterpretasikan menjadi tanggal dan waktu yang diformat sebagai berikut -

def parse_windows_filetime(date_value):
   microseconds = float(date_value) / 10
   ts = datetime.datetime(1601, 1, 1) + datetime.timedelta(microseconds = microseconds)
   return ts.strftime('%Y-%m-%d %H:%M:%S.%f')

def parse_unix_epoch(date_value):
   ts = datetime.datetime.fromtimestamp(date_value)
   return ts.strftime('%Y-%m-%d %H:%M:%S.%f')

Sekarang dengan bantuan metode berikut kita dapat memproses SOFTWARE sarang -

def process_software_hive(hive):
   root = hive.root()
   nt_curr_ver = root.find_key("Microsoft").find_key("Windows NT")
      .find_key("CurrentVersion")
   
   print("Product name: {}".format(nt_curr_ver.value("ProductName").value()))
   print("CSD Version: {}".format(nt_curr_ver.value("CSDVersion").value()))
   print("Current Build: {}".format(nt_curr_ver.value("CurrentBuild").value()))
   print("Registered Owner: {}".format(nt_curr_ver.value("RegisteredOwner").value()))
   print("Registered Org: 
      {}".format(nt_curr_ver.value("RegisteredOrganization").value()))
   
   raw_install_date = nt_curr_ver.value("InstallDate").value()
   install_date = parse_unix_epoch(raw_install_date)
   print("Installation Date: {}".format(install_date))

Setelah menjalankan script di atas, kita akan mendapatkan metadata yang tersimpan di file Windows Registry.

Bab ini membahas tentang beberapa artefak penting di Windows dan metode ekstraksinya menggunakan Python.

Aktivitas Pengguna

Windows memiliki NTUSER.DATfile untuk menyimpan berbagai aktivitas pengguna. Setiap profil pengguna memiliki sarang sepertiNTUSER.DAT, yang menyimpan informasi dan konfigurasi yang terkait dengan pengguna tersebut secara khusus. Oleh karena itu, ini sangat berguna untuk keperluan investigasi oleh analis forensik.

Skrip Python berikut akan mengurai beberapa kunci dari NTUSER.DATuntuk menjelajahi tindakan pengguna di sistem. Sebelum melangkah lebih jauh, untuk skrip Python, kita perlu menginstal modul pihak ketiga yaituRegistry, pytsk3, pyewf dan Jinja2. Kita dapat menggunakan pip untuk menginstalnya.

Kami dapat mengikuti langkah-langkah berikut untuk mengekstrak informasi NTUSER.DAT file -

  • Pertama, telusuri semuanya NTUSER.DAT file dalam sistem.

  • Kemudian parse file WordWheelQuery, TypePath and RunMRU kunci untuk masing-masing NTUSER.DAT mengajukan.

  • Akhirnya kita akan menulis artefak ini, yang sudah diproses, menjadi laporan HTML dengan menggunakan Jinja2 fmodule.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama-tama, kita perlu mengimpor modul Python berikut -

from __future__ import print_function
from argparse import ArgumentParser

import os
import StringIO
import struct

from utility.pytskutil import TSKUtil
from Registry import Registry
import jinja2

Sekarang, berikan argumen untuk penangan baris perintah. Di sini akan menerima tiga argumen - pertama adalah jalur ke file bukti, kedua adalah jenis file bukti dan ketiga adalah jalur keluaran yang diinginkan ke laporan HTML, seperti yang ditunjukkan di bawah ini -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Information from user activities')
   parser.add_argument('EVIDENCE_FILE',help = "Path to evidence file")
   parser.add_argument('IMAGE_TYPE',help = "Evidence file format",choices = ('ewf', 'raw'))
   parser.add_argument('REPORT',help = "Path to report file")
   args = parser.parse_args()
   main(args.EVIDENCE_FILE, args.IMAGE_TYPE, args.REPORT)

Sekarang, mari kita definisikan main() berfungsi untuk mencari semua NTUSER.DAT file, seperti yang ditunjukkan -

def main(evidence, image_type, report):
   tsk_util = TSKUtil(evidence, image_type)
   tsk_ntuser_hives = tsk_util.recurse_files('ntuser.dat','/Users', 'equals')
   
   nt_rec = {
      'wordwheel': {'data': [], 'title': 'WordWheel Query'},
      'typed_path': {'data': [], 'title': 'Typed Paths'},
      'run_mru': {'data': [], 'title': 'Run MRU'}
   }

Sekarang, kami akan mencoba menemukan kuncinya NTUSER.DAT file dan setelah Anda menemukannya, tentukan fungsi pemrosesan pengguna seperti yang ditunjukkan di bawah ini -

for ntuser in tsk_ntuser_hives:
   uname = ntuser[1].split("/")

open_ntuser = open_file_as_reg(ntuser[2])
try:
   explorer_key = open_ntuser.root().find_key("Software").find_key("Microsoft")
      .find_key("Windows").find_key("CurrentVersion").find_key("Explorer")
   except Registry.RegistryKeyNotFoundException:
      continue
   nt_rec['wordwheel']['data'] += parse_wordwheel(explorer_key, uname)
   nt_rec['typed_path']['data'] += parse_typed_paths(explorer_key, uname)
   nt_rec['run_mru']['data'] += parse_run_mru(explorer_key, uname)
   nt_rec['wordwheel']['headers'] = \ nt_rec['wordwheel']['data'][0].keys()
   nt_rec['typed_path']['headers'] = \ nt_rec['typed_path']['data'][0].keys()
   nt_rec['run_mru']['headers'] = \ nt_rec['run_mru']['data'][0].keys()

Sekarang, teruskan objek kamus dan jalurnya ke write_html() metode sebagai berikut -

write_html(report, nt_rec)

Sekarang, tentukan metode yang dibutuhkan pytsk menangani file dan membacanya ke kelas Registry melalui StringIO kelas.

def open_file_as_reg(reg_file):
   file_size = reg_file.info.meta.size
   file_content = reg_file.read_random(0, file_size)
   file_like_obj = StringIO.StringIO(file_content)
   return Registry.Registry(file_like_obj)

Sekarang, kita akan menentukan fungsi yang akan mengurai dan menangani WordWheelQuery kunci dari NTUSER.DAT mengajukan sebagai berikut -

def parse_wordwheel(explorer_key, username):
   try:
      wwq = explorer_key.find_key("WordWheelQuery")
   except Registry.RegistryKeyNotFoundException:
      return []
   mru_list = wwq.value("MRUListEx").value()
   mru_order = []
   
   for i in xrange(0, len(mru_list), 2):
      order_val = struct.unpack('h', mru_list[i:i + 2])[0]
   if order_val in mru_order and order_val in (0, -1):
      break
   else:
      mru_order.append(order_val)
   search_list = []
   
   for count, val in enumerate(mru_order):
      ts = "N/A"
      if count == 0:
         ts = wwq.timestamp()
      search_list.append({
         'timestamp': ts,
         'username': username,
         'order': count,
         'value_name': str(val),
         'search': wwq.value(str(val)).value().decode("UTF-16").strip("\x00")
})
   return search_list

Sekarang, kita akan menentukan fungsi yang akan mengurai dan menangani TypedPaths kunci dari NTUSER.DAT mengajukan sebagai berikut -

def parse_typed_paths(explorer_key, username):
   try:
      typed_paths = explorer_key.find_key("TypedPaths")
   except Registry.RegistryKeyNotFoundException:
      return []
   typed_path_details = []
   
   for val in typed_paths.values():
      typed_path_details.append({
         "username": username,
         "value_name": val.name(),
         "path": val.value()
      })
   return typed_path_details

Sekarang, kita akan menentukan fungsi yang akan mengurai dan menangani RunMRU kunci dari NTUSER.DAT mengajukan sebagai berikut -

def parse_run_mru(explorer_key, username):
   try:
      run_mru = explorer_key.find_key("RunMRU")
   except Registry.RegistryKeyNotFoundException:
      return []
   
   if len(run_mru.values()) == 0:
      return []
   mru_list = run_mru.value("MRUList").value()
   mru_order = []
   
   for i in mru_list:
      mru_order.append(i)
   mru_details = []
   
   for count, val in enumerate(mru_order):
      ts = "N/A"
      if count == 0:
         ts = run_mru.timestamp()
      mru_details.append({
         "username": username,
         "timestamp": ts,
         "order": count,
         "value_name": val,
         "run_statement": run_mru.value(val).value()
      })
   return mru_details

Sekarang, fungsi berikut akan menangani pembuatan laporan HTML -

def write_html(outfile, data_dict):
   cwd = os.path.dirname(os.path.abspath(__file__))
   env = jinja2.Environment(loader=jinja2.FileSystemLoader(cwd))
   template = env.get_template("user_activity.html")
   rendering = template.render(nt_data=data_dict)
   
   with open(outfile, 'w') as open_outfile:
      open_outfile.write(rendering)

Akhirnya kita bisa menulis dokumen HTML untuk laporan. Setelah menjalankan script diatas, kita akan mendapatkan informasi dari file NTUSER.DAT dalam format dokumen HTML.

TAUTKAN file

File pintasan dibuat ketika pengguna atau sistem operasi membuat file pintasan untuk file yang sering digunakan, diklik dua kali atau diakses dari drive sistem seperti penyimpanan terpasang. Jenis file shortcut seperti itu disebut file link. Dengan mengakses file link ini, investigator dapat menemukan aktivitas window seperti waktu dan lokasi dimana file tersebut diakses.

Mari kita bahas script Python yang bisa kita gunakan untuk mendapatkan informasi dari file LINK Windows ini.

Untuk skrip Python, instal modul pihak ketiga yaitu pylnk, pytsk3, pyewf. Kami dapat mengikuti langkah-langkah berikut untuk mengekstrak informasilnk file

  • Pertama, cari lnk file dalam sistem.

  • Kemudian, ekstrak informasi dari file itu dengan mengulanginya.

  • Sekarang, akhirnya kami membutuhkan informasi ini untuk laporan CSV.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, impor pustaka Python berikut -

from __future__ import print_function
from argparse import ArgumentParser

import csv
import StringIO

from utility.pytskutil import TSKUtil
import pylnk

Sekarang, berikan argumen untuk penangan baris perintah. Di sini ia akan menerima tiga argumen - pertama adalah jalur ke file bukti, kedua adalah jenis file bukti dan ketiga adalah jalur keluaran yang diinginkan ke laporan CSV, seperti yang ditunjukkan di bawah ini -

if __name__ == '__main__':
   parser = argparse.ArgumentParser('Parsing LNK files')
   parser.add_argument('EVIDENCE_FILE', help = "Path to evidence file")
   parser.add_argument('IMAGE_TYPE', help = "Evidence file format",choices = ('ewf', 'raw'))
   parser.add_argument('CSV_REPORT', help = "Path to CSV report")
   args = parser.parse_args()
   main(args.EVIDENCE_FILE, args.IMAGE_TYPE, args.CSV_REPORT)

Sekarang, tafsirkan file bukti dengan membuat objek TSKUtil dan lakukan iterasi melalui sistem file untuk menemukan file yang diakhiri dengan lnk. Itu bisa dilakukan dengan mendefinisikanmain() berfungsi sebagai berikut -

def main(evidence, image_type, report):
   tsk_util = TSKUtil(evidence, image_type)
   lnk_files = tsk_util.recurse_files("lnk", path="/", logic="endswith")
   
   if lnk_files is None:
      print("No lnk files found")
      exit(0)
   columns = [
      'command_line_arguments', 'description', 'drive_serial_number',
      'drive_type', 'file_access_time', 'file_attribute_flags',
      'file_creation_time', 'file_modification_time', 'file_size',
      'environmental_variables_location', 'volume_label',
      'machine_identifier', 'local_path', 'network_path',
      'relative_path', 'working_directory'
   ]

Sekarang dengan bantuan kode berikut, kita akan melakukan iterasi lnk file dengan membuat fungsi sebagai berikut -

parsed_lnks = []

for entry in lnk_files:
   lnk = open_file_as_lnk(entry[2])
   lnk_data = {'lnk_path': entry[1], 'lnk_name': entry[0]}
   
   for col in columns:
      lnk_data[col] = getattr(lnk, col, "N/A")
   lnk.close()
   parsed_lnks.append(lnk_data)
write_csv(report, columns + ['lnk_path', 'lnk_name'], parsed_lnks)

Sekarang kita perlu mendefinisikan dua fungsi, satu akan membuka pytsk objek file dan lainnya akan digunakan untuk menulis laporan CSV seperti yang ditunjukkan di bawah ini -

def open_file_as_lnk(lnk_file):
   file_size = lnk_file.info.meta.size
   file_content = lnk_file.read_random(0, file_size)
   file_like_obj = StringIO.StringIO(file_content)
   lnk = pylnk.file()
   lnk.open_file_object(file_like_obj)
   return lnk
def write_csv(outfile, fieldnames, data):
   with open(outfile, 'wb') as open_outfile:
      csvfile = csv.DictWriter(open_outfile, fieldnames)
      csvfile.writeheader()
      csvfile.writerows(data)

Setelah menjalankan skrip di atas, kita akan mendapatkan informasi dari yang ditemukan lnk file dalam laporan CSV -

Ambil File

Setiap kali aplikasi berjalan untuk pertama kalinya dari lokasi tertentu, Windows akan membuat prefetch files. Ini digunakan untuk mempercepat proses startup aplikasi. Ekstensi untuk file-file ini adalah.PF dan ini disimpan di ”\Root\Windows\Prefetch” map.

Pakar forensik digital dapat mengungkap bukti pelaksanaan program dari lokasi tertentu bersama dengan detail pengguna. File prefetch adalah artefak yang berguna untuk pemeriksa karena entri mereka tetap ada bahkan setelah program dihapus atau di-uninstal.

Mari kita bahas skrip Python yang akan mengambil informasi dari file prefetch Windows seperti yang diberikan di bawah ini -

Untuk skrip Python, instal modul pihak ketiga yaitu pylnk, pytsk3 dan unicodecsv. Ingatlah bahwa kita telah bekerja dengan pustaka ini dalam skrip Python yang telah kita bahas di bab-bab sebelumnya.

Kami harus mengikuti langkah-langkah yang diberikan di bawah ini untuk mengekstrak informasi prefetch file -

  • Pertama, pindai .pf file ekstensi atau file prefetch.

  • Sekarang, lakukan verifikasi tanda tangan untuk menghilangkan positif palsu.

  • Selanjutnya, parsing format file prefetch Windows. Ini berbeda dengan versi Windows. Misalnya, untuk Windows XP adalah 17, untuk Windows Vista dan Windows 7 adalah 23, 26 untuk Windows 8.1 dan 30 untuk Windows 10.

  • Terakhir, kami akan menulis hasil parsing dalam file CSV.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, impor pustaka Python berikut -

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

import os
import pytsk3
import pyewf
import struct
import sys
import unicodecsv as csv
from utility.pytskutil import TSKUtil

Sekarang, berikan argumen untuk penangan baris perintah. Di sini akan menerima dua argumen, pertama akan menjadi jalur ke file bukti dan kedua akan menjadi jenis file bukti. Ini juga menerima argumen opsional untuk menentukan jalur untuk memindai file prefetch -

if __name__ == "__main__":
   parser = argparse.ArgumentParser('Parsing Prefetch files')
   parser.add_argument("EVIDENCE_FILE", help = "Evidence file path")
   parser.add_argument("TYPE", help = "Type of Evidence",choices = ("raw", "ewf"))
   parser.add_argument("OUTPUT_CSV", help = "Path to write output csv")
   parser.add_argument("-d", help = "Prefetch directory to scan",default = "/WINDOWS/PREFETCH")
   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.OUTPUT_CSV, args.d)
else:
   print("[-] Supplied input file {} does not exist or is not a ""file".format(args.EVIDENCE_FILE))
   sys.exit(1)

Sekarang, tafsirkan file bukti dengan membuat objek TSKUtil dan lakukan iterasi melalui sistem file untuk menemukan file yang diakhiri dengan .pf. Itu bisa dilakukan dengan mendefinisikanmain() berfungsi sebagai berikut -

def main(evidence, image_type, output_csv, path):
   tsk_util = TSKUtil(evidence, image_type)
   prefetch_dir = tsk_util.query_directory(path)
   prefetch_files = None
   
   if prefetch_dir is not None:
      prefetch_files = tsk_util.recurse_files(".pf", path=path, logic="endswith")
   
   if prefetch_files is None:
      print("[-] No .pf files found")
      sys.exit(2)
   print("[+] Identified {} potential prefetch files".format(len(prefetch_files)))
   prefetch_data = []
   
   for hit in prefetch_files:
      prefetch_file = hit[2]
      pf_version = check_signature(prefetch_file)

Sekarang, tentukan metode yang akan melakukan validasi tanda tangan seperti yang ditunjukkan di bawah ini -

def check_signature(prefetch_file):
   version, signature = struct.unpack("^<2i", prefetch_file.read_random(0, 8))
   
   if signature == 1094927187:
      return version
   else:
      return None
   
   if pf_version is None:
      continue
   pf_name = hit[0]
   
   if pf_version == 17:
      parsed_data = parse_pf_17(prefetch_file, pf_name)
      parsed_data.append(os.path.join(path, hit[1].lstrip("//")))
      prefetch_data.append(parsed_data)

Sekarang, mulailah memproses file prefetch Windows. Di sini kami mengambil contoh file prefetch Windows XP -

def parse_pf_17(prefetch_file, pf_name):
   create = convert_unix(prefetch_file.info.meta.crtime)
   modify = convert_unix(prefetch_file.info.meta.mtime)
def convert_unix(ts):
   if int(ts) == 0:
      return ""
   return datetime.utcfromtimestamp(ts)
def convert_filetime(ts):
   if int(ts) == 0:
      return ""
   return datetime(1601, 1, 1) + timedelta(microseconds=ts / 10)

Sekarang, ekstrak data yang disematkan dalam file prefetch dengan menggunakan struct sebagai berikut -

pf_size, name, vol_info, vol_entries, vol_size, filetime, \
   count = struct.unpack("<i60s32x3iq16xi",prefetch_file.read_random(12, 136))
name = name.decode("utf-16", "ignore").strip("/x00").split("/x00")[0]

vol_name_offset, vol_name_length, vol_create, \
   vol_serial = struct.unpack("<2iqi",prefetch_file.read_random(vol_info, 20))
   vol_serial = hex(vol_serial).lstrip("0x")
   vol_serial = vol_serial[:4] + "-" + vol_serial[4:]
   vol_name = struct.unpack(
      "<{}s".format(2 * vol_name_length),
      prefetch_file.read_random(vol_info + vol_name_offset,vol_name_length * 2))[0]

vol_name = vol_name.decode("utf-16", "ignore").strip("/x00").split("/x00")[0]
return [
   pf_name, name, pf_size, create,
   modify, convert_filetime(filetime), count, vol_name,
   convert_filetime(vol_create), vol_serial ]

Seperti yang telah kami sediakan versi prefetch untuk Windows XP tetapi bagaimana jika akan menemui versi prefetch untuk Windows lainnya. Maka itu harus menampilkan pesan kesalahan sebagai berikut -

elif pf_version == 23:
   print("[-] Windows Vista / 7 PF file {} -- unsupported".format(pf_name))
   continue
elif pf_version == 26:
   print("[-] Windows 8 PF file {} -- unsupported".format(pf_name))
   continue
elif pf_version == 30:
   print("[-] Windows 10 PF file {} -- unsupported".format(pf_name))
continue

else:
   print("[-] Signature mismatch - Name: {}\nPath: {}".format(hit[0], hit[1]))
continue
write_output(prefetch_data, output_csv)

Sekarang, tentukan metode penulisan hasil ke dalam laporan CSV sebagai berikut -

def write_output(data, output_csv):
   print("[+] Writing csv report")
   with open(output_csv, "wb") as outfile:
      writer = csv.writer(outfile)
      writer.writerow([
         "File Name", "Prefetch Name", "File Size (bytes)",
         "File Create Date (UTC)", "File Modify Date (UTC)",
         "Prefetch Last Execution Date (UTC)",
         "Prefetch Execution Count", "Volume", "Volume Create Date",
         "Volume Serial", "File Path" ])
      writer.writerows(data)

Setelah menjalankan script diatas, kita akan mendapatkan informasi dari file prefetch versi Windows XP ke dalam spreadsheet.

Bab ini akan menjelaskan tentang artefak lebih lanjut yang dapat diperoleh penyelidik selama analisis forensik di Windows.

Log Peristiwa

File log peristiwa Windows, seperti namanya –sarankan, adalah file khusus yang menyimpan peristiwa penting seperti saat pengguna masuk ke komputer, saat program mengalami kesalahan, tentang perubahan sistem, akses RDP, peristiwa khusus aplikasi, dll. Penyelidik dunia maya selalu tertarik dengan peristiwa informasi log karena memberikan banyak informasi historis yang berguna tentang akses sistem. Dalam skrip Python berikut, kita akan memproses format log peristiwa Windows lama dan saat ini.

Untuk skrip Python, kita perlu menginstal modul pihak ketiga yaitu pytsk3, pyewf, unicodecsv, pyevt and pyevtx. Kami dapat mengikuti langkah-langkah yang diberikan di bawah ini untuk mengekstrak informasi dari log peristiwa -

  • Pertama, cari semua log peristiwa yang cocok dengan argumen input.

  • Kemudian, lakukan verifikasi tanda tangan file.

  • Sekarang, proses setiap log peristiwa yang ditemukan dengan perpustakaan yang sesuai.

  • Terakhir, tulis hasilnya ke spreadsheet.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, impor pustaka Python berikut -

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

Sekarang, berikan argumen untuk penangan baris perintah. Perhatikan bahwa di sini ia akan menerima tiga argumen - pertama adalah jalur ke file bukti, kedua adalah jenis file bukti dan ketiga adalah nama log peristiwa yang akan diproses.

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)

Sekarang, berinteraksilah dengan log peristiwa untuk menanyakan keberadaan jalur yang disediakan pengguna dengan membuat TSKUtilobyek. Itu bisa dilakukan dengan bantuanmain() metode sebagai berikut -

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)

Sekarang, kita perlu melakukan verifikasi tanda tangan diikuti dengan menentukan metode yang akan menulis seluruh konten ke direktori saat ini -

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

Terakhir, tentukan metode untuk menulis output ke spreadsheet sebagai berikut -

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)

Setelah Anda berhasil menjalankan script di atas, kita akan mendapatkan informasi event log in spreadsheet.

Sejarah Internet

Sejarah internet sangat berguna bagi analis forensik; karena sebagian besar kejahatan dunia maya hanya terjadi melalui internet. Mari kita lihat cara mengekstrak riwayat internet dari Internet Explorer, saat kita membahas tentang forensik Windows, dan Internet Explorer hadir secara default dengan Windows.

Di Internet Explorer, riwayat internet disimpan di index.datmengajukan. Mari kita lihat skrip Python, yang akan mengekstrak informasinyaindex.dat mengajukan.

Kami dapat mengikuti langkah-langkah yang diberikan di bawah ini untuk mengekstrak informasi index.dat file -

  • Pertama, cari index.dat file dalam sistem.

  • Kemudian, ekstrak informasi dari file itu dengan mengulanginya.

  • Sekarang, tulis semua informasi ini ke laporan CSV.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, impor pustaka Python berikut -

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

Sekarang, berikan argumen untuk penangan baris perintah. Perhatikan bahwa di sini akan menerima dua argumen - pertama akan menjadi jalur ke file bukti dan yang kedua adalah jenis file bukti -

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)

Sekarang, tafsirkan file bukti dengan membuat objek TSKUtildan lakukan iterasi melalui sistem file untuk menemukan file index.dat. Ini dapat dilakukan dengan mendefinisikan filemain() berfungsi sebagai berikut -

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)

Sekarang, tentukan fungsi dengan bantuan yang kita dapat menyalin informasi dari file index.dat ke direktori kerja saat ini dan nanti mereka dapat diproses oleh modul pihak ketiga -

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

Sekarang, gunakan kode berikut untuk melakukan validasi tanda tangan dengan bantuan fungsi bawaan yaitu 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)

Sekarang, tentukan metode yang akan mencetak output dalam file CSV, seperti yang ditunjukkan di bawah ini -

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)

Setelah menjalankan script diatas kita akan mendapatkan informasi dari file index.dat dalam file CSV.

Salinan Bayangan Volume

Salinan bayangan adalah teknologi yang disertakan dalam Windows untuk mengambil salinan cadangan atau snapshot dari file komputer secara manual atau otomatis. Ini juga disebut layanan snapshot volume atau layanan bayangan volume (VSS).

Dengan bantuan file VSS ini, ahli forensik dapat memiliki beberapa informasi historis tentang bagaimana sistem berubah dari waktu ke waktu dan file apa yang ada di komputer. Teknologi salinan bayangan membutuhkan sistem file menjadi NTFS untuk membuat dan menyimpan salinan bayangan.

Di bagian ini, kita akan melihat skrip Python, yang membantu mengakses setiap volume salinan bayangan yang ada dalam gambar forensik.

Untuk skrip Python kita perlu menginstal modul pihak ketiga yaitu pytsk3, pyewf, unicodecsv, pyvshadow dan vss. Kami dapat mengikuti langkah-langkah yang diberikan di bawah ini untuk mengekstrak informasi dari file VSS

  • Pertama, akses volume gambar mentah dan identifikasi semua partisi NTFS.

  • Kemudian, ekstrak informasi dari salinan bayangan itu dengan mengulanginya.

  • Sekarang, akhirnya kita perlu membuat daftar file data di dalam snapshot.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, impor pustaka Python berikut -

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

Sekarang, berikan argumen untuk penangan baris perintah. Di sini ia akan menerima dua argumen - pertama adalah jalur ke file bukti dan kedua adalah file keluaran.

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()

Sekarang, validasi keberadaan jalur file input dan juga pisahkan direktori dari file output.

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)

Sekarang, berinteraksi dengan volume file bukti dengan membuat file TSKUtilobyek. Itu bisa dilakukan dengan bantuanmain() metode sebagai berikut -

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)

Sekarang, tentukan metode untuk menjelajahi file bayangan volume yang diuraikan sebagai berikut -

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)

Terakhir, tentukan metode penulisan hasil dalam spreadsheet sebagai berikut -

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)

Setelah Anda berhasil menjalankan skrip Python ini, kami akan mendapatkan informasi yang berada di VSS ke dalam spreadsheet.

Sampai sekarang, kami telah melihat cara mendapatkan artefak di Windows menggunakan Python. Di bab ini, mari kita belajar tentang investigasi artefak berbasis log menggunakan Python.

pengantar

Artefak berbasis kayu gelondongan adalah harta karun informasi yang bisa sangat berguna bagi ahli forensik digital. Meskipun kami memiliki berbagai perangkat lunak pemantauan untuk mengumpulkan informasi, masalah utama untuk mengurai informasi yang berguna darinya adalah kami membutuhkan banyak data.

Berbagai Artefak Berbasis Log dan Investigasi dengan Python

Di bagian ini, mari kita bahas berbagai artefak berbasis log dan penyelidikannya dengan Python -

Stempel waktu

Stempel waktu menyampaikan data dan waktu aktivitas di log. Ini adalah salah satu elemen penting dari file log apa pun. Perhatikan bahwa data dan nilai waktu ini bisa datang dalam berbagai format.

Skrip Python yang ditunjukkan di bawah ini akan menggunakan tanggal-waktu mentah sebagai masukan dan memberikan stempel waktu yang diformat sebagai keluarannya.

Untuk skrip ini, kita perlu mengikuti langkah-langkah berikut -

  • Pertama, siapkan argumen yang akan mengambil nilai data mentah bersama dengan sumber data dan tipe datanya.

  • Sekarang, sediakan kelas untuk menyediakan antarmuka umum untuk data di berbagai format tanggal.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, impor modul Python berikut -

from __future__ import print_function
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
from datetime import datetime as dt
from datetime import timedelta

Sekarang seperti biasa kita perlu memberikan argumen untuk penangan baris perintah. Di sini ia akan menerima tiga argumen, pertama adalah nilai tanggal yang akan diproses, kedua akan menjadi sumber nilai tanggal itu dan ketiga adalah tipenya -

if __name__ == '__main__':
   parser = ArgumentParser('Timestamp Log-based artifact')
   parser.add_argument("date_value", help="Raw date value to parse")
   parser.add_argument(
      "source", help = "Source format of date",choices = ParseDate.get_supported_formats())
   parser.add_argument(
      "type", help = "Data type of input value",choices = ('number', 'hex'), default = 'int')
   
   args = parser.parse_args()
   date_parser = ParseDate(args.date_value, args.source, args.type)
   date_parser.run()
   print(date_parser.timestamp)

Sekarang, kita perlu mendefinisikan kelas yang akan menerima argumen untuk nilai tanggal, sumber tanggal, dan jenis nilai -

class ParseDate(object):
   def __init__(self, date_value, source, data_type):
      self.date_value = date_value
      self.source = source
      self.data_type = data_type
      self.timestamp = None

Sekarang kita akan mendefinisikan metode yang akan bertindak seperti pengontrol seperti metode main () -

def run(self):
   if self.source == 'unix-epoch':
      self.parse_unix_epoch()
   elif self.source == 'unix-epoch-ms':
      self.parse_unix_epoch(True)
   elif self.source == 'windows-filetime':
      self.parse_windows_filetime()
@classmethod
def get_supported_formats(cls):
   return ['unix-epoch', 'unix-epoch-ms', 'windows-filetime']

Sekarang, kita perlu mendefinisikan dua metode yang masing-masing akan memproses waktu epoch Unix dan FILETIME -

def parse_unix_epoch(self, milliseconds=False):
   if self.data_type == 'hex':
      conv_value = int(self.date_value)
      if milliseconds:
         conv_value = conv_value / 1000.0
   elif self.data_type == 'number':
      conv_value = float(self.date_value)
      if milliseconds:
         conv_value = conv_value / 1000.0
   else:
      print("Unsupported data type '{}' provided".format(self.data_type))
      sys.exit('1')
   ts = dt.fromtimestamp(conv_value)
   self.timestamp = ts.strftime('%Y-%m-%d %H:%M:%S.%f')
def parse_windows_filetime(self):
   if self.data_type == 'hex':
      microseconds = int(self.date_value, 16) / 10.0
   elif self.data_type == 'number':
      microseconds = float(self.date_value) / 10
   else:
      print("Unsupported data type '{}'   provided".format(self.data_type))
      sys.exit('1')
   ts = dt(1601, 1, 1) + timedelta(microseconds=microseconds)
   self.timestamp = ts.strftime('%Y-%m-%d %H:%M:%S.%f')

Setelah menjalankan skrip di atas, dengan memberikan stempel waktu kita bisa mendapatkan nilai yang dikonversi dalam format yang mudah dibaca.

Log Server Web

Dari sudut pandang ahli forensik digital, log server web adalah artefak penting lainnya karena mereka bisa mendapatkan statistik pengguna yang berguna bersama dengan informasi tentang pengguna dan lokasi geografis. Berikut ini adalah skrip Python yang akan membuat spreadsheet, setelah memproses log server web, untuk memudahkan analisis informasi.

Pertama-tama kita perlu mengimpor modul Python berikut -

from __future__ import print_function
from argparse import ArgumentParser, FileType

import re
import shlex
import logging
import sys
import csv

logger = logging.getLogger(__file__)

Sekarang, kita perlu menentukan pola yang akan diurai dari log -

iis_log_format = [
   ("date", re.compile(r"\d{4}-\d{2}-\d{2}")),
   ("time", re.compile(r"\d\d:\d\d:\d\d")),
   ("s-ip", re.compile(
      r"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}")),
   ("cs-method", re.compile(
      r"(GET)|(POST)|(PUT)|(DELETE)|(OPTIONS)|(HEAD)|(CONNECT)")),
   ("cs-uri-stem", re.compile(r"([A-Za-z0-1/\.-]*)")),
   ("cs-uri-query", re.compile(r"([A-Za-z0-1/\.-]*)")),
   ("s-port", re.compile(r"\d*")),
   ("cs-username", re.compile(r"([A-Za-z0-1/\.-]*)")),
   ("c-ip", re.compile(
      r"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}")),
   ("cs(User-Agent)", re.compile(r".*")),
   ("sc-status", re.compile(r"\d*")),
   ("sc-substatus", re.compile(r"\d*")),
   ("sc-win32-status", re.compile(r"\d*")),
   ("time-taken", re.compile(r"\d*"))]

Sekarang, berikan argumen untuk penangan baris perintah. Di sini akan menerima dua argumen, pertama akan menjadi log IIS yang akan diproses, yang kedua adalah jalur file CSV yang diinginkan.

if __name__ == '__main__':
   parser = ArgumentParser('Parsing Server Based Logs')
   parser.add_argument('iis_log', help = "Path to IIS Log",type = FileType('r'))
   parser.add_argument('csv_report', help = "Path to CSV report")
   parser.add_argument('-l', help = "Path to processing log",default=__name__ + '.log')
   args = parser.parse_args()
   logger.setLevel(logging.DEBUG)
   msg_fmt = logging.Formatter(
      "%(asctime)-15s %(funcName)-10s ""%(levelname)-8s %(message)s")
   
   strhndl = logging.StreamHandler(sys.stdout)
   strhndl.setFormatter(fmt = msg_fmt)
   fhndl = logging.FileHandler(args.log, mode = 'a')
   fhndl.setFormatter(fmt = msg_fmt)
   
   logger.addHandler(strhndl)
   logger.addHandler(fhndl)
   logger.info("Starting IIS Parsing ")
   logger.debug("Supplied arguments: {}".format(", ".join(sys.argv[1:])))
   logger.debug("System " + sys.platform)
   logger.debug("Version " + sys.version)
   main(args.iis_log, args.csv_report, logger)
   iologger.info("IIS Parsing Complete")

Sekarang kita perlu mendefinisikan metode main () yang akan menangani skrip untuk informasi log massal -

def main(iis_log, report_file, logger):
   parsed_logs = []

for raw_line in iis_log:
   line = raw_line.strip()
   log_entry = {}

if line.startswith("#") or len(line) == 0:
   continue

if '\"' in line:
   line_iter = shlex.shlex(line_iter)
else:
   line_iter = line.split(" ")
   for count, split_entry in enumerate(line_iter):
      col_name, col_pattern = iis_log_format[count]

      if col_pattern.match(split_entry):
         log_entry[col_name] = split_entry
else:
   logger.error("Unknown column pattern discovered. "
      "Line preserved in full below")
      logger.error("Unparsed Line: {}".format(line))
      parsed_logs.append(log_entry)
      
      logger.info("Parsed {} lines".format(len(parsed_logs)))
      cols = [x[0] for x in iis_log_format]
      
      logger.info("Creating report file: {}".format(report_file))
      write_csv(report_file, cols, parsed_logs)
      logger.info("Report created")

Terakhir, kita perlu mendefinisikan metode yang akan menulis output ke spreadsheet -

def write_csv(outfile, fieldnames, data):
   with open(outfile, 'w', newline="") as open_outfile:
      csvfile = csv.DictWriter(open_outfile, fieldnames)
      csvfile.writeheader()
      csvfile.writerows(data)

Setelah menjalankan skrip di atas kita akan mendapatkan log berbasis server web dalam spreadsheet.

Memindai File Penting menggunakan YARA

YARA (Yet Another Recursive Algorithm) adalah utilitas pencocokan pola yang dirancang untuk identifikasi malware dan respons insiden. Kami akan menggunakan YARA untuk memindai file. Dalam skrip Python berikut, kami akan menggunakan YARA.

Kami dapat menginstal YARA dengan bantuan perintah berikut -

pip install YARA

Kami dapat mengikuti langkah-langkah yang diberikan di bawah ini untuk menggunakan aturan YARA untuk memindai file -

  • Pertama, siapkan dan kompilasi aturan YARA

  • Kemudian, pindai satu file dan kemudian lakukan iterasi melalui direktori untuk memproses file individual.

  • Terakhir, kami akan mengekspor hasilnya ke CSV.

Kode Python

Mari kita lihat bagaimana menggunakan kode Python untuk tujuan ini -

Pertama, kita perlu mengimpor modul Python berikut -

from __future__ import print_function
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter

import os
import csv
import yara

Selanjutnya, berikan argumen untuk penangan baris perintah. Perhatikan bahwa di sini ia akan menerima dua argumen - pertama adalah jalur ke aturan YARA, kedua adalah file yang akan dipindai.

if __name__ == '__main__':
   parser = ArgumentParser('Scanning files by YARA')
   parser.add_argument(
      'yara_rules',help = "Path to Yara rule to scan with. May be file or folder path.")
   parser.add_argument('path_to_scan',help = "Path to file or folder to scan")
   parser.add_argument('--output',help = "Path to output a CSV report of scan results")
   args = parser.parse_args()
   main(args.yara_rules, args.path_to_scan, args.output)

Sekarang kita akan menentukan fungsi main () yang akan menerima jalur ke aturan yara dan file yang akan dipindai -

def main(yara_rules, path_to_scan, output):
   if os.path.isdir(yara_rules):
      yrules = yara.compile(yara_rules)
   else:
      yrules = yara.compile(filepath=yara_rules)
   if os.path.isdir(path_to_scan):
      match_info = process_directory(yrules, path_to_scan)
   else:
      match_info = process_file(yrules, path_to_scan)
   columns = ['rule_name', 'hit_value', 'hit_offset', 'file_name',
   'rule_string', 'rule_tag']
   
   if output is None:
      write_stdout(columns, match_info)
   else:
      write_csv(output, columns, match_info)

Sekarang, tentukan metode yang akan melakukan iterasi melalui direktori dan meneruskan hasilnya ke metode lain untuk diproses lebih lanjut -

def process_directory(yrules, folder_path):
   match_info = []
   for root, _, files in os.walk(folder_path):
      for entry in files:
         file_entry = os.path.join(root, entry)
         match_info += process_file(yrules, file_entry)
   return match_info

Selanjutnya, tentukan dua fungsi. Perhatikan bahwa pertama kita akan menggunakanmatch() metode untuk yrulesobject dan lainnya akan melaporkan informasi yang cocok ke konsol jika pengguna tidak menentukan file output apa pun. Perhatikan kode yang ditunjukkan di bawah ini -

def process_file(yrules, file_path):
   match = yrules.match(file_path)
   match_info = []
   
   for rule_set in match:
      for hit in rule_set.strings:
         match_info.append({
            'file_name': file_path,
            'rule_name': rule_set.rule,
            'rule_tag': ",".join(rule_set.tags),
            'hit_offset': hit[0],
            'rule_string': hit[1],
            'hit_value': hit[2]
         })
   return match_info
def write_stdout(columns, match_info):
   for entry in match_info:
      for col in columns:
         print("{}: {}".format(col, entry[col]))
   print("=" * 30)

Terakhir, kami akan menentukan metode yang akan menulis output ke file CSV, seperti yang ditunjukkan di bawah ini -

def write_csv(outfile, fieldnames, data):
   with open(outfile, 'w', newline="") as open_outfile:
      csvfile = csv.DictWriter(open_outfile, fieldnames)
      csvfile.writeheader()
      csvfile.writerows(data)

Setelah Anda berhasil menjalankan skrip di atas, kami dapat memberikan argumen yang sesuai di baris perintah dan dapat membuat laporan CSV.