Python Forensics - 快速指南
Python Forensics - Introduction
Python是一种通用编程语言,具有简单易读的代码,专业开发人员和新手程序员都可以轻松理解。 Python包含许多有用的库,可以与任何堆栈框架一起使用。 许多实验室依靠Python来构建预测的基本模型并运行实验。 它还有助于控制关键操作系统。
Python具有内置功能,可在调查期间支持数字调查并保护证据的完整性。 在本教程中,我们将解释在数字或计算取证中应用Python的基本概念。
什么是计算取证?
计算取证是一个新兴的研究领域。 它涉及使用数字方法解决法医问题。 它使用计算科学来研究数字证据。
计算取证包括广泛的主题,其中包括调查的对象,物质和过程,主要基于模式证据,如工具标记,指纹,shoeprints,文档等,还包括生理和行为模式,DNA和数字证据在犯罪现场。
下图显示了计算取证所涵盖的广泛主题。
计算取证是在一些算法的帮助下实现的。 这些算法用于信号和图像处理,计算机视觉和图形。 它还包括数据挖掘,机器学习和机器人技术。
计算取证涉及多种数字方法。 在法医学中简化所有数字方法的最佳解决方案是使用像Python这样的通用编程语言。
Python Forensics - Installation of Python
由于我们需要Python用于计算取证的所有活动,让我们一步一步地移动并了解如何安装它。
Step 1 - 转到https://www.python.org/downloads/并根据系统上的操作系统下载Python的安装文件。
Step 2 - 下载软件包/安装程序后,单击exe文件以开始安装过程。
安装完成后,您将看到以下屏幕。
Step 3 - 下一步是在系统中设置Python的环境变量。
Step 4 - 设置环境变量后,在命令提示符下键入命令“python”以验证安装是否成功。
如果安装成功,那么您将在控制台上获得以下输出。
Python Forensics - Overview of Python
用Python编写的代码看起来与用其他传统编程语言(如C或Pascal)编写的代码非常相似。 还有人说,Python的语法是从C语言中大量借用的。这包括许多类似于C语言的Python关键字。
Python包括条件语句和循环语句,可用于准确提取数据以进行取证。 对于流控制,它提供if/else , while和循环遍历任何“可迭代”对象的高级for语句。
if a < b:
max = b
else:
max = a
Python与其他编程语言不同的主要领域是dynamic typing使用。 它使用引用对象的变量名称。 不需要声明这些变量。
数据类型 (Data Types)
Python包含一组内置数据类型,如字符串,布尔值,数字等。还有不可变类型,这意味着在执行期间无法更改的值。
Python还具有复合内置数据类型,其中包括作为哈希表的不可变数tuples , lists和dictionaries tuples 。 所有这些都用于数字取证,以收集证据时存储价值。
第三方模块和包
Python支持模块和/或包组,这些模块和/或包也称为third-party modules (在单个源文件中组合在一起的相关代码),用于组织程序。
Python包含一个广泛的标准库,这是其在计算取证中流行的主要原因之一。
Python代码的生命周期
首先,当您执行Python代码时,解释器会检查代码是否存在语法错误。 如果解释器发现任何语法错误,则它们会立即显示为错误消息。
如果没有语法错误,则编译代码以生成字节码并发送到PVM(Python虚拟机)。
PVM检查字节码是否存在任何运行时或逻辑错误。 如果PVM发现任何运行时错误,则会立即将它们报告为错误消息。
如果字节码没有错误,那么代码将被处理并获得其输出。
下图以图形方式显示了如何首先解释Python代码以生成字节码以及PVM如何处理字节码以生成输出。
Python Forensics - Basic Forensic Application
要根据Forensic指南创建应用程序,了解并遵循其命名约定和模式非常重要。
命名约定
在Python取证应用程序的开发过程中,要遵循的规则和约定如下表所述。
命名惯例 | 例 | |
---|---|---|
Constants | Uppercase with underscore separation | HIGH_TEMPERATURE |
局部变量名称 | 带有凹凸帽的小写字母(下划线是可选的) | currentTemperature |
全局变量名称 | 带有凹凸帽的前缀gl小写(下划线是可选的) | gl_maximumRecordedTemperature |
功能名称 | 大写字母带有颠簸的帽子(下划线可选),带有主动语音 | ConvertFarenheitToCentigrade(...) |
对象名称 | 使用颠簸大写字母前缀ob_小写 | ob_myTempRecorder |
Module | 下划线后跟小写字母,带有颠簸的大写字母 | _tempRecorder |
class名称 | 前缀class_然后颠簸帽并保持简短 | class_TempSystem |
让我们通过一个场景来理解在计算取证中命名约定的重要性。 假设我们有一个通常用于加密数据的散列算法。 单向散列算法将输入作为二进制数据流; 这可以是密码,文件,二进制数据或任何数字数据。 然后,散列算法针对在输入中接收的数据产生message digest (md)。
实际上不可能创建将生成给定消息摘要的新二进制输入。 即使是二进制输入数据的单个位,如果改变,也将生成唯一的消息,该消息与前一个消息不同。
例子 (Example)
请查看以下遵循上述约定的示例程序。
import sys, string, md5 # necessary libraries
print "Please enter your full name"
line = sys.stdin.readline()
line = line.rstrip()
md5_object = md5.new()
md5_object.update(line)
print md5_object.hexdigest() # Prints the output as per the hashing algorithm i.e. md5
exit
上述程序产生以下输出。
在此程序中,Python脚本接受输入(您的全名)并根据md5哈希算法对其进行转换。 如果需要,它会加密数据并保护信息。 根据法医指南,证据名称或任何其他证据可以在此模式中得到保障。
Python Forensics - Hash Function
hash function定义为将大量数据映射到具有指定长度的固定值的函数。 此函数确保相同的输入产生相同的输出,实际上定义为哈希和。 哈希和包括具有特定信息的特征。
这个功能几乎不可能恢复。 因此,任何第三方攻击都像蛮力攻击几乎是不可能的。 此外,这种算法称为one-way cryptographic algorithm 。
理想的加密哈希函数有四个主要属性 -
- 必须很容易计算任何给定输入的哈希值。
- 从哈希生成原始输入必须是不可行的。
- 在不更改哈希值的情况下修改输入是不可行的。
- 找到具有相同散列的两个不同输入是不可行的。
例子 (Example)
请考虑以下示例,该示例有助于使用十六进制格式的字符匹配密码。
import uuid
import hashlib
def hash_password(password):
# userid is used to generate a random number
salt = uuid.uuid4().hex #salt is stored in hexadecimal value
return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt
def check_password(hashed_password, user_password):
# hexdigest is used as an algorithm for storing passwords
password, salt = hashed_password.split(':')
return password == hashlib.sha256(salt.encode()
+ user_password.encode()).hexdigest()
new_pass = raw_input('Please enter required password ')
hashed_password = hash_password(new_pass)
print('The string to store in the db is: ' + hashed_password)
old_pass = raw_input('Re-enter new password ')
if check_password(hashed_password, old_pass):
print('Yuppie!! You entered the right password')
else:
print('Oops! I am sorry but the password does not match')
流程图(Flowchart)
我们借助以下流程图解释了该程序的逻辑 -
输出 (Output)
我们的代码将产生以下输出 -
输入的密码两次与哈希函数匹配。 这可确保输入两次的密码准确无误,这有助于收集有用数据并以加密格式保存。
Python Forensics - Cracking an Encryption
在本章中,我们将学习如何破解在分析和证据过程中获取的文本数据。
密码学中的纯文本是一些正常的可读文本,例如消息。 另一方面,密文是输入纯文本后获取的加密算法的输出。
我们如何将纯文本消息转换为密文的简单算法是由朱利叶斯凯撒发明的凯撒密码,以保证纯文本对他的敌人保密。 该密码涉及将消息中的每个字母“向前”移动字母表中的三个位置。
以下是演示图示。
a→D
b→E
c→F
....
w→Z
x→A
y→B
z→C
例子 (Example)
运行Python脚本时输入的消息提供了字符的所有可能性,用于模式证据。
使用的模式证据类型如下 -
- Tire Tracks and Marks
- Impressions
- Fingerprints
每个生物识别数据都包含矢量数据,我们需要破解这些数据以收集完整的证据。
以下Python代码显示了如何从纯文本生成密文 -
import sys
def decrypt(k,cipher):
plaintext = ''
for each in cipher:
p = (ord(each)-k) % 126
if p < 32:
p+=95
plaintext += chr(p)
print plaintext
def main(argv):
if (len(sys.argv) != 1):
sys.exit('Usage: cracking.py')
cipher = raw_input('Enter message: ')
for i in range(1,95,1):
decrypt(i,cipher)
if __name__ == "__main__":
main(sys.argv[1:])
输出 (Output)
现在,检查此代码的输出。 当我们输入简单的文本“Radhika”时,程序将生成以下密文。
Python Forensics - Virtualization
Virtualization是模拟IT系统(如服务器,工作站,网络和存储)的过程。 它只不过是创建任何操作系统,服务器,存储设备或网络进程的虚拟而非实际版本。
有助于模拟虚拟硬件的主要组件被定义为hyper-visor 。
下图说明了使用的两种主要系统虚拟化类型。
虚拟化已经以多种方式用于计算取证。 它以这样一种方式帮助分析人员,即工作站可以在每个调查的有效状态下使用。 通过将驱动器的dd映像作为辅助驱动器附加到虚拟机上,可以实现数据恢复。 同一台机器可以用作恢复软件来收集证据。
以下示例有助于在Python编程语言的帮助下理解虚拟机的创建。
Step 1 - 让虚拟机命名为'dummy1'。
每个虚拟机必须具有最小容量的512 MB内存,以字节为单位表示。
vm_memory = 512 * 1024 * 1024
Step 2 - 必须将虚拟机连接到已计算的默认群集。
vm_cluster = api.clusters.get(name = "Default")
Step 3 - 虚拟机必须从虚拟硬盘驱动器启动。
vm_os = params.OperatingSystem(boot = [params.Boot(dev = "hd")])
在将vms集合的add方法用于虚拟机之前,所有选项都合并到虚拟机参数对象中。
例子 (Example)
以下是用于添加虚拟机的完整Python脚本。
from ovirtsdk.api import API #importing API library
from ovirtsdk.xml import params
try: #Api credentials is required for virtual machine
api = API(url = "https://HOST",
username = "Radhika",
password = "a@123",
ca_file = "ca.crt")
vm_name = "dummy1"
vm_memory = 512 * 1024 * 1024 #calculating the memory in bytes
vm_cluster = api.clusters.get(name = "Default")
vm_template = api.templates.get(name = "Blank")
#assigning the parameters to operating system
vm_os = params.OperatingSystem(boot = [params.Boot(dev = "hd")])
vm_params = params.VM(name = vm_name,
memory = vm_memory,
cluster = vm_cluster,
template = vm_template
os = vm_os)
try:
api.vms.add(vm = vm_params)
print "Virtual machine '%s' added." % vm_name #output if it is successful.
except Exception as ex:
print "Adding virtual machine '%s' failed: %s" % (vm_name, ex)
api.disconnect()
except Exception as ex:
print "Unexpected error: %s" % ex
输出 (Output)
我们的代码将产生以下输出 -
Python Forensics - Network Forensics
现代网络环境的情况是,由于许多困难,调查可能充满困难。 无论您是在响应违规支持,调查内部活动,执行与漏洞相关的评估,还是验证法规遵从性,都可能发生这种情况。
网络编程的概念
以下定义用于网络编程。
Client - 客户端是在个人计算机和工作站上运行的网络编程的客户端 - 服务器体系结构的一部分。
Server - 服务器是客户端 - 服务器体系结构的一部分,为同一台计算机或其他计算机中的其他计算机程序提供服务。
WebSockets - WebSockets在客户端和服务器之间提供协议,该协议在持久TCP连接上运行。 通过这种方式,可以在TCP套接字连接之间(同时)发送双向消息。
WebSockets采用许多其他技术,允许服务器向客户端发送信息。 除了握手升级标头之外,WebSockets独立于HTTP。
这些协议用于验证第三方用户发送或接收的信息。 由于加密是用于保护消息的方法之一,因此保护通过其传输消息的信道也很重要。
考虑以下Python程序,客户端用于handshaking 。
例子 (Example)
# client.py
import socket
# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 8080
# connection to hostname on the port.
s.connect((host, port))
# Receive no more than 1024 bytes
tm = s.recv(1024)
print("The client is waiting for connection")
s.close()
输出 (Output)
它将产生以下输出 -
接受通信通道请求的服务器将包括以下脚本。
# server.py
import socket
import time
# create a socket object
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 8080
# bind to the port
serversocket.bind((host, port))
# queue up to 5 requests
serversocket.listen(5)
while True:
# establish a connection
clientsocket,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
currentTime = time.ctime(time.time()) + "\r\n"
clientsocket.send(currentTime.encode('ascii'))
clientsocket.close()
在Python编程的帮助下创建的客户端和服务器会监听主机号。 最初,客户端向服务器发送关于主机号中发送的数据的请求,服务器接受请求并立即发送响应。 这样,我们就可以拥有一个安全的通信渠道。
Python Forensics - Python Modules
Python程序中的模块有助于组织代码。 它们有助于将相关代码分组到单个模块中,这使其更易于理解和使用。 它包括任意命名的值,可用于绑定和引用。 简单来说,模块是一个由Python代码组成的文件,其中包含函数,类和变量。
模块(文件)的Python代码以.py扩展名保存,并在需要时进行编译。
Example
def print_hello_func( par ):
print "Hello : ", par
return
Import 语句
Python源文件可以通过执行import其他包或第三方库的import语句用作模块。 使用的语法如下 -
import module1[, module2[,... moduleN]
当Python解释器遇到import语句时,它会导入指定的模块,该模块存在于搜索路径中。
Example
请考虑以下示例。
#!/usr/bin/python
# Import module support
import support
# Now you can call defined function that module as follows
support.print_func("Radhika")
它将产生以下输出 -
无论Python代码导入的次数如何,模块只加载一次。
From...import 语句
From属性有助于将特定属性从模块导入当前命名空间。 这是它的语法。
from modname import name1[, name2[, ... nameN]]
Example
要从模块fib导入函数fibonacci ,请使用以下语句。
from fib import fibonacci
定位模块
导入模块时,Python解释器会搜索以下序列 -
当前目录。
如果模块不存在,Python随后会搜索shell变量PYTHONPATH中的每个目录。
如果shell变量位置失败,Python将检查默认路径。
计算取证使用Python模块和第三方模块来获取信息并更轻松地提取证据。 进一步的章节侧重于模块的实现,以获得必要的输出。
Python Forensics - Dshell and Scapy
DShell
Dshell是一个基于Python的网络取证分析工具包。 该工具包由美国陆军研究实验室开发。 该开源工具包的发布于2014年。该工具包的主要重点是轻松进行取证调查。
该工具包由大量解码器组成,如下表所示。
Sr.No. | 解码器名称和描述 |
---|---|
1 | dns 这用于提取DNS相关的查询 |
2 | reservedips 标识DNS问题的解决方案 |
3 | large-flows netflows列表 |
4 | rip-http 它用于从HTTP流量中提取文件 |
5 | Protocols 用于识别非标准协议 |
美国陆军实验室通过以下链接在GitHub中维护了克隆存储库 -
https://github.com/USArmyResearchLab/Dshell
该克隆包含用于安装此工具包的脚本install-ubuntu.py () 。
安装成功后,它将自动构建稍后将使用的可执行文件和依赖项。
依赖关系如下 -
dependencies = {
"Crypto": "crypto",
"dpkt": "dpkt",
"IPy": "ipy",
"pcap": "pypcap"
}
此工具包可用于pcap(数据包捕获)文件,这些文件通常在事件期间或警报期间记录。 这些pcap文件由Linux平台上的libpcap或Windows平台上的WinPcap创建。
Scapy
Scapy是一个基于Python的工具,用于分析和操纵网络流量。 以下是Scapy工具包的链接 -
http://www.secdev.org/projects/scapy/
此工具包用于分析数据包操作。 它能够解码大量协议的数据包并捕获它们。 Scapy与Dshell工具包的不同之处在于向研究者提供了有关网络流量的详细描述。 这些描述已实时记录。
Scapy能够使用第三方工具或操作系统指纹识别进行绘图。
请考虑以下示例。
import scapy, GeoIP #Imports scapy and GeoIP toolkit
from scapy import *
geoIp = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE) #locates the Geo IP address
def locatePackage(pkg):
src = pkg.getlayer(IP).src #gets source IP address
dst = pkg.getlayer(IP).dst #gets destination IP address
srcCountry = geoIp.country_code_by_addr(src) #gets Country details of source
dstCountry = geoIp.country_code_by_addr(dst) #gets country details of destination
print src+"("+srcCountry+") >> "+dst+"("+dstCountry+")\n"
此脚本提供了网络数据包中相互通信的国家/地区详细信息的详细说明。
上面的脚本将产生以下输出。
Python Forensics - Searching
Searching肯定是法医调查的支柱之一。 如今,搜索只能与运行证据的调查员一样好。
当我们在关键字的帮助下搜索证据时,从邮件中搜索关键字在取证中起着至关重要的作用。 了解特定文件中要搜索的内容以及已删除文件中的内容需要经验和知识。
Python有各种内置机制和标准库模块,以支持search操作。 从根本上说,调查人员使用搜索操作来查找诸如“谁”,“什么”,“何处”,“何时”等问题的答案。
例子 (Example)
在下面的示例中,我们声明了两个字符串然后,我们使用了find函数来检查第一个字符串是否包含第二个字符串。
# Searching a particular word from a message
str1 = "This is a string example for Computational forensics of gathering evidence!";
str2 = "string";
print str1.find(str2)
print str1.find(str2, 10)
print str1.find(str2, 40)
上面的脚本将产生以下输出。
Python中的“find”函数有助于在消息或段落中搜索关键字。 这对于收集适当的证据至关重要。
Python Forensics - Indexing
Indexing实际上提供了调查员完整查看文件并从中收集潜在证据。 证据可以包含在文件,磁盘映像,内存快照或网络跟踪中。
索引有助于缩短keyword searching等耗时任务的时间。 法医调查还涉及交互式搜索阶段,其中索引用于快速定位关键字。
索引还有助于在关键字列表中列出关键字。
例子 (Example)
以下示例显示了如何在Python中使用indexing 。
aList = [123, 'sample', 'zara', 'indexing'];
print "Index for sample : ", aList.index('sample')
print "Index for indexing : ", aList.index('indexing')
str1 = "This is sample message for forensic investigation indexing";
str2 = "sample";
print "Index of the character keyword found is "
print str1.index(str2)
上面的脚本将产生以下输出。
Python Forensics - Python Imaging Library
从可用资源中提取有价值的信息是数字取证的重要组成部分。 获取所有可用信息对于调查过程至关重要,因为它有助于检索适当的证据。
包含数据的资源可以是简单的数据结构(如数据库),也可以是复杂的数据结构(如JPEG图像)。 使用简单的桌面工具可以轻松访问简单的数据结构,而从复杂的数据结构中提取信息则需要复杂的编程工具。
Python Imaging Library
Python Imaging Library(PIL)为Python解释器添加了图像处理功能。 该库支持多种文件格式,并提供强大的图像处理和图形功能。 您可以从http://www.pythonware.com/products/pil/下载PIL的源文件http://www.pythonware.com/products/pil/
下图显示了从PIL中的图像(复杂数据结构)中提取数据的完整流程图。
例子 (Example)
现在,让我们有一个编程示例来了解它实际上是如何工作的。
Step 1 - 假设我们有需要提取信息的下图。
Step 2 - 当我们使用PIL打开此图像时,它将首先记录提取证据所需的必要点,其中包括各种像素值。 以下是打开图像并记录其像素值的代码 -
from PIL import Image
im = Image.open('Capture.jpeg', 'r')
pix_val = list(im.getdata())
pix_val_flat = [x for sets in pix_val for x in sets]
print pix_val_flat
Step 3 - 在提取图像的像素值后,我们的代码将产生以下输出。
提供的输出表示RGB组合的像素值,可以更好地了解证据所需的数据。 获取的数据以数组的形式表示。
Python Forensics - Mobile Forensics
对诸如硬盘之类的标准计算机硬件的取证调查和分析已经发展成为一种稳定的学科,并且借助于分析非标准硬件或瞬时证据的技术。
尽管智能手机越来越多地用于数字调查,但它们仍然被认为是非标准的。
法医分析
法医调查从智能手机中搜索接收的电话或拨打的号码等数据。 它可以包括短信,照片或任何其他有罪证据。 大多数智能手机都具有使用密码或字母数字字符的屏幕锁定功能。
在这里,我们将举例说明Python如何帮助破解屏幕锁定密码以从智能手机中检索数据。
手动检查
Android支持使用PIN码或字母数字密码进行密码锁定。 两个密码的限制要求在4到16位或字符之间。 智能手机的密码存储在Android系统中,位于/data/system名为password.key的特殊文件中。
Android存储salted SHA1-hashsum和密码的MD5-hashsum。 可以使用以下代码处理这些密码。
public byte[] passwordToHash(String password) {
if (password == null) {
return null;
}
String algo = null;
byte[] hashed = null;
try {
byte[] saltedPassword = (password + getSalt()).getBytes();
byte[] sha1 = MessageDigest.getInstance(algo = "SHA-1").digest(saltedPassword);
byte[] md5 = MessageDigest.getInstance(algo = "MD5").digest(saltedPassword);
hashed = (toHex(sha1) + toHex(md5)).getBytes();
} catch (NoSuchAlgorithmException e) {
Log.w(TAG, "Failed to encode string because of missing algorithm: " + algo);
}
return hashed;
}
由于散列密码存储在salt file ,因此在dictionary attack的帮助下破解密码是不可行的。 该salt是一个64位随机整数的十六进制表示字符串。 使用Rooted Smartphone或JTAG Adapter很容易访问salt 。
扎根的智能手机
文件/data/system/password.key的转储存储在lockscreen.password_salt键下的SQLite数据库中。 在settings.db ,将存储密码,并在以下屏幕截图中清楚地显示该值。
JTAG适配器
可以使用称为JTAG(联合测试操作组)适配器的特殊硬件来访问salt 。 类似地, Riff-Box或JIG-Adapter也可用于相同的功能。
使用从Riff-box获得的信息,我们可以找到加密数据的位置,即salt 。 以下是规则 -
搜索关联的字符串“lockscreen.password_salt”。
该字节表示盐的实际宽度,即其length 。
这是实际搜索的长度,以获取智能手机的存储密码/引脚。
这些规则有助于获取适当的盐数据。
Python Forensics - Network Time Protocol
用于同步时间的最广泛使用的协议已被广泛接受为实践,其通过网络时间协议(NTP)来完成。
NTP使用用户数据报协议(UDP),该协议使用最短时间在服务器和希望与给定时间源同步的客户端之间传送数据包。
网络时间协议的特点如下 -
默认服务器端口为123。
该协议由许多与国家实验室同步的可访问时间服务器组成。
NTP协议标准由IETF管理,建议标准为RFC 5905,标题为“网络时间协议版本4:协议和算法规范”[NTP RFC]
操作系统,程序和应用程序使用NTP以正确的方式同步时间。
在本章中,我们将重点介绍使用Python的NTP,这可以从第三方Python库ntplib中获得。 该库有效地处理繁重的工作,将结果与本地系统时钟进行比较。
安装NTP库
ntplib可从https://pypi.python.org/pypi/ntplib/下载,如下图所示。
该库借助可转换NTP协议字段的方法为NTP服务器提供简单的接口。 这有助于访问其他键值,例如闰秒。
以下Python程序有助于理解NTP的用法。
import ntplib
import time
NIST = 'nist1-macon.macon.ga.us'
ntp = ntplib.NTPClient()
ntpResponse = ntp.request(NIST)
if (ntpResponse):
now = time.time()
diff = now-ntpResponse.tx_time
print diff;
上述程序将产生以下输出。
在上述程序中计算时间差。 这些计算有助于法医调查。 获得的网络数据与硬盘驱动器上的数据分析根本不同。
时区的差异或获得准确的时区有助于收集通过此协议捕获消息的证据。
Python Forensics - Multiprocessing Support
法医专家通常发现很难应用数字解决方案来分析常见犯罪中的大量数字证据。 大多数数字调查工具都是单线程的,它们一次只能执行一个命令。
在本章中,我们将重点介绍Python的多处理功能,这些功能可以解决常见的取证挑战。
多处理器 Multiprocessing
多处理定义为计算机系统支持多个进程的能力。 支持多处理的操作系统使多个程序能够同时运行。
存在各种类型的多处理,例如symmetric和asymmetric processing 。 下图是指对称多处理系统,通常在法医调查中遵循。
例子 (Example)
以下代码显示了Python编程内部如何列出不同的进程。
import random
import multiprocessing
def list_append(count, id, out_list):
#appends the count of number of processes which takes place at a time
for i in range(count):
out_list.append(random.random())
if __name__ == "__main__":
size = 999
procs = 2
# Create a list of jobs and then iterate through
# the number of processes appending each process to
# the job list
jobs = []
for i in range(0, procs):
out_list = list() #list of processes
process1 = multiprocessing.Process(
target = list_append, args = (size, i, out_list))
# appends the list of processes
jobs.append(process)
# Calculate the random number of processes
for j in jobs:
j.start() #initiate the process
# After the processes have finished execution
for j in jobs:
j.join()
print "List processing complete."
这里,函数list_append()有助于列出系统中的进程集。
输出 (Output)
我们的代码将产生以下输出 -
Python Forensics - Memory and Forensics
在本章中,我们将专注于在Volatility的帮助下研究易失性内存, Volatility是一个适用于以下平台的基于Python的取证框架: Android和Linux 。
易失性内存
易失性存储器是一种存储器,当系统电源关闭或中断时,内容将被擦除。 RAM是易失性存储器的最佳示例。 这意味着,如果您正在处理尚未保存到非易失性存储器(如硬盘驱动器)的文档,并且计算机断电,则所有数据都将丢失。
一般而言,易失性记忆取证遵循与其他法医调查相同的模式 -
- 选择调查目标
- 获取取证数据
- Forensic analysis
用于Android的基本volatility plugins收集RAM dump进行分析。 收集RAM转储进行分析后,开始寻找RAM中的恶意软件非常重要。
YARA规则
YARA是一种流行的工具,它提供了一种强大的语言,与基于Perl的正则表达式兼容,并用于检查可疑文件/目录和匹配字符串。
在本节中,我们将基于模式匹配实现使用YARA,并将它们与实用功能结合起来。 整个过程将有利于法医分析。
例子 (Example)
请考虑以下代码。 此代码有助于提取代码。
import operator
import os
import sys
sys.path.insert(0, os.getcwd())
import plyara.interp as interp
# Plyara is a script that lexes and parses a file consisting of one more Yara
# rules into a python dictionary representation.
if __name__ == '__main__':
file_to_analyze = sys.argv[1]
rulesDict = interp.parseString(open(file_to_analyze).read())
authors = {}
imps = {}
meta_keys = {}
max_strings = []
max_string_len = 0
tags = {}
rule_count = 0
for rule in rulesDict:
rule_count += 1
# Imports
if 'imports' in rule:
for imp in rule['imports']:
imp = imp.replace('"','')
if imp in imps:
imps[imp] += 1
else:
imps[imp] = 1
# Tags
if 'tags' in rule:
for tag in rule['tags']:
if tag in tags:
tags[tag] += 1
else:
tags[tag] = 1
# Metadata
if 'metadata' in rule:
for key in rule['metadata']:
if key in meta_keys:
meta_keys[key] += 1
else:
meta_keys[key] = 1
if key in ['Author', 'author']:
if rule['metadata'][key] in authors:
authors[rule['metadata'][key]] += 1
else:
authors[rule['metadata'][key]] = 1
#Strings
if 'strings' in rule:
for strr in rule['strings']:
if len(strr['value']) > max_string_len:
max_string_len = len(strr['value'])
max_strings = [(rule['rule_name'], strr['name'], strr['value'])]
elif len(strr['value']) == max_string_len:
max_strings.append((rule['rule_name'], strr['key'], strr['value']))
print("\nThe number of rules implemented" + str(rule_count))
ordered_meta_keys = sorted(meta_keys.items(), key = operator.itemgetter(1),
reverse = True)
ordered_authors = sorted(authors.items(), key = operator.itemgetter(1),
reverse = True)
ordered_imps = sorted(imps.items(), key = operator.itemgetter(1), reverse = True)
ordered_tags = sorted(tags.items(), key = operator.itemgetter(1), reverse = True)
上面的代码将产生以下输出。
实施的YARA规则数量有助于更好地了解可疑文件。 间接地,可疑文件列表有助于收集取证的适当信息。
以下是github中的源代码: https://github.com/radhikascs/Python_yara : https://github.com/radhikascs/Python_yara
Python Forensics in Linux
数字调查的主要问题是通过加密或任何其他格式保护重要证据或数据。 基本示例是存储密码。 因此,有必要了解Linux操作系统在数字取证实施中的使用,以保护这些有价值的数据。
所有本地用户的信息大多存储在以下两个文件中 -
- /etc/passwd
- etc/shadow
第一个是必需的,它存储所有密码。 第二个文件是可选的,它存储有关本地用户的信息,包括散列密码。
关于将密码信息存储在文件中的安全性问题出现了问题,每个用户都可以读取该信息。 因此,散列密码存储在/etc/passwd ,其中内容由特殊值“ x ”替换。
必须在/etc/shadow查找相应的哈希值。 /etc/passwd的设置可能会覆盖/etc/shadow的详细信息。
Linux中的两个文本文件每行包含一个条目,条目由多个字段组成,以冒号分隔。
/etc/passwd的格式如下 -
Sr.No. | 字段名称和描述 |
---|---|
1 | Username 该字段由人类可读格式的属性组成 |
2 | Password hash 它由根据Posix crypt函数的编码形式的密码组成 |
如果哈希密码保存为empty ,则相应的用户将不需要任何密码即可登录系统。 如果此字段包含无法通过哈希算法生成的值(例如感叹号),则用户无法使用密码登录。
具有锁定密码的用户仍可以使用其他身份验证机制(例如,SSH密钥)登录。 如前所述,特殊值“ x ”表示必须在影子文件中找到密码哈希。
password hash包括以下内容 -
Encrypted salt - encrypted salt有助于维护屏幕锁定,引脚和密码。
Numerical user ID - 该字段表示用户的ID。 Linux内核将此用户标识分配给系统。
Numerical group ID - 该字段指的是用户的主要组。
Home directory - 新进程以此目录的引用启动。
Command shell - 此可选字段表示成功登录系统后要启动的默认shell。
数字取证包括收集与跟踪证据相关的信息。 因此,用户ID在维护记录时很有用。
使用Python,可以自动分析所有这些信息以获取分析指标,重建最近的系统活动。 通过Linux Shell的实现,跟踪简单易行。
Python Programming with Linux
例子 (Example)
import sys
import hashlib
import getpass
def main(argv):
print '\nUser & Password Storage Program in Linux for forensic detection v.01\n'
if raw_input('The file ' + sys.argv[1] + ' will be erased or overwrite if
it exists .\nDo you wish to continue (Y/n): ') not in ('Y','y') :
sys.exit('\nChanges were not recorded\n')
user_name = raw_input('Please Enter a User Name: ')
password = hashlib.sha224(getpass.getpass('Please Enter a Password:')).hexdigest()
# Passwords which are hashed
try:
file_conn = open(sys.argv[1],'w')
file_conn.write(user_name + '\n')
file_conn.write(password + '\n')
file_conn.close()
except:
sys.exit('There was a problem writing the passwords to file!')
if __name__ == "__main__":
main(sys.argv[1:])
输出 (Output)
密码以pass_db.txt中的十六进制格式存储,如以下屏幕截图所示。 保存文本文件以进一步用于计算取证。
Python Forensics - Indicators of Compromise
妥协指标(IOC)被定义为“法医数据,包括在系统日志条目或文件中找到的数据,用于识别系统或网络上的潜在恶意活动。”
通过监控IOC,组织可以检测攻击并迅速采取行动,防止此类攻击发生,或通过阻止早期攻击来限制损害。
有一些用例,允许查询法医文物,如 -
- 通过MD5查找特定文件
- 搜索实际存储在内存中的特定实体
- 特定条目或条目集,存储在Windows注册表中
上述所有组合在搜索工件方面提供了更好的结果。 如上所述,Windows注册表为生成和维护IOC提供了一个完美的平台,它直接有助于计算取证。
方法 Methodology
查找文件系统中的位置,特别是现在进入Windows注册表。
搜索由取证工具设计的工件集。
寻找任何不良活动的迹象。
调查生命周期
调查生命周期跟随IOC,它在注册表中搜索特定条目。
Stage 1: Initial Evidence - 在主机或网络上检测到危害的证据。 响应者将调查并确定确切的解决方案,这是一个具体的取证指标。
Stage 2: Create IOCs for Host & Network - 在收集的数据之后,创建了IOC,使用Windows注册表很容易实现。 OpenIOC的灵活性为如何制作指标提供了无限的排列数量。
Stage 3: Deploy IOCs in the Enterprise - 一旦创建了指定的IOC,调查员将在Windows寄存器中借助API部署这些技术。
Stage 4: Identification of Suspects - IOC的部署有助于以正常方式识别嫌疑人。 甚至还会识别其他系统。
Stage 5: Collect and Analyze Evidence - 相应地Stage 5: Collect and Analyze Evidence针对嫌疑人的证据。
Stage 6: Refine & Create New IOCs - 调查团队可以根据企业中的证据和数据以及其他情报创建新的IOC,并继续完善其周期。
下图显示了调查生命周期的各个阶段 -
Python Forensics - Implementation of Cloud
Cloud computing可以定义为通过Internet提供给用户的托管服务的集合。 它使组织能够使用甚至计算资源,包括虚拟机(VM),存储或应用程序作为实用程序。
在Python编程语言中构建应用程序的最重要优势之一是它包括在任何平台上虚拟部署应用程序的能力,包括cloud 。 这意味着Python可以在云服务器上执行,也可以在台式机,平板电脑或智能手机等便捷设备上启动。
其中一个有趣的观点是通过生成Rainbow tables创建云基础。 它有助于集成应用程序的单个和多个处理版本,这需要一些考虑因素。
Pi Cloud
Pi Cloud是云计算平台,它将Python编程语言与Amazon Web Services的计算能力集成在一起。
我们来看一个用rainbow tables实现Pi云的例子。
彩虹表
rainbow table被定义为特定于给定散列算法的加密密码的所有可能的纯文本排列的列表。
彩虹表遵循标准模式,创建一个散列密码列表。
文本文件用于生成密码,其中包括要加密的密码的字符或纯文本。
该文件由Pi cloud使用,它调用要存储的主函数。
散列密码的输出也存储在文本文件中。
此算法也可用于在数据库中保存密码,并在云系统中具有备份存储。
以下内置程序在文本文件中创建加密密码列表。
例子 (Example)
import os
import random
import hashlib
import string
import enchant #Rainbow tables with enchant
import cloud #importing pi-cloud
def randomword(length):
return ''.join(random.choice(string.lowercase) for i in range(length))
print('Author- Radhika Subramanian')
def mainroutine():
engdict = enchant.Dict("en_US")
fileb = open("password.txt","a+")
# Capture the values from the text file named password
while True:
randomword0 = randomword(6)
if engdict.check(randomword0) == True:
randomkey0 = randomword0+str(random.randint(0,99))
elif engdict.check(randomword0) == False:
englist = engdict.suggest(randomword0)
if len(englist) > 0:
randomkey0 = englist[0]+str(random.randint(0,99))
else:
randomkey0 = randomword0+str(random.randint(0,99))
randomword3 = randomword(5)
if engdict.check(randomword3) == True:
randomkey3 = randomword3+str(random.randint(0,99))
elif engdict.check(randomword3) == False:
englist = engdict.suggest(randomword3)
if len(englist) > 0:
randomkey3 = englist[0]+str(random.randint(0,99))
else:
randomkey3 = randomword3+str(random.randint(0,99))
if 'randomkey0' and 'randomkey3' and 'randomkey1' in locals():
whasher0 = hashlib.new("md5")
whasher0.update(randomkey0)
whasher3 = hashlib.new("md5")
whasher3.update(randomkey3)
whasher1 = hashlib.new("md5")
whasher1.update(randomkey1)
print(randomkey0+" + "+str(whasher0.hexdigest())+"\n")
print(randomkey3+" + "+str(whasher3.hexdigest())+"\n")
print(randomkey1+" + "+str(whasher1.hexdigest())+"\n")
fileb.write(randomkey0+" + "+str(whasher0.hexdigest())+"\n")
fileb.write(randomkey3+" + "+str(whasher3.hexdigest())+"\n")
fileb.write(randomkey1+" + "+str(whasher1.hexdigest())+"\n")
jid = cloud.call(randomword) #square(3) evaluated on PiCloud
cloud.result(jid)
print('Value added to cloud')
print('Password added')
mainroutine()
输出 (Output)
此代码将生成以下输出 -
密码存储在文本文件中,这些文件是可见的,如以下屏幕截图所示。