Windows-II'deki Önemli Eserler
Bu bölüm, Windows'taki bazı daha önemli eserlerden ve bunların Python'u kullanarak 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 bir kovan varNTUSER.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 kurmamız gerekiyor.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 raporuna giden 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ı bulun ve 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, takılı 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. Bu bağlantı dosyalarına erişerek, bir araştırmacı, 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ının türü ve üçüncüsü, aşağıda gösterildiği gibi CSV raporunun 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 bir 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 girdileri 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 betiklerinde bu kitaplıklarla 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 de 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.