Python Digital Forensics - Hızlı Kılavuz
Bu bölüm size dijital adli bilimin neyle ilgili olduğuna ve tarihsel incelemesine bir giriş sağlayacaktır. Ayrıca gerçek hayatta dijital adli tıpı nerede uygulayabileceğinizi ve sınırlamalarını da anlayacaksınız.
Dijital Adli Tıp nedir?
Dijital adli tıp, elektronik cihazlarda bulunan dijital delilleri analiz eden, inceleyen, tanımlayan ve kurtaran adli tıp dalı olarak tanımlanabilir. Genellikle ceza hukuku ve özel soruşturmalar için kullanılır.
Örneğin, birisinin elektronik bir cihazdaki bazı verileri çalması durumunda dijital adli tıp kanıtlarının çıkarılmasına güvenebilirsiniz.
Dijital Adli Bilimin Kısa Tarihsel İncelemesi
Bilgisayar suçlarının tarihçesi ve dijital adli tıpın tarihsel incelemesi aşağıda verildiği gibi bu bölümde açıklanmaktadır -
1970'ler-1980'ler: İlk Bilgisayar Suçu
Bu on yıldan önce, hiçbir bilgisayar suçu tanınmamıştı. Ancak, olması bekleniyorsa, o zaman mevcut yasalar bunlarla ilgileniyordu. Daha sonra, 1978'de ilk bilgisayar suçu, bir bilgisayar sistemindeki verilerin yetkisiz olarak değiştirilmesine veya silinmesine karşı yasayı içeren Florida Bilgisayar Suçları Yasasında kabul edildi. Ancak zamanla, teknolojinin gelişmesine bağlı olarak, işlenen bilgisayar suçlarının yelpazesi de arttı. Telif hakkı, mahremiyet ve çocuk pornografisiyle ilgili suçların üstesinden gelmek için çeşitli başka yasalar çıkarıldı.
1980'ler-1990'lar: Geliştirme On Yılı
Bu on yıl, Cliff Stoll'un Markus Hess adlı hacker'ı takip ettiği ilk araştırma (1986) nedeniyle, dijital adli tıp için geliştirme on yılıydı. Bu dönemde, iki tür dijital adli tıp disiplini geliştirildi - birincisi, bunu hobi olarak alan uygulayıcılar tarafından geliştirilen geçici araçlar ve tekniklerin yardımıyla, ikincisi ise bilimsel topluluk tarafından geliştirildi. 1992'de terim“Computer Forensics”akademik literatürde kullanılmıştır.
2000'ler-2010'lar: On Yıl Standardizasyon
Dijital adli bilimin belirli bir seviyeye gelmesinden sonra, soruşturma yapılırken izlenebilecek bazı spesifik standartlar yapma ihtiyacı doğmuştur. Buna göre, çeşitli bilimsel kurum ve kuruluşlar dijital adli tıp için kılavuzlar yayınladı. 2002 yılında, Dijital Kanıt üzerine Bilimsel Çalışma Grubu (SWGDE) "Bilgisayar Adli Tıp için En İyi Uygulamalar" adlı bir makale yayınladı. Kapaktaki bir başka tüy ise, Avrupa liderliğindeki uluslararası bir antlaşmaydı:“The Convention on Cybercrime”43 ülke tarafından imzalanmış ve 16 ülke tarafından onaylanmıştır. Bu standartlardan sonra bile, araştırmacılar tarafından tespit edilen bazı sorunların çözülmesine ihtiyaç vardır.
Adli Bilişim Süreci
1978'deki ilk bilgisayar suçundan bu yana, dijital suç faaliyetlerinde büyük bir artış var. Bu artış nedeniyle, bunlarla başa çıkmak için yapılandırılmış bir şekle ihtiyaç vardır. 1984 yılında resmileştirilmiş bir süreç başlatılmış ve bundan sonra çok sayıda yeni ve geliştirilmiş bilgisayar adli tıp inceleme süreci geliştirilmiştir.
Bir bilgisayar adli soruşturma süreci, aşağıda açıklandığı gibi üç ana aşamadan oluşur -
Aşama 1: Sergilerin Alınması veya Görüntülenmesi
Dijital adli bilimin ilk aşaması, daha sonra analiz edilebilmesi için dijital sistemin durumunu kaydetmeyi içerir. Suç mahallinden fotoğraflar, kan örnekleri vb. Çekmeye çok benzer. Örneğin, bir sabit diskin veya RAM'in tahsis edilmiş ve ayrılmamış alanlarının bir görüntüsünü yakalamayı içerir.
2. Aşama: Analiz
Bu aşamanın girdisi, edinim aşamasında elde edilen verilerdir. Burada delilleri belirlemek için bu veriler incelenmiştir. Bu aşama, aşağıdaki gibi üç tür kanıt verir:
Inculpatory evidences - Bu kanıtlar belirli bir geçmişi destekliyor.
Exculpatory evidences - Bu kanıtlar belirli bir tarihle çelişiyor.
Evidence of tampering- Bu kanıtlar, sistemin kimlik tespitinden kaçınmak için düzenlenmiş olduğunu gösteriyor. Silinen dosyaları kurtarmak için dosyaları ve dizin içeriğini incelemeyi içerir.
3. Aşama: Sunum veya Raporlama
Adından da anlaşılacağı gibi, bu aşama araştırmanın sonucunu ve ilgili kanıtları sunar.
Sayısal Adli Tıp Uygulamaları
Dijital adli tıp, herhangi bir dijital cihazda bulunan kanıtların toplanması, analizi ve korunmasıyla ilgilenir. Dijital adli tıp kullanımı uygulamaya bağlıdır. Daha önce de belirtildiği gibi, esas olarak aşağıdaki iki uygulamada kullanılır -
Ceza Hukuku
Ceza hukukunda, mahkemede bir hipotezi desteklemek veya buna karşı çıkmak için deliller toplanır. Adli tıp prosedürleri, ceza soruşturmalarında kullanılanlara çok benzer, ancak farklı yasal gereklilikler ve sınırlamalara sahiptir.
Özel soruşturma
Esas olarak kurumsal dünya, özel soruşturma için dijital adli tıp kullanır. Şirketlerin, çalışanların bilgisayarlarında şirket politikasına aykırı olarak yasa dışı bir eylem gerçekleştirdiğinden şüphelenmesi durumunda kullanılır. Dijital adli tıp, birisini dijital suistimal için araştırırken şirket veya kişi için en iyi yollardan birini sağlar.
Dijital Adli Tıp Dalları
Dijital suç sadece bilgisayarlarla sınırlı değil, ancak bilgisayar korsanları ve suçlular da çok büyük ölçekte tablet, akıllı telefon vb. Gibi küçük dijital cihazlar kullanıyor. Bazı cihazların geçici hafızası varken bazılarının kalıcı hafızası vardır. Bu nedenle, cihazların türüne bağlı olarak, dijital adli tıp aşağıdaki şubelere sahiptir -
Bilgisayar Adli Tıp
Bu dijital adli tıp dalı, bilgisayarlar, gömülü sistemler ve USB sürücüler gibi statik belleklerle ilgilenir. Bilgisayar adli tıpta günlüklerden sürücüdeki gerçek dosyalara kadar çok çeşitli bilgiler araştırılabilir.
Mobil Adli Tıp
Bu, mobil cihazlardan gelen verilerin araştırılmasıyla ilgilidir. Bu şube, mobil cihazların konumla ilgili yararlı bilgiler sağlamak için yararlı olan dahili bir iletişim sistemine sahip olması açısından bilgisayar adli tıptan farklıdır.
Ağ Adli Tıp
Bu, bilgi toplama, kanıt toplama veya saldırı tespiti amacıyla hem yerel hem de WAN (geniş alan ağı) olmak üzere bilgisayar ağı trafiğinin izlenmesi ve analizi ile ilgilidir.
Veritabanı Adli Tıp
Bu dijital adli tıp dalı, veritabanlarının ve meta verilerinin adli tıp çalışmasıyla ilgilenir.
Dijital Adli Tıp Araştırması için Gerekli Beceriler
Dijital adli tıp denetçileri, bilgisayar korsanlarının izlenmesine, çalınan verilerin kurtarılmasına, bilgisayar saldırılarının kaynağına kadar takip edilmesine ve bilgisayarları içeren diğer araştırma türlerine yardımcı olmaya yardımcı olur. Aşağıda tartışıldığı gibi dijital adli tıp denetçisi olmak için gerekli temel becerilerden bazıları -
Üstün Düşünme Yetenekleri
Bir dijital adli tıp araştırmacısı, olağanüstü bir düşünür olmalı ve çıktıyı elde etmek için belirli bir görevde farklı araçlar ve metodolojiler uygulayabilmelidir. Farklı örüntüler bulabilmeli ve aralarında korelasyon kurabilmelidir.
Teknik beceriler
Bir dijital adli tıp denetçisinin iyi teknolojik becerilere sahip olması gerekir, çünkü bu alan ağ bilgisini, dijital sistemin nasıl etkileşim kurduğunu gerektirir.
Siber Güvenlik konusunda tutkulu
Dijital adli tıp alanı tamamen siber suçları çözmekle ilgili olduğundan ve bu sıkıcı bir görev olduğundan, birinin as bir dijital adli tıp araştırmacısı olması için çok fazla tutkuya ihtiyacı var.
İletişim yetenekleri
İyi iletişim becerileri, çeşitli ekiplerle koordinasyon sağlamak ve eksik verileri veya bilgileri çıkarmak için bir zorunluluktur.
Rapor Yapmada Becerikli
Edinme ve analizin başarılı bir şekilde uygulanmasından sonra, bir dijital adli tıp denetçisi, nihai rapor ve sunumdaki tüm bulguları belirtmelidir. Bu nedenle rapor hazırlama konusunda iyi becerilere sahip olmalı ve ayrıntılara dikkat etmelidir.
Sınırlamalar
Dijital adli soruşturma, burada tartışıldığı gibi belirli sınırlamalar sunar -
İkna edici kanıtlar üretme ihtiyacı
Dijital adli tıp incelemesinin en büyük aksaklıklarından biri, veriler kolayca değiştirilebildiğinden, denetçinin hukuk mahkemesindeki kanıtlar için gerekli olan standartlara uymak zorunda olmasıdır. Öte yandan, adli bilişim araştırmacısı, mahkemede ikna edici kanıtlar sunmak için yasal gereklilikler, delil işleme ve dokümantasyon prosedürleri hakkında tam bilgiye sahip olmalıdır.
Araştırma Araçları
Dijital araştırmanın etkinliği tamamen dijital adli tıp denetçisinin uzmanlığına ve uygun araştırma aracının seçimine bağlıdır. Kullanılan alet belirtilen standartlara uygun değilse, mahkemede deliller hakim tarafından reddedilebilir.
İzleyiciler arasında teknik bilgi eksikliği
Diğer bir sınırlama, bazı kişilerin bilgisayar adli tıpa tam olarak aşina olmamasıdır; bu nedenle birçok insan bu alanı anlamıyor. Müfettişler, herkesin sonuçları anlamasına yardımcı olacak şekilde bulgularını mahkemelere ilettiğinden emin olmalıdır.
Maliyet
Dijital kanıtlar üretmek ve korumak çok maliyetlidir. Dolayısıyla bu süreç, maliyeti karşılayamayan birçok kişi tarafından seçilmeyebilir.
Önceki bölümde, dijital adli bilimin temellerini, avantajlarını ve sınırlamalarını öğrendik. Bu bölüm, bu dijital adli tıp araştırmasında kullandığımız temel araç olan Python ile rahat etmenizi sağlayacaktır.
Neden Dijital Adli Tıp için Python?
Python, popüler bir programlama dilidir ve siber güvenlik, sızma testi ve dijital adli araştırmalar için bir araç olarak kullanılır. Dijital adli tıp aracınız olarak Python'u seçtiğinizde, görevi tamamlamak için başka herhangi bir üçüncü taraf yazılıma ihtiyacınız yoktur.
Python programlama dilinin onu dijital adli tıp projeleri için uygun kılan benzersiz özelliklerinden bazıları aşağıda verilmiştir -
Simplicity of Syntax - Python'un sözdizimi diğer dillere kıyasla basittir, bu da birinin öğrenmesini ve dijital adli tıp için kullanılmasını kolaylaştırır.
Comprehensive inbuilt modules - Python'un kapsamlı dahili modülleri, eksiksiz bir dijital adli soruşturma gerçekleştirmek için mükemmel bir yardımcıdır.
Help and Support - Açık kaynaklı bir programlama dili olan Python, geliştiricinin ve kullanıcı topluluğunun mükemmel desteğine sahiptir.
Python'un Özellikleri
Yüksek seviyeli, yorumlanmış, etkileşimli ve nesne yönelimli bir betik dili olan Python, aşağıdaki özellikleri sağlar:
Easy to Learn - Python, geliştirici dostu ve öğrenmesi kolay bir dildir, çünkü daha az anahtar kelimeye ve en basit yapıya sahiptir.
Expressive and Easy to read- Python dili doğası gereği anlamlıdır; dolayısıyla kodu daha anlaşılır ve okunabilir.
Cross-platform Compatible - Python, platformlar arası uyumlu bir dildir, yani UNIX, Windows ve Macintosh gibi çeşitli platformlarda verimli bir şekilde çalışabilir.
Interactive Mode Programming - Python, programlama için etkileşimli bir modu desteklediğinden, etkileşimli kod testi ve hata ayıklama yapabiliriz.
Provides Various Modules and Functions - Python, betiğimiz için zengin modül ve işlev seti kullanmamıza izin veren geniş bir standart kitaplığa sahiptir.
Supports Dynamic Type Checking - Python, dinamik tür denetimini destekler ve çok yüksek düzeyde dinamik veri türleri sağlar.
GUI Programming - Python, Grafik kullanıcı arayüzleri geliştirmek için GUI programlamayı destekler.
Integration with other programming languages - Python, C, C ++, JAVA vb. Gibi diğer programlama dilleriyle kolayca entegre edilebilir.
Python'u Yükleme
Python dağıtımı Windows, UNIX, Linux ve Mac gibi çeşitli platformlar için mevcuttur. Platformumuza göre sadece ikili kodu indirmemiz gerekiyor. Herhangi bir platform için ikili kod mevcut değilse, kaynak kodunun manuel olarak derlenebilmesi için bir C derleyicisine sahip olmamız gerekir.
Bu bölüm, çeşitli platformlarda Python kurulumuna aşina olmanızı sağlayacaktır−
Unix ve Linux'ta Python Kurulumu
Python'u Unix / Linux makinesine kurmak için aşağıda gösterilen adımları takip edebilirsiniz.
Step 1- Bir Web tarayıcısı açın. Www.python.org/downloads/ yazın ve girin
Step 2 - Unix / Linux için mevcut olan sıkıştırılmış kaynak kodunu indirin.
Step 3 - İndirilen sıkıştırılmış dosyaları çıkarın.
Step 4 - Bazı seçenekleri özelleştirmek isterseniz, Modules/Setup file.
Step 5 - Kurulumu tamamlamak için aşağıdaki komutları kullanın -
run ./configure script
make
make install
Yukarıda verilen adımları başarıyla tamamladığınızda, Python standart konumuna kurulacaktır. /usr/local/bin ve kütüphaneleri /usr/local/lib/pythonXX XX, Python sürümüdür.
Windows'ta Python Kurulumu
Windows makineye Python kurmak için aşağıdaki basit adımları takip edebiliriz.
Step 1- Bir web tarayıcısı açın. Www.python.org/downloads/ yazın ve girin
Step 2 - Windows yükleyiciyi indirin python-XYZ.msi dosyası, burada XYZ, yüklememiz gereken sürümdür.
Step 3 - Şimdi, yükleyici dosyasını yerel makinenize kaydettikten sonra bu MSI dosyasını çalıştırın.
Step 4 - Python kurulum sihirbazını getirecek olan indirilen dosyayı çalıştırın.
Macintosh'ta Python Kurulumu
Python 3'ü Mac OS X'e yüklemek için, adlı bir paket yükleyici kullanmalıyız Homebrew.
Sisteminizde yoksa Homebrew'u kurmak için aşağıdaki komutu kullanabilirsiniz -
$ ruby -e "$(curl -fsSL
https://raw.githubusercontent.com/Homebrew/install/master/install)"
Paket yöneticisini güncellemeniz gerekiyorsa, aşağıdaki komutun yardımı ile yapılabilir -
$ brew update
Şimdi, sisteminize Python3 yüklemek için aşağıdaki komutu kullanın -
$ brew install python3
PATH'i Ayarlama
Python kurulumunun yolunu belirlememiz gerekir ve bu UNIX, WINDOWS veya MAC gibi platformlarda farklılık gösterir.
Unix / Linux'ta yol ayarı
Yolu Unix / Linux'ta ayarlamak için aşağıdaki seçenekleri kullanabilirsiniz -
If using csh shell - Tür setenv PATH "$PATH:/usr/local/bin/python" ve ardından Enter tuşuna basın.
If using bash shell (Linux) - Tür export ATH="$PATH:/usr/local/bin/python" ve ardından Enter tuşuna basın.
If using sh or ksh shell - Tür PATH="$PATH:/usr/local/bin/python" ve ardından Enter tuşuna basın.
Windows'ta Yol Ayarı
Tür path %path%;C:\Python komut isteminde ve ardından Enter tuşuna basın.
Python çalıştırma
Python yorumlayıcısını başlatmak için aşağıdaki üç yöntemden herhangi birini seçebilirsiniz -
Yöntem 1: Etkileşimli Yorumlayıcıyı Kullanma
Python'u başlatmak için komut satırı yorumlayıcısı veya kabuk sağlayan bir sistem kolayca kullanılabilir. Örneğin, Unix, DOS vb. Etkileşimli yorumlayıcıda kodlamaya başlamak için aşağıda verilen adımları takip edebilirsiniz -
Step 1 - Giriş python komut satırında.
Step 2 - Aşağıda gösterilen komutları kullanarak etkileşimli yorumlayıcıda hemen kodlamaya başlayın -
$python # Unix/Linux
or
python% # Unix/Linux
or
C:> python # Windows/DOS
Yöntem 2: Komut Satırından Komut Dosyası Kullanma
Ayrıca uygulamamızdaki yorumlayıcıyı çağırarak komut satırında bir Python betiği çalıştırabiliriz. Aşağıda gösterilen komutları kullanabilirsiniz -
$python script.py # Unix/Linux
or
python% script.py # Unix/Linux
or
C: >python script.py # Windows/DOS
Yöntem 3: Tümleşik Geliştirme Ortamı
Bir sistemde Python'u destekleyen GUI uygulaması varsa, Python bu GUI ortamından çalıştırılabilir. Çeşitli platformlar için bazı IDE'ler aşağıda verilmiştir -
Unix IDE - UNIX, Python için IDLE IDE'ye sahiptir.
Windows IDE - Windows, GUI ile birlikte Python için ilk Windows arayüzü olan PythonWin'e sahiptir.
Macintosh IDE - Macintosh, ana web sitesinden edinilebilen, MacBinary veya BinHex'd dosyaları olarak indirilebilen IDLE IDE'ye sahiptir.
Artık yerel sisteminizde Python komutlarını yükleme ve çalıştırma konusunda rahat olduğunuza göre, adli tıp kavramlarına ayrıntılı olarak geçelim. Bu bölüm, Python dijital adli tıpta eserlerin ele alınmasına ilişkin çeşitli kavramları açıklayacaktır.
Rapor Oluşturma İhtiyacı
Dijital adli tıp süreci, üçüncü aşama olarak raporlamayı içerir. Bu, dijital adli tıp sürecinin en önemli bölümlerinden biridir. Aşağıdaki nedenlerden dolayı rapor oluşturulması gereklidir -
Dijital adli tıp denetçisinin soruşturma sürecini ve bulgularını özetlediği belgedir.
İyi bir dijital adli tıp raporu, aynı havuzlar tarafından aynı sonucu elde etmek için başka bir denetmen tarafından referans alınabilir.
Dijital kanıtların 1'ler ve 0'larında bulunan gerçekleri içeren teknik ve bilimsel bir belgedir.
Rapor Oluşturma Genel Yönergeleri
Raporlar okuyucuya bilgi vermek için yazılır ve sağlam bir temelle başlamalıdır. Araştırmacılar, rapor bazı genel yönergeler veya standartlar olmadan hazırlanırsa bulgularını verimli bir şekilde sunmakta zorluklarla karşılaşabilir. Dijital adli tıp raporları oluştururken uyulması gereken bazı genel yönergeler aşağıda verilmiştir -
Summary - Rapor, okuyucunun raporun amacını belirleyebilmesi için bilgilerin kısa bir özetini içermelidir.
Tools used - Dijital adli tıp sürecini taşımak için kullanılan araçları, amaçlarıyla birlikte belirtmeliyiz.
Repository - Diyelim ki, birinin bilgisayarını araştırdık, ardından e-posta, dahili arama geçmişi vb. Gibi ilgili materyallerin kanıtlarının ve analizlerinin özetini araştırdık, ardından vakanın açıkça sunulabilmesi için rapora dahil edilmeleri gerekiyor.
Recommendations for counsel - Raporda, rapordaki bulgulara dayalı olarak avukatın araştırmaya devam etmesi veya soruşturmayı durdurması için tavsiyeler bulunmalıdır.
Farklı Türde Raporlar Oluşturmak
Yukarıdaki bölümde, dijital adli tıpta raporun önemi ve aynısını oluşturmaya yönelik yönergeler hakkında bilgi sahibi olduk. Python'da farklı türden raporlar oluşturmak için kullanılan formatlardan bazıları aşağıda tartışılmaktadır -
CSV Raporları
Raporların en yaygın çıktı biçimlerinden biri CSV elektronik tablo raporudur. Aşağıda gösterildiği gibi Python kodunu kullanarak işlenmiş verilerin bir raporunu oluşturmak için bir CSV oluşturabilirsiniz -
İlk olarak, elektronik tabloyu yazmak için yararlı kitaplıkları içe aktarın -
from __future__ import print_function
import csv
import os
import sys
Şimdi, aşağıdaki yöntemi çağırın -
Write_csv(TEST_DATA_LIST, ["Name", "Age", "City", "Job description"], os.getcwd())
Örnek veri türlerini temsil etmek için aşağıdaki global değişkeni kullanıyoruz -
TEST_DATA_LIST = [["Ram", 32, Bhopal, Manager],
["Raman", 42, Indore, Engg.],
["Mohan", 25, Chandigarh, HR],
["Parkash", 45, Delhi, IT]]
Daha sonra, daha ileri işlemlere devam etmek için yöntemi tanımlayalım. Dosyayı "w" modunda açıyoruz ve yeni satır anahtar kelime argümanını boş bir dizeye ayarlıyoruz.
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)
Yukarıdaki komut dosyasını çalıştırırsanız, aşağıdaki ayrıntıları report1.csv dosyasında saklayacaksınız.
İsim | Yaş | Kent | Tanımlama |
---|---|---|---|
Veri deposu | 32 | Bhopal | Menajer |
Raman | 42 | Indore | Engg |
Mohan | 25 | Chandigarh | İK |
Parkash | 45 | Delhi | O |
Excel Raporları
Raporların diğer bir yaygın çıktı biçimi Excel (.xlsx) elektronik tablo raporudur. Excel kullanarak tablo oluşturabilir ve grafiği çizebiliriz. İşlenmiş verilerin raporunu aşağıda gösterildiği gibi Python kodunu kullanarak Excel formatında oluşturabiliriz−
İlk olarak, elektronik tablo oluşturmak için XlsxWriter modülünü içe aktarın -
import xlsxwriter
Şimdi bir çalışma kitabı nesnesi oluşturun. Bunun için Workbook () yapıcısını kullanmamız gerekiyor.
workbook = xlsxwriter.Workbook('report2.xlsx')
Şimdi, add_worksheet () modülünü kullanarak yeni bir çalışma sayfası oluşturun.
worksheet = workbook.add_worksheet()
Ardından, aşağıdaki verileri çalışma sayfasına yazın -
report2 = (['Ram', 32, ‘Bhopal’],['Mohan',25, ‘Chandigarh’] ,['Parkash',45, ‘Delhi’])
row = 0
col = 0
Bu verileri yineleyebilir ve aşağıdaki gibi yazabilirsiniz -
for item, cost in (a):
worksheet.write(row, col, item)
worksheet.write(row, col+1, cost)
row + = 1
Şimdi bu Excel dosyasını close () yöntemini kullanarak kapatalım.
workbook.close()
Yukarıdaki komut dosyası, aşağıdaki verileri içeren report2.xlsx adlı bir Excel dosyası oluşturacaktır -
Veri deposu | 32 | Bhopal |
Mohan | 25 | Chandigarh |
Parkash | 45 | Delhi |
Araştırma Edinme Medyası
Bir araştırmacının bulguları doğru bir şekilde hatırlaması veya tüm araştırma parçalarını bir araya getirmesi için ayrıntılı araştırma notlarına sahip olması önemlidir. Bir ekran görüntüsü, belirli bir araştırma için atılan adımları takip etmek için çok kullanışlıdır. Aşağıdaki Python kodunun yardımıyla, ekran görüntüsünü alıp ileride kullanmak üzere sabit diske kaydedebiliriz.
Öncelikle, aşağıdaki komutu kullanarak pyscreenshot adlı Python modülünü kurun -
Pip install pyscreenshot
Şimdi, gerekli modülleri gösterildiği gibi içe aktarın -
import pyscreenshot as ImageGrab
Ekran görüntüsünü almak için aşağıdaki kod satırını kullanın -
image = ImageGrab.grab()
Ekran görüntüsünü verilen konuma kaydetmek için aşağıdaki kod satırını kullanın -
image.save('d:/image123.png')
Şimdi, ekran görüntüsünü grafik olarak açmak istiyorsanız, aşağıdaki Python kodunu kullanabilirsiniz -
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()
Bu bölüm, mobil cihazlarda Python dijital adli tıp ve ilgili kavramları açıklayacaktır.
Giriş
Mobil cihaz adli tıp, araştırmanın ilgisini çeken dijital kanıtları kurtarmak için mobil cihazların edinimi ve analizi ile ilgilenen dijital adli tıp dalıdır. Bu dal, bilgisayar adli tıptan farklıdır çünkü mobil cihazlar, konumla ilgili yararlı bilgiler sağlamak için yararlı olan dahili bir iletişim sistemine sahiptir.
Dijital adli tıpta akıllı telefonların kullanımı gün geçtikçe artıyor olsa da, heterojenliği nedeniyle yine de standart dışı olduğu düşünülüyor. Öte yandan sabit disk gibi bilgisayar donanımları da standart kabul edilir ve kararlı bir disiplin olarak geliştirilir. Dijital adli tıp endüstrisinde, akıllı telefonlar gibi geçici kanıtlara sahip standart dışı cihazlar için kullanılan teknikler hakkında çok fazla tartışma vardır.
Mobil Cihazlardan Çıkarılabilen Eserler
Modern mobil cihazlar, yalnızca bir arama kaydı veya SMS mesajı olan eski telefonlara kıyasla çok sayıda dijital bilgiye sahiptir. Böylece, mobil cihazlar araştırmacılara kullanıcısı hakkında pek çok bilgi sağlayabilir. Mobil cihazlardan çıkarılabilecek bazı eserler aşağıda belirtildiği gibidir -
Messages - Bunlar, sahibinin ruh halini ortaya çıkarabilen ve hatta araştırmacıya daha önce bilinmeyen bazı bilgileri verebilen yararlı eserlerdir.
Location History- Konum geçmişi verileri, araştırmacılar tarafından bir kişinin belirli konumunu doğrulamak için kullanılabilecek yararlı bir yapaydır.
Applications Installed - Araştırmacı, yüklü türdeki uygulamalara erişerek, mobil kullanıcının alışkanlıkları ve düşünceleri hakkında bilgi edinir.
Python'da Kanıt Kaynakları ve İşleme
Akıllı telefonlarda ana kanıt kaynakları olarak SQLite veritabanları ve PLIST dosyaları bulunur. Bu bölümde, kanıtların kaynaklarını python'da işleyeceğiz.
PLIST dosyalarını analiz etme
PLIST (Özellik Listesi), özellikle iPhone cihazlarında uygulama verilerini depolamak için esnek ve kullanışlı bir formattır. Uzantıyı kullanır.plist. Paketler ve uygulamalar hakkında bilgi depolamak için kullanılan bu tür dosyalar. İki biçimde olabilir:XML ve binary. Aşağıdaki Python kodu PLIST dosyasını açacak ve okuyacaktır. Buna devam etmeden önce, kendiInfo.plist dosya.
İlk olarak, adlı üçüncü taraf kitaplığı kurun biplist aşağıdaki komutla -
Pip install biplist
Şimdi, plist dosyalarını işlemek için bazı yararlı kitaplıkları içe aktarın -
import biplist
import os
import sys
Şimdi, ana yöntem altındaki aşağıdaki komutu kullanın, plist dosyasını bir değişkene okumak için kullanılabilir -
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)
Şimdi bu değişkenden ister konsoldaki verileri okuyabiliriz ister doğrudan yazdırabiliriz.
SQLite Veritabanları
SQLite, mobil cihazlarda birincil veri deposu olarak hizmet verir. SQLite, bağımsız, sunucusuz, sıfır konfigürasyonlu, işlemsel SQL veritabanı motorunu uygulayan bir işlem içi kitaplık. Sıfır yapılandırılmış bir veritabanıdır, diğer veritabanlarından farklı olarak sisteminizde yapılandırmanıza gerek yoktur.
Eğer SQLite veritabanları ile acemi veya bilginiz yoksa, bağlantı takip edebilirsiniz www.tutorialspoint.com/sqlite/index.htm link takip edebilirsiniz, Ayrıca www.tutorialspoint.com/sqlite/sqlite_python.htm istediğiniz durumda Python ile SQLite'ın ayrıntılarına inin.
Mobil adli tıp sırasında, sms.db bir mobil cihazın dosyası ve değerli bilgileri ayıklayabilir messagetablo. Python adında yerleşik bir kitaplığa sahiptirsqlite3SQLite veritabanına bağlanmak için. Aynısını aşağıdaki komutla içe aktarabilirsiniz -
import sqlite3
Şimdi aşağıdaki komutun yardımıyla veri tabanına bağlanabiliriz, diyelim ki sms.db mobil cihazlar durumunda -
Conn = sqlite3.connect(‘sms.db’)
C = conn.cursor()
Burada C, veritabanı ile etkileşime girebileceğimiz imleç nesnesidir.
Şimdi, belirli bir komutu yürütmek istiyorsak, diyelim ki ayrıntıları almak için abc table, aşağıdaki komutun yardımıyla yapılabilir -
c.execute(“Select * from abc”)
c.close()
Yukarıdaki komutun sonucu, cursornesne. Benzer şekilde kullanabilirizfetchall() Sonucu işleyebileceğimiz bir değişkene dökmek için yöntem.
Mesaj tablosunun sütun adları verilerini almak için aşağıdaki komutu kullanabiliriz. sms.db -
c.execute(“pragma table_info(message)”)
table_data = c.fetchall()
columns = [x[1] for x in table_data
Burada, SQLite ortamındaki çeşitli çevresel değişkenleri ve durum bayraklarını kontrol etmek için kullanılacak özel bir komut olan SQLite PRAGMA komutunu kullandığımıza dikkat edin. Yukarıdaki komutta,fetchall()yöntem bir sonuç demeti döndürür. Her sütunun adı, her demetin ilk dizininde saklanır.
Şimdi aşağıdaki komutun yardımıyla tabloyu tüm verileri için sorgulayabilir ve isimli değişkende saklayabiliriz. data_msg -
c.execute(“Select * from message”)
data_msg = c.fetchall()
Yukarıdaki komut veriyi değişkende saklayacaktır ve ayrıca yukarıdaki verileri kullanarak CSV dosyasına da yazabiliriz. csv.writer() yöntem.
iTunes Yedeklemeleri
iPhone mobil adli bilişim, iTunes tarafından yapılan yedeklemeler üzerinde gerçekleştirilebilir. Adli tıp uzmanları, iTunes aracılığıyla alınan iPhone mantıksal yedeklemelerini analiz etmeye güveniyor. Yedekleme almak için iTunes tarafından AFC (Apple dosya bağlantısı) protokolü kullanılır. Ayrıca, yedekleme işlemi, emanet anahtar kayıtları dışında iPhone'daki hiçbir şeyi değiştirmez.
Şimdi, bir dijital adli tıp uzmanının iTunes yedeklemelerindeki teknikleri anlamasının neden önemli olduğu sorusu ortaya çıkıyor. Şüphelinin iPhone yerine doğrudan bilgisayarına erişmemiz durumunda önemlidir, çünkü iPhone ile senkronizasyon için bir bilgisayar kullanıldığında, iPhone'daki bilgilerin çoğu muhtemelen bilgisayarda yedeklenecektir.
Yedekleme Süreci ve Konumu
Bir Apple ürünü bilgisayara yedeklendiğinde, iTunes ile eşzamanlanır ve aygıtın benzersiz kimliğine sahip belirli bir klasör bulunur. En son yedekleme biçiminde dosyalar, dosya adının ilk iki onaltılık karakterini içeren alt klasörlerde saklanır. Bu yedekleme dosyalarından, Manifest.db adlı veritabanı ile birlikte yararlı olan info.plist gibi bazı dosyalar vardır. Aşağıdaki tablo, iTunes yedeklemelerinin işletim sistemlerine göre değişen yedekleme konumlarını göstermektedir -
işletim sistemi | Yedekleme Yeri |
---|---|
Win7 | C: \ Kullanıcılar \ [kullanıcı adı] \ AppData \ Roaming \ AppleComputer \ MobileSync \ Backup \ |
MAC OS X | ~ / Kitaplık / Uygulama Desteği / MobileSync / Yedekleme / |
İTunes yedeklemesini Python ile işlemek için, öncelikle işletim sistemimize göre yedekleme konumundaki tüm yedeklemeleri tanımlamamız gerekir. Daha sonra her yedeklemeyi tekrarlayacağız ve Manifest.db veritabanını okuyacağız.
Şimdi, Python kodunu takip ederek aynı şeyi yapabiliriz -
İlk önce, gerekli kitaplıkları aşağıdaki gibi içe aktarın -
from __future__ import print_function
import argparse
import logging
import os
from shutil import copyfile
import sqlite3
import sys
logger = logging.getLogger(__name__)
Şimdi, iTunes yedeklemesini ve istenen çıktı klasörünü temsil eden INPUT_DIR ve OUTPUT_DIR olmak üzere iki konumsal bağımsız değişken sağlayın -
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()
Şimdi, günlüğü aşağıdaki gibi ayarlayın -
if args.v:
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.INFO)
Şimdi, bu günlük için mesaj formatını aşağıdaki gibi ayarlayın -
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)
Aşağıdaki kod satırı, kullanarak istenen çıktı dizini için gerekli klasörleri oluşturacaktır. os.makedirs() işlev -
if not os.path.exists(args.OUTPUT_DIR):
os.makedirs(args.OUTPUT_DIR)
Şimdi, sağlanan girdi ve çıktı dizinlerini aşağıdaki gibi main () işleve geçirin -
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)
Şimdi yaz main() daha fazla arayacak fonksiyon backup_summary() girdi klasöründe bulunan tüm yedeklemeleri tanımlama işlevi -
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
Şimdi, her yedeklemenin özetini konsola aşağıdaki gibi yazdırın -
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]))
Şimdi, Manifest.db dosyasının içeriğini db_items adlı değişkene boşaltın.
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
Şimdi, yedeklemenin dizin yolunu alacak bir işlev tanımlayalım -
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
Şimdi, SQLite3'ü kullanarak veritabanına c adında bir imleçle bağlanacağız -
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)
Şimdi tanımlayın create_files() yöntem aşağıdaki gibidir -
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)
Şimdi, içindeki her anahtarı yineleyin. db_items sözlük -
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)
Şimdi kullan shutil.copyfile() yedeklenen dosyayı aşağıdaki gibi kopyalama yöntemi -
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"))
Yukarıdaki Python betiği ile, çıktı klasörümüzde güncellenmiş yedek dosya yapısını alabiliriz. Kullanabilirizpycrypto yedeklerin şifresini çözmek için python kitaplığı.
Kablosuz internet
Mobil cihazlar, her yerde mevcut olan Wi-Fi ağları üzerinden bağlanarak dış dünyaya bağlanmak için kullanılabilir. Bazen cihaz bu açık ağlara otomatik olarak bağlanır.
İPhone söz konusu olduğunda, cihazın bağlandığı açık Wi-Fi bağlantılarının listesi adlı bir PLIST dosyasında saklanır. com.apple.wifi.plist. Bu dosya Wi-Fi SSID, BSSID ve bağlantı süresini içerecektir.
Python kullanarak standart Cellebrite XML raporundan Wi-Fi ayrıntılarını çıkarmamız gerekiyor. Bunun için, Wi-Fi ağlarının adlarını kullanarak bir cihazın yerini bulmak için kullanılabilecek popüler bir platform olan Wireless Geographic Logging Engine (WIGLE) 'den API kullanmamız gerekiyor.
Adlı Python kitaplığını kullanabiliriz requestsAPI'ye WIGLE'dan erişmek için. Aşağıdaki gibi kurulabilir -
pip install requests
WIGLE'dan API
WIGLE web sitesine kayıt olmamız gerekiyor https://wigle.net/accountWIGLE'dan ücretsiz bir API almak için. Kullanıcı cihazı ve WIGEL'in API'si aracılığıyla bağlantısı hakkında bilgi almak için Python betiği aşağıda tartışılmaktadır -
İlk olarak, farklı şeyleri işlemek için aşağıdaki kitaplıkları içe aktarın -
from __future__ import print_function
import argparse
import csv
import os
import sys
import xml.etree.ElementTree as ET
import requests
Şimdi, iki konumsal argüman sağlayın: INPUT_FILE ve OUTPUT_CSV giriş dosyasını Wi-Fi MAC adresi ve istenen çıktı CSV dosyasını sırasıyla temsil eder -
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()
Şimdi aşağıdaki kod satırları, girdi dosyasının var olup olmadığını ve bir dosya olup olmadığını kontrol edecektir. Değilse, komut dosyasından çıkar -
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(":")
Şimdi, argümanı main'e aşağıdaki gibi geçirin -
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)
Şimdi XML dosyasını aşağıdaki gibi ayrıştıracağız -
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()
Şimdi, kökün alt öğesini aşağıdaki gibi yineleyin -
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
Şimdi, değerin metninde 'ssid' dizesinin mevcut olup olmadığını kontrol edeceğiz -
if "SSID" in value.text:
bssid, ssid = value.text.split("\t")
bssid = bssid[7:]
ssid = ssid[6:]
Şimdi, BSSID, SSID ve timestamp'ı wifi sözlüğüne aşağıdaki gibi eklememiz gerekiyor -
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
XML ayrıştırıcısının aşağıda gösterildiği çok daha basit olan metin ayrıştırıcısı -
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
Şimdi istekler modülünü kullanalım. WIGLE APIaramaları ve devam etmesi gereken query_wigle() yöntem -
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()
Aslında WIGLE API çağrıları için günlük bir sınır vardır, bu sınır aşılırsa aşağıdaki gibi bir hata göstermelidir -
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)
Şimdi kullanacağız prep_output() sözlüğü kolayca yazılabilir parçalara düzleştirme yöntemi -
def prep_output(output, data):
csv_data = {}
google_map = https://www.google.com/maps/search/
Şimdi, şu ana kadar topladığımız tüm verilere aşağıdaki şekilde erişin -
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"])
Şimdi, bu bölümde önceki betiklerde yaptığımız gibi çıktıyı CSV dosyasına yazabiliriz. write_csv() işlevi.
Bu bölümde, gömülü meta verileri Python dijital adli tıp kullanarak araştırmayı ayrıntılı olarak öğreneceğiz.
Giriş
Gömülü meta veriler, bu verilerle tanımlanan nesneye sahip olan aynı dosyada depolanan verilerle ilgili bilgilerdir. Başka bir deyişle, dijital dosyanın kendisinde depolanan bir dijital varlık hakkındaki bilgidir. Her zaman dosyayla ilişkilendirilir ve asla ayrılamaz.
Dijital adli tıp durumunda, belirli bir dosya hakkındaki tüm bilgileri çıkaramayız. Öte yandan, gömülü meta veriler bize soruşturma için kritik olan bilgileri sağlayabilir. Örneğin, bir metin dosyasının meta verileri, yazar hakkında bilgi, uzunluğu, yazılı tarih ve hatta o belge hakkında kısa bir özet içerebilir. Dijital bir görüntü, görüntünün uzunluğu, deklanşör hızı vb. Gibi meta verileri içerebilir.
Meta Veri Niteliklerini İçeren Yapılar ve Bunların Çıkarılması
Bu bölümde, meta veri özniteliklerini içeren çeşitli yapılar ve bunların Python kullanarak ayıklama işlemleri hakkında bilgi edineceğiz.
Ses ve video
Bunlar, katıştırılmış meta verilere sahip çok yaygın iki yapaydır. Bu meta veriler, araştırma amacıyla çıkarılabilir.
Ses veya MP3 dosyasından ve bir video veya MP4 dosyasından ortak öznitelikleri veya meta verileri çıkarmak için aşağıdaki Python komut dosyasını kullanabilirsiniz.
Bu komut dosyası için, ses ve video dosyalarından meta verileri çıkarmamıza izin veren mutagen adlı üçüncü taraf bir python kitaplığı yüklememiz gerektiğini unutmayın. Aşağıdaki komutun yardımıyla kurulabilir -
pip install mutagen
Bu Python betiği için içe aktarmamız gereken kullanışlı kitaplıklardan bazıları aşağıdaki gibidir -
from __future__ import print_function
import argparse
import json
import mutagen
Komut satırı işleyicisi, MP3 veya MP4 dosyalarının yolunu temsil eden bir bağımsız değişken alacaktır. Sonra kullanacağızmutagen.file() aşağıdaki gibi dosyaya bir tanıtıcı açma yöntemi -
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)
Şimdi, biri MP3'ten veri çıkarmak ve diğeri MP4 dosyasından veri çıkarmak için iki tutamaç kullanmamız gerekiyor. Bu tutamaçları şu şekilde tanımlayabiliriz -
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'))
Şimdi, bu MP4 dosyasını aşağıdaki gibi yinelememiz gerekiyor -
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))
Yukarıdaki komut dosyası bize MP3 ve MP4 dosyaları hakkında ek bilgi verecektir.
Görüntüler
Görüntüler, dosya formatına bağlı olarak farklı türde meta veriler içerebilir. Ancak, görüntülerin çoğu GPS bilgilerini içerir. Bu GPS bilgilerini üçüncü taraf Python kitaplıklarını kullanarak çıkarabiliriz. Aynısını yapmak için aşağıdaki Python betiğini kullanabilirsiniz -
İlk olarak, adlı üçüncü taraf python kitaplığını indirin Python Imaging Library (PIL) aşağıdaki gibi -
pip install pillow
Bu, görüntülerden meta verileri çıkarmamıza yardımcı olacaktır.
Görüntülere gömülü GPS ayrıntılarını KML dosyasına da yazabiliriz, ancak bunun için adlı üçüncü taraf Python kitaplığını indirmemiz gerekir. simplekml aşağıdaki gibi -
pip install simplekml
Bu komut dosyasında, önce aşağıdaki kitaplıkları içe aktarmamız gerekiyor -
from __future__ import print_function
import argparse
from PIL import Image
from PIL.ExifTags import TAGS
import simplekml
import sys
Şimdi, komut satırı işleyicisi, temelde fotoğrafların dosya yolunu temsil eden bir konumsal bağımsız değişkeni kabul edecektir.
parser = argparse.ArgumentParser('Metadata from images')
parser.add_argument('PICTURE_FILE', help = "Path to picture")
args = parser.parse_args()
Şimdi, koordinat bilgilerini dolduracak URL'leri belirtmemiz gerekiyor. URL'lergmaps ve open_maps. Ayrıca PIL kitaplığı tarafından sağlanan derece dakika saniye (DMS) demet koordinatını ondalık sayıya dönüştürmek için bir işleve ihtiyacımız var. Aşağıdaki gibi yapılabilir -
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
Şimdi kullanacağız image.open() dosyayı PIL nesnesi olarak açma işlevi.
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
Bulduktan sonra GPSInfo etiketi, GPS referansını saklayacağız ve koordinatları process_coords() yöntem.
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
Şimdi başla kml nesneden simplekml kütüphane aşağıdaki gibidir -
kml = simplekml.Kml()
kml.newpoint(name = args.PICTURE_FILE, coords = [(lon, lat)])
kml.save(args.PICTURE_FILE + ".kml")
Artık işlenen bilgilerden koordinatları aşağıdaki gibi yazdırabiliriz -
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"))
PDF Belgeleri
PDF belgeleri, görüntüler, metinler, formlar vb. Dahil olmak üzere çok çeşitli ortamlara sahiptir. PDF belgelerine gömülü meta verileri çıkardığımızda, ortaya çıkan verileri Genişletilebilir Meta Veri Platformu (XMP) adı verilen formatta alabiliriz. Aşağıdaki Python kodunun yardımıyla meta verileri çıkarabiliriz -
İlk olarak, adlı üçüncü taraf bir Python kitaplığı yükleyin. PyPDF2XMP formatında depolanan meta verileri okumak için. Aşağıdaki gibi kurulabilir -
pip install PyPDF2
Şimdi, meta verileri PDF dosyalarından çıkarmak için aşağıdaki kitaplıkları içe aktarın -
from __future__ import print_function
from argparse import ArgumentParser, FileType
import datetime
from PyPDF2 import PdfFileReader
import sys
Şimdi, komut satırı işleyicisi temelde PDF dosyasının dosya yolunu temsil eden bir konumsal bağımsız değişkeni kabul edecektir.
parser = argparse.ArgumentParser('Metadata from PDF')
parser.add_argument('PDF_FILE', help='Path to PDF file',type=FileType('rb'))
args = parser.parse_args()
Şimdi kullanabiliriz getXmpMetadata() aşağıdaki gibi mevcut meta verileri içeren bir nesne sağlama yöntemi -
pdf_file = PdfFileReader(args.PDF_FILE)
xmpm = pdf_file.getXmpMetadata()
if xmpm is None:
print("No XMP metadata found in document.")
sys.exit()
Kullanabiliriz custom_print() başlık, oluşturan, katkıda bulunan vb. gibi ilgili değerleri aşağıdaki gibi çıkarma ve yazdırma yöntemi -
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)
Ayrıca tanımlayabiliriz custom_print() PDF birden fazla yazılım kullanılarak oluşturulmuşsa aşağıdaki gibi yöntem -
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)))
Yazılım tarafından kaydedilen diğer özel mülkleri de aşağıdaki gibi çıkarabiliriz -
if xmpm.custom_properties:
print("Custom Properties:")
for k, v in xmpm.custom_properties.items():
print("\t{}: {}".format(k, v))
Yukarıdaki komut dosyası, PDF belgesini okuyacak ve yazılım tarafından saklanan bazı özel özellikler de dahil olmak üzere XMP formatında saklanan meta verileri, bu PDF'nin yapıldığı yardımıyla yazdıracaktır.
Windows Yürütülebilir Dosyaları
Bazen şüpheli veya yetkisiz bir yürütülebilir dosyayla karşılaşabiliriz. Ancak araştırma amacıyla, gömülü meta veriler nedeniyle faydalı olabilir. Yeri, amacı ve üretici, derleme tarihi gibi diğer öznitelikler gibi bilgileri alabiliriz. Python betiğini takip ederek derleme tarihini, başlıklardan ve içe aktarılan faydalı verileri ve ayrıca dışa aktarılan sembolleri alabiliriz.
Bu amaçla, önce üçüncü taraf Python kitaplığını kurun pefile. Aşağıdaki gibi yapılabilir -
pip install pefile
Bunu başarıyla yükledikten sonra, aşağıdaki kitaplıkları aşağıdaki gibi içe aktarın -
from __future__ import print_function
import argparse
from datetime import datetime
from pefile import PE
Şimdi, komut satırı işleyicisi, temelde çalıştırılabilir dosyanın dosya yolunu temsil eden bir konumsal bağımsız değişkeni kabul edecektir. Ayrıntılı ve ayrıntılı bir şekilde veya basitleştirilmiş bir şekilde ihtiyacınız olsun, çıktı stilini de seçebilirsiniz. Bunun için aşağıda gösterildiği gibi isteğe bağlı bir argüman vermeniz gerekir -
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()
Şimdi, giriş çalıştırılabilir dosyasını PE sınıfını kullanarak yükleyeceğiz. Ayrıca çalıştırılabilir verileri kullanarak bir sözlük nesnesine dökeceğizdump_dict() yöntem.
pe = PE(args.EXE_FILE)
ped = pe.dump_dict()
Gömülü yazarlık, sürüm ve derleme süresi gibi temel dosya meta verilerini aşağıda gösterilen kodu kullanarak çıkarabiliriz -
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()))
Faydalı verileri başlıklardan aşağıdaki gibi çıkarabiliriz -
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'])
)
Şimdi, aşağıda gösterildiği gibi yürütülebilir dosyalardan içe ve dışa aktarımların listesini çıkarın -
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()
Şimdi yazdır exports, names ve addresses kodu aşağıda gösterildiği gibi kullanarak -
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)))
Yukarıdaki komut dosyası, temel meta verileri, başlıklardan bilgileri Windows çalıştırılabilir dosyalardan çıkaracaktır.
Office Belge Meta Verileri
Bilgisayardaki işin çoğu, MS Office'in üç uygulamasında yapılır - Word, PowerPoint ve Excel. Bu dosyalar, yazarları ve geçmişleri hakkında ilginç bilgileri açığa çıkarabilecek çok büyük meta verilere sahiptir.
2007 biçimindeki word (.docx), excel (.xlsx) ve powerpoint (.pptx) biçimindeki meta verilerin bir XML dosyasında saklandığını unutmayın. Bu XML dosyalarını aşağıda gösterilen Python betiğinin yardımıyla Python'da işleyebiliriz -
Öncelikle, gerekli kitaplıkları aşağıda gösterildiği gibi içe aktarın -
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()
Şimdi dosyanın bir ZIP dosyası olup olmadığını kontrol edin. Aksi takdirde, bir hata oluşturun. Şimdi, dosyayı açın ve aşağıdaki kodu kullanarak işlenecek temel öğeleri çıkarın -
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'))
Şimdi, meta verilerin çıkarılmasını başlatmak için bir sözlük oluşturun -
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'
}
Kullanım iterchildren() XML dosyasındaki etiketlerin her birine erişme yöntemi -
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))
Benzer şekilde, bunu belgenin içeriği hakkında istatistiksel bilgiler içeren app.xml dosyası için yapın -
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))
Şimdi yukarıdaki komut dosyasını çalıştırdıktan sonra, belirli belge hakkında farklı ayrıntıları alabiliriz. Bu komut dosyasını yalnızca Office 2007 veya sonraki sürüm belgelerinde uygulayabileceğimizi unutmayın.
Bu bölüm, Python kullanarak ağ adli bilişim gerçekleştirmenin temellerini açıklayacaktır.
Ağ Adli Tıpını Anlamak
Ağ adli bilişim, bilgi toplama, kanıt toplama veya saldırı tespiti amacıyla hem yerel hem de WAN (geniş alan ağı) bilgisayar ağı trafiğinin izlenmesi ve analizi ile ilgilenen bir dijital adli tıp dalıdır. Ağ adli tıp, fikri mülkiyet hırsızlığı veya bilgi sızıntısı gibi dijital suçların araştırılmasında kritik bir rol oynar. Ağ iletişiminin bir resmi, bir araştırmacının bazı önemli soruları aşağıdaki gibi çözmesine yardımcı olur:
Hangi web sitelerine erişildi?
Ağımıza ne tür içerik yüklendi?
Ağımızdan ne tür içerik indirildi?
Hangi sunuculara erişiliyor?
Birisi şirket güvenlik duvarlarının dışında hassas bilgiler mi gönderiyor?
İnternet Kanıt Bulucu (IEF)
IEF, bilgisayar, akıllı telefonlar, tabletler vb. Gibi farklı dijital ortamlarda bulunan dijital kanıtları bulmak, analiz etmek ve sunmak için dijital bir adli tıp aracıdır. Çok popülerdir ve binlerce adli tıp uzmanı tarafından kullanılmaktadır.
IEF kullanımı
IEF, popülaritesi nedeniyle adli tıp uzmanları tarafından büyük ölçüde kullanılmaktadır. IEF'in kullanımlarından bazıları aşağıdaki gibidir:
Güçlü arama yetenekleri sayesinde, aynı anda birden fazla dosya veya veri ortamını aramak için kullanılır.
Ayrıca, yeni oyma teknikleriyle RAM'in ayrılmamış alanından silinen verileri kurtarmak için de kullanılır.
Araştırmacılar, web sayfalarını açıldıkları tarihte orijinal biçimlerinde yeniden oluşturmak isterlerse, IEF'i kullanabilirler.
Ayrıca mantıksal veya fiziksel disk hacimlerini aramak için de kullanılır.
Python kullanarak IEF’ten CSV’ye Rapor Dökümü
IEF, verileri bir SQLite veritabanında depolar ve aşağıdaki Python betiği, IEF veritabanı içindeki sonuç tablolarını dinamik olarak tanımlar ve bunları ilgili CSV dosyalarına aktarır.
Bu işlem aşağıda gösterilen adımlarda yapılır
İlk olarak, .db uzantısıyla biten bir SQLite veritabanı dosyası olacak IEF sonuç veritabanını oluşturun.
Ardından, tüm tabloları tanımlamak için bu veritabanını sorgulayın.
Son olarak, bu sonuç tablolarını ayrı bir CSV dosyasına yazın.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Python betiği için gerekli kitaplıkları aşağıdaki gibi içe aktarın -
from __future__ import print_function
import argparse
import csv
import os
import sqlite3
import sys
Şimdi, IEF veritabanı dosyasının yolunu sağlamamız gerekiyor -
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()
Şimdi, IEF veritabanının varlığını şu şekilde teyit edeceğiz -
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)
Şimdi, önceki betiklerde yaptığımız gibi, sorguları imleç aracılığıyla yürütmek için SQLite veritabanıyla aşağıdaki gibi bağlantı kurun -
def main(database, out_directory):
print("[+] Connecting to SQLite database")
conn = sqlite3.connect(database)
c = conn.cursor()
Aşağıdaki kod satırları, tabloların adlarını veritabanından alacaktır -
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')]
Şimdi tablodan tüm verileri seçeceğiz ve kullanarak fetchall() yöntem imleç nesnesinde tablonun verilerini bir bütün olarak içeren tuplelar listesini bir değişkende saklayacağız -
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()
Şimdi, kullanarak CSV_Writer() yöntem içeriği CSV dosyasına yazacağız -
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)
Yukarıdaki komut dosyası, IEF veritabanı tablolarından tüm verileri alacak ve içeriği seçtiğimiz CSV dosyasına yazacaktır.
Önbelleğe Alınmış Verilerle Çalışma
IEF sonuç veritabanından, IEF'in kendisi tarafından desteklenmesi gerekmeyen daha fazla bilgi alabiliriz. Yahoo, Google vb. E-posta hizmet sağlayıcılarından IEF sonuç veri tabanını kullanarak önbelleğe alınmış verileri, bilgi amaçlı bir iki ürün olarak alabiliriz.
Aşağıda, Yahoo postadan önbelleğe alınmış veri bilgilerine IEF veritabanı kullanılarak Google Chrome üzerinden erişilen Python betiği verilmiştir. Adımların aşağı yukarı son Python betiğinde izlenenlerle aynı olacağını unutmayın.
Öncelikle, Python için gerekli kitaplıkları aşağıdaki gibi içe aktarın -
from __future__ import print_function
import argparse
import csv
import os
import sqlite3
import sys
import json
Şimdi, son komut dosyasında yapıldığı gibi komut satırı işleyicisi tarafından kabul edilen iki konumsal bağımsız değişkenle birlikte IEF veritabanı dosyasının yolunu sağlayın -
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()
Şimdi, IEF veritabanının varlığını aşağıdaki şekilde doğrulayın -
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)
Şimdi, sorguları imleç aracılığıyla yürütmek için SQLite veritabanıyla bağlantıyı aşağıdaki gibi yapın -
def main(database, out_csv):
print("[+] Connecting to SQLite database")
conn = sqlite3.connect(database)
c = conn.cursor()
Yahoo Mail kişi önbellek kaydı örneklerini almak için aşağıdaki kod satırlarını kullanabilirsiniz -
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)
Şimdi, bir değişkene kaydedilmek üzere yukarıdaki sorgudan döndürülen tuple listesi aşağıdaki gibi -
contact_cache = c.fetchall()
contact_data = process_contacts(contact_cache)
write_csv(contact_data, out_csv)
Burada iki yöntem kullanacağımızı unutmayın: process_contacts() sonuç listesini ayarlamak ve her bir kontak önbellek kaydında yinelemek için ve json.loads() tablodan çıkarılan JSON verilerini daha fazla manipülasyon için bir değişkene depolamak için -
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"]])
Şimdi şirket, başlık ve notlar için get yöntemi aşağıda gösterildiği gibi kullanılır -
company = c.get("company", "")
title = c.get("jobTitle", "")
notes = c.get("notes", "")
Şimdi, metadata ve çıkarılan veri öğelerinin listesini aşağıdaki gibi sonuç listesine ekleyelim -
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
Şimdi, kullanarak CSV_Writer() yöntem, içeriği CSV dosyasına yazacağız -
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)
Yukarıdaki script yardımı ile Yahoo mailden önbelleğe alınmış verileri IEF veritabanını kullanarak işleyebiliyoruz.
Önceki bölümde, Python kullanarak ağ adli bilişiminin bazı kavramları ele alındı. Bu bölümde, Python kullanarak ağ adli bilimi daha derin bir düzeyde anlayalım.
Güzel Çorba ile Web Sayfasının Korunması
World Wide Web (WWW) benzersiz bir bilgi kaynağıdır. Ancak, endişe verici bir oranda içerik kaybı nedeniyle mirası yüksek risk altındadır. Bir dizi kültürel miras ve akademik kurum, kar amacı gütmeyen kuruluşlar ve özel işletmeler, ilgili sorunları araştırmış ve web arşivlemesi için teknik çözümlerin geliştirilmesine katkıda bulunmuştur.
Web sayfasının korunması veya web arşivlemesi, verilerin World Wide Web'den toplanması, verilerin bir arşivde korunmasının sağlanması ve gelecekteki araştırmacılar, tarihçiler ve halkın kullanımına sunulması sürecidir. Web sayfasını korumaya devam etmeden önce, aşağıda verildiği gibi web sayfasının korunmasıyla ilgili bazı önemli konuları tartışalım -
Change in Web Resources - Web kaynakları, web sayfasının korunması için bir zorluk olan her gün değişmeye devam ediyor.
Large Quantity of Resources - Web sayfasının korunması ile ilgili bir diğer konu da, korunması gereken kaynakların büyük miktardır.
Integrity - Web sayfaları, bütünlüğünü korumak için yetkisiz değişikliklere, silinmeye veya kaldırılmaya karşı korunmalıdır.
Dealing with multimedia data - Web sayfalarını korurken multimedya verileriyle de ilgilenmemiz gerekir ve bunlar bunu yaparken sorunlara neden olabilir.
Providing access - Korumanın yanı sıra, web kaynaklarına erişim sağlama ve sahiplik sorunlarıyla ilgilenme sorunu da çözülmelidir.
Bu bölümde, adlı Python kitaplığını kullanacağız. Beautiful Soup web sayfasının korunması için.
Güzel Çorba Nedir?
Beautiful Soup, HTML ve XML dosyalarından veri çekmek için bir Python kitaplığıdır. İle kullanılabilirurlibçünkü bir çorba nesnesi oluşturmak için bir girişe (belge veya url) ihtiyaç duyar, çünkü web sayfasının kendisini getiremez. Bununla ilgili ayrıntılı bilgiyi www.crummy.com/software/BeautifulSoup/bs4/doc/ adresinden öğrenebilirsiniz.
Kullanmadan önce aşağıdaki komutu kullanarak bir üçüncü taraf kitaplığı kurmamız gerektiğini unutmayın -
pip install bs4
Ardından, Anaconda paket yöneticisini kullanarak Beautiful Soup'u aşağıdaki gibi kurabiliriz -
conda install -c anaconda beautifulsoup4
Web Sayfalarını Korumak için Python Komut Dosyası
Beautiful Soup adlı üçüncü taraf kitaplığı kullanarak web sayfalarını korumak için Python betiği burada tartışılmaktadır -
İlk olarak, gerekli kitaplıkları aşağıdaki gibi içe aktarın -
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__)
Bu komut dosyasının iki konumsal bağımsız değişken alacağını unutmayın; aşağıda gösterildiği gibi, biri korunacak URL ve diğeri istenen çıktı dizini -
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()
Şimdi, döngüde olmak için bir dosya ve akış işleyicisi belirleyerek komut dosyası için günlük kaydını ayarlayın ve edinme sürecini gösterildiği gibi belgeleyin -
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)
Şimdi, istenen çıktı dizini üzerinde aşağıdaki gibi girdi doğrulamasını yapalım -
if not os.path.exists(args.OUTPUT_DIR):
os.makedirs(args.OUTPUT_DIR)
main(args.DOMAIN, args.OUTPUT_DIR)
Şimdi, tanımlayacağız main() Aşağıdaki gibi giriş URL'sinde ek doğrulama ile birlikte asıl adın önündeki gereksiz öğeleri kaldırarak web sitesinin temel adını çıkaran işlev -
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()
Şimdi urlopen () yöntemini kullanarak URL ile bir bağlantı açmamız gerekiyor. Try-exclude bloğunu aşağıdaki gibi kullanalım -
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))
Sonraki kod satırları, aşağıda açıklandığı gibi üç işlevi içerir -
write_output() ilk web sayfasını çıktı dizinine yazmak için
find_links() bu web sayfasındaki bağlantıları tanımlama işlevi
recurse_pages() web sayfasındaki tüm bağlantıları yineleme ve keşfetme işlevi.
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))
Şimdi tanımlayalım write_output() yöntem aşağıdaki gibidir -
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)
Web sayfasıyla ilgili bazı ayrıntıları günlüğe kaydetmemiz ve ardından verilerin karmasını kullanarak hash_data() yöntem aşağıdaki gibidir -
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)))
Şimdi tanımla hash_data() yardımı ile okuduğumuz yöntem UTF-8 kodlanmış veriler ve ardından SHA-256 hash'i aşağıdaki gibidir -
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()
Şimdi bir oluşturalım Beautifulsoup altında web sayfası verilerinin dışında nesne find_links() yöntem aşağıdaki gibidir -
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
Şimdi tanımlamalıyız recurse_pages() web sitesi URL'sinin, mevcut bağlantı kuyruğunun, doğrulanmamış SSL bağlamının ve çıktı dizininin girişlerini aşağıdaki gibi sağlayarak yöntemi -
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
Şimdi, bağlantı adını, sayfa verilerini, çıktı dizinini ve sayacı aşağıdaki gibi ileterek bir dosyada erişilen her web sayfasının çıktısını yazın -
write_output(link, page, output_dir, counter)
queue = find_links(website, page, queue)
logger.info("Identified {} links throughout website".format(
len(queue)))
Şimdi, web sitesinin URL'sini, çıktı dizinini ve günlük dosyasının yolunu sağlayarak bu betiği çalıştırdığımızda, ileride kullanılmak üzere bu web sayfasıyla ilgili ayrıntıları alacağız.
Virüs Avı
Adli analistlerin, güvenlik araştırmacılarının ve olay yanıtlayanların yararlı yazılım ile kötü amaçlı yazılım arasındaki farkı nasıl anlayabileceğini hiç merak ettiniz mi? Cevap sorunun kendisinde yatıyor, çünkü bilgisayar korsanları tarafından hızla üretilen kötü amaçlı yazılım hakkında çalışmadan, araştırmacıların ve uzmanların yararlı yazılım ile kötü amaçlı yazılım arasındaki farkı anlamaları oldukça imkansız. Bu bölümde tartışalımVirusShare, bu görevi gerçekleştirmek için bir araç.
VirusShare'i Anlamak
VirusShare, güvenlik araştırmacılarına, olay müdahale ekiplerine ve adli analistlere canlı kötü amaçlı kod örneklerini sağlamak için özel sektöre ait en büyük kötü amaçlı yazılım örnekleri koleksiyonudur. 30 milyondan fazla örnek içerir.
VirusShare'in avantajı, ücretsiz olarak kullanılabilen kötü amaçlı yazılım karmalarının listesidir. Herkes bu karmaları çok kapsamlı bir karma kümesi oluşturmak için kullanabilir ve bunu potansiyel olarak kötü amaçlı dosyaları tanımlamak için kullanabilir. Ancak VirusShare'i kullanmadan önce, şu adresi ziyaret etmenizi öneririz:https://virusshare.com daha fazla ayrıntı için.
Python kullanarak VirusShare'den Yeni Satırla Sınırlandırılmış Karma Listesi Oluşturma
VirusShare'den bir karma listesi, X-way ve EnCase gibi çeşitli adli araçlar tarafından kullanılabilir. Aşağıda tartışılan komut dosyasında, yeni satırla ayrılmış bir karma listesi oluşturmak için VirusShare'den karma listelerin indirilmesini otomatikleştireceğiz.
Bu komut dosyası için üçüncü taraf bir Python kitaplığına ihtiyacımız var tqdm aşağıdaki gibi indirilebilir -
pip install tqdm
Bu komut dosyasında, önce VirusShare hash sayfasını okuyacağımızı ve en son hash listesini dinamik olarak tanımlayacağımızı unutmayın. Ardından ilerleme çubuğunu başlatacağız ve hash listesini istenen aralıkta indireceğiz.
Önce, aşağıdaki kitaplıkları içe aktarın -
from __future__ import print_function
import argparse
import os
import ssl
import sys
import tqdm
from urllib.request import urlopen
import urllib.error
Bu komut dosyası, hash kümesi için istenen yol olan bir konumsal bağımsız değişken alacaktır -
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()
Şimdi, standart giriş doğrulamasını aşağıdaki gibi gerçekleştireceğiz -
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)
Şimdi tanımlamalıyız main() ile işlev **kwargs argüman olarak bu bir sözlük oluşturacağından aşağıda gösterildiği gibi sağlanan anahtar argümanları desteklemeye başvurabiliriz -
def main(hashset, **kwargs):
url = "https://virusshare.com/hashes.4n6"
print("[+] Identifying hash set range from {}".format(url))
context = ssl._create_unverified_context()
Şimdi, kullanarak VirusShare hash sayfasını açmamız gerekiyor urlib.request.urlopen()yöntem. Try-exclude bloğunu aşağıdaki gibi kullanacağız -
try:
index = urlopen(url, context = context).read().decode("utf-8")
except urllib.error.HTTPError as e:
print("[-] Error accessing webpage - exiting..")
sys.exit(1)
Şimdi, indirilen sayfalardan en son hash listesini tanımlayın. Bunu HTML'nin son örneğini bularak yapabilirsinizhrefVirusShare karma listesine etiket. Aşağıdaki kod satırları ile yapılabilir -
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
Şimdi kullanacağız tqdm.trange() aşağıdaki gibi bir döngü ve ilerleme çubuğu oluşturma yöntemi -
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
Yukarıdaki adımları başarıyla gerçekleştirdikten sonra, metin dosyasının altına eklemek için hash set metin dosyasını + modunda açacağız.
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))
Yukarıdaki komut dosyasını çalıştırdıktan sonra, metin biçiminde MD5 hash değerlerini içeren en son hash listesini alacaksınız.
Önceki bölümlerde adli ağın önemi ve süreci ve ilgili kavramlar hakkında tartışıldı. Bu bölümde, dijital adli tıpta e-postaların rolü ve Python kullanarak araştırmaları hakkında bilgi edinelim.
E-postanın Araştırmadaki Rolü
E-postalar, iş iletişiminde çok önemli bir rol oynar ve internetteki en önemli uygulamalardan biri olarak ortaya çıkmıştır. Yalnızca bilgisayarlardan değil, aynı zamanda cep telefonları ve tabletler gibi diğer elektronik aygıtlardan da belge ve mesaj göndermek için uygun bir moddur.
E-postaların olumsuz tarafı, suçluların şirketleri hakkında önemli bilgileri sızdırabilmeleridir. Bu nedenle, e-postaların dijital adli tıp alanındaki rolü son yıllarda artmıştır. Dijital adli tıpta, e-postalar çok önemli kanıtlar olarak kabul edilir ve E-posta Üstbilgi Analizi, adli süreç sırasında kanıt toplamak için önemli hale gelmiştir.
Bir araştırmacının, e-posta adli araştırması gerçekleştirirken aşağıdaki hedefleri vardır:
- Ana suçluyu belirlemek için
- Gerekli delilleri toplamak için
- Bulguları sunmak
- Davayı oluşturmak için
E-posta Adli Bilişimindeki Zorluklar
E-posta adli tıp, günümüzdeki iletişimin çoğu e-postalara dayandığından, araştırmada çok önemli bir rol oynamaktadır. Bununla birlikte, bir e-posta adli tıp araştırmacısı, soruşturma sırasında aşağıdaki zorluklarla karşılaşabilir:
Sahte E-postalar
E-posta adli tıpta en büyük zorluk, üstbilgiler vb. Manipüle edilerek ve yazılarak oluşturulan sahte e-postaların kullanılmasıdır. Bu kategoride suçlular ayrıca kayıtlı bir kullanıcının süresi dolan geçici bir adresten e-posta almasına izin veren bir hizmet olan geçici e-postayı kullanır. belirli bir süre sonra.
Adres sahteciliği
E-posta adli tıpta bir başka zorluk da, suçluların bir e-postayı başkasınınki gibi sundukları sahtekarlıktır. Bu durumda makine hem sahte hem de orijinal IP adresi alacaktır.
Anonim Yeniden E-posta Gönderme
Burada, E-posta sunucusu, daha fazla iletmeden önce e-posta mesajından kimlik bilgileri çıkarır. Bu, e-posta araştırmaları için başka bir büyük zorluğa yol açar.
E-posta Adli Soruşturmasında Kullanılan Teknikler
E-posta adli bilişim, bir iletinin gerçek göndereni ve alıcısının yanı sıra aktarım tarihi / saati ve gönderenin niyeti gibi bazı diğer bilgileri belirlemek için kanıt olarak e-postanın kaynağı ve içeriğinin incelenmesidir. Meta verilerin araştırılmasını, bağlantı noktası taramasını ve anahtar kelime aramayı içerir.
E-posta adli inceleme için kullanılabilecek yaygın tekniklerden bazıları şunlardır:
- Başlık Analizi
- Sunucu araştırması
- Ağ Cihazı İncelemesi
- Gönderen Posta Gönderen Parmak İzleri
- Yazılım Gömülü Tanımlayıcılar
Aşağıdaki bölümlerde, e-posta incelemesi amacıyla Python kullanarak nasıl bilgi alınacağını öğreneceğiz.
EML dosyalarından Bilgilerin Çıkarılması
EML dosyaları temelde e-posta mesajlarını depolamak için yaygın olarak kullanılan dosya biçimindeki e-postalardır. Microsoft Outlook, Outlook Express ve Windows Live Mail gibi birden çok e-posta istemcisi ile uyumlu yapılandırılmış metin dosyalarıdır.
Bir EML dosyası, e-posta başlıklarını, gövde içeriğini, ek verilerini düz metin olarak depolar. İkili verileri kodlamak için base64 ve içerik bilgilerini depolamak için Quoted-Printable (QP) kodlamayı kullanır. EML dosyasından bilgi çıkarmak için kullanılabilecek Python betiği aşağıda verilmiştir -
Öncelikle, aşağıdaki Python kitaplıklarını aşağıda gösterildiği gibi içe aktarın -
from __future__ import print_function
from argparse import ArgumentParser, FileType
from email import message_from_file
import os
import quopri
import base64
Yukarıdaki kütüphanelerde, quopriEML dosyalarından QP kodlanmış değerlerin kodunu çözmek için kullanılır. Base64 ile kodlanmış herhangi bir verinin şifresi çözülebilir.base64 kütüphane.
Sonra, komut satırı işleyicisi için argüman sağlayalım. Burada, aşağıda gösterildiği gibi EML dosyasının yolu olabilecek tek bir argümanı kabul edeceğini unutmayın -
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)
Şimdi tanımlamalıyız main() isimli yöntemi kullanacağımız fonksiyon message_from_file()e-posta kitaplığından dosyayı nesne gibi okumak için. Burada sonuçta adı verilen değişkeni kullanarak başlıklara, gövde içeriğine, eklere ve diğer yük bilgilerine erişeceğiz.emlfile aşağıda verilen kodda gösterildiği gibi -
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])
Şimdi tanımlamalıyız process_payload() kullanarak mesaj gövdesi içeriğini çıkaracağımız yöntem get_payload()yöntem. QP kodlu verilerin kodunu kullanarakquopri.decodestring()işlevi. E-postanın depolanmasını düzgün bir şekilde idare edebilmesi için içerik MIME türünü de kontrol edeceğiz. Aşağıda verilen koda uyun -
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)
Yukarıdaki betiği çalıştırdıktan sonra, konsolda çeşitli yükler ile birlikte başlık bilgisini alacağız.
Python kullanarak MSG Dosyalarını Analiz Etme
E-posta mesajları birçok farklı biçimde gelir. MSG, Microsoft Outlook ve Exchange tarafından kullanılan bu tür bir formattır. MSG uzantılı dosyalar, başlıklar ve ana mesaj gövdesi için düz ASCII metni, köprüler ve ekler içerebilir.
Bu bölümde, Outlook API kullanarak MSG dosyasından nasıl bilgi çıkarılacağını öğreneceğiz. Aşağıdaki Python komut dosyasının yalnızca Windows'ta çalışacağını unutmayın. Bunun için, adlı üçüncü taraf Python kitaplığı kurmamız gerekiyor.pywin32 aşağıdaki gibi -
pip install pywin32
Şimdi, gösterilen komutları kullanarak aşağıdaki kitaplıkları içe aktarın -
from __future__ import print_function
from argparse import ArgumentParser
import os
import win32com.client
import pywintypes
Şimdi, komut satırı işleyicisi için bir argüman sağlayalım. Burada, biri MSG dosyasına giden yol, diğeri ise aşağıdaki gibi istenen çıktı klasörü olacak iki bağımsız değişkeni kabul edecektir -
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)
Şimdi tanımlamalıyız main() arayacağımız fonksiyon win32com kurmak için kitaplık Outlook API hangi daha fazla erişim sağlar MAPI ad alanı.
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)
Şimdi, bu komut dosyasında kullandığımız farklı işlevleri tanımlayın. Aşağıda verilen kod,display_msg_attribs() konu, alıcı, BCC, CC, Boyut, GönderenAdı, gönderildi vb.
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')))
Şimdi tanımlayın display_msg_recipeints() Mesajlar arasında yinelenen ve alıcı ayrıntılarını görüntüleyen işlev.
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
Sonra, tanımlıyoruz extract_msg_body() Mesajdan gövde içeriğini, HTML'nin yanı sıra Düz metni çıkaran işlev.
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"))
Sonra, tanımlayacağız extract_attachments() ek verilerini istenen çıktı dizinine aktaran işlev.
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
Tüm işlevler tanımlandıktan sonra, tüm öznitelikleri aşağıdaki kod satırıyla konsola yazdıracağız -
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
Yukarıdaki betiği çalıştırdıktan sonra, çıktı dizinindeki birkaç dosyayla birlikte konsol penceresinde ileti özniteliklerini ve eklerini alacağız.
Python kullanarak Google Takeout'tan MBOX dosyalarını yapılandırma
MBOX dosyaları, içinde depolanan mesajları bölen özel biçimlendirmeye sahip metin dosyalarıdır. Genellikle UNIX sistemleri, Thunderbolt ve Google Paket Servisi ile ilişkili olarak bulunurlar.
Bu bölümde, Google Paket Servisi'nden aldığımız MBOX dosyalarını yapılandıracağımız bir Python betiği göreceksiniz. Ancak bundan önce, bu MBOX dosyalarını Google hesabımızı veya Gmail hesabımızı kullanarak nasıl oluşturabileceğimizi bilmeliyiz.
Google Hesabı Posta Kutusunu MBX Biçimine Alma
Google hesabı posta kutusunu almak, Gmail hesabımızın yedeğini almak anlamına gelir. Çeşitli kişisel veya profesyonel nedenlerle yedek alınabilir. Google'ın Gmail verilerinin yedeklenmesini sağladığını unutmayın. Google hesabı posta kutumuzu MBOX biçiminde almak için, aşağıda verilen adımları izlemeniz gerekir -
Açık My account Gösterge Paneli.
Kişisel bilgiler ve gizlilik bölümüne gidin ve İçeriğinizi kontrol edin bağlantısını seçin.
Yeni bir arşiv oluşturabilir veya mevcut bir arşivi yönetebilirsiniz. Tıklarsak,CREATE ARCHIVE bağlantı, daha sonra eklemek istediğimiz her Google ürünü için bazı onay kutuları alacağız.
Ürünleri seçtikten sonra, arşivimiz için dosya türünü ve maksimum boyutu seçme özgürlüğünün yanı sıra listeden seçim yapabileceğiniz teslim yöntemini de elde edeceğiz.
Son olarak, bu yedeği MBOX formatında alacağız.
Python Kodu
Şimdi, yukarıda tartışılan MBOX dosyası aşağıda gösterildiği gibi Python kullanılarak yapılandırılabilir -
Öncelikle, aşağıdaki gibi Python kitaplıklarını içe aktarmanız gerekir -
from __future__ import print_function
from argparse import ArgumentParser
import mailbox
import os
import time
import csv
from tqdm import tqdm
import base64
Tüm kütüphaneler, daha önceki komut dosyalarında kullanılmış ve açıklanmıştır. mailbox MBOX dosyalarını ayrıştırmak için kullanılan kitaplık.
Şimdi, komut satırı işleyicisi için bir bağımsız değişken sağlayın. Burada iki bağımsız değişkeni kabul edecektir - biri MBOX dosyasına giden yol, diğeri ise istenen çıktı klasörü olacaktır.
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)
Şimdi tanımlayacak main() işlev ve çağrı mbox Bir MBOX dosyasını yolunu sağlayarak ayrıştırabileceğimiz bir posta kutusu kitaplığı sınıfı -
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)))
Şimdi, bir okuyucu yöntemi tanımlayın mailbox kütüphane aşağıdaki gibidir -
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)
Şimdi, daha ileri işlemler için aşağıdaki gibi bazı değişkenler oluşturun -
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"]
Sonra kullan tqdm bir ilerleme çubuğu oluşturmak ve yineleme sürecini aşağıdaki gibi izlemek için -
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")
Şimdi, hava durumu mesajının yüklü olup olmadığını kontrol edin. Eğer sahipse o zaman tanımlayacağızwrite_payload() yöntem aşağıdaki gibidir -
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)
Şimdi verilerin eklenmesi gerekiyor. Sonra arayacağızcreate_report() yöntem aşağıdaki gibidir -
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
Yukarıdaki if-else ifadelerinin anlaşılmasının kolay olduğuna dikkat edin. Şimdi, dosya adını dosyadan çıkaracak bir yöntem tanımlamamız gerekiyor.msg aşağıdaki gibi nesne -
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)
Şimdi, aşağıdaki kod satırlarının yardımıyla, dosyayı gerçekten dışa aktarabilirsiniz -
if isinstance(content_data, str):
open(file_name, 'w').write(content_data)
else:
open(file_name, 'wb').write(content_data)
return file_name
Şimdi, dosyadan dosya adlarını çıkarmak için bir işlev tanımlayalım. message bu dosyaların adlarını aşağıdaki gibi doğru şekilde temsil etmek için -
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)
Şimdi, bir CSV dosyası yazabiliriz. create_report() aşağıdaki gibi işlev -
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)
Yukarıda verilen komut dosyasını çalıştırdıktan sonra, CSV raporunu ve eklerle dolu dizini alacağız.
Bu bölüm, Microsoft Windows adli tıp ile ilgili çeşitli kavramları ve bir araştırmacının araştırma sürecinden elde edebileceği önemli eserleri açıklayacaktır.
Giriş
Artefaktlar, bir bilgisayar sistemi içinde, bilgisayar kullanıcısı tarafından gerçekleştirilen faaliyetlerle ilgili önemli bilgiler içeren nesneler veya alanlardır. Bu bilgilerin türü ve konumu işletim sistemine bağlıdır. Adli analiz sırasında, bu eserler, araştırmacının gözlemini onaylamada veya reddetmede çok önemli bir rol oynar.
Adli Tıp için Windows Yapılarının Önemi
Windows yapıları, aşağıdaki nedenlerden dolayı önem kazanır -
Dünyadaki trafiğin yaklaşık% 90'ı işletim sistemi olarak Windows'u kullanan bilgisayarlardan geliyor. Bu nedenle, dijital adli tıp araştırmacıları için Windows artefaktları çok önemlidir.
Windows işletim sistemi, bilgisayar sistemindeki kullanıcı aktivitesi ile ilgili farklı türden kanıtları saklar. Bu, dijital adli tıp için Windows eserlerinin önemini gösteren başka bir nedendir.
Çoğu zaman araştırmacı, araştırmayı kullanıcı kasalı veriler gibi eski ve geleneksel alanlar etrafında döndürür. Windows yapıları, araştırmayı sistem tarafından oluşturulan veriler veya yapılar gibi geleneksel olmayan alanlara yönlendirebilir.
Windows tarafından, araştırmacıların yanı sıra gayri resmi soruşturma yapan şirketler ve bireyler için yararlı olan çok sayıda eser sağlanmaktadır.
Son yıllarda siber suçlardaki artış, Windows eserlerinin önemli olmasının bir başka nedenidir.
Windows Yapıları ve Python Komut Dosyaları
Bu bölümde, onlardan bilgi almak için bazı Windows yapıları ve Python betikleri hakkında tartışacağız.
Geridönüşüm kutusu
Adli soruşturma için önemli Windows eserlerinden biridir. Windows geri dönüşüm kutusu, kullanıcı tarafından silinmiş ancak sistem tarafından henüz fiziksel olarak kaldırılmamış dosyaları içerir. Kullanıcı dosyayı sistemden tamamen kaldırsa bile bu önemli bir araştırma kaynağı olarak hizmet eder. Bunun nedeni, incelemeyi yapan kişinin silinen dosyalardan orijinal dosya yolu ve Geri Dönüşüm Kutusu'na gönderilme zamanı gibi değerli bilgileri çıkarabilmesidir.
Geri Dönüşüm Kutusu kanıtlarının depolanmasının Windows sürümüne bağlı olduğunu unutmayın. Aşağıdaki Python betiğinde, iki dosya oluşturduğu Windows 7 ile ilgileneceğiz:$R geri dönüştürülmüş dosyanın gerçek içeriğini içeren dosya ve $I dosya silindiğinde orijinal dosya adını, yolunu, dosya boyutunu içeren dosya.
Python betiği için üçüncü taraf modülleri yüklememiz gerekir. pytsk3, pyewf ve unicodecsv. Kullanabilirizpiponları yüklemek için. Geri Dönüşüm Kutusu'ndan bilgi almak için aşağıdaki adımları takip edebiliriz -
İlk olarak, taramak için özyinelemeli yöntem kullanmalıyız $Recycle.bin klasörüne gidin ve ile başlayan tüm dosyaları seçin $I.
Daha sonra, dosyaların içeriğini okuyacağız ve mevcut meta veri yapılarını ayrıştıracağız.
Şimdi, ilişkili $ R dosyasını arayacağız.
Sonunda sonuçları incelenmek üzere CSV dosyasına yazacağız.
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Öncelikle, aşağıdaki Python kitaplıklarını içe aktarmamız gerekiyor -
from __future__ import print_function
from argparse import ArgumentParser
import datetime
import os
import struct
from utility.pytskutil import TSKUtil
import unicodecsv as csv
Sonra, komut satırı işleyicisi için argüman sağlamamız gerekiyor. Burada üç argümanı kabul edeceğini unutmayın - ilki kanıt dosyasına giden yol, ikincisi kanıt dosyasının türü ve üçüncüsü, aşağıda gösterildiği gibi CSV raporuna giden istenen çıktı yoludur -
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)
Şimdi tanımlayın main()tüm işlemleri gerçekleştirecek işlev. Arayacak$I aşağıdaki gibi dosya -
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")
Şimdi bulursak $I dosya, daha sonra gönderilmelidir process_dollar_i() kabul edecek işlev tsk_util nesnenin yanı sıra listesi $I dosyalar, aşağıda gösterildiği gibi -
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:])
Şimdi $ R dosyalarını aşağıdaki gibi arayın -
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
Şimdi tanımla read_dollar_i() okuma yöntemi $Idosyalar, başka bir deyişle meta verileri ayrıştırır. Kullanacağızread_random()İmzanın ilk sekiz baytını okuma yöntemi. İmza eşleşmezse bu hiçbiri döndürmez. Bundan sonra, aşağıdaki değerleri okuyup paketini açmamız gerekecek$I dosya geçerli bir dosyaysa.
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)
Şimdi, bu dosyaları çıkardıktan sonra, tam sayıları kullanarak insan tarafından okunabilir değerlere yorumlamamız gerekir. sizeof_fmt() aşağıda gösterildiği gibi işlev -
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}
Şimdi tanımlamalıyız sizeof_fmt() aşağıdaki gibi işlev -
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)
Şimdi, yorumlanmış tamsayılar için biçimlendirilmiş tarih ve saate aşağıdaki gibi bir işlev tanımlayın -
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')
Şimdi tanımlayacağız write_csv() işlenen sonuçları bir CSV dosyasına aşağıdaki gibi yazma yöntemi -
def write_csv(outfile, fieldnames, data):
with open(outfile, 'wb') as open_outfile:
csvfile = csv.DictWriter(open_outfile, fieldnames)
csvfile.writeheader()
csvfile.writerows(data)
Yukarıdaki betiği çalıştırdığınızda, verileri $ I ve $ R dosyasından alacağız.
Yapışkan notlar
Windows Yapışkan Notlar, gerçek dünyadaki yazma alışkanlığını kalem ve kağıtla değiştirir. Bu notlar, farklı renkler, yazı tipleri vb. Seçenekleriyle masaüstünde yüzerdi. Windows 7'de Sticky Notes dosyası bir OLE dosyası olarak saklanır, bu nedenle aşağıdaki Python betiğinde Sticky Notes'tan meta verileri çıkarmak için bu OLE dosyasını inceleyeceğiz.
Bu Python betiği için, üçüncü taraf modülleri kurmamız gerekiyor. olefile, pytsk3, pyewfve unicodecsv. Komutu kullanabilirizpip onları yüklemek için.
Yapışkan not dosyasından bilgileri çıkarmak için aşağıda tartışılan adımları takip edebiliriz. StickyNote.sn -
İlk olarak, kanıt dosyasını açın ve tüm StickyNote.snt dosyalarını bulun.
Ardından, OLE akışından meta verileri ve içeriği ayrıştırın ve RTF içeriğini dosyalara yazın.
Son olarak, bu meta verilerin CSV raporunu oluşturun.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Önce, aşağıdaki Python kitaplıklarını içe aktarın -
from __future__ import print_function
from argparse import ArgumentParser
import unicodecsv as csv
import os
import StringIO
from utility.pytskutil import TSKUtil
import olefile
Ardından, bu komut dosyasında kullanılacak global bir değişken tanımlayın -
REPORT_COLS = ['note_id', 'created', 'modified', 'note_text', 'note_file']
Sonra, komut satırı işleyicisi için argüman sağlamamız gerekiyor. Burada üç argümanı kabul edeceğine dikkat edin - birincisi kanıt dosyasına giden yol, ikincisi kanıt dosyasının türü ve üçüncüsü istenen çıktı yolu aşağıdaki gibidir -
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)
Şimdi tanımlayacağız main() aşağıda gösterildiği gibi önceki betiğe benzer olan işlev -
def main(evidence, image_type, report_folder):
tsk_util = TSKUtil(evidence, image_type)
note_files = tsk_util.recurse_files('StickyNotes.snt', '/Users','equals')
Şimdi, ortaya çıkan dosyaları yineleyelim. Sonra arayacağızparse_snt_file() dosyayı işlemek için işlev ve ardından RTF dosyasını write_note_rtf() yöntem aşağıdaki gibidir -
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)
Sonra, bu betikte kullanılan çeşitli fonksiyonları tanımlamamız gerekiyor.
Öncelikle tanımlayacağız create_file_like_obj() dosyanın boyutunu okumak için işlev pytskdosya nesnesi. Sonra tanımlayacağızparse_snt_file() dosya benzeri nesneyi girdi olarak kabul eden ve yapışkan not dosyasını okumak ve yorumlamak için kullanılan işlev.
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
Şimdi, tanımlayarak bir RTF dosyası oluşturun write_note_rtf() aşağıdaki gibi işlev
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'])
Şimdi, iç içe geçmiş sözlüğü bir CSV elektronik tablosu için daha uygun olan düz bir sözlükler listesine çevireceğiz. Tanımlanarak yapılacaktırprep_note_report()işlevi. Son olarak tanımlayacağızwrite_csv() işlevi.
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)
Yukarıdaki komut dosyasını çalıştırdıktan sonra, meta verileri Sticky Notes dosyasından alacağız.
Kayıt Dosyaları
Windows kayıt dosyaları, bir adli tıp analisti için bir bilgi hazinesi gibi birçok önemli ayrıntı içerir. İşletim sistemi konfigürasyonu, kullanıcı aktivitesi, yazılım kurulumu vb. İle ilgili ayrıntıları içeren hiyerarşik bir veritabanıdır. Aşağıdaki Python komut dizisinde, aşağıdaki ortak temel bilgilere erişeceğiz.SYSTEM ve SOFTWARE kurdeşen.
Bu Python betiği için, üçüncü taraf modülleri kurmamız gerekiyor. pytsk3, pyewf ve registry. Kullanabilirizpip onları yüklemek için.
Bilgileri Windows kayıt defterinden çıkarmak için aşağıda verilen adımları takip edebiliriz -
İlk olarak, adının yanı sıra yola göre işlenecek kayıt defteri kovanlarını bulun.
Daha sonra bu dosyaları StringIO ve Registry modüllerini kullanarak açacağız.
Sonunda, her bir kovanı işlememiz ve ayrıştırılan değerleri yorumlama için konsola yazdırmamız gerekiyor.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Önce, aşağıdaki Python kitaplıklarını içe aktarın -
from __future__ import print_function
from argparse import ArgumentParser
import datetime
import StringIO
import struct
from utility.pytskutil import TSKUtil
from Registry import Registry
Şimdi, komut satırı işleyicisi için bağımsız değişken sağlayın. Burada iki argümanı kabul edecektir - ilki kanıt dosyasına giden yol, ikincisi aşağıda gösterildiği gibi kanıt dosyasının türüdür -
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)
Şimdi tanımlayacağız main() arama işlevi SYSTEM ve SOFTWARE içinde kurdeşen /Windows/System32/config aşağıdaki gibi klasör -
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)
Şimdi, kayıt dosyasını açma işlevini tanımlayın. Bu amaçla, dosyanın boyutunu aşağıdaki kaynaklardan toplamamız gerekir:pytsk meta veriler aşağıdaki gibidir -
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)
Şimdi aşağıdaki yöntem yardımı ile işleyebiliyoruz SYSTEM> kovan -
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))
Şimdi, yorumlanmış tamsayılar için biçimlendirilmiş tarih ve saate aşağıdaki gibi bir işlev tanımlamamız gerekiyor -
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')
Şimdi aşağıdaki yöntem yardımıyla işleyebiliriz SOFTWARE kovan -
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))
Yukarıdaki komut dosyasını çalıştırdıktan sonra, Windows Kayıt Defteri dosyalarında depolanan meta verileri alacağız.
Bu bölüm, Windows'taki bazı daha önemli eserlerden ve bunların Python kullanan ayıklama yöntemlerinden bahsediyor.
Kullanıcı Aktiviteleri
Windows sahip NTUSER.DATçeşitli kullanıcı etkinliklerini depolamak için dosya. Her kullanıcı profili gibi kovan yaşıyorNTUSER.DAT, özellikle o kullanıcıyla ilgili bilgileri ve yapılandırmaları depolayan. Bu nedenle, adli tıp analistleri tarafından araştırma amacıyla oldukça faydalıdır.
Aşağıdaki Python betiği, şu anahtarların bazılarını ayrıştıracaktır: NTUSER.DATsistemdeki bir kullanıcının eylemlerini keşfetmek için. Daha fazla ilerlemeden önce, Python betiği için, üçüncü taraf modülleri yüklememiz gerekir.Registry, pytsk3, pyewf ve Jinja2. Bunları kurmak için pip kullanabiliriz.
Bilgi almak için aşağıdaki adımları takip edebiliriz NTUSER.DAT dosya -
Önce hepsini arayın NTUSER.DAT sistemdeki dosyalar.
Sonra ayrıştırın WordWheelQuery, TypePath and RunMRU her biri için anahtar NTUSER.DAT dosya.
Sonunda, zaten işlenmiş olan bu eserleri kullanarak bir HTML raporuna yazacağız. Jinja2 fmodule.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Her şeyden önce, aşağıdaki Python modüllerini içe aktarmamız gerekiyor -
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
Şimdi, komut satırı işleyicisi için bağımsız değişken sağlayın. Burada üç argümanı kabul edecektir - ilki kanıt dosyasına giden yol, ikincisi kanıt dosyasının türü ve üçüncüsü, aşağıda gösterildiği gibi HTML raporu için istenen çıktı yoludur -
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)
Şimdi tanımlayalım main() hepsini arama işlevi NTUSER.DAT dosyalar, gösterildiği gibi -
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'}
}
Şimdi, anahtarı bulmaya çalışacağız NTUSER.DAT dosyasını bulduğunuzda, kullanıcı işleme işlevlerini aşağıda gösterildiği gibi tanımlayın -
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()
Şimdi, sözlük nesnesini ve yolunu write_html() yöntem aşağıdaki gibidir -
write_html(report, nt_rec)
Şimdi, bir yöntem tanımlayın, pytsk dosya tanıtıcısı ve bunu aracılığıyla Registry sınıfına okuyun. StringIO sınıf.
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)
Şimdi, ayrıştıracak ve işleyecek işlevi tanımlayacağız WordWheelQuery anahtar NTUSER.DAT aşağıdaki gibi dosya -
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
Şimdi, ayrıştıracak ve işleyecek işlevi tanımlayacağız TypedPaths anahtar NTUSER.DAT aşağıdaki gibi dosya -
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
Şimdi, ayrıştıracak ve işleyecek işlevi tanımlayacağız RunMRU anahtar NTUSER.DAT aşağıdaki gibi dosya -
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
Şimdi, aşağıdaki işlev HTML raporunun oluşturulmasını sağlayacaktır -
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)
Sonunda rapor için HTML belgesi yazabiliriz. Yukarıdaki betiği çalıştırdıktan sonra, bilgileri NTUSER.DAT dosyasından HTML belge formatında alacağız.
LINK dosyaları
Kısayol dosyaları, bir kullanıcı veya işletim sistemi ekli depolama gibi sistem sürücülerinden sık kullanılan, çift tıklanan veya erişilen dosyalar için kısayol dosyaları oluşturduğunda oluşturulur. Bu tür kısayol dosyalarına bağlantı dosyaları denir. Araştırmacı, bu bağlantı dosyalarına erişerek, bu dosyalara erişilen zaman ve konum gibi pencere faaliyetlerini bulabilir.
Bu Windows LINK dosyalarından bilgi almak için kullanabileceğimiz Python betiğini tartışalım.
Python betiği için üçüncü taraf modülleri yükleyin, yani pylnk, pytsk3, pyewf. Bilgi almak için aşağıdaki adımları takip edebilirizlnk Dosyalar
Önce şunu arayın: lnk sistem içindeki dosyalar.
Ardından, bu dosyadaki bilgileri yineleyerek çıkarın.
Şimdi, sonunda bu bilgiyi bir CSV raporuna ihtiyacımız var.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Önce, aşağıdaki Python kitaplıklarını içe aktarın -
from __future__ import print_function
from argparse import ArgumentParser
import csv
import StringIO
from utility.pytskutil import TSKUtil
import pylnk
Şimdi, komut satırı işleyicisi için bağımsız değişken sağlayın. Burada üç argümanı kabul edecektir - ilki kanıt dosyasına giden yol, ikincisi kanıt dosyası türü ve üçüncüsü, aşağıda gösterildiği gibi CSV raporuna giden istenen çıktı yoludur -
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)
Şimdi, bir nesne oluşturarak kanıt dosyasını yorumlayın. TSKUtil ile biten dosyaları bulmak için dosya sisteminde yineleyin lnk. Tanımlanarak yapılabilirmain() aşağıdaki gibi işlev -
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'
]
Şimdi aşağıdaki kodun yardımıyla, adım adım ilerleyeceğiz lnk dosyaları aşağıdaki gibi bir işlev oluşturarak -
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)
Şimdi iki işlevi tanımlamamız gerekiyor, biri pytsk dosya nesnesi ve diğerleri, aşağıda gösterildiği gibi CSV raporu yazmak için kullanılacaktır -
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)
Yukarıdaki komut dosyasını çalıştırdıktan sonra, keşfedilen bilgiden bilgi alacağız. lnk CSV raporundaki dosyalar -
Dosyaları Önceden Getir
Bir uygulama belirli bir konumdan ilk kez çalıştırıldığında, Windows prefetch files. Bunlar, uygulama başlatma sürecini hızlandırmak için kullanılır. Bu dosyaların uzantısı.PF ve bunlar şurada saklanır ”\Root\Windows\Prefetch” Klasör.
Dijital adli tıp uzmanları, programın belirli bir konumdan yürütüldüğüne dair kanıtların yanı sıra kullanıcının ayrıntılarını ortaya çıkarabilir. Önceden getirilen dosyalar, program silindikten veya kaldırıldıktan sonra bile girişleri kaldığı için denetleyen için yararlı yapılardır.
Aşağıda verilen Windows ön getirme dosyalarından bilgi alacak Python betiğini tartışalım -
Python betiği için üçüncü taraf modülleri yükleyin, yani pylnk, pytsk3 ve unicodecsv. Önceki bölümlerde tartıştığımız Python komut dosyalarında bu kütüphanelerle zaten çalıştığımızı hatırlayın.
Bilgi almak için aşağıda verilen adımları izlemeliyiz prefetch dosyalar -
İlk önce tara .pf uzantı dosyaları veya önceden getirilmiş dosyalar.
Şimdi, yanlış pozitifleri ortadan kaldırmak için imza doğrulamasını gerçekleştirin.
Ardından, Windows önceden getirilmiş dosya biçimini ayrıştırın. Bu, Windows sürümüne göre farklılık gösterir. Örneğin, Windows XP için 17, Windows Vista ve Windows 7 için 23, 26 ve Windows 10 için 30'dur.
Son olarak, ayrıştırılan sonucu bir CSV dosyasına yazacağız.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Önce, aşağıdaki Python kitaplıklarını içe aktarın -
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
Şimdi, komut satırı işleyicisi için bir bağımsız değişken sağlayın. Burada iki argümanı kabul edecek, ilki kanıt dosyasına giden yol, ikincisi ise kanıt dosyasının türü olacaktır. Ayrıca, önceden getirilmiş dosyalar için taranacak yolu belirtmek için isteğe bağlı bir bağımsız değişken kabul eder -
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)
Şimdi, bir nesne oluşturarak kanıt dosyasını yorumlayın. TSKUtil ile biten dosyaları bulmak için dosya sisteminde yineleyin .pf. Tanımlanarak yapılabilirmain() aşağıdaki gibi işlev -
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)
Şimdi, aşağıda gösterildiği gibi imzaların doğrulanmasını sağlayacak bir yöntem tanımlayın -
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)
Şimdi, Windows önceden getirme dosyalarını işlemeye başlayın. Burada Windows XP önceden getirme dosyalarının örneğini alıyoruz -
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)
Şimdi, aşağıdaki gibi struct kullanarak önceden getirilmiş dosyalara gömülü verileri çıkarın -
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 ]
Windows XP için ön yükleme sürümünü sağladığımızdan, ancak ya diğer Windows için önceden getirilmiş sürümlerle karşılaşırsa? Ardından aşağıdaki gibi bir hata mesajı göstermesi gerekir -
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)
Şimdi, sonucu CSV raporuna yazma yöntemini aşağıdaki gibi tanımlayın -
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)
Yukarıdaki komut dosyasını çalıştırdıktan sonra, bilgileri Windows XP sürümünün önceden getirilmiş dosyalarından bir elektronik tabloya alacağız.
Bu bölümde, bir araştırmacının Windows'ta adli tıp analizi sırasında elde edebileceği diğer eserler açıklanacaktır.
Olay Günlükleri
Windows olay günlüğü dosyaları, ad öngörüleri olarak, kullanıcının bilgisayarda oturum açması, program bir hatayla karşılaşması, sistem değişiklikleri, RDP erişimi, uygulamaya özgü olaylar vb. Gibi önemli olayları depolayan özel dosyalardır. Siber araştırmacılar her zaman olaylarla ilgilenirler. günlük bilgileri, çünkü sisteme erişim hakkında birçok yararlı tarihsel bilgi sağlar. Aşağıdaki Python betiğinde hem eski hem de mevcut Windows olay günlüğü formatlarını işleyeceğiz.
Python betiği için, üçüncü taraf modülleri kurmamız gerekiyor. pytsk3, pyewf, unicodecsv, pyevt and pyevtx. Olay günlüklerinden bilgi almak için aşağıda verilen adımları takip edebiliriz -
İlk olarak, giriş bağımsız değişkeniyle eşleşen tüm olay günlüklerini arayın.
Ardından, dosya imzası doğrulaması yapın.
Şimdi, bulunan her olay günlüğünü uygun kitaplıkla işleyin.
Son olarak, çıktıyı elektronik tabloya yazın.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Önce, aşağıdaki Python kitaplıklarını içe aktarın -
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
Şimdi, komut satırı işleyicisi için bağımsız değişkenleri sağlayın. Burada üç argümanı kabul edeceğini unutmayın - ilki kanıt dosyasına giden yol, ikincisi kanıt dosyası türü ve üçüncüsü işlenecek olay günlüğünün adıdır.
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)
Şimdi, kullanıcı tarafından sağlanan yolun varlığını sorgulamak için olay günlükleriyle etkileşime geçin. TSKUtilnesne. Yardımı ile yapılabilirmain() yöntem aşağıdaki gibidir -
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)
Şimdi, imza doğrulaması yapmalı ve ardından tüm içeriği mevcut dizine yazacak bir yöntem tanımlamalıyız -
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
Son olarak, çıktıyı elektronik tabloya yazmak için aşağıdaki gibi bir yöntem tanımlayın -
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)
Yukarıdaki komut dosyasını başarıyla çalıştırdığınızda, olayların bilgilerini elektronik tabloda alacağız.
İnternet Geçmişi
İnternet geçmişi, adli tıp analistleri için çok yararlıdır; siber suçların çoğu yalnızca internet üzerinden gerçekleştiği için. Windows adli tıp hakkında tartışırken Internet Explorer'dan internet geçmişini nasıl çıkaracağımızı görelim ve Internet Explorer varsayılan olarak Windows ile birlikte gelir.
Internet Explorer'da internet geçmişi şuraya kaydedilir: index.datdosya. Bilgiyi buradan çıkaracak bir Python betiğine bakalım.index.dat dosya.
Bilgi almak için aşağıda verilen adımları takip edebiliriz index.dat dosyalar -
Önce şunu arayın: index.dat sistem içindeki dosyalar.
Ardından, bu dosyadaki bilgileri yineleyerek çıkarın.
Şimdi, tüm bu bilgileri bir CSV raporuna yazın.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Önce, aşağıdaki Python kitaplıklarını içe aktarın -
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
Şimdi, komut satırı işleyicisi için bağımsız değişkenler sağlayın. Burada iki argümanı kabul edeceğini unutmayın - ilki kanıt dosyasına giden yol, ikincisi ise kanıt dosyasının türü olacaktır -
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)
Şimdi, bir nesne oluşturarak kanıt dosyasını yorumlayın. TSKUtilindex.dat dosyalarını bulmak için dosya sisteminde yineleyin. Tanımlanarak yapılabilirmain() aşağıdaki gibi işlev -
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)
Şimdi, index.dat dosyasının bilgilerini mevcut çalışma dizinine kopyalayabileceğimiz ve daha sonra üçüncü taraf bir modül tarafından işlenebilecek bir işlev tanımlayın -
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
Şimdi, yerleşik işlevin yardımıyla imza doğrulamasını gerçekleştirmek için aşağıdaki kodu kullanın: 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)
Şimdi, aşağıda gösterildiği gibi CSV dosyasında çıktıyı yazdıracak bir yöntem tanımlayın -
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)
Yukarıdaki betiği çalıştırdıktan sonra, bilgileri CSV dosyasındaki index.dat dosyasından alacağız.
Birim Gölge Kopyaları
Gölge kopya, bilgisayar dosyalarının yedek kopyalarını veya anlık görüntülerini manuel veya otomatik olarak almak için Windows'ta bulunan teknolojidir. Birim anlık görüntü hizmeti veya birim gölge hizmeti (VSS) olarak da adlandırılır.
Bu VSS dosyalarının yardımıyla, adli tıp uzmanları, sistemin zaman içinde nasıl değiştiği ve bilgisayarda hangi dosyaların bulunduğu hakkında bazı tarihsel bilgilere sahip olabilir. Gölge kopya teknolojisi, gölge kopyaları oluşturmak ve depolamak için dosya sisteminin NTFS olmasını gerektirir.
Bu bölümde, adli görüntüde bulunan herhangi bir gölge kopya hacmine erişmeye yardımcı olan bir Python betiği göreceğiz.
Python betiği için üçüncü taraf modülleri yüklememiz gerekir. pytsk3, pyewf, unicodecsv, pyvshadow ve vss. VSS dosyalarından bilgi çıkarmak için aşağıda verilen adımları takip edebiliriz
İlk olarak, ham görüntünün hacmine erişin ve tüm NTFS bölümlerini tanımlayın.
Ardından, bu gölge kopyalardan bilgileri yineleyerek çıkarın.
Şimdi, nihayet anlık görüntülerde verilerin bir dosya listesi oluşturmamız gerekiyor.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Önce, aşağıdaki Python kitaplıklarını içe aktarın -
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
Şimdi, komut satırı işleyicisi için bağımsız değişkenler sağlayın. Burada iki argümanı kabul edecektir - ilki kanıt dosyasına giden yol ve ikincisi çıktı dosyasıdır.
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()
Şimdi, girdi dosyası yolunun varlığını doğrulayın ve ayrıca dizini çıktı dosyasından ayırın.
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)
Şimdi, kanıt dosyasının hacmiyle etkileşime girmek için TSKUtilnesne. Yardımı ile yapılabilirmain() yöntem aşağıdaki gibidir -
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)
Şimdi, ayrıştırılmış birim gölge dosyasını keşfetmek için aşağıdaki gibi bir yöntem tanımlayın -
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)
Son olarak, sonucu elektronik tabloya yazma yöntemini aşağıdaki gibi tanımlayın -
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)
Bu Python betiğini başarıyla çalıştırdıktan sonra, VSS'de bulunan bilgileri bir elektronik tabloya alacağız.
Şimdiye kadar, Python kullanarak Windows'ta eserlerin nasıl elde edildiğini gördük. Bu bölümde, Python kullanarak günlük tabanlı yapıların araştırılması hakkında bilgi edinelim.
Giriş
Günlük tabanlı eserler, dijital bir adli tıp uzmanı için çok yararlı olabilecek bilgi hazinesidir. Bilgileri toplamak için çeşitli izleme yazılımlarımız olsa da, bunlardan faydalı bilgileri ayrıştırmanın ana sorunu çok fazla veriye ihtiyacımız olmasıdır.
Çeşitli Günlük Tabanlı Yapılar ve Python'da Araştırma
Bu bölümde, çeşitli günlük tabanlı yapıları ve bunların Python'daki araştırmalarını tartışalım -
Zaman damgaları
Zaman damgası, etkinlik verilerini ve zamanını günlükte iletir. Herhangi bir günlük dosyasının önemli unsurlarından biridir. Bu veri ve zaman değerlerinin çeşitli biçimlerde gelebileceğini unutmayın.
Aşağıda gösterilen Python betiği, ham tarih-saati girdi olarak alır ve çıktı olarak biçimlendirilmiş bir zaman damgası sağlar.
Bu komut dosyası için aşağıdaki adımları izlememiz gerekiyor -
İlk olarak, veri kaynağı ve veri türü ile birlikte ham veri değerini alacak argümanları ayarlayın.
Şimdi, farklı tarih biçimlerindeki veriler için ortak arabirim sağlamak için bir sınıf sağlayın.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Öncelikle, aşağıdaki Python modüllerini içe aktarın -
from __future__ import print_function
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
from datetime import datetime as dt
from datetime import timedelta
Şimdi her zamanki gibi komut satırı işleyicisi için argüman sağlamamız gerekiyor. Burada üç bağımsız değişken kabul edecek, ilki işlenecek tarih değeri, ikincisi bu tarih değerinin kaynağı ve üçüncüsü de türü olacaktır -
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)
Şimdi, tarih değeri, tarih kaynağı ve değer türü için argümanları kabul edecek bir sınıf tanımlamamız gerekiyor -
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
Şimdi, main () yöntemi gibi bir denetleyici gibi davranacak bir yöntem tanımlayacağız -
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']
Şimdi, sırasıyla Unix epoch time ve FILETIME işleyecek iki yöntem tanımlamamız gerekiyor -
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')
Yukarıdaki komut dosyasını çalıştırdıktan sonra, bir zaman damgası sağlayarak dönüştürülen değeri okunması kolay biçimde elde edebiliriz.
Web Sunucusu Günlükleri
Dijital adli tıp uzmanının bakış açısına göre, web sunucusu günlükleri, kullanıcı ve coğrafi konumlarla ilgili bilgilerle birlikte yararlı kullanıcı istatistikleri de alabildikleri için bir başka önemli eserdir. Aşağıda, bilgilerin kolay analizi için web sunucusu günlüklerini işledikten sonra bir elektronik tablo oluşturacak Python betiği verilmiştir.
Öncelikle aşağıdaki Python modüllerini içe aktarmamız gerekiyor -
from __future__ import print_function
from argparse import ArgumentParser, FileType
import re
import shlex
import logging
import sys
import csv
logger = logging.getLogger(__file__)
Şimdi, günlüklerden ayrıştırılacak kalıpları tanımlamamız gerekiyor -
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*"))]
Şimdi, komut satırı işleyicisi için bir bağımsız değişken sağlayın. Burada iki bağımsız değişkeni kabul edecek, ilki işlenecek IIS günlüğü, ikincisi istenen CSV dosyası yolu olacaktır.
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")
Şimdi, toplu günlük bilgileri için komut dosyasını işleyecek main () yöntemini tanımlamamız gerekiyor -
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")
Son olarak, çıktıyı elektronik tabloya yazacak bir yöntem tanımlamamız gerekiyor -
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)
Yukarıdaki komut dosyasını çalıştırdıktan sonra, web sunucusu tabanlı günlükleri bir elektronik tabloda alacağız.
YARA kullanarak Önemli Dosyaları Tarama
YARA (Yine Başka Bir Yinelemeli Algoritma), kötü amaçlı yazılım tanımlama ve olay yanıtı için tasarlanmış bir kalıp eşleştirme aracıdır. Dosyaları taramak için YARA'yı kullanacağız. Aşağıdaki Python betiğinde YARA'yı kullanacağız.
YARA'yı aşağıdaki komutun yardımıyla kurabiliriz -
pip install YARA
Dosyaları taramak için YARA kurallarını kullanmak için aşağıda verilen adımları takip edebiliriz -
Öncelikle YARA kurallarını ayarlayın ve derleyin
Ardından, tek bir dosyayı tarayın ve ardından tek tek dosyaları işlemek için dizinlerde yineleyin.
Son olarak, sonucu CSV'ye aktaracağız.
Python Kodu
Bu amaçla Python kodunu nasıl kullanacağımızı görelim -
Öncelikle, aşağıdaki Python modüllerini içe aktarmamız gerekiyor -
from __future__ import print_function
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
import os
import csv
import yara
Ardından, komut satırı işleyicisi için bağımsız değişken sağlayın. Burada iki argümanı kabul edeceğini unutmayın - ilki YARA kurallarına giden yol, ikincisi ise taranacak dosyadır.
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)
Şimdi yara kurallarına ve taranacak dosyanın yolunu kabul edecek main () işlevi tanımlayacağız -
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)
Şimdi, dizinde yineleyecek ve sonucu daha fazla işlem için başka bir yönteme aktaracak bir yöntem tanımlayın -
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
Ardından, iki işlevi tanımlayın. İlk önce kullanacağımızı unutmayınmatch() yöntemi yrulesnesne ve diğeri, kullanıcı herhangi bir çıktı dosyası belirtmezse bu eşleşme bilgisini konsola bildirir. Aşağıda gösterilen kodu inceleyin -
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)
Son olarak, aşağıda gösterildiği gibi çıktıyı CSV dosyasına yazacak bir yöntem tanımlayacağız -
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)
Yukarıdaki komut dosyasını başarıyla çalıştırdığınızda, komut satırında uygun argümanlar sağlayabilir ve bir CSV raporu oluşturabiliriz.