近日,兰云科技银河实验室通过“兰眼下一代威胁感知系统”发现一款新型勒索软件 —— MZP 勒索软件,也可叫作 Dot 勒索软件,最早由 AmigoA 和 AkhmendTaia 在 2019 年 12 月 31 日首次发现。在勒索软件的开头前三个字节为 4D 5A 50,即 MZP,所以称为 MZP(这个 P 代表的是 Pascal) 勒索软件,其特征为附加到加密文件的扩展名为一个长度为 8 的随机字符串。”兰眼下一代威胁感知系统”对其检测结果如图 1-1 所示:
图 1-1
勒索软件的图标为一个卡通人物 Dot(20 世纪 90 年代中期流行的华纳兄弟卡通系列《Animaniacs》中的人物)的样子,这也就是为什么把它称作 Dot 勒索软件,如图 2-1 所示:
图 2-1
勒索后桌面出现如图 2-2 所示情况:
图 2-2
勒索信息文本如图 2-3 所示:
图 2-3
勒索后加密文件的后缀名为:przfqehd(随机的一个 8 位的字符串)
经 DIE 查壳可知,该勒索病毒加了 UPX 壳(3.91),且为 Delphi 编译的 Win32 程序,如图 3-1-1 所示:
图 3-1-1
这也证实了 MZP 中的 P,Delphi 的前身就为 Pascal,MZP 勒索软件二进制数据如图 3-1-2 所示:
图 3-1-2
既然有壳,则先脱之,如图 3-1-3 所示:
图 3-1-3
在对其反编译后,发现使用了 KOL 。众所周知,对于用 Delphi 开发的程序(GUI)来说,体积都比较大,为了尽可能减少体积,可使用 KOL,如图 3-2-1 所示:
图 3-2-1
除此之外,在类的名字里发现有 AES 字样,从这可猜测用了 AES 算法加密,如图 3-2-2 所示:
图 3-2-2
那这个类是在哪个单元呢,通过列举出的单元列表中,发现 Unit_0040E340 单元处的类信息显示出 ThiAESCipher,起始地址为 0x0040E340,如图 3-2-3 所示:
图 3-2-3
由于没有重定位,所以可以直接定位到加密算法处,如图 3-2-4 所示:
图 3-2-4
同时 HiAsm 这个字符串也引起了我的注意,HiAsm 是一个用于 Delphi 开发的旧 IDE,这个 IDE 是由俄罗斯人开发的,包括上面提到的 KOL,这款勒索软件可能由这个 IDE 开发的,如图 3-2-5 所示:
图 3-2-5
我们再来看看字符串,通过字符串一般能够猜测出程序需要做哪些操作,如图 3-2-6 所示:
图 3-2-6
比如 comctl32.dll 中的 InitCommonControlEx 和 _TrackMouseEvent,用于初始化控件和捕获鼠标的位置,可能存在反沙箱,也可能是绕过 UAC(UACME 中的 #21 和 #22)。除了这个,还有与注册表和加密文本有关。
勒索软件最开始会去尝试打开 HKEY_CURRENT_USER\Software\Borland\Locales 和 HKEY_CURRENT_USER\Software\Borland\Delphi\Locales 注册表项来探测环境,如图 3-3-1 所示:
图 3-3-1
只需两者中的一个存在,就会去查询相关环境配置信息,如图 3-3-2 所示:
图 3-3-2
除了上述两个注册表项外,它还会去 HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Delphi\RTL 下读取 FPUMaskValue,来确定此环境下是否能支持 Delphi 程序的运行,如图 3-3-3 所示:
图 3-3-3
在完成上述操作后,紧接着是获取语言版本信息,并以此作为扩展名将自身加载为数据文件,如图 3-4-1 所示:
图 3-4-1
在测试环境中,获取到的语言为 CHS,具体信息如图 3-4-2 所示:
图 3-4-2
以上总的流程如图 3-4-3 所示:
图 3-4-3
勒索核心主要是位于 sub_410BB4 中,如图 3-5-1 所示:
图 3-5-1
还记得最开始提到的 MZP 吗?其实可以用压缩软件解压出来,这里用 7-ZIP 对其进行解压,如图 3-5-2 所示:
图 3-5-2
在上述解压出来的资源文件中,发现有个 STR1,这个就为勒索信息文本字符串,%1 表示的是 Key,如图 3-5-3 所示:
图 3-5-3
将资源全部拷贝到内存中,这是通过 sub_403218 实现,如图 3-5-4 和 3-5-5 所示:
图 3-5-4
图3-5-5
循环遍历目录下的文件,并对其进行加密,如图 3-5-6 所示:
图 3-5-6
加密操作主要是在 sub_40CE00 当中进行,每当加密完后会对原文件进行删除操作,如图 3-5-7 所示:
图 3-5-7
在加密的过程中会以字符串 QWAHNJZCUF 为基础,经过 sub_004026F4 和 sub_00403430 算出一个 0×258 大小的字符串存储在起始地址为 0x004221AC 的内存中,这个就是密钥,如图 3-5-8 和 3-5-9 所示:
图 3-5-8
图 3-5-9
这块大小为 0×258 的字符串密钥生成取决于 EDX 中的值,EDX 的值是通过 GetSystemTime 获取当前时间得到的,它会把毫秒的值给到 EDX,并做下一步计算(sub_004026F4),先来看下 SYSTEMTIME 结构体的定义,如下:
// System time is represented with the following structure:
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
SYSTEMTIME 结构体里有 8 个成员,全部为 WORD 类型,占 2 个字节,分别为年、月、周、天、时、分、秒、毫秒,如图 3-5-10 所示:
图 3-5-10
在上面需要注意一个地方,那就是时,因为现在处在东八区,所以这里的时需要加上 8 才会等于当前时间表示的时。我们再转到 0x004026F4 处,在运算过程中,EDX 与 EAX 相乘后结果存放在 EAX 会发生溢出,溢出的最高位会存放在 EDX 中,如图 3-5-11 所示:
图 3-5-11
结果如图 3-5-12 所示:
图 3-5-12
此时 EDX 的值是 0×5,它代表的是字符串 QWAHNJZCUF 下标的索引,从 0 开始,所以该处会去索引 J,如图 3-5-13 所示:
图 3-5-13
一共会循环 0×258 次,将此次过程用 C 来描述,相关代码如下:
#include <stdio.h>
#include <windows.h>
int main(void)
{
char BaseStr[] = "QWAHNJZCUF";
char TargetStr[601] = "";
SYSTEMTIME SystemTime;
GetSystemTime(&SystemTime);
DWORD EDX = 0;
DWORD EAX = (SystemTime.wHour * 0x3C + SystemTime.wMinute) * 0x3C;
EAX = (EAX + SystemTime.wSecond) * 0x3E8;
EDX = SystemTime.wMilliseconds;
EAX = EAX + EDX;
// 取开始计算的 EAX 的初始值
DWORD Temp = EAX;
__int64 EAX64 = 0;
// 0x258
for (int n = 0; n < 600; ++n)
{
// EDX 为 UTC 时间的毫秒数,EAX 为上面计算出来的数
EDX = Temp * 0x8088405;
EDX = EDX + 1;
// 将 EDX 的值临时保存起来以便下一次运算
Temp = EDX;
EAX64 = (__int64)EDX * 0xA;
// 将高位的数保存到 EDX 中,并将其右移 32 位作为下标索引值
EDX = (EAX64 & 0x0000000F00000000) >> 32;
TargetStr[n] = BaseStr[EDX];
}
printf("%s\n", TargetStr);
return 0;
}
根据当前时间的毫秒数生成一个密钥,如图 3-5-14 所示:
图 3-5-14
生成的 8 位随机后缀名为 przfqehd,这是 MZP 勒索软件特征之一,与之过程涉及到的字符串跟图 3-2-6 最后圈出来的 qwertyuiopasdfghjklzxcvbnm 有关,这看起来是键盘上键的排列顺序。同样也是算出下标来索引,通过索引出来的值组成后缀名,也是通过 GetSystemTime 来获取当前时间的毫秒数来决定,不过需要注意一下数据类型, 索引可超 10,生成的后缀如图 3-5-15 所示:
图 3-5-15
MZP 勒索软件采用 AES-256 加密,首次加密时,会将文件内容的 16 字节以每 4 字节一组进行反转再与反转后的密钥进行异或,最后开始多次轮循加密(每次加密轮数 0xE),如图 3-5-1 所示:
图 3-5-16
根据 AES 算法的轮函数,可以建立 4 张置换表,通过查询这 4 张表,并与该轮的密钥进行异或,可以直接得到该轮加密的结果,伪代码如图 3-5-17 所示:
图 3-5-17
提取其加密的轮函数如图 3-5-18 所示:
图 3-5-18
经多轮加密后将区块内容写到以 przfqehd 为后缀的文件中,如图 3-5-18 所示:
图 3-5-18
待所有文件加密完成后,又会重新开始遍历文件(回跳到图 3-5-6 中),将生成的勒索信息写入到文本文件中,并放到每个目录下面,写入的勒索信息如图 3-5-19 所示:
图 3-5-19
上图出现的一串 key 的长度为 0×258,这个 key 为是通过如图 3-5-20 对应关系生成的:
图 3-5-20
关于解密,黑客可通过图 3-5-19 勒索信息中给出的 key,再用图 3-5-20 对应的字母关系表转换成密钥,而没再通过非对称加密对密钥进行进一步处理,黑客不需要当时加密文件的时间来获取 0×258 大小的密钥。最后,可通过上述 AES 算法的逆运算就可解出。
在分析过程中,还发现有一个特殊操作,MZP 勒索软件会通过 GetKeyboardType 来获取键盘的信息,如图 4-1 所示:
图 4-1
第一个传入的参数为 0,代表获取键盘类型信息,然后用返回值与 0×7 作比较,判断是否为日语键盘布局;第二个传入的参数为 1,代表获取键盘子类型信息,即键盘的 OEM 信息,通过该函数的返回值的高位再去和 0xD00 和 0×400 作比较,如图 4-2 所示:
图 4-2
现在大多数勒索软件会通过区域语言 ID 或者键盘布局来判断所处的地区,然后再决定是否执行恶意操作,但是在这个 MZP 勒索软件中,发现并不是,虽然说这段可疑,但依然阻止不了我的好奇心,在一家***论坛,发现与之有关,如图 4-3 所示:
图 4-3
但这位坛友并未透露意图,看函数名称发现,_isNECWindows,这个 NEC 和注释 wordaround a Japanse Win95 bug 引起了我的注意,NEC 为日本一家跨国信息技术公司,其中出产的产品就有 NEC 键盘,似乎与这个有关,后来发现,这一段其实是来自于 KOL 源码中的 system.pas 中的一部分,至于用途,不得而知!
近年勒索病毒频繁出现,我们每一个人都应该提高警惕,切勿打开来自可疑邮箱的附件,避免使用来源不明的第三方软件资源;同时,建议提前部署具备高级威胁检测能力的安全产品进行及时监控、防范,降低安全隐患。
MD5:
d00c79e8e9a7552aee66db55c855f26b
Email:
recover_24_7@protonmail[.]com
*本文作者:兰云科技银河实验室,转载请注明来自FreeBuf.COM