原程序分析
样本下载链接
基本文件信息
ExeInfo 查看文件信息,PE32位且有壳
Ollydbg 入口点代码如下
脱壳后单步跟到OEP,dump内存修复IAT
,成功脱壳后用 Die 查看编译语言为 Delphi7
IDA 和 OD 的入口代码
反沙箱手段
- 消息循环
复杂的消息循环,使用了定时器消息,以及自定义 SendMsg,发送大量消息,使程序的运行时间延长
- 设备上下文
长时间消息循环到达核心代码区,里面又有许多的动态解密函数以及大量的GetDC
和GetStockObject
,既消耗了一定的时间又消耗了大量的内存资源
- Sleep
最关键的手段还是一个 Sleep(),Sleep了4分钟
释放文件
- Call下断
程序的很多代码都是动态解密的,不用跟具体的解密过程,直接在 call 跳转时下断即可。如图在释放文件的关键call下断
,注意先 Patch 掉之前的 Sleep
- OD粗略分析
F7 跟过去分析,发现先是获取了一些 API,然后创建一个进程,再是写入数据到子进程
- IDA详细分析
使用ODScript的dma指令dump
这段内存,然后IDA打开静态分析!先是GetProcAddress
获取多个 API 的地址,然后CreateProcess
创建自身路径所在的一个进程,传入CREATE_SUSPENDED
使其挂起,利用ZwUnmapViewOfSection
卸载原来所有区段以及RtlZeroMemory
将内存区域置0,VirtualAllocEx
配合WriteProcessMemory
写入新的数据,利用SetThreadContext
和ResumeThread
修改程序的入口点,且恢复挂起进程运行
Tips:dma指令很简单的: "dma start,size,path"
提取病毒体
在WriteProcessMemory
下断,发现写入的是一个完整的 PE 文件
利用 dma 指令提取了总共9段数据,然后新建 PE 文件,手动对齐文件偏移,更改节区的正确偏移量以及节区的可执行属性,最后提取出了病毒体!P.S.之后我用PCHunter提取出整段内存然后再去对齐偏移也是可以的
第一部分总结
原程序首先是加了壳,然后拥有大量的混淆手段,如图用ProcessMonitor
检测到只会读取某些注册表的值并没有写注册表,更没有其它危险的操作,因此能过很多的杀软!又使用了Sleep
等延时手段过掉很大一部分的沙箱分析,再者程序执行核心病毒的手段也很隐蔽,利用傀儡进程写入新的PE文件并更改入口点执行,让核心恶意代码很难被杀软检测到
病毒体分析
基本文件信息
PE32位程序,总共8个节区,有个自写的壳
脱壳文件信息
这壳好脱,简单的异或加密壳,3个jmp eax
下断即可到 OEP,然后dump以及修复IAT
,找到的 OEP 如下
脚本去花
脱了壳之后拖入 IDA 发现 F5 失效,因为代码的每个jnz和jz
之后有一段垃圾指令,干扰了 IDA 等反汇编工具的汇编,写了个IDAPython
去除花指令之后就能够反编译了,代码如下
def patch_junkcode(addr):
data = list(get_bytes(addr,4))
if(ord(data[0]) == 0x75 and ord(data[1]) == 0x5 and ord(data[2]) == 0x74 and ord(data[3]) == 0x3):
for i in range(4,10):
patch_byte(addr+i,0x90)
base = 0x401000
len = 0x414C00 - base
for i in range(len):
patch_junkcode(base+i)
print 'Finished!'
病毒执行流程
- 关闭指定进程
遍历系统进程,关闭"msftesql.exe","sqlagent.exe","sqlbrowser.exe"等多个特定进程
- 打开互斥体
打开一个互斥体,同步与父进程的内存数据操作
- 要求操作系统Win7以上
使用VerifyVersionInfoW
函数判断操作系统大于Win7
,否则退出程序
- 要求用户权限Low以上
使用GetSidSubAuthority
函数判断当前用户的权限在Low
以上
- Win7以及Win8提权
先是创建位图写入数据,其实数据是之后的shellcode
,这么做是为了隐蔽这段 shellcode
获取 shellcode,调用ZWQueryIntervalProfile
提升当前用户权限为系统权限,提权原理相关链接
- Win10提权
判断操作系统为Win10
,利用不久前Task Scheduler
的一个0day
提权,先是获取StartXpsprintJob
的地址,提权原理相关链接
之后链接到printconfig.dll
来触发漏洞,然后提升为系统权限
- 创建进程运行自身
判断操作系统大于 Win7 以及用于权限大于 Low 之后,获取自身完整路径,使用GetShortPathNameW
来避免Unicode
路径的影响,之后利用wmic
传入路径再次启动自身
- 检查区域
通过键盘布局检查区域,某些区域不会执行之后的代码,直接会删掉自己然后退出
通过默认的语言判断区域
- 创建互斥体
一堆花里胡哨的操作,就为了创建一个互斥体!好像作者在嘲讽 ahnlab,这个不太了解
- 解密必要数据
解密了一些数据,之后初始化 Key 的时候用到了
- 查询系统信息
通过注册表检查了当前用户组,所在地区,操作系统,系统版本号,CPU信息,以及磁盘类型和磁盘容量
,最重要的是查找了一些常见的杀毒进程
,但仅仅是查找
- 生成随机字符
使用CryptGenRandom
生成随机数,运算后得到几个宽字符,取六个之后转换为大写,拼接到文件名。P.S.文件名就是指导你付款的那个文件的名称,诸如:TZYLVF-DECRYPT.txt
- 生成公私钥对
使用CryptGenKey
生成RSA
的公私钥对,之后用CryptExportKey
导出到内存中
- 公私钥对写入注册表
创建HKEY_LOCAL_MACHINE\\SOFTWARE\\keys_data\\data
再创建public
和private
,将之前的公钥和公私钥对分别写入这两个子键中
- 解密说明信息
解密出之后要写入XXXXXX-DECRYPT.txt
中的字符串,相当于给用户的说明书
- 开启线程准备加密文件
第一个线程会遍历局域网共享文件
第二个线程会遍历本地有效磁盘以及移动存储设备
- 采用的遍历方法
遍历局域网与遍历本地采用的方法都是相同的,先判断磁盘的有效性,有效则进行下一步遍历!下一步则必须先满足不是.
以及..
,然后获取当前目录的属性,是文件夹的话则递归遍历,SQL目录会进行单独处理,直到遍历到文件则利用之前的 RSA 公钥加密
- 创建说明文件
之前的说明书内容一直在内存中,尚未写入到文件。在每个目录遍历开始时就在当前目录建立一个文件,文件名就是之前的随机字符,然后将内存中的说明书写入文件!除此之外还会建立一个.lock
文件用于记录加密时的时间
- 加密白名单
加密的白名单主要有三个,一是特定目录下的文件不加密,诸如:Program Files,Windows,Boot等系统目录
第二个就是特定的后缀不加密
,动态才能看得到
第三个就是特定的文件不加密
- 执行加密
当遍历到非白名单文件时,便开始加密文件
- 删除卷影拷贝
加密完成后,删除Shadow Copy
,防止普通用户恢复删除的未加密原文件
- 设置桌面背景
先创建位图再写入颜色数据,之后新建文件写到文件中,文件在Temp
目录下,最后使用SystemParametersInfoW
设置该图片为桌面背景
- 发送POST请求
创建一个线程,先是解密出网址信息
然后随机选取字符串拼接网址
我测试时拼接的字符串是http://www.2mmotorsport.biz/includes/pics/zurukafu.jpg
,最后向这个网址发送一个POST请求
- 删除自身
病毒加密文件完成后会调用cmd延时5s
再删除自己
第二部分总结
上述的执行流程是病毒体的顺序执行流程
,这个勒索病毒主要是释放时非常隐蔽不好定位,dump 出的病毒体也有花指令影响静态分析,不过 IDAPython 能去除花指令!虽然如此这病毒的主体还是如此复杂,各种判断使得病毒的抗干扰性异常强大
,可以运行在 Windows 不同的版本以及运行在不同的国家!一个字形容:强!