恶意代码分析实战 数据加密 lab 13-1 13-2 13-3 常见base64 aes这些都是比较好解密的 实在不行还可以immunity dbg打断点写py脚本解密
Lab13-1
整体功能:向远程主机发送本机gethostname信息,该信息通过base64加密,远程请求的主机域名也被xor加密。
看下代码反编译的情况:
下面函数是从资源文件里提取加密的:www.practicalmalwareanalysis.com
使用了简单的xor加密:
接下来就是发送加密的gethostname:
base64加密的函数:
下面是详细分析:
1. 比较恶意代码中的字符串与动态分析提供的有用信息,基于这些比较,哪些数据可能被加密?
string查看Lab13-01.exe字符串注意到有http字符串,并且%s表示有输出的值。
利用火绒剑监控Lab13-01.exe,可以看到文件正在访问www.practicalmalwareanalysis.com/aGFueHUtUEM=/
推测两个%s表示的正是www.practicalmalwareanalysis.com和aGFueHUtUEM=,但在查看Lab13-01.exe字符串时并没有以上两个,所以推测www.practicalmalwareanalysis.com和aGFueHUtUEM=可能被加密。
分析Lab13-01.exe
首先用peid查壳发现无壳,IDA打开恶意文件。
首先可以看到对函数sub_401300的调用,跟进函数分析。
GetModuleHandleA函数获得Lab13-01.exe的句柄,FindResourceA函数确定Lab13-01.exe文件中名为65h的资源节所在位置。根据对资源的获取函数,推测Lab13-01.exe包含一个资源节,StudyPE查看Lab13-01.exe。
可以看到资源节0065中的内容。但是内容中看不出重要信息,可能已被加密。回到IDA中继续分析。
loc_401357处已将资源加载到进程内存中。继续乡下分析:
LockResource函数所返回的是指向内中资源的指针,在004013A6处被入栈;dwBytes变量是0040135F处SizeofResource函数所返回的资源大小,在004013A2处被入栈。两个参数入栈后调用了sub_401190函数
其中arg_0是第一个参数,既是指向资源的指针;arg_4是第二个参数,是资源的大小;var_4是for循环的计数器。mov al, [edx]获得资源内容;xor eax, 3Bh进行对资源解密操作。OD中在004013A7处下断点步过,查看自解密之后的内容:
观察栈中内容“www.practicalmalwareanalysis.com”,说明对资源节中的内容进行xor eax, 3Bh解密后即为“www.practicalmalwareanalysis.com”。继续回到IDA中分析
在自揭秘操作之后,调用了WSAStartup函数初始化网络。向下分析
在Sleep等待后,将变量var_19C压栈,00401402处判断var_19C就是对资源节内容解密后的内容。使用peid插件KANAL查询加密方式。
可以看出KANAL已经是被出一个BASE64编码,IDA中跳转到4050E8处分析
查看byte_4050E8处交叉引用
在后头看IDA中执行流程
可知程序再sub_4010B1函数中调用sub_401000函数最终引用了BASE64编码。在00401201处获得主机名然后在0040122A处进行加密。OD中比较加密前后主机名
加密前主机名为“hanxu-PC”
加密后主机名为“aGFueHUtUEM=” 。
我自己机器的尝试效果:
和网络中火绒剑监控的一样:
通过PEID加密分析插件看到的!的确是有加密!
分析恶意代码文件Lab13-02.exe
整体功能:定期一段时间获取屏幕截图,将其加密存放在本地文件中。
问题:
1.使用动态分析,确定恶意代码创建了什么?
2.使用静态分析技术,例如xor指令搜索、FindCrypt2、KANAL 以及 IDA嫡插件,查找潜在的加密,你发现了什么?
3.基于问题1的回答,哪些导入函数将是寻找加密函数比较好的一个证据?
4.加密函数在反汇编的何处?
5.从加密函数追溯原始的加密内容,原始加密内容是什么?
6.你是否能够找到加密算法?如果没有,你如何解密这些内容?
7.使用解密工具,你是否能够恢复加密文件中的一个文件到原始文件?
开始分析:
利用procmon监控,运行样本。
能够发现他在当前目录下不断生成大小为5185KB的文件,这些文件的命名以temp开始,以不同的8个十六进制数字结束。
接下来查下壳,能够发现无壳。
顺便就看看有没有加密。
也没有加密。
打开IDA,载入样本,用Findcrypt插件,什么都没有。
查一下XOR指令。
可以看到sub_401739用了很多异或,看看他的关联
我们可以猜测sub_401851与加密有关。
接下来先看main函数
能看到函数里call了个sub_401851,跟过去看看
发现这个函数用了几个API,而且还有sub_401070和sub_40181F。
再往下可以发现这里出现了和生成的文件名有关的部分,显示用了个GetTickCount函数返回从操作系统启动所经过的毫秒数,将其传递下来作为后面函数的参数。还有调用sub_401000函数。
先看一下sub_401070吧
看到这一部分,我们能看出他是截屏的一个功能。完整分析过后可知程序调用了获取用户的桌面,创建bitmap对象,加密放在桌面。
再来看sub_40181F
这里调用了sub_401739,跟进去看看
调用了sub_4012DD后就开始了一大堆异或,看看sub_4012DD
看起来应该是一堆加密过程了,具体咋加密的不管他,掉头回去看sub_401000
能看到里面是一些文件操作。wirteFile 调用之前可能会发现加密函数,加密函数是sub_40181F.
分析到这里,我们大概已经知道这个恶意程序的行为:
定时截取屏幕内容,将内容数据存入一个缓冲区,将缓冲区中的数据加密并写入文件之中。
根据猜想,生成的文件可能是图片格式,我们将生成的文件后缀改为png,但是文件已经加密了无法打开。
接下来进行解密。
解密的话可以分析加密过程编写脚本来进行解密,也可以用OD解密流量,不过我选择直接不执行加密过程。
为了验证猜想,我在这里利用一个取巧的办法,程序有加密函数,那么我们便不让加密函数执行,直接在函数头返回。
OD载入样本,找到加密函数0040181F这个位置。把头部retn掉。
执行程序,把生成的图片打开
能够查看。
当然,还有一种方法,使用immunity debugger脚本功能,因为解密和加密都是同一个函数(如何知道?猜想再验证),所以直接用py脚本进行解密,将待解密文件放在c盘根目录下:
2个断点对应位置:
加密的函数内容:
为啥有
因为:
但是IDA看不出来也是很gg!
这个脚本还不很熟悉,等后面有机会再实战下。
lab 13-03
本次实验我们将会分析lab13-03.exe文件。先来看看要求解答的问题
Q1.比较恶意代码的输出字符串和动态分析提供的信息,通过这些比较,你发现哪些元素可能被加密?
Q2.使用静态分析搜索字符串xor来查找潜在的加密。通过这种方法,你发现什么类型的加密?
Q3.使用静态工具,如FindCrypt2、KANAL识别其他类型的加密机制。发现的结果与搜索字符XOR结果比较如何?
Q4.恶意代码使用哪两种加密技术?
Q5.对于每-种加密技术,它们的密钥是什么?
Q6.对于加密算法,它的密钥足够可靠吗?另外你必须知道什么?
Q7.恶意代码做了什么?
Q8.构造代码来解密动态分析过程中生成的一些内容,解密后的内容是什么?
首先启动wireshark进行监控,然后双击运行lab13-03.exe
可以看到恶意代码尝试通过dns解析域名www.practicalmalwareanalysis.com
并且尝试建立tcp连接,连接到远程主机的8910端口
接下来啊打开IDA进行分析,打开strings子窗口
看到了在wireshark中的发现的域名,下面的字符串疑似与某种加密有关,从字面意义可知,如空密钥,不正确的密钥长度,不正确的块长度等等
Q1.比较恶意代码的输出字符串和动态分析提供的信息,通过这些比较,你发现哪些元素可能被加密?
A1.动态分析发现了一个域名。string窗口的输出中没有可以识别的字符串,可能应用了加密,至于是哪些元素被加密则不好判断。
接着在IDA中搜索xor
结果找到了很多xor,不过我们需要排除用于寄存器清零和库函数相关的xor指令
为了便于我们分析,可以给找到的包含剩下的xor指令的函数分别重命名为s_xor1(2,3,4,5,6)
比如
Q2.使用静态分析搜索字符串xor来查找潜在的加密。通过这种方法,你发现什么类型的加密?
A2. 搜索xor指令发现了6个可能与加密相关的单独函数,但是加密的类型看不出来。
sub_401ac2是第一个,就重命名为s_xor1
我们使用IDA的find crypt插件来查找
输出如下
可以看到是Rijndeal算法,其实就是AES
我们先去第一处看看
查看交叉引用
注意xor2,xor4通过加密常量Te0关联
再看看解密常量
查看交叉引用
xor3,xor5通过解密常量Td0关联 ==》这个有经验主义的成本,要判断哪些是加密和解密。
使用peid的krypto analyzer插件的结果如下
上图的S,S-inv参考了S-box结构,它是一些加密算法的基本机构
和IDA识别出的加密算法是一样的
Q3.使用静态工具,如FindCrypt2、KANAL识别一些其他类型的加密机制。发现的结果与搜索字符XOR结果比较如何?
A3.都识别出了高级加密标准AES算法(Rijndael算法),它与识别的6个XOR函数相关。
我们知道了s_xor2,s_xor4和AES加密相关,而s_xor3,x_xor5与AES解密相关
看看s_xor6
这里有一个循环,004039e8处的xor指令表明该函数是用于进行XOR加密的
这里的arg_0是一个指针,指向用来进行转换的原缓冲区,arg_4也是指针,指向用来提供异或原数据的缓冲区
在循环中则是通过004039f2,004039f8指令对指向两个缓冲区的指针自增
通过004039cc对计数器变量var_4自增
接着查看s_xor6的交叉引用
先跟入sub_40352d,查看xrefs from
从上图中可以看到s_xor6和s_xor2,s_xor4相关
都是加密相关的,所以可以给sub_40352d重命名为s_encrypt
还有s_xor1不知道是做什么的,可以去看看
通过cmp将arg_0与0比较。如果不正确,往左边走
会报错空密钥
如果arg_0通过检测,则往右走
会检测arg_8是否正确,如果错误,往左走
会报错不正确的密钥长度
如果arg_8正确,往右走
此时会检测arg_c
如果错误,则往左
会报错不正确的块长度
那么也就是说s_xor1是密钥的初始化代码
那么s_xor1和之前那几个函数有什么关系呢
可以查看交叉引用
跟入main函数
在调用s_xor1之前,存在unk_412ef8的引用,00401890通过ecx将这个偏移量传入s_xor1
我们看看unk_412ef8的其他引用
跟入第三处
可以看到,00401429将unk_412ef8的偏移量载入ecx
而随后就是s_encrypt的调用
可知unk_412ef8是一个表示AES加密器的C++对象,并且s_xor1是加密器的初始化函数
前面分析的时候说过,比较arg_0参数,如果失败则会提示空密钥,说明arg_0参数就是一个密钥。
在main中调用s_xor1的地方如下
最近的一个push是字符串。所以我们可以认为这个字符串被用于进行AES加密
我们来回顾本次AES的流程
先用过交叉引用来到调用s_encrypt的地方
可以看到对s_encrypt的调用是在WriteFile之前
在ReadFile之后
而s_xor1是AES初始化函数,会在进程启动时执行
s_xor1设置的AES密码就是之前看到的那串字符串
而我们之前在strings窗口还看到
联想到我们之前分析过的,这里可能存在base64
Q4.恶意代码使用哪两种加密技术?
A4.恶意代码使用AES和自定义的Base64加密。
Q5.对于每种加密技术,它们的密钥是什么?
A5. AES的密钥是ijklmnopqrstuvwx, 自定义的Base64 加密的索引字符串是:CDEFGHIJKLMNOPQRSTUVWXYZABcdefghi jklmnopqrstuvwxyzab0123456789+/.
查看对其的引用
跟入sub_40103f查看其交叉引用
跟入sub_401082查看交叉引用
跟入StartAddress
可以看到sub_401082是在ReadFIle和WriteFile之间被调用的,这和我们前面分析的AES很像
前面我们知道s_encrypt是在sub_40132b处被调用的
查看其交叉引用来到sub_4015b7
可以看到sub_10432b是一个新线程的开始,这个新线程使用CreateThread创建,所以可以给sub_40132b重命名为aes_thread
传递给线程的参数保存在lpParameter,也就是var_58中
00401826处var18移入var_58
0040182c处arg_10移入var_54
00401835处dwrord_41336c移入var_50
然后跟进aes_thread看看这些参数在函数中的流程
先看ReadFile
其参数hFile来自var_BE0
往上回溯,可知其来自该函数的唯一参数
回到上层函数
可以看到唯一的lpParameter参数来自var_58,或者说来自var_18
在看看ase_thread的WriteFile
去参数hFIle来自var_BE0+4,就是var_54或者说是arg_10
我们看到var_58和var_18持有一个管道的句柄,并且这个管道的与一个shell命令的输出相连接
命令hSourceHandle通过DuplicateHandle复制到shell命令的标准输出和标准错误
这条shell命令由CreateProcess启动
而var_54或者说arg_10往前回溯
看到是sub_4015b7的唯一参数
查看交叉引用来到main
如下所示
可知其参数来自ebp+s,而它是用connnect调用创建的一个网络套接字
那么我们也就知道了,aes_thread用于读取shell命令的输出结果,在写入网络套接字之前加密它
而base64加密函数也在一个由他们宿主进程启动的函数中使用,所以我们猜测base64线程会读取远程套接字的内容作为输入,经过解密后,再将结果发送作为命令shell的输入
Q6.对于加密算法,它的密钥足够可靠吗?另外你必须知道什么?
A6.对于自定义Base64加密的实现,索引字符串已经足够了。但是对于AES, 实现解密可能需要密钥之外的变量。如果使用密钥生成算法,则包括密钥生成算法、密钥大小、操作模式,如果需要还包括向量的初始化等
Q7.恶意代码做了什么?
A7.恶意代码使用以自定义Base64加密算法加密传入命令和以AES加密传出shell命令响应来建立反连命令shell。
我们已经知道了程序中有两种类型的加密。
先看看如何解密base64
脚本如下(1.py),这里是假设截取到网络通信的部分信息为BInaEi==
运行后得到解密结果为dir
也就是说攻击者尝试发送的是一个shell命令dir,用于列目录
再解密AES
假设通过wireshark捕获到的加密内容为
解密脚本如下
raw是我们捕获到的原始内容
2处是删除字符串中的空格,并将16进制转为2进制
3处是我们在IDA中找到的密钥
4处解密
运行后得到的解密结果为
Q8.构造代码来解密动态分析过程中生成的一些内容,解密后的内容是什么?
A8.如何解密内容的具体过程,请查看上文,这里不再复述。