1.背景
1.1来源
接到客户通知发现NAS遭到勒索病毒攻击,其中的文件无法打开并且被添加了lvt后缀。经排查该次勒索攻击是一款名为LvtLocker的勒索软件所为,而该勒索软件的攻击目标主要是国内某知名的NAS设备系统。
1.2入侵路线图
2.溯源分析
2.1查看日志
远程访问客户中招服务器,通过排查NAS web日志,默认SSH端口为9222,登录用户名为root,密码与web端admin用户相同。
查看nginx日志 /var/log/nginx/access.log
可以发现在2024年3月1日黑客利用CVE-2022-24990漏洞远程下载木马、添加执行权限并执行的行为。
2.2排查异常文件
查看NAS web路径: /usr/www/,发现该系统在2023年就遭受过非勒索团伙的攻击,发现了遗留的webshell
webshell地址
/usr/www/my.php
/usr/www/include/dwz.php
最终通过在web目录中查找ELF文件发现加密器路径
/usr/www/module/tnasupdate
2.3漏洞验证
漏洞名称:任意命令执行漏洞(CVE-2022-24990)
POC:https://github.com/lishang520/CVE-2022-24990/tree/main
验证结果:存在漏洞
2.4钱包溯源
通过区块链浏览器查看勒索信中的黑客钱包地址
3JD9xwA9HQuZSSEKZemmuTTpEmtM1L8Uwt
查看该地址的交易记录,可得出结论:黑客每次进行勒索的金额为0.01BTC(约为4927元),一共完成7次与受害者的交易,其中最早的交易可追溯到2024年2月23日
最终在2024年2月29日黑客将所有BTC转入新地址
1LLh7KvmjmJuEELxSN2PKQKEywt6FfrfYi
后续有受害者尝试通过邮箱联系黑客,但均未得到答复,期间新地址钱包的BTC被转出,怀疑黑客已跑路
3.恶意文件基础信息
3.1加密器基本信息
文件名 | lvt勒索病毒加密器 |
---|---|
编译器 | GO |
大小 | 2330624(2.22 MiB) |
操作系统 | Unix |
架构 | 386 |
模式 | 32 位 |
类型 | EXEC |
字节序 | LE |
MD5 | 349dd0a75d5cebe1d3ffd620bca4ff7f |
SHA1 | 2a56190a0ee07f989c1e752a954674bc77c1b85e |
SHA256 | cd729507d2e17aea23a56a56e0c593214dbda4197e8a353abe4ed0c5fbc4799c |
3.2解密器基本信息
客户向黑客支付赎金后提供的解密器
文件名 | lvt解密器-d_nas_win.exe |
---|---|
编译器 | GO |
大小 | 2336768(2.23 MiB) |
操作系统 | Windows |
架构 | AMD64 |
模式 | 64 位 |
类型 | 控制台 |
字节序 | LE |
MD5 | 0d3d9522bdb4fe4bfdc071f1918b095e |
SHA1 | d497fab04c4254b685c92f4d35f7eed92e5dda9c |
SHA256 | 2fc9dfaa373d867eb9932a9d428599af7453da3f902ee85b5cf961e72004ae6b |
3.3勒索信
--------------- Hello ---------------
*** By LVT LOCKER ***
Your computers and servers are encrypted, and backups are deleted.
We use strong encryption algorithms, so no one has yet been able to decrypt their files without our participation.
The only way to decrypt your files is to purchase a universal decoder from us, which will restore all the encrypted data and your network.
Follow our instructions below, and you will recover all your data:
1) Pay 0.01 bitcoin to 3JD9xwA9HQuZSSEKZemmuTTpEmtM1L8Uwt
2) Send us message with transaction id and your personal key (which is in the README_lvt_PersonalKey.txt file) to ghzsr@onionmail.org
3) Launch decryptor.exe, which our supportor will send you through email
What guarantees?
------------------
We value our reputation. If we will not do our work and liabilities, nobody will pay us. This is not in our interests.
All our decryption software is tested by time and will decrypt all your data.
------------------
!!! DO NOT TRY TO RECOVER ANY FILES YOURSELF. WE WILL NOT BE ABLE TO RESTORE THEM!!!
3.4其他注意事项
分析的样本中加密器与解密器不配套,但patch部分数据后即可搭配使用,后文将详细解释
4.加密后文件分析
加密的测试文件为1.txt
,具体内容如下
经过lvt勒索病毒加密器
加密之后如下
文件的大小增加了38Byte,经过多次实验结果仍然相同
5.逆向分析
5.1 加密器逆向分析
加密器使用方法为./lvt勒索病毒加密器 [path to be encrypted]
5.1.1 main_generateKeysAndSendPrivateKey函数
main_generateKeysAndSendPrivateKey
在main_main
函数开始时被调用,用于生成ecc私钥并使用rsa公钥进行加密
程序中内置的RSA公钥如下
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7KmV+4LWc4oI5ngkOSAg
dUmX7/4cOmgEUnu0463BN1PcQ6OowOrneReJKt3/bEqc1nmPY9Z3nUH8dmF7kFpb
lHiSQLh0lFB55SYxrFsugtVEOO4Zo9zWM/2lpjqhhqhTAJx8TV76aLdxbQzztnms
CFYqPesy+R5ing2PmUE5jcMh9/4MYbGQ/l5WVqgpXs8kUphPCZSRQSEbIGZ1AAia
56ovyiKbOjXTg8do/LEdajGRYLYG+BMaXeEjq4Xss3HmyIrRmTeaqvB7vOCniry4
pZ4PPEM1wk0w79LF5bssGm+Dq1MpyUOVlBcz9dS4IthwAWTKOW8vUy27l18/K7qC
pwIDAQAB
-----END PUBLIC KEY-----
程序首先利用crypto/rand
生成Elliptic Curve Cryptography
(下文简称为ecc
)的私钥,由于crypto/rand
调用了系统底层函数进行初始化,不可预测
crypto/rand
使用操作系统提供的底层熵源(entropy source)来生成随机数。在Linux和Unix系统上,它通常使用/dev/urandom
或类似的机制,而在Windows上,它使用CryptGenRandom
API。这些底层机制都旨在提供足够的熵,使得生成的随机数在理论上难以预测
生成的ecc
私钥利用内置的rsa公钥进行加密,在rsa
加密时使用了PKCS#1 v1.5
填充协议,导致对于同一数据加密后的结果不同
最后main_generateKeysAndSendPrivateKey
函数返回加密后的ecc
私钥,下述代码仅保留了关键逻辑
retval_8179D20 __golang main_generateKeysAndSendPrivateKey()
{
ecc_private.ptr = (uint8 *)runtime_newobject((int)&RTYPE__32_uint8);
*(_OWORD *)((char *)&v18 - 4) = io_ReadAtLeast(no, rand_reader, (int)ecc_private.ptr, 32, 32, 32);
ecc_private1.ptr = ecc_private.ptr;
LODWORD(v16) = golang_org_x_crypto_curve25519_scalarBaseMult((int)v20, ecc_private1);
v14 = runtime_stringtoslicebyte(
(int)v21,
(int)"-----BEGIN PUBLIC KEY-----\n"
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7KmV+4LWc4oI5ngkOSAg\n"
"dUmX7/4cOmgEUnu0463BN1PcQ6OowOrneReJKt3/bEqc1nmPY9Z3nUH8dmF7kFpb\n"
"lHiSQLh0lFB55SYxrFsugtVEOO4Zo9zWM/2lpjqhhqhTAJx8TV76aLdxbQzztnms\n"
"CFYqPesy+R5ing2PmUE5jcMh9/4MYbGQ/l5WVqgpXs8kUphPCZSRQSEbIGZ1AAia\n"
"56ovyiKbOjXTg8do/LEdajGRYLYG+BMaXeEjq4Xss3HmyIrRmTeaqvB7vOCniry4\n"
"pZ4PPEM1wk0w79LF5bssGm+Dq1MpyUOVlBcz9dS4IthwAWTKOW8vUy27l18/K7qC\n"
"pwIDAQAB\n"
"-----END PUBLIC KEY-----\n",
451);
v15 = encoding_pem_Decode(v14, v16);
LODWORD(v15) = crypto_x509_ParsePKIXPublicKey(*(_DWORD *)(v15 + 12), *(_DWORD *)(v15 + 16), *(_DWORD *)(v15 + 20));
v17 = crypto_rsa_EncryptPKCS1v15(no, rand_reader, SDWORD1(v15), (int)ecc_private.ptr, 32, 32);
}
5.1.2 main_main函数
首先判断用户输入的参数是否为2个,如果用户输入的参数不为两个,则输出提示信息
if(用户输入个数==2)
do_something;
else
{
v38 = 0;
v39 = 0;
if ( !dword_828063C )
runtime_panicIndex(0);
v13 = runtime_convTstring(*(_DWORD *)dword_8280638, *(_DWORD *)(dword_8280638 + 4));
v38 = (int)&RTYPE_string;
v39 = v13;
fmt_Fprintf((int)&off_81D2D64, dword_8280408, (int)"%s [path to be encrypted]\n", 26, (int)&v38, 1, 1);
}
首先判断了用户是否拥有root权限,如果用户拥有root权限,则从系统根目录进行加密,如果用户没有root权限,则用用户输入的路径进行加密
if ( *(_DWORD *)(dword_8280638 + 12) == 10
&& runtime_memequal(*(_DWORD *)(dword_8280638 + 8), (int)"linux_root", 10) )
{
encode_path_len = 1;
encode_path = "/";
}
else
{
if ( (unsigned int)dword_828063C <= 1 )
runtime_panicIndex(dword_828063C);
encode_path = *(const char **)(dword_8280638 + 8);
encode_path_len = *(_DWORD *)(dword_8280638 + 12);
}
释放勒索信,勒索信硬编码在程序中,写入文件README_lvt.txt
v12.ptr = (uint8 *)runtime_stringtoslicebyte(
(int)v34,
(int)"--------------- Hello ---------------\n"
"\n"
" *** By LVT LOCKER ***\n"
"\n"
"Your computers and servers are encrypted, and backups are deleted.\n"
"We use strong encryption algorithms, so no one has yet been able to decrypt their files wi"
"thout our participation.\n"
"\n"
"The only way to decrypt your files is to purchase a universal decoder from us, which will "
"restore all the encrypted data and your network.\n"
"\n"
"Follow our instructions below, and you will recover all your data:\n"
"\n"
"1) Pay 0.01 bitcoin to 3JD9xwA9HQuZSSEKZemmuTTpEmtM1L8Uwt\n"
"2) Send us message with transaction id and your personal key (which is in the README_lvt_P"
"ersonalKey.txt file) to ghzsr@onionmail.org\n"
"3) Launch decryptor.exe, which our support will send you through email\n"
"\n"
"What guarantees?\n"
"------------------\n"
"We value our reputation. If we will not do our work and liabilities, nobody will pay us. T"
"his is not in our interests.\n"
"All our decryption software is tested by time and will decrypt all your data.\n"
"------------------\n"
"\n"
"!!! DO NOT TRY TO RECOVER ANY FILES YOURSELF. WE WILL NOT BE ABLE TO RESTORE THEM!!!",
1055);
*(_QWORD *)&v12.len = v19;
os_WriteFile((int)"./README_lvt.txt", 16, v12, 511);
对main_generateKeysAndSendPrivateKey
返回的数据进行hex encode
写入文件README_lvt_PersonalKey.txt
v4 = runtime_makeslice((int)RTYPE_uint8, 2 * v28, 2 * v28);
v5 = 2 * v28;
v6 = KeysAndSendPrivateKey;
v7 = v28;
v8 = 0;
v9 = 0;
while ( v8 < v7 )
{
v25 = *(_BYTE *)(v8 + v6);
if ( v9 >= v5 )
runtime_panicIndex(v5);
*(_BYTE *)(v4 + v9) = a0123456789abcd[v25 >> 4];
if ( v5 <= v9 + 1 )
runtime_panicIndex(v5);
*(_BYTE *)(v9 + v4 + 1) = a0123456789abcd[v25 & 0xF];
++v8;
v9 += 2;
v6 = KeysAndSendPrivateKey;
v7 = v28;
}
v26 = 2 * v31;
v16 = runtime_slicebytetostring((int)v33, v4, v5);
v14.ptr = (uint8 *)runtime_stringtoslicebyte((int)v32, v16, v20);
*(_QWORD *)&v14.len = v20;
os_WriteFile((int)"./README_lvt_PersonalKey.txt", 28, v14, 511);
.rodata:081A01D2 a0123456789abcd db '0123456789abcdef'
最后调用path_filepath_Walk
对文件夹进行加密
5.1.3 main_main_func1函数
即使加密的为根目录,勒索软件还是对一些系统关键目录与关键文件进行了规避
if ( strings_Index(v27, v31, (int)"/proc", 5) >= 0
|| strings_Index((int)a1, a2, (int)"/boot", 5) >= 0
|| strings_Index((int)a1, a2, (int)"/sys", 4) >= 0
|| strings_Index((int)a1, a2, (int)"/run", 4) >= 0
|| strings_Index((int)a1, a2, (int)"/dev", 4) >= 0
|| strings_Index((int)a1, a2, (int)"/etc", 4) >= 0
|| strings_Index((int)a1, a2, (int)"/home/httpd", 11) >= 0
|| strings_Index((int)a1, a2, (int)".system/thumbnail", 17) >= 0
|| strings_Index((int)a1, a2, (int)".system/opt", 11) >= 0
|| strings_Index((int)a1, a2, (int)".config", 7) >= 0
|| strings_Index((int)a1, a2, (int)".qpkg", 5) >= 0 )
{
return qword_8280590;
}
v36 = strings_Index((int)a1, a2, (int)"/mnt/ext/opt", 12);
if ( v36 >= 0 )
return qword_8280590;
也规避了不加密README_lvt_PersonalKey.txt
与README_lvt.txt
也不加密以.lvt
后缀结尾的文件,避免重复加密
通过判断的文件将加入加密队列等待加密
5.1.4 main_encrypt_file函数
首先会对文件添加.lvt
后缀
v20 = runtime_concatstring2(0, v68.len, v68.cap, (int)".lvt", 4);
v18 = os_rename(v68.len, v68.cap, v20, v23);
随机生成32Byte的数据进行sha256
作为chacha20
的密钥生成chacha20加密实例(下述代码仅保留了关键代码)
v23 = io_ReadAtLeast(no, rand_reader, (int)v46, 32, 32, 32);
crypto_sha256_Sum256(v5, 0);
((void (*)(void))loc_80AF350)();
v6.ptr = v42;
*(_QWORD *)&v6.len = 0x2000000020LL;
crypto_sha256_Sum256(v6, v17);
((void (*)(void))loc_80AF350)();
sync__ptr_Mutex_Unlock(&stru_8293188);
((void (*)(void))loc_80AEE66)();
DWORD1(v23) = golang_org_x_crypto_chacha20_newUnauthenticatedCipher((int)&v43, (int)v42, 32, 32, (int)&v41, 12, 22);
通过文件的原始大小,选择加密方式Large cipher mode
或者Small cipher mode
if ( SHIDWORD(filesize) > 0 || HIDWORD(filesize) == 0 && (unsigned int)filesize > 0x1400000 )
{
v49 = 0;
v50 = 0;
v11 = runtime_convTstring(v68.len, v68.cap);
v49 = &RTYPE_string;
v50 = v11;
fmt_Fprintf((int)&off_81D2D64, dword_8280408, (int)"Large cipher mode for: %s\n", 26, (int)&v49, 1, 1);
v31 = runtime_int64div(filesize, (int)v30, 10485760, 0);
v32 = v22;
v46 = (_BYTE *)runtime_makeslice((int)RTYPE_uint8, 0x100000, 0x100000);
v0 = 0;
for ( i = 0; v0 == v32 && i < v31 || v0 < v32; i = v34 )
{
v28 = v0;
((void (*)(void))loc_80AEE8A)();
v27 = 10485760 * v4;
v35 = (10485760 * __PAIR64__(v28, v4)) >> 32;
v34 = v4 + 1;
v33 = __CFADD__(v4, 1) + v28;
v14 = runtime_convT64(v4 + 1, v33);
v65[0] = &RTYPE_int64;
v65[1] = v14;
v15 = runtime_convT64(v31, v32);
v65[2] = &RTYPE_int64;
v65[3] = v15;
v16 = runtime_convTstring(v68.len, v68.cap);
v65[4] = &RTYPE_string;
v65[5] = v16;
fmt_Fprintf((int)&off_81D2D64, dword_8280408, (int)"Processing chunk %d\\%d (%s)\n", 28, (int)v65, 3, 3);
os__ptr_File_ReadAt((int)v45, (int)v46, 0x100000, 0x100000, v27, v35);
golang_org_x_crypto_chacha20__ptr_Cipher_XORKeyStream(v44, v46, 0x100000, 0x100000, v46, 0x100000, 0x100000);
os__ptr_File_WriteAt((int)v45, (int)v46, 0x100000, 0x100000, v27, v35);
v0 = v33;
}
}
else
{
v47 = 0;
v48 = 0;
v12 = runtime_convTstring(v68.len, v68.cap);
v47 = &RTYPE_string;
v48 = v12;
fmt_Fprintf((int)&off_81D2D64, dword_8280408, (int)"Small cipher mode for: %s\n", 26, (int)&v47, 1, 1);
if ( SHIDWORD(filesize) > 0 || HIDWORD(filesize) == 0 && (unsigned int)filesize > 0x400000 )
{
v2 = 0x400000;
v3 = 0;
}
else
{
v2 = filesize;
v3 = (int)v30;
}
v25 = v2;
v26 = v3;
v46 = (_BYTE *)runtime_makeslice64((int)RTYPE_uint8, v2, v3, v2, v3);
v24 = os__ptr_File_ReadAt((int)v45, (int)v46, v25, v25, 0, 0);
if ( v25 != v24 || v26 != v24 >> 31 )
{
v61 = 0;
v62 = 0;
v63 = 0;
v64 = 0;
v10 = runtime_convT32(v24);
v61 = &RTYPE_int;
v62 = v10;
v13 = runtime_convT64(v25, v26);
v63 = &RTYPE_int64;
v64 = v13;
fmt_Fprintf((int)&off_81D2D64, dword_8280408, (int)"ERROR: %d != %d\n", 16, (int)&v61, 2, 2);
(*v66)();
(*v67)();
return;
}
golang_org_x_crypto_chacha20__ptr_Cipher_XORKeyStream(v44, v46, v25, v25, v46, v25, v25);
os__ptr_File_WriteAt((int)v45, (int)v46, v25, v25, 0, 0);
}
将随机生成32Byte的数据通过ecc
公钥加密之后存入文件尾部(下述代码仅保留了关键代码)
v7.ptr = v40;
golang_org_x_crypto_curve25519_scalarBaseMult((int)v39, v7);
v8.ptr = v40;
v8.len = (size_t)&v69;
golang_org_x_crypto_curve25519_scalarMult((int)v38, v8);
......
os__ptr_File_WriteAt((int)v45, (int)v39, 32, 32, filesize, (int)v30);
向文件尾部写入6Byte的特征码,特征码硬编码在程序中
v36 = 0xDECDBCAB;
v37 = 0xF0EF;
......
os__ptr_File_WriteAt((int)v45, (int)&v36, 6, 6, filesize + 32, (filesize + 32) >> 32);// 写入特征
5.2 解密器逆向分析
通过客户反馈得知,客户已交付赎金并且黑客交付了解密器,但解密器无法正常使用恢复被加密文件,solar团队工程师对该解密器进行逆向分析排查无法正常恢复的原因:
解密器的使用方法为解密器 [path to be decrypted] [personal key]
5.2.1 main_main函数
if ( qword_2F0928 == 3 )
{
v10 = *(_QWORD *)(os_Args + 24);
v11 = path_filepath_Walk(*(_QWORD *)(os_Args + 16), v10, (unsigned int)&off_2512E0, v1, v2, v3, v4);
if ( v11 )
{
v20 = v6;
*(_QWORD *)&v20 = *(_QWORD *)(v11 + 8);
*((_QWORD *)&v20 + 1) = v10;
fmt_Fprintln(
(unsigned int)go_itab__os_File_io_Writer,
os_Stdout,
(unsigned int)&v20,
1,
1,
v12,
v13,
v14,
v15,
v16,
v17,
v18);
}
}
else
{
v19 = v6;
if ( !qword_2F0928 )
runtime_panicIndex(0LL, v0);
v7 = runtime_convTstring(*(_QWORD *)os_Args, *(_QWORD *)(os_Args + 8), os_Args, v1, v2, v3, v4);
*(_QWORD *)&v19 = &RTYPE_string;
*((_QWORD *)&v19 + 1) = v7;
fmt_Fprintf(
(unsigned int)go_itab__os_File_io_Writer,
os_Stdout,
(unsigned int)"%s [path to be decrypted] [personal key]\n",
41,
(unsigned int)&v19,
1,
1,
v8,
v9,
v16,
v17);
}
仅检查了参数的个数便调用path_filepath_Walk
进行接下来的步骤
5.2.2 main_decrypt_file
此函数的参数主要包括解密文件的完整路径,与解密使用的key
__int64 __golang main_decrypt_file(
__int64 vfilename,
unsigned __int64 filename_len,
__int64 key,
__int64 kenlen,
__int64 a5,
__int64 a6,
__int64 a7,
__int64 a8,
__int64 a9)
首先将key
进行hex decode
解码
key_1 = key;
key_2 = (__int128 *)runtime_stringtoslicebyte((unsigned int)&v174, key, kenlen, kenlen, a5, a6, a7, a8, a9);
v159 = v12;
v13 = key_1;
v14 = encoding_hex_Decode((__int64)key_2, key_1, v12, (__int64)key_2, key_1);
if ( v159 < v14 )
runtime_panicSliceAcap(v14, key_1, v14);
ecc_key[0] = v10;
ecc_key[1] = v10;
if ( v159 < 0x20 )
runtime_panicSliceAcap(v14, key_1, 32LL);
key_3 = key_2;
key_4 = ecc_key;
if ( key_2 != ecc_key )
key_4 = (__int128 *)runtime_memmove(ecc_key, key_2, 32LL);
然后修改文件名,即删除了文件的.lvt
后缀
if ( filename_len < filename_len - 4 )
runtime_panicSliceAlen(key_4, key_3, filename_len - 4);
new_filename_len = filename_len - 4;
v21 = os_rename(filename3, filename_len, filename3, (int)filename_len - 4, v13, v15, v16, v17, v18, v109, v125, v138);
接着打开文件,并获得了相关文件信息(下述代码删除了异常处理部分)
openfile = (os_File *)os_OpenFile(filename3, new_filename_len, 2, 0, v13, v22, v23, v24, v25, v110, v126, v139);
file_stat = os__ptr_File_Stat(openfile);
file_len = (*((__int64 (__golang **)(void *))file_stat.0.tab + 7))(file_stat.0.data);
接下来判断文件的长度是否大于38,如果小于等于38,则抛出异常,从这也可以看出加密后的文件有额外的38byte
接着读取文件的后6Byte,与程序中的硬编码数据比较,如果比较不通过则不进行解密,我们称这6Byte的编码为识别码
上文所说的加密器与解密器不配套即为此识别码不同
if ( file_len > 38 ) // 额外数据块大小为38
{
v164 = file_len;
file_stat.0.data = v158;
file_stat.1.data = (void *)6;
os__ptr_File_ReadAt( // 读取后6Byte
(_DWORD)openfile1,
(unsigned int)v158,
6,
6,
file_len - 6,
v40,
v41,
v42,
v43,
v111,
v127,
v140,
v151);
if ( v158[0] == 7 && v158[1] == 0x21 && v158[2] == 0x51 && v158[3] == 0x4E && v158[4] == 0x41 && v158[5] == 0x50 )
do_decrypt;
识别码判断通过之后,读取文件除识别码的后32Byte,并使用上文hex decode
解码后的key作为Elliptic Curve Cryptography
的私钥对32Byte的数据进行解密,解密后的数据再进行sha256
计算,最终得到的数据用于生成chacha20
加密器实例
if ( v158[0] == 7 && v158[1] == 0x21 && v158[2] == 0x51 && v158[3] == 0x4E && v158[4] == 0x41 && v158[5] == 0x50 )// 文件尾部特征
{
v166 = v164 - 38;
v48 = v164 - 38;
os__ptr_File_ReadAt( // 读取32Byte
(_DWORD)openfile1,
(unsigned int)data32Byte,
32,
32,
v164 - 38,
v44,
v45,
v46,
v47,
v112,
v128,
v141,
v152);
golang_org_x_crypto_curve25519_scalarMult(
(int)under_ecc_32Byte_data,
(int)ecc_key,
(int)data32Byte,
32,
v48,
v49,
v50,
v51,
v52,
v113,
v124,
v129,
v137,
v142);
crypto_sha256_Sum256((uint8 *)under_ecc_32Byte_data, 0x20uLL, 0x20uLL, 32LL, v48, v53, v54, v55, v56);
*(_OWORD *)v172 = v114;
v173 = v143;
crypto_sha256_Sum256((uint8 *)v172, 0x20uLL, 0x20uLL, 32LL, v48, v57, v58, v59, v60);
v171[0] = v114;
v171[1] = v143;
((void (__fastcall *)(__int64 *))loc_1CE5AF)(&v175);
file_stat.1.data = (void *)32;
v63 = golang_org_x_crypto_chacha20_newUnauthenticatedCipher(
(unsigned int)&v176,
(unsigned int)v172,
32,
32,
(unsigned int)v171 + 10,
12,
22,
v61,
v62,
v114,
*((__int64 *)&v114 + 1),
v143,
*((__int64 *)&v143 + 1));
最后通过文件大小判断采用的是Large cipher mode
或者Small cipher mode
进行解密
6.解密步骤
利用相关技术获得ecc私钥如下
CFA61669D96E10861AEFF1FBD2E362139602AF74F3DBA36C96CDB3330433C0A8
patch文件或者解密程序,使得文件可以通过特征码
验证
成功解密,因此得出结论,黑客提供的解密器可以做到解密文件,但黑客提供的KEY有误导致客户无法正常解密。
7.总结
从技术层面而言,该LVT勒索病毒目前只针对这款NAS的漏洞进行了渗透入侵,并且释放LVT勒索病毒,据不完全统计,目前国内受害者有几十家使用该NAS的用户,同时LVT勒索加密程序生成了一对ecc
公私钥,ecc
公私钥利用crypto/rand
生成,每次生成结果不同。其中私钥利用程序内置的RSA
公钥加密后保存在README_lvt_PersonalKey.txt
中,ecc
公钥参与chacha20
的加密工作,如需解密文件,必须需要ecc
私钥,ecc
私钥只能通过黑客的RSA
私钥解密README_lvt_PersonalKey.txt
获得。上文解密程序中ecc
私钥获得为在加密器加密文件时调试获得私钥,但实际情况中勒索病毒进程结束之后,内存空间也被清空时,ecc
私钥无法存在在任何位置,无法通过此方法或者类似方法捕获ecc
私钥,此类方法在实际情况中不适用。因此唯一能解开lvt加密的办法是联系黑客获取正确的ecc私钥,但是目前已知的几位受害者给黑客支付了比特币赎金之后,黑客提供的ecc私钥是错误的,解开的文件是乱码的错误文件,并且后续再也联系不上该黑客团队。
从该勒索病毒团队做法而言,该漏洞也是NAS的历史漏洞,技术难度和攻击手法也都算不上高超,但是对受害者的网络、资料的破坏和骗取虚拟币行为也是令人无法理解的,如同某位受害者所说“没有江湖道义”,但其实再退一步来说,他们都能做出勒索的行为,就不要指望他遵守道德准则了。
因此如果您成为勒索软件的受害者,我们团队有大量专业的应急响应和网络安全专家,我们会全力协助您处理勒索软件事件。以下是我们提供的服务:
- 应急响应: 1. 我们将立即采取行动,帮助您隔离受感染的系统,以防止进一步的数据损失。 2. 分析受影响的文件和系统,以确定勒索软件的类型和传播方式。 3. 提供紧急解密工具(如果可行)或建议其他解决方案。
- 溯源分析: 1. 我们将追踪攻击来源,以便识别黑客并采取法律行动。 2. 分析网络流量、日志和其他数据,以确定攻击的起源和传播路径。
- 勒索病毒分析: 1. 我们会对受感染的文件进行深入分析,以了解勒索软件的工作原理。 2. 研究加密算法和密钥管理,以便更好地理解解密过程。
- 解密工具和恢复文件: 1. 如果我们成功获得了解密工具,我们将协助您进行恢复和处理相关被勒索病毒加密的文件。
- 清除恶意软件和修复系统: 1. 使用我们的杀毒软件和勒索病毒处理安全工具扫描受感染的系统,以删除恶意软件。 2. 更新操作系统和应用程序,以填补已知的漏洞。 3. 检查系统日志,以查找异常活动或其他潜在的威胁。
- 加强安全措施: 1. 加强网络安全策略,包括防火墙、入侵检测系统和访问控制。 2. 培训员工,提高安全意识,以防止未来的勒索软件攻击。
- 报告事件: 1. 将整个勒索病毒入侵事件做完整的梳理,形成汇报总结方案,呈递给用户方,以便后续针对这次事件之后的总结和改进。
8.安全建议
1. 风险消减措施
资产梳理排查目标: 根据实际情况,对内外网资产进行分时期排查
服务方式: 调研访谈、现场勘查、工具扫描
服务关键内容: 流量威胁监测系统排查、互联网暴露面扫描服务、技术加固服务、集权系统排查
2. 安全设备调优
目标
通过对安全现状的梳理和分析,识别安全策略上的不足,结合目标防御、权限最小化、缩小攻击面等一系列参考原则,对设备的相关配置策略进行改进调优,一方面,减低无效或低效规则的出现频次;另一方面,对缺失或遗漏的规则进行补充,实现将安全设备防护能力最优化。
主要目标设备
网络安全防护设备、系统防护软件、日志审计与分析设备、安全监测与入侵识别设备。
3. 全员安全意识增强调优
目标:
通过网络安全意识宣贯、培训提升全方位安全能力
形式:
培训及宣贯
线下培训课表
若无法组织线下的集体培训,考虑两种方式:
1.提供相关的安全意识培训材料,由上而下分发学习
2.组织相关人员线上开会学习。线上培训模式。
线上学习平台
以下是solar安全团队近期处理过的常见勒索病毒后缀:后缀.360勒索病毒,.halo勒索病毒,.phobos勒索病毒,.Lockfiles勒索病毒,.stesoj勒索病毒,.src勒索病毒,.svh勒索病毒,.Elbie勒索病毒,.Wormhole勒索病毒.live勒索病毒, .rmallox勒索病毒, .mallox 勒索病毒,.hmallox勒索病毒,.jopanaxye勒索病毒, .2700勒索病毒, .elbie勒索病毒, .mkp勒索病毒, .dura勒索病毒, .halo勒索病毒, .DevicData勒索病毒, .faust勒索病毒, ..locky勒索病毒, .cryptolocker勒索病毒, .cerber勒索病毒, .zepto勒索病毒, .wannacry勒索病毒, .cryptowall勒索病毒, .teslacrypt勒索病毒, .gandcrab勒索病毒, .dharma勒索病毒, .phobos勒索病毒, .lockergoga勒索病毒, .coot勒索病毒, .lockbit勒索病毒, .nemty勒索病毒, .contipa勒索病毒, .djvu勒索病毒, .marlboro勒索病毒, .stop勒索病毒, .etols勒索病毒, .makop勒索病毒, .mado勒索病毒, .skymap勒索病毒, .aleta勒索病毒, .btix勒索病毒, .varasto勒索病毒, .qewe勒索病毒, .mylob勒索病毒, .coharos勒索病毒, .kodc勒索病毒, .tro勒索病毒, .mbed勒索病毒, .wannaren勒索病毒, .babyk勒索病毒, .lockfiles勒索病毒, .locked勒索病毒, .DevicData-P-XXXXXXXX勒索病毒, .lockbit3.0勒索病毒, .blackbit勒索病毒等。
勒索攻击作为成熟的攻击手段,很多勒索家族已经形成了一套完整的商业体系,并且分支了很多团伙组织,导致勒索病毒迭代了多个版本。而每个家族擅用的攻击手法皆有不同,TellYouThePass勒索软件家族常常利用系统漏洞进行攻击;Phobos勒索软件家族通过RDP暴力破解进行勒索;Mallox勒索软件家族利用数据库及暴力破解进行加密,攻击手法极多防不胜防。
而最好的预防方法就是针对自身业务进行定期的基线加固、补丁更新及数据备份,在其基础上加强公司安全人员意识。如果您想了解有关勒索病毒的最新发展情况,或者需要获取相关帮助,请关注“solar专业应急响应团队”。
9.团队介绍
团队坚持自主研发及创新,在攻防演练平台、网络安全竞赛平台、网络安全学习平台方面加大研发投入,目前已获得十几项专利及知识产权。团队也先后通过了ISO9001质量管理体系、ISO14000环境管理体系、ISO45001职业安全健康管理体系 、ITSS(信息技术服务运行维护标准四级)等认证,已构建了网络安全行业合格的资质体系;
10.我们的数据恢复服务流程
多年的数据恢复处理经验,在不断对客户服务优化的过程中搭建了"免费售前+安心保障+专业恢复+安全防御"一体化的专业服务流程。
① 免费咨询/数据诊断分析
专业的售前技术顾问服务,免费在线咨询,可第一时间获取数据中毒后的正确处理措施,防范勒索病毒在内网进一步扩散或二次执行,避免错误操作导致数据无法恢复。
售前技术顾问沟通了解客户的机器中毒相关信息,结合团队数据恢复案例库的相同案例进行分析评估,初步诊断分析中毒数据的加密/损坏情况。
② 评估报价/数据恢复方案
您获取售前顾问的初步诊断评估信息后,若同意进行进一步深入的数据恢复诊断,我们将立即安排专业病毒分析工程师及数据恢复工程师进行病毒逆向分析及数据恢复检测分析。
专业数据恢复工程师根据数据检测分析结果,定制数据恢复方案(恢复价格/恢复率/恢复工期),并为您解答数据恢复方案的相关疑问。
③ 确认下单/签订合同
您清楚了解数据恢复方案后,您可自主选择以下下单方式:
双方签署对公合同:根据中毒数据分析情况,量身定制输出数据恢复合同,合同内明确客户的数据恢复内容、数据恢复率、恢复工期及双方权责条款,双方合同签订,正式进入数据恢复专业施工阶段,数据恢复后进行验证确认,数据验证无误,交易完成。
④ 开始数据恢复专业施工
安排专业数据恢复工程师团队全程服务,告知客户数据恢复过程注意事项及相关方案措施,并可根据客户需求及数据情况,可选择上门恢复/远程恢复。
数据恢复过程中,团队随时向您报告数据恢复每一个节点工作进展(数据扫描 → 数据检测 → 数据确认 → 恢复工具定制 → 执行数据恢复 → 数据完整性确认)。
⑤ 数据验收/安全防御方案
完成数据恢复后,我司将安排数据分析工程师进行二次检查确认数据恢复完整性,充分保障客户的数据恢复权益,二次检测确认后,通知客户进行数据验证。
客户对数据进行数据验证完成后,我司将指导后续相关注意事项及安全防范措施,并可提供专业的企业安全防范建设方案及安全顾问服务,抵御勒索病毒再次入侵。
我们在此郑重承诺:
不成功不收费
全程一对一服务
365天不间断服务
免费提供安全方案
24h服务热线:
18894665383
17864099776
18299173318