Enmity勒索软件分析

概述

Enmity勒索软件使用AESRSA加密算法组合的方式对本地数据进行加密以此要挟用户支付赎金,其显著特征是加密后的文件名及后缀由自定义算法生成,格式为:<随机生成字符串>-Mail[<email>]ID-[<随机生成的ID值>].<随机生成字符串>。除此之外,该勒索软件密钥的获取方式也做了改进,相关的密钥均在本地随机生成,由于缺少相应的解密私钥,所在暂时无法解密。

样本分析

字段 内容
文件大小 924.00 KB
文件 MD5 a5be93a7b653a7e8fcf0c653607d4e7c
文件类型 Win32 EXE
病毒名 Ransom.Enmity!1.EB7B
主要功能 加密文件,释放勒索信要求被害者支付赎金

该样本利用CryptoPP库的相关函数生成一组RSA密钥组(包括主机RSA公钥和主机RSA私钥),数据均存储于本地。

.text:0041FB53                 mov     dword ptr [ebp-460h], offset ??_7RSAFunction@CryptoPP@@6B@ ; const CryptoPP::RSAFunction::`vftable'
.text:0041FB5D                 mov     dword ptr [ebp-45Ch], offset ??_7RSAFunction@CryptoPP@@6B@_0 ; const CryptoPP::RSAFunction::`vftable'
.text:0041FB67                 mov     dword ptr [ebp-35Ch], offset ??_7RSAFunction@CryptoPP@@6B@_1 ; const CryptoPP::RSAFunction::`vftable'
.text:0041FB71                 call    sub_432E50
.text:0041FB76                 lea     ecx, [ebp-43Ch] ; void *
.text:0041FB76 ;   } // starts at 41FB46
.text:0041FB7C ;   try {
.text:0041FB7C                 mov     byte ptr [ebp-4], 30h ; '0'
.text:0041FB80                 call    sub_432E50
.text:0041FB80 ;   } // starts at 41FB7C
.text:0041FB85 ;   try {
.text:0041FB85                 mov     dword ptr [ebp-4], 31h ; '1'
.text:0041FB8C                 lea     ecx, [ebp-414h]
.text:0041FB92                 mov     eax, [ebp-418h]
.text:0041FB98                 mov     dword ptr [ebp-420h], offset ??_7PKCS8PrivateKey@CryptoPP@@6B@ ; const CryptoPP::PKCS8PrivateKey::`vftable'
.text:0041FBA2                 mov     dword ptr [ebp-41Ch], offset ??_7PKCS8PrivateKey@CryptoPP@@6B@_0 ; const CryptoPP::PKCS8PrivateKey::`vftable'
.text:0041FBAC                 push    0
.text:0041FBAE                 mov     eax, [eax+4]
.text:0041FBB1                 mov     dword ptr [ebp+eax-418h], offset ??_7PKCS8PrivateKey@CryptoPP@@6B@_1 ; const CryptoPP::PKCS8PrivateKey::`vftable'
.text:0041FBBC                 call    sub_4577D0
.text:0041FBBC ;   } // starts at 41FB85
.text:0041FBC1 ;   try {
.text:0041FBC1                 mov     byte ptr [ebp-4], 32h ; '2'
.text:0041FBC5                 lea     ecx, [ebp-3ECh] ; void *
.text:0041FBCB                 mov     eax, [ebp-458h]
.text:0041FBD1                 mov     dword ptr [ebp-460h], offset ??_7InvertibleRSAFunction@CryptoPP@@6B@ ; const CryptoPP::InvertibleRSAFunction::`vftable'
.text:0041FBDB                 mov     dword ptr [ebp-45Ch], offset ??_7InvertibleRSAFunction@CryptoPP@@6B@_0 ; const CryptoPP::InvertibleRSAFunction::`vftable'
.text:0041FBE5                 mov     dword ptr [ebp-424h], offset ??_7InvertibleRSAFunction@CryptoPP@@6B@_1 ; const CryptoPP::InvertibleRSAFunction::`vftable'
.text:0041FBEF                 mov     dword ptr [ebp-420h], offset ??_7InvertibleRSAFunction@CryptoPP@@6B@_2 ; const CryptoPP::InvertibleRSAFunction::`vftable'
.text:0041FBF9                 mov     dword ptr [ebp-41Ch], offset ??_7InvertibleRSAFunction@CryptoPP@@6B@_3 ; const CryptoPP::InvertibleRSAFunction::`vftable'
.text:0041FC03                 mov     eax, [eax+4]
.text:0041FC06                 mov     dword ptr [ebp+eax-458h], offset ??_7InvertibleRSAFunction@CryptoPP@@6B@_4 ; const CryptoPP::InvertibleRSAFunction::`vftable'

收集部分信息包括加密时间、本地标识ID等,然后和RSA密钥组中的主机RSA私钥一同写入文件DecryptionKey.txt

image

RSA密钥组中的主机RSA公钥则存储在注册表键HKCU\Software\Enmity下面的pubkey中。

公钥字段截图

接着生成主机AES密钥,以此密钥加密文件DecryptionKey.txt

.text:00406B01                 mov     [ebp+var_4], 7
.text:00406B08                 mov     eax, [ebp+var_10]
.text:00406B0B                 push    1
.text:00406B0D                 lea     ebx, [eax+90h]
.text:00406B13                 mov     dword ptr [eax], offset ??_7?$GCM_Final@VRijndael@CryptoPP@@$0A@$00@CryptoPP@@6B@ ; const CryptoPP::GCM_Final<CryptoPP::Rijndael,0,1>::`vftable'
.text:00406B19                 lea     ecx, [ebx+4]
.text:00406B1C                 mov     dword ptr [eax+4], offset ??_7?$GCM_Final@VRijndael@CryptoPP@@$0A@$00@CryptoPP@@6B@_0 ; const CryptoPP::GCM_Final<CryptoPP::Rijndael,0,1>::`vftable'
.text:00406B23                 mov     dword ptr [eax+8], offset ??_7?$GCM_Final@VRijndael@CryptoPP@@$0A@$00@CryptoPP@@6B@_1 ; const CryptoPP::GCM_Final<CryptoPP::Rijndael,0,1>::`vftable'
.text:00406B2A                 mov     [ebp+var_14], ebx
.text:00406B2D                 call    sub_42BD20

使用程序内部的硬编码RSA公钥加密主机AES密钥。

.text:00407418                 mov     [ebp+var_18], edi
.text:0040741B                 mov     dword ptr [edi+3Ch], offset ??_7NameValuePairs@CryptoPP@@6B@ ; const CryptoPP::NameValuePairs::`vftable'
.text:00407422                 mov     eax, [edi+8]
.text:00407425                 mov     dword ptr [edi+4], offset ??_7X509PublicKey@CryptoPP@@6B@ ; const CryptoPP::X509PublicKey::`vftable'
.text:0040742C                 mov     [ebp+var_10], 1
.text:00407433                 mov     eax, [eax+4]
.text:00407436                 mov     dword ptr [eax+edi+8], offset ??_7X509PublicKey@CryptoPP@@6B@_0 ; const CryptoPP::X509PublicKey::`vftable'
.text:0040743E ;   try {
.text:0040743E                 mov     [ebp+var_4], 1
.text:00407445                 lea     ecx, [edi+0Ch]  ; void *
.text:00407448                 mov     eax, [edi+8]
.text:0040744B                 mov     dword ptr [edi], offset ??_7RSAFunction@CryptoPP@@6B@ ; const CryptoPP::RSAFunction::`vftable'
.text:00407451                 mov     dword ptr [edi+4], offset ??_7RSAFunction@CryptoPP@@6B@_0 ; const CryptoPP::RSAFunction::`vftable'
.text:00407458                 mov     eax, [eax+4]
.text:0040745B                 mov     dword ptr [eax+edi+8], offset ??_7RSAFunction@CryptoPP@@6B@_1 ; const CryptoPP::RSAFunction::`vftable'
.text:00407463                 call    sub_432E50
.text:00407468                 lea     ecx, [edi+24h]  ; void *
.text:00407468 ;   } // starts at 40743E
.text:0040746B ;   try {
.text:0040746B                 mov     byte ptr [ebp+var_4], 2
.text:0040746F                 call    sub_432E50
.text:00407474                 mov     dword ptr [ebx], offset ??_7?$TF_EncryptorImpl@U?$TF_CryptoSchemeOptions@V?$TF_ES@URSA@CryptoPP@@V?$OAEP@VSHA1@CryptoPP@@VP1363_MGF1@2@@2@H@CryptoPP@@URSA@2@V?$OAEP@VSHA1@CryptoPP@@VP1363_MGF1@2@@2@@CryptoPP@@@CryptoPP@@6B@ ; const CryptoPP::TF_EncryptorImpl<CryptoPP::TF_CryptoSchemeOptions<CryptoPP::TF_ES<CryptoPP::RSA,CryptoPP::OAEP<CryptoPP::SHA1,CryptoPP::P1363_MGF1>,int>,CryptoPP::RSA,CryptoPP::OAEP<CryptoPP::SHA1,CryptoPP::P1363_MGF1>>>::`vftable'
.text:0040747A                 mov     dword ptr [ebx+4], offset ??_7?$TF_EncryptorImpl@U?$TF_CryptoSchemeOptions@V?$TF_ES@URSA@CryptoPP@@V?$OAEP@VSHA1@CryptoPP@@VP1363_MGF1@2@@2@H@CryptoPP@@URSA@2@V?$OAEP@VSHA1@CryptoPP@@VP1363_MGF1@2@@2@@CryptoPP@@@CryptoPP@@6B@_0 ; const CryptoPP::TF_EncryptorImpl<CryptoPP::TF_CryptoSchemeOptions<CryptoPP::TF_ES<CryptoPP::RSA,CryptoPP::OAEP<CryptoPP::SHA1,CryptoPP::P1363_MGF1>,int>,CryptoPP::RSA,CryptoPP::OAEP<CryptoPP::SHA1,CryptoPP::P1363_MGF1>>>::`vftable'
.text:00407481                 mov     dword ptr [ebx+8], offset ??_7?$TF_EncryptorImpl@U?$TF_CryptoSchemeOptions@V?$TF_ES@URSA@CryptoPP@@V?$OAEP@VSHA1@CryptoPP@@VP1363_MGF1@2@@2@H@CryptoPP@@URSA@2@V?$OAEP@VSHA1@CryptoPP@@VP1363_MGF1@2@@2@@CryptoPP@@@CryptoPP@@6B@_1 ; const CryptoPP::TF_EncryptorImpl<CryptoPP::TF_CryptoSchemeOptions<CryptoPP::TF_ES<CryptoPP::RSA,CryptoPP::OAEP<CryptoPP::SHA1,CryptoPP::P1363_MGF1>,int>,CryptoPP::RSA,CryptoPP::OAEP<CryptoPP::SHA1,CryptoPP::P1363_MGF1>>>::`vftable'
.text:00407488                 push    [ebp+arg_0]
.text:00407488 ;   } // starts at 40746B
.text:0040748B ;   try {
.text:0040748B                 mov     [ebp+var_4], 3
.text:00407492                 lea     ecx, [edi+8]
.text:00407495                 mov     eax, [edi+8]
.text:00407498                 mov     eax, [eax+4]
.text:0040749B                 add     ecx, eax
.text:0040749D                 mov     eax, [ecx]
.text:0040749F                 call    dword ptr [eax+8]

将上面生成的两组数据使用字段KY拼接后写入文件Key.secret,后续解密阶段需要把该文件发送给攻击者。

密钥字段截图

使用AES加密文件,其中文件AES密钥与上述生成主机AES密钥的代码相同,然后使用该密钥加密文件。

.text:00447CFA                 lea     eax, [ebx+18h]
.text:00447CFD                 mov     dword ptr [eax], offset ??_7FilterPutSpaceHelper@CryptoPP@@6B@ ; const CryptoPP::FilterPutSpaceHelper::`vftable'
.text:00447D03                 mov     [ebp+var_20], eax
.text:00447D06                 mov     dword ptr [eax+8], 0FFFFFFFFh
.text:00447D0D                 mov     dword ptr [eax+0Ch], 0
.text:00447D14                 mov     dword ptr [eax+10h], 0
.text:00447D1B                 mov     dword ptr [eax], offset ??_7HashFilter@CryptoPP@@6B@_1 ; const CryptoPP::HashFilter::`vftable'
.text:00447D21                 lea     ecx, [ebx+3Ch]
.text:00447D24                 mov     eax, [ebp+var_14]
.text:00447D27                 add     eax, 4
.text:00447D27 ;   } // starts at 447CD5
.text:00447D2A ;   try {
.text:00447D2A                 mov     byte ptr [ebp+var_4], 4
.text:00447D2E                 mov     [ebx+2Ch], eax
.text:00447D31                 mov     al, [ebp+arg_8]
.text:00447D34                 push    offset Src      ; Src
.text:00447D39                 mov     dword ptr [ebx], offset ??_7HashFilter@CryptoPP@@6B@ ; const CryptoPP::HashFilter::`vftable'
.text:00447D3F                 mov     dword ptr [ebx+4], offset ??_7HashFilter@CryptoPP@@6B@_0 ; const CryptoPP::HashFilter::`vftable'
.text:00447D46                 mov     [ebx+30h], al

从注册表键pubkey中获取主机RSA公钥。

.text:00416875                 lea     eax, [ebx+50h]  ; pubkey的值
.text:00416878                 mov     dword ptr [esi], offset ??_7Base64Decoder@CryptoPP@@6B@ ; const CryptoPP::Base64Decoder::`vftable'
.text:0041687E                 push    eax
.text:0041687F                 lea     ecx, [ebp-2C0h]
.text:00416885                 mov     dword ptr [esi+4], offset ??_7Base64Decoder@CryptoPP@@6B@_0 ; const CryptoPP::Base64Decoder::`vftable'
.text:00416885 ;   } // starts at 416856
.text:0041688C ;   try {
.text:0041688C                 mov     byte ptr [ebp-4], 2Ah ; '*'
.text:00416890                 call    sub_405A60      ; base64解码

使用此公钥加密文件AES密钥。

.text:004169B0                 mov     dword ptr [edi], offset ??_7?$StringSinkTemplate@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@CryptoPP@@6B@ ; const CryptoPP::StringSinkTemplate<std::string>::`vftable'
.text:004169B6                 mov     dword ptr [edi+4], offset ??_7?$StringSinkTemplate@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@CryptoPP@@6B@_0 ; const CryptoPP::StringSinkTemplate<std::string>::`vftable'
.text:004169BD                 mov     eax, [ebp-3F8h]
.text:004169C3                 push    0
.text:004169C5                 push    ecx
.text:004169C6                 lea     ecx, [ebp-3F8h]
.text:004169CC                 mov     eax, [eax+1Ch]
.text:004169CF                 call    eax
.text:004169D1                 push    edi
.text:004169D2                 push    0
.text:004169D4                 push    0
.text:004169D6                 push    eax
.text:004169D7                 mov     ecx, esi
.text:004169D9                 call    sub_448400
.text:004169DE                 push    esi
.text:004169DF                 push    ecx
.text:004169E0                 lea     eax, [ebp-0F4h]
.text:004169E6                 mov     dword ptr [esi], offset ??_7PK_EncryptorFilter@CryptoPP@@6B@ ; const CryptoPP::PK_EncryptorFilter::`vftable'
.text:004169EC                 push    eax
.text:004169ED                 lea     ecx, [ebp-3A8h]
.text:004169F3                 mov     dword ptr [esi+4], offset ??_7PK_EncryptorFilter@CryptoPP@@6B@_0 ; const CryptoPP::PK_EncryptorFilter::`vftable'
.text:004169F3 ;   } // starts at 416997
.text:004169FA ;   try {
.text:004169FA                 mov     byte ptr [ebp-4], 30h ; '0'
.text:004169FE                 call    sub_405A60

将加密后的文件数据和加密后的文件AES密钥使用字段N:<原始文件名>拼接后写入加密后的加密文件。

加密后的文件名

勒索信名为Enmity-Unlock-Guide.txt,内容如下。

Your Files Have Been Locked With  Enmity Ransomware

you have to pay Bitcoin for Unlock Process

you can send a little file (less than 1 or 2 mb) for Decryption test (if we assume file is important we may ask you to Send another one)

Contact Us and Pay and get Decryption

Contact Our Email:rxyyno@gmail.com
in Case of no reply from Email send message to my telegram  id below
Telegram ID:@Rxyyno
Your ID:96976448501380 

解密时攻击者需要使用自己持有的硬编码RSA私钥去解密文件Key.secret,获取AES密钥后才能解密被加密的文件。而硬编码RSA私钥目前未知,所以暂时无法对该勒索软件进行解密。

预防措施

  1. 部署网络安全态势感知、预警系统等网关安全产品。

    网关安全产品可利用威胁情报追溯威胁行为轨迹,帮助用户进行威胁行为分析、定位威胁源和目的,追溯攻击的手段和路径,从源头解决网络威胁,最大范围内发现被攻击的节点,帮助企业更快响应和处理。

  2. 安装有效的杀毒软件,拦截查杀恶意文档和木马病毒。

    杀毒软件可拦截恶意文档和木马病毒,如果用户不小心下载了恶意文件,杀毒软件可拦截查杀,阻止病毒运行,保护用户的终端安全。

瑞星ESM扫描截图

沦陷信标(IOC)

  • MD5

    a5be93a7b653a7e8fcf0c653607d4e7c
  • 瑞星病毒名

    Ransom.Enmity!1.EB7B

Author