在写完上篇后,一直想写个脚本来帮助我们进行取证分析,我想取证现场不可能真的对着一条一条指令去找寻证据吧。。。其实他们都是在现场将磁盘镜像进行拷贝的,这样尽最大化程序不去破坏证据~但是将镜像拷回去还是要进行分析的。。因此我写了一个python脚本,来帮助我能够快速的进行计算机取证~
这里我一共写了七个功能:文件使用记录、最近输入的url地址、启动项、曾使用的U盘名、系统端口、系统账号、无线历史记录,有的可能大家在cmd下就能够运行,但是一个脚本能跑的事干嘛自己去一条指令一条指令的敲呢~目前只想到了上述比较实用的七条指令,主要编程上的话,有对注册表的操作和对cmd命令的调用分析等,如果想要学习这两种编程操作的话,可以重点mark下~
代码会在最后贴出,大概200行,但是其中有很多代码是重复的,这里我没用函数去写是因为虽然都是对注册表的操作或是对cmd的调用,但是每次调用都是其唯一性,就像点名一样,虽然都是点名,但是每个人的名字性别都不一样,调用时也是,每次操作都不可能说跟前面完全一样,其实大概的复制粘贴也是很快~
这里重点讲几点编程中遇到的问题
1.utf16进制编码
这个我百度了各种办法,依然对x开头的这种16进制编码无能为力。。。
如果有人知道,敬请留言~
2.注册表的操作
注册表的操作大体步骤是一样的,都是通过HKEY的键值来调用,但是在调用过程中我发现如果这个注册表地址存在空格,会出现windows error[2]的错误,如”Windows NT”,这之前就有一个空格,百度也没搜到什么好的解决办法。。。这儿error[2]大意就是找不到指定的路径
3.cmd的调用
在这个cmd调用可能卡了有半天,程序总共也就写了一天。。百度到常用的有三种办法
①os.system(‘dir’)
这条命令只会输出执行的cmd命令,甚至都不用print,直接输出,但是我们需要对输出的命令进行分析,必须得到它的返回值,因此在这里不考虑这个函数
②os.popen(‘dir’)
好了,这个据说可以解决上述无返回值的办法,但是经过实际测试一开始怎么试都没有返回值,,就在我现在测试的时候,我发现了这条命令的正确打开姿势。。。
1
2
3
4
5
|
#coding:utf-8
import os
shell=os.popen(‘netstat -ano’)
for line in shell:
print line
|
返回值很正常,好像比subprocess.Popen还好用。。。好吧。。
③subprocess.Popen(‘netstat -ano’,shell=True,stdout=subprocess.PIPE)
这个函数主要是创建一个进程去访问subprocess,但是返回值是通过一个管道来传输给我们的,因此过程可能会稍微复杂些,并且在创建完进程后需要我们去释放进程,另外这个stdout参数如果不输的话,那就没有返回值,,在这里疑惑了好久。。。
另外我们读取返回值与上述方式相同,它返回的是一个列表(list)
具体用法参见下面的代码吧。。全是用这个subprocess.Popen()写的。。
最后附上代码(python2.7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
#-*-coding:utf-8-*-
import _winreg
import os
import subprocess
def namelist(string):
string=string.replace(”’,”)
string=string.replace(‘ ‘,”)
#这个函数主要是字符串进行处理
loca=string.find(r‘x00x00’)
#十六进制文件名的结尾标志x00x00
#print loca
return string[:loca].replace(‘\x00’,”)
#返回结束标志前的文件名
fp=open(‘forensics.txt’,‘w’)
key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,r‘SoftwareMicrosoftWindowsCurrentVersionExplorerRecentDocs’)
#注册表文件使用记录的位置
i=0
fp.write(‘一、最近的文件使用记录:n’)
try:
while True:
#没有其他办法获取所有键值,只能遍历
name, value, type = _winreg.EnumValue(key, i)
#读取键值中的信息
keyvalue=str(repr(value))
#这里的repr()是将内存中的内容转化为编译器能够识别的内容
#print i,”,namelist(keyvalue)
fp.write(str(i))
fp.write(‘ ‘)
fp.write(namelist(keyvalue))
#经过我们的处理后,写入最近使用的文件名
fp.write(‘n’)
i+=1
except:
print ‘文件使用记录已写入文件!’
fp.write(‘n’)
fp.write(‘二、最近Internet Explorer输入的url地址:n’)
key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,r‘SoftwareMicrosoftInternet ExplorerTypedURLs’)
#这里同样是利用注册表,取证分析的是IE浏览器曾经输入的url地址
j=0
try:
while True:
name, value, type = _winreg.EnumValue(key, j)
keyvalue=namelist(str(repr(value)))
#与上述步骤一样,不多说
keyvalue=keyvalue.replace(‘u’,”)
#可能是unicode编码,在地址头总是有个u的标志,将这个标志去掉
fp.write(str(j))
fp.write(‘ ‘)
fp.write(keyvalue)
#写入url地址
fp.write(‘n’)
j+=1
except:
print ‘最近输入的url地址已写入文件!’
fp.write(‘n’)
fp.write(‘三、系统启动项:n’)
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,r‘SoftwareMicrosoftWindowsCurrentVersionRun’)
#启动项分为永久启动还有一次启动,这里只讨论永久启动项
m=0
try:
while True:
name, value, type = _winreg.EnumValue(key, m)
keyvalue=namelist(str(repr(value)))
keyvalue=keyvalue.replace(‘u’,”)
#同样开头有u标志,做replace处理
fp.write(str(m))
fp.write(‘ ‘)
fp.write(keyvalue)
fp.write(‘n’)
m+=1
except:
print ‘启动项已写入文件!’
fp.write(‘n’)
fp.write(‘四、曾经接入过的U盘:n’)
open_key=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,r“SystemControlSet001EnumUSBSTOR”)
#这里取证分析的是曾经插入电脑的u盘设备
#这里我获取的是USBTOR注册表下的所有目录名称
#因为目录名称即为U盘名,因此不用获取键值
countkey=_winreg.QueryInfoKey(open_key)[0]
#获取目录数目
ulist=[]
for i in range(int(countkey)):
name=_winreg.EnumKey(open_key,i)
ulist.append(name)
#将目录名添加到列表中
_winreg.CloseKey(open_key)
for i in range(len(ulist)):
fp.write(ulist[i])
#将u盘名写入文件里
fp.write(‘n’)
print ‘曾使用的U盘名已写入文件!’
fp.write(‘n’)
fp.write(‘五、系统端口号:n’)
#从这里开始,我主要使用的是cmd命令的调用
port=[]
shell=subprocess.Popen(“netstat -ano”,shell=True,stdout=subprocess.PIPE)
#这里我使用的是subprocess.Popen()函数,主要它可以调用返回值
#这里的stdout一定要加,不然返回值获取不到
shell=shell.stdout.readlines()
#按行读取
for line in shell:
line=line.strip()
#删去字符串前后的空格
#print line
lineloc=line.find(“0.0.0.0”)
#寻找本地端口
if lineloc!=–1:
#find存在返回值,若未找到,值为-1
lineloc+=8
#+8是为了跳过0.0.0.0:这个前缀
portnum=int(line[lineloc:lineloc+5].strip())
#端口号最大65535,即最大五位数
if portnum!=0:
#实际测试本地端口有环回接口,这些接口不做考虑
port.append(line[:3])
port.append(portnum)
for i in range(len(port)):
#print port[i]
fp.write(str(port[i]))
fp.write(‘ ‘)
if i%2==1:
fp.write(‘n’)
#因为端口号之前会标记TCP还是UDP,因此每写一个TCP/UDP和端口就换行
print ‘系统端口已写入文件!’
fp.write(‘n’)
fp.write(‘六、系统账号:n’)
sysuser=subprocess.Popen(“net user”,shell=True,stdout=subprocess.PIPE)
sysuser_list=sysuser.stdout.readlines()
#同上述
flag=False
for line in sysuser_list:
line=repr(line.strip())
#这里在实际获取中得不到系统账号
#因此只能用repr()进行转化
if “Administrator” in line:
flag=True
#开始进行写入
if r“xc3xfc” in line:
flag=False
#这是命令的utf16进制编码,尚未想到办法转化
#在查询完系统用户后,会有一个”命令成功完成。”,以这个作为终止条件
if flag==True:
fp.write(line.replace(”’,”))
fp.write(‘n’)
#写入Administrator开始到结束中间的用户
print ‘系统账号已写入文件!’
sysuser.kill()
fp.write(‘n’)
fp.write(‘七、无线网络历史记录:n’)
wirelesscommand=”‘for /f “skip=9 tokens=1,2 delims=:” %i in (‘netsh wlan show profiles‘) do @echo %j | findstr -i -v echo | netsh wlan show profiles %j key=clear’”
#这里的cmd命令可以查询所有曾经连接的无线网络信息
wireless=subprocess.Popen(wirelesscommand,shell=True,stdout=subprocess.PIPE)
wireless_list=wireless.stdout.readlines()
ssid_name=0
ssid_passwd=0
for line in wireless_list:
line=repr(line.strip())
#repr()转化为可以输出的字符串
#print line
if r‘SSID xc3xfbxb3xc6’ in line :
#这里同样是utf16进制编码,其实中文为”SSID 名称”
line=line.replace(r‘SSID xc3xfbxb3xc6’,”)
line=line.replace(‘:’,”)
line=line.replace(r‘xa1xb0’,”)
line=line.replace(r‘xa1xb1’,”)
line=line.replace(”’,”)
#将获取的无线网络名称进行字符串处理
#print line.strip()
ssid_name+=1
if ssid_name–ssid_passwd>=2:
fp.write(‘n’)
fp.write(line.strip())
if r‘xb9xd8xbcxfcxc4xdaxc8xdd’ in line :
#这里的16进制编码中文为”关键内容”,一般情况下无线网路密码均在这行
line=line.replace(”’,”)
line=line.replace(r‘xb9xd8xbcxfcxc4xdaxc8xdd’,”)
#对无线网密码这行进行处理
#print line
ssid_passwd+=1
fp.write(line)
#这里在将无线网ID、密码写入文件时会出现这样一种状况,只有SSID名称,没有密码
#因此可能会造成写入文件,一直写到无线网密码才转行,而前面可能堆积了很多没有密码的SSID 名称
#这里给名称和密码做数字标记,当名称连续写入时作转行处理
print ‘无线历史记录已写入文件!’
wireless.kill()
#将查询无线网信息的subprocess开启的进程关闭(前面很多进程未关闭)
fp.close()
#关闭文件
|
这篇没有技术亮点,就算给那些小白站长一个简易的搭建教程吧~ 有人可能会说我们个人网站要搭建企业邮箱干嘛(首先你得有个域名)。。可能原先你的邮箱是qq号@qq.com,但是搭建之后,你可以跟别人说你的邮箱是xx@域名.cn 瞬间给人感觉就不一样了。。。对吧。。。…
请登录后发表评论
注册