对某勒索病毒样本的分析

文件MD5: 6735d02b856b0e7fffefdfc940843d74

IDA载入样本 发现所有函数都是白的 没有发现什么可疑信息

运行 用行为检测工具 发现样本创建了一个子进程 所有行为都是在子进程中完成

下面来看样本的行为

CreateProcess函数创建子进程

子进程是以挂起形式创建的(在挂起状态下 OD是无法附加进程的)

在当前内存申请一段空间

获取进程上下文

从子进程中读内存到当刚才申请的空间

利用ZwUnmapViewOfSection取消子进程的内存映射

第二参数为0x400000 是取消0x400000处的内存映射

在子进程0x400000处开辟0x13000字节大小的空间(这个数据在下面会用到)

利用多次WriteProcessMemory向子进程0x400000后的内存写数据,实际是在每次循环将一个section写入

设置进程上下文

跟到context结构体中看 EP为0xBO处的数据 0x408665

恢复进程

到此为止 外壳程序的任务已经完成 由子进程完成恶意代码操作

其实外壳程序完成了一种代码注入操作 只是和常见的注入方式不同

来总结一下外壳程序到底做了什么

1. 通过给CreateProcess传递CREATE_SUSPENDED参数来创建一个处于挂起状态的进程。(这里称新进程为进程B)

2. 通过调用GetThreadContext来获取被挂起进程(进程B)的CONTEXT。

3. 通过调用ZwUnmapViewOfSection来取消进程B的映像映射。

4. 通过VirtualAllocEx在进程B中分配足够的空间。

5. 通过WriteProcessMemory将恶意代码写到进程B刚分配的空间中

6. 通过调用SetThreadContext来设置线程的上下文。

7. 通过调用ResumeThread来执行被挂起的进程。

所以到现在为止,是没有办法直接对子进程进行调试的,因为OD无法附加挂起的进程,所以只能选择dump的方式,在对子进程的Write操作结束之后,进程恢复之前,将子进程dump下来

用LoadPE选择对应的PID

选择部分dump

地址和大小是刚才VirtuallAllocEx的参数

因为此时dump下来的文件是解压的 所以要修改对齐粒度和偏移 并且要把EP修改成刚才SetThreadContext设置的

并将所有区段的文件偏移修改为和内存偏移相同的值 并保存

保存 然后可以直接对该文件进行分析来分析实际的恶意行为

下面是实际的恶意行为分析

使用FindFirstFile和FindNextFile对硬盘进行遍历

根据dwFileAttributes

判断是文件还是文件夹

附上文件属性

 

如果为0x10则为文件夹

这里有个问题 为什么要用&而不用==

我在网上找到了答案

但是当程序运行起来的时候却发现有一些文件夹是会忽略掉的,并没有被当作文件夹处理。而且在Debug的时候通过跟踪dwFileAttributes可以看到它的值会在16与32之间出现,所以使用“==”来判断一个目标是否为文档或目录是出现问题。

为文件夹时继续递归该函数0x407B98继续搜索

如果不是文件夹 而且属性不是删除属性 继续向下判断

在0x407872函数中判断文件类型

在0x406622函数中将所有文件类型解压出来

在这里比较文件类型

所有加密类型大体如下

对于符合加密类型的文件在0x407984函数中进行加密操作

利用CreateFile打开文件

将文件内容映射到内存

执行加密操作的地方 每次加密0x10个字节

具体的加密函数

具体加密过程我就不分析了……..密码学是真渣

取消映射并回写

将加密后的文件用MoveFile改名

在目录下所有文件都被加密之后 调用两次0x4077D8处的函数 其中一个写key 另一个写勒索信息

所有key相关的在0x406622函数中

总结一下,其实写这个样本的分析是因为这种自身代码注入的行为很有意思,并且对于调试也很有针对性,算是见过的比较有趣的一个样本,所以记录下来方便以后遇到相同的问题时来解决。

发表评论

电子邮件地址不会被公开。 必填项已用*标注