-
-
[原创]【病毒分析】伪造微软官网+勒索加密+支付威胁,CTF中勒索病毒解密题目真实还原!
-
发表于: 3天前 1018
-
该CTF挑战题目完整复现了黑客的攻击链路,攻击者通过伪造钓鱼页面引导受害者下载恶意软件。用户访问伪造的 Microsoft 365 官网后,在点击“Windows Installer (64-bit)”下载选项时,页面会自动跳转至伪造的 GitHub 项目链接,并下载加密器的恶意程序。
伪造Microsoft 365官网
受害者双击运行该程序后,勒索软件会访问远程服务器加载定制的hacked.png图片并当作壁纸,通过调用api遍历文件,判断文件后缀是否为.Montelli,加密完文件后创建一个被加了勒索后缀的文件,从而完成攻击链闭环。(目前该服务器已关停,无法访问该图片)
远程服务器:https://raw.githubusercontent.com/R4ven1elia/something/refs/heads/main/hacked.png
定制图片
在所有文件被添加.Montelli后缀后,会弹出的勒索提示信息告知受害者支付1337美元到黑客提供的Pi网络钱包地址 。
翻译:
噢,不!你的文件被劫持了!
亲爱的极其不幸的电脑用户,
我们很遗憾地通知你,你珍贵的文件被现存最复杂、训练有素、极其懒惰的勒索软件绑架了。但是不要害怕!你可以找回他们!
如何恢复它们?
不要害怕,我亲爱的用户,
你可以简单地在Pi网络中支付我们1337美元,我们已经为你提供了我们Pi网络钱包的地址,只要转账给我们1337,我们会给你发送你的解密密钥
发送1337$到此Pl网络地址,否则您的所有数据将被删除!!
加密文件名 = 原始文件名+Montelli,例如:sierting.txt.Montelli
文件加密使用rc4算法,密钥嵌入加密器中。
根据rc4密钥初始化s数组
根据输入的s数组对输入的数据进行加密,由于加密完成后未对S盒进行重置操作,因此会导致如下问题
加密存在BUG:
在创建多线程的部分,该勒索的所有多线程仅仅只处理了一次RC4的SBOX初始化部分,加密完毕后并未针对RC4的SBOX再次初始化,所以就导致了RC4加密后,SBOX的值发生改变,所以会影响后续加密。
将自带的字符串解码后并执行
解码后结果如下,该代码的作用是在远程加载一个图片并当作壁纸
将这个写入C:\\Users\\username\\dosomething.ps1
并执行如下poweshell指令,隐藏窗口执行上面的替换壁纸的代码
调用api遍历文件
判断后缀是否为.Montelli
加密完文件后创建一个被加了勒索后缀的文件,然后写入加密内容
删除原文件
使用多线程异步执行加密
恢复思路如下:调用rc4算法使用密钥FLAG{s1mpl3_3nCrYpt1on_
对加密文件解密。
但是由于该加密器加密存在bug:在创建多线程的部分,该勒索的所有多线程仅仅只处理了一次RC4的SBOX初始化部分,加密完毕后并未针对RC4的SBOX再次初始化,所以就导致了RC4加密后,SBOX的值发生改变,所以会影响后续加密。因此使用密钥解密只能解密出少数几个文件,恢复代码如下
本案例中,Montelli勒索软件因硬编码密钥暴露(FLAG{s1mpl3_3nCrYpt1on_
)导致可以对被加密文件进行解密,但是由于RC4加密实现缺陷(S盒单次初始化+状态污染)导致加密漏洞,结合其只能解密小部分文件。
文件名 | office64 |
---|---|
编译器 | Microsoft Visual C/C++(19.36.34435)[LTCG/C++] |
大小 | 300 KB |
操作系统 | Windows(Vista)[AMD64, 64位, Console] |
架构 | 386 |
模式 | 64 位 |
类型 | EXEC |
字节序 | LE |
MD5 | b7da7b88697e543da7c734ff276b5fe2 |
SHA1 | 0f9429137d002162c3cf00df80ff352333a715da |
SHA256 | 09faaeeb52d5c0bdba222478e9787a5232bb88003ea42282bd7edc855a320de3 |
病毒家族 | Montelli |
---|---|
首次出现时间/捕获分析时间 | 2025/02/28 || 2025/03/7 |
威胁类型 | 勒索软件,加密病毒 |
加密文件扩展名 | .Montelli |
感染症状 | 无法打开存储在计算机上的文件,以前功能的文件现在具有不同的扩展名(例如,solar.docx.Montelli)。桌面上会显示一条勒索要求消息。网络犯罪分子要求支付赎金(通常以比特币)来解锁您的文件。 |
感染方式 | 受感染的电子邮件附件(宏)、恶意广告、漏洞利用、恶意链接 |
受灾影响 | 所有文件都经过加密,如果不支付赎金就无法打开。其他密码窃取木马和恶意软件感染可以与勒索软件感染一起安装。 |
FLAG{s1mpl3_3nCrYpt1on_
FLAG{s1mpl3_3nCrYpt1on_
__int64
__fastcall sub_140002E70(unsigned
__int64
a1, _QWORD *a2)
{
char
*v3;
// rbp
__int64
n256;
// rsi
__int64
v6;
// rdx
unsigned
__int64
n0x100;
// rcx
char
*v8;
// rax
unsigned
__int64
v9;
// rbx
__int64
v10;
// rdx
__m128i si128;
// xmm3
int
n256_1;
// ecx
__int64
v13;
// rdx
__m128 v14;
// xmm2
unsigned
int
n8;
// ecx
__int64
n8_1;
// r8
unsigned
int
v17;
// eax
__m128i v18;
// xmm0
__m128i v19;
// xmm1
__m128i v20;
// xmm0
__m128i v21;
// xmm1
__m128i v22;
// xmm0
__m128i v23;
// xmm0
__m128i v24;
// xmm0
__m128i v25;
// xmm1
__m128i v26;
// xmm1
__int64
v27;
// r8
unsigned
__int64
v28;
// r9
_QWORD *v29;
// rcx
__int64
v30;
// r10
int
v31;
// eax
char
v32;
// cl
__int64
v33;
// rdx
__int64
result;
// rax
v3 = *(
char
**)(a1 + 8);
n256 = 256LL;
v6 = *(_QWORD *)a1;
n0x100 = (unsigned
__int64
)&v3[-*(_QWORD *)a1];
if
( n0x100 <= 0x100 )
{
if
( n0x100 >= 0x100 )
goto
LABEL_8;
if
( (unsigned
__int64
)(*(_QWORD *)(a1 + 16) - v6) < 0x100 )
{
sub_140008E60(a1);
goto
LABEL_8;
}
v9 = 256 - n0x100;
memset
(v3, 0, 256 - n0x100);
v8 = &v3[v9];
}
else
{
v8 = (
char
*)(v6 + 256);
}
*(_QWORD *)(a1 + 8) = v8;
LABEL_8:
v10 = *(_QWORD *)a1;
si128 = _mm_load_si128((
const
__m128i *)&xmmword_14000D850);
n256_1 = 0;
if
( *(_QWORD *)a1 > a1 || *(_QWORD *)a1 + 255LL < a1 )
{
v14 = (__m128)_mm_load_si128((
const
__m128i *)&xmmword_14000D860);
n8 = 8;
n8_1 = 8LL;
do
{
n8_1 += 16LL;
v17 = n8 + 4;
v18 = (__m128i)_mm_and_ps((__m128)_mm_add_epi32(_mm_shuffle_epi32(_mm_cvtsi32_si128(n8 - 8), 0), si128), v14);
v19 = (__m128i)_mm_and_ps((__m128)_mm_add_epi32(_mm_shuffle_epi32(_mm_cvtsi32_si128(n8 - 4), 0), si128), v14);
v20 = _mm_packus_epi16(v18, v18);
v21 = _mm_packus_epi16(v19, v19);
*(_DWORD *)(v10 + n8_1 - 24) = _mm_cvtsi128_si32(_mm_packus_epi16(v20, v20));
*(_DWORD *)(v10 + n8_1 - 20) = _mm_cvtsi128_si32(_mm_packus_epi16(v21, v21));
v22 = _mm_cvtsi32_si128(n8);
n8 += 16;
v23 = (__m128i)_mm_and_ps((__m128)_mm_add_epi32(_mm_shuffle_epi32(v22, 0), si128), v14);
v24 = _mm_packus_epi16(v23, v23);
v25 = (__m128i)_mm_and_ps((__m128)_mm_add_epi32(_mm_shuffle_epi32(_mm_cvtsi32_si128(v17), 0), si128), v14);
*(_DWORD *)(n8_1 + v10 - 16) = _mm_cvtsi128_si32(_mm_packus_epi16(v24, v24));
v26 = _mm_packus_epi16(v25, v25);
*(_DWORD *)(v10 + n8_1 - 12) = _mm_cvtsi128_si32(_mm_packus_epi16(v26, v26));
}
while
( (
int
)(n8 - 8) < 256 );
}
else
{
v13 = 0LL;
do
*(_BYTE *)(++v13 + *(_QWORD *)a1 - 1) = n256_1++;
while
( n256_1 < 256 );
}
*(_DWORD *)(a1 + 28) = 0;
v27 = 0LL;
v28 = 0LL;
do
{
v29 = a2;
if
( a2[3] > 0xFuLL )
v29 = (_QWORD *)*a2;
v30 = *(_QWORD *)a1;
v31 = (*(_DWORD *)(a1 + 28) + *(unsigned
__int8
*)(*(_QWORD *)a1 + v27) + *((unsigned
__int8
*)v29 + v28 % a2[2]))
% 256;
*(_DWORD *)(a1 + 28) = v31;
++v28;
v32 = *(_BYTE *)(v30 + v27);
v33 = v31;
result = *(unsigned
__int8
*)(v31 + v30);
*(_BYTE *)(v30 + v27++) = result;
*(_BYTE *)(v33 + v30) = v32;
--n256;
}
while
( n256 );
*(_QWORD *)(a1 + 24) = 0LL;
return
result;
}
__int64
__fastcall sub_140002E70(unsigned
__int64
a1, _QWORD *a2)
{
char
*v3;
// rbp
__int64
n256;
// rsi
__int64
v6;
// rdx
unsigned
__int64
n0x100;
// rcx
char
*v8;
// rax
unsigned
__int64
v9;
// rbx
__int64
v10;
// rdx
__m128i si128;
// xmm3
int
n256_1;
// ecx
__int64
v13;
// rdx
__m128 v14;
// xmm2
unsigned
int
n8;
// ecx
__int64
n8_1;
// r8
unsigned
int
v17;
// eax
__m128i v18;
// xmm0
__m128i v19;
// xmm1
__m128i v20;
// xmm0
__m128i v21;
// xmm1
__m128i v22;
// xmm0
__m128i v23;
// xmm0
__m128i v24;
// xmm0
__m128i v25;
// xmm1
__m128i v26;
// xmm1
__int64
v27;
// r8
unsigned
__int64
v28;
// r9
_QWORD *v29;
// rcx
__int64
v30;
// r10
int
v31;
// eax
char
v32;
// cl
__int64
v33;
// rdx
__int64
result;
// rax
v3 = *(
char
**)(a1 + 8);
n256 = 256LL;
v6 = *(_QWORD *)a1;
n0x100 = (unsigned
__int64
)&v3[-*(_QWORD *)a1];
if
( n0x100 <= 0x100 )
{
if
( n0x100 >= 0x100 )
goto
LABEL_8;
if
( (unsigned
__int64
)(*(_QWORD *)(a1 + 16) - v6) < 0x100 )
{
sub_140008E60(a1);
goto
LABEL_8;
}
v9 = 256 - n0x100;
memset
(v3, 0, 256 - n0x100);
v8 = &v3[v9];
}
else
{
v8 = (
char
*)(v6 + 256);
}
*(_QWORD *)(a1 + 8) = v8;
LABEL_8:
v10 = *(_QWORD *)a1;
si128 = _mm_load_si128((
const
__m128i *)&xmmword_14000D850);
n256_1 = 0;
if
( *(_QWORD *)a1 > a1 || *(_QWORD *)a1 + 255LL < a1 )
{
v14 = (__m128)_mm_load_si128((
const
__m128i *)&xmmword_14000D860);
n8 = 8;
n8_1 = 8LL;
do
{
n8_1 += 16LL;
v17 = n8 + 4;
v18 = (__m128i)_mm_and_ps((__m128)_mm_add_epi32(_mm_shuffle_epi32(_mm_cvtsi32_si128(n8 - 8), 0), si128), v14);
v19 = (__m128i)_mm_and_ps((__m128)_mm_add_epi32(_mm_shuffle_epi32(_mm_cvtsi32_si128(n8 - 4), 0), si128), v14);
v20 = _mm_packus_epi16(v18, v18);
v21 = _mm_packus_epi16(v19, v19);
*(_DWORD *)(v10 + n8_1 - 24) = _mm_cvtsi128_si32(_mm_packus_epi16(v20, v20));
*(_DWORD *)(v10 + n8_1 - 20) = _mm_cvtsi128_si32(_mm_packus_epi16(v21, v21));
v22 = _mm_cvtsi32_si128(n8);
n8 += 16;
v23 = (__m128i)_mm_and_ps((__m128)_mm_add_epi32(_mm_shuffle_epi32(v22, 0), si128), v14);
v24 = _mm_packus_epi16(v23, v23);
v25 = (__m128i)_mm_and_ps((__m128)_mm_add_epi32(_mm_shuffle_epi32(_mm_cvtsi32_si128(v17), 0), si128), v14);
*(_DWORD *)(n8_1 + v10 - 16) = _mm_cvtsi128_si32(_mm_packus_epi16(v24, v24));
v26 = _mm_packus_epi16(v25, v25);
*(_DWORD *)(v10 + n8_1 - 12) = _mm_cvtsi128_si32(_mm_packus_epi16(v26, v26));
}
while
( (
int
)(n8 - 8) < 256 );
}
else
{
v13 = 0LL;
do
*(_BYTE *)(++v13 + *(_QWORD *)a1 - 1) = n256_1++;
while
( n256_1 < 256 );
}
*(_DWORD *)(a1 + 28) = 0;
v27 = 0LL;
v28 = 0LL;
do
{
v29 = a2;
if
( a2[3] > 0xFuLL )
v29 = (_QWORD *)*a2;
v30 = *(_QWORD *)a1;
v31 = (*(_DWORD *)(a1 + 28) + *(unsigned
__int8
*)(*(_QWORD *)a1 + v27) + *((unsigned
__int8
*)v29 + v28 % a2[2]))
% 256;
*(_DWORD *)(a1 + 28) = v31;
++v28;
v32 = *(_BYTE *)(v30 + v27);
v33 = v31;