1625-5 王子昂 总结《2017年12月23日》 【连续第449天总结】
A. JarvisOJ-EvilExe
B.
挑战:《恶意软件分析》
赛题背景: 员工小A收到了一封邮件,带一个文档附件,小A随手打开了附件。随后IT部门发现小A的电脑发出了异常网络访问请求,进一步调查发现小A当时所打开的附件其实是一个伪装成word文档的恶意可执行文件。
赛题描述: 请在试着分析evil.exe和其所下载的x.jpg, 从中找出key.
评分标准: 密钥正确则可进入下一题。
打开x.jpg查看一下,发现是乱码
那么还是分析evil.exe吧
首先查壳,ExeInfoPE认为有可能是UPX
拿UPX脱壳失败,只能乖乖手脱
ESP定律轻松解决,dump下来拖入IDA进行分析
首先可以确定它进行了联网,那么一定调用了相关的函数
到Imports导入函数列表查看
最下面几个InternetOpenUrl很明显就是连接网络的函数,跟过去
发现确实是在下载x.jpg
查看调用,发现在WinMain函数中
下载的内容放在v8中,根据指针可以发现在Decrypt函数中引用了它
发现在Decrypt函数中进行了异或解码,异或的值来自于v6,也就是InitKey函数中由常数0x4A8754F5745174进行初始化的Key数组
初始化过程就是从低向高循环取1个字节再加i
生成长度为256的表
解码过程中还进行了对Key的变换,来进一步增加难度。不过由于提供的是解码函数,因此只需要照样操作即可
之后在ExecShellcode函数中,再次对data进行了一次异或解码
data[i] ^= data[i]+i
最后直接跳转执行
最简单的方法就是修改Dns,搭建本地服务器来传递x.jpg,在函数中正常解码,通过动态调试来查看Shellcode
复杂一点的方法就是重现算法,解码x.jpg并反汇编Shellcode
前者除了搭服务器麻烦点外其他都很简单,正常下断点调试即可,因此下面给出后者的脚本
# InitKey
a = 0x4A8754F5745174
key = [0 for i in range(8)]
for i in range(256):
key.append((((a>>(i%8*8))+i)&0xff))
f = open("x.jpg", "rb")
data = f.read()
f.close()
# Decrypt
new_data = b""
j = 0
print(data)
for ii in range(len(data)):
i = (ii+1)%256
j = (key[i] + j) % 256
key[i], key[j] = key[j], key[i]
new_data += bytes((((data[ii] ^ key[(key[i] + key[j]) % 256])^ii)%256, ) )
print(new_data)
f = open("decrypt.jpg", "wb")
f.write(new_data)
f.close()
这样就能得到Shellcode了
十六进制查看发现有明文字符串
每4个字符前有一个0x68,即汇编的push
并且由于push一次只有4个字符,因此顺序还有点反人类
再写下脚本提取(续在刚才的脚本之后)即可
flag = []
i = 0
while(i<len(new_data)):
if(new_data[i]==0x68):
flag.append(new_data[i+1:i+5])
i += 3
i += 1
print(flag[::-1])
for i in flag[::-1]:
print(str(i)[2:-1], end='')
C. 明日计划
看书OTZ