Emotet分析
编写启动器方便调试。
#include <iostream>
#include<windows.h>
typedef int(WINAPI* fnRunDLL)();
fnRunDLL My_RunDLL;
int main()
{
HMODULE hModule = LoadLibraryA("C:\\Users\\xiao\\Desktop\\samples\\1.dll");
My_RunDLL = (fnRunDLL)GetProcAddress(hModule, "Control_RunDLL");
My_RunDLL();
return 0;
}
样本经过控制流平坦化和大数运算混淆阻碍样本逻辑的分析
控制流平坦化:使得程序反编译为复杂的循环结构和选择结构
大数运算混淆:
样本没有导入函数,通过遍历内存加载的模块(peb)和其导出函数的名称,计算hash,和存储的hash对比,得到对应的API函数地址。
github下载ida脚本使得反编译更可读。
通过对MY_GetProcAddr函数下断,可以得到动态调用的所有函数的名称和地址。2410
MY_RtlAllocateHeap:
解密函数内调用MY_RtlAllocateHeap。对此解密函数下断可以得到解密出的内容。
解密出dll名称,加载dll
加载并初始化 CNG 提供程序,生成大小4000h的随机数后关闭算法提供程序。
将自身作为服务,
获取自1601年1月1日起,到现在的时间,如果时间与v9相差一周以上,则返回1 否则返回值为0。
时间相差一周以上:
遍历进程,获取PID,进而获取进程的完整路径,根据路径获取程序名
获取机器名,c根目录下磁盘驱动器信息,snprintf拼接
设置事件对象来通知等待线程发生事件,创建线程,线程函数sub_5BEC27检查当前目录下文件改动的情况。
sub_5BEC27
线程会通过ReadDirectoryChangesW 函数,检索描述指定目录中的更改的信息,更改包括重命名 删除 创建文件。F8无响应,nop掉此函数。
网络通信
Emotet在此版本中的网络流量保护和验证使用了椭圆曲线加密算法(ECC)
sub_9DD10C解密出ECC公钥ECK1 ECS1
解密逻辑:长度是第一个dword异或第二个dword ,长度经过处理。
以dword为单位,用第一块异或后面每一块。
ECK1
ECS1
可以提取出来base64编码后得到公钥。
C2配置是加密存储在DLL的数据节区中。在通讯的过程中会进行IP解密、加密流量和验证数据一系列操作,获取服务器的返回结果后就会根据结果继续执行流程。
加密的C2配置存储在.data段
sub_9DD10C解密c2配置模块,sprint出C2服务器地址。
c2配置解密后:格式ip 端口 01表示可用
按照后面的操作将每一个ip都过一遍,如下格式存放。
BCryptOpenAlgorithmProvider函数加载并初始化CNG提供程序,请求ECDH_P256算法
ECDH 是椭圆曲线的笛福赫尔曼算法的变种,它其实不单单是一种加密算法,而是一种密钥协商协议,也就是说 ECDH 定义了(在某种程度上)密钥怎么样在通信双方之间生成和交换,至于使用这些密钥怎么样来进行加密完全取决通信双方。
BCryptGenerateKeyPair 创建一个空的公钥/私钥对
BCryptFinalizeKeyPair 函数完成公钥/私钥对
导出创建的公钥对。把导出密钥的第三块之后部分复制。
导入之前解密的ECK1。
创建机密协议值。
BCryptOpenAlgorithmProvider函数加载并初始化CNG提供程序,请求AES算法
BCryptDeriveKey 从秘密协议值派生密钥。
BCryptImportKey 从密钥BLOB 导入对称密钥
导入之前解密的ECS1公钥。
检索文件目录确认只有一个文件。(FindFirstFile 如果cmp 文件名不相同则退出并且删除文件)
获取系统信息
ProcessIdTooSessionId 检索与指定进程关联的远程桌面服务会话
请求AES256算法,创建哈希或MAC对象,
执行单向hash或mac 计算 计算机名称和驱动器信息
调用BCryptEncrypt 加密数据。pbOutput为NULL,如果此参数为 NULL, BCryptEncrypt 函数将计算 在 pbInput 参数中传递的数据的密码文本所需的大小。
用BCryptEncrypt 加密数据。 大小60h
调用CryptBinaryToStringW将加密信息转为base64字符串,之后格式化输出为Cookie: %s=%s\r\n
网络通信模块:
利用cookie发送加密数据,
循环发送数据包,不同的服务器会调用InternetReadFile下载数据。通过 VirtualAlloc 申请空间在执行。
调试过程中并未接收到数据。
对接收到的数据调用BCryptDecrypt解密数据,根据后面的流程,解密后也不是明文pe,还要进行操作
猜测创建线程对下载的数据解密之后执行。