前情提要:LockBit 4.0 是自2019年以来最活跃的勒索软件组织之一,采用双重勒索策略并具备高度专业化运营能力。尽管在2024年遭遇国际打击并被揭露核心身份,该组织仍迅速恢复并于2025年推出LockBit 4.0版本。2025年5月,其运营数据库泄露暴露了大量内部细节。详情可见【独家揭秘】LockBit 4.0 解密器失效|首发谈判日志+万字深剖:发展脉络 · TTP 演进 · 2025最新 IOC。
本文将重点分析我们在该用户受害设备上提取到的 LockBit 4.0 加密器样本,揭示其程序行为及加密特征。在此前的分析中,我们曾对一款盗版LockBit 3.0加密器进行深入研究,发现其在对MSSQL数据库文件加密时,仅加密了文件头部内容,主体数据并未受损。
基于这一特征,我们通过修复数据库结构的方式成功实现了数据恢复,相关技术细节可参考文章【成功案例】lockbit家族百万赎金不必付!技术手段修复被加密的数据库,附溯源分析报告。我们将在接下来的两篇文章中,深入解析该版本解密器存在缺陷的技术原因,并免费公开本次成功研发的专属数据恢复工具,欢迎持续关注。
| 描述 | 说明 |
|---|---|
| 名称 | f53f84ac24e0ae43cd5b59a0e031d6423f8dce2400d21e0d59ea5511b57f256f.vir |
| 大小 | 61,952 bytes |
| 样本路径 | C:\users\mcadmin\desktop |
| 操作系统 | windows |
| 架构 | 80386 |
| 类型 | PE文件 |
| 字节序 | 小端 |
| MD5 | 004422b08f2b638179d5a75e64bf0af9 |
| SHA1 | af726bedd69174990bb6b1dea902f318ca780adf |
| SHA256 | bd0649d701f4092c4431b1e597d9a61afff7fcad0b304e1f433cffff42190760 |
文件名:Restore-My-Files.txt

分析的样本中加密器与提供的解密器不配套,但核心加密算法完全一致,仅存在密钥差别,后文将详细解释.
| 病毒家族 | Lockbit系列 |
|---|---|
| 首次出现时间/捕获分析时间 | 2025/4/14 |
| 威胁类型 | 勒索软件,加密病毒 |
| 加密文件扩展名 | .随机12bytes小写hex字符串 |
| 勒索信文件名 | Restore-My-Files.txt |
| 有无免费解密器? | 无 |
| 联系邮箱 | 无 |
| 感染症状 | 无法打开存储在计算机上的文件,以前功能的文件现在具有不同的扩展名(例如,solar.docx.随机12bytes小写hex字符串)。桌面上会显示一条勒索要求消息。网络犯罪分子要求支付赎金(通常以比特币)来解锁您的文件。 |
| 感染方式 | 受感染的电子邮件附件(宏)、恶意广告、漏洞利用、恶意链接 |
| 受灾影响 | 所有文件都经过加密,如果不支付赎金就无法打开。其他密码窃取木马和恶意软件感染可以与勒索软件感染一起安装。 |
3.2.1 文件1 sierting.txt
加密前:

加密后:

3.2.2 文件2 公司logo 透明.png
加密前:

加密后:

3.3.1 加密后文件名
加密文件名 = 原始文件名+.(12bytes随机小写hex字符串) ,例如:sierting.txt.12345678abcd
3.3.2 加密后文件结构
在文件中,在被加密数据之后,多出92bytes附加信息,结构如下:

3.3.3 加密算法概览
使用自定义512位类sha512哈希算法生成文件密钥的加密密钥,使用了chacha20-poly1305算法,具体使用chacha20作为文件加密算法,文件加密密钥使用ecdh密钥交换算法(x25519)生成,使用poly1305算法和普通的异或计算字符串校验被加密文件的密钥.

4.2.1 脱壳
该样本使用自定义加壳器加壳,脱壳方式如下:
使用pe编辑器打开样本文件,去除PE文件头中的aslr配置(动态基址).


入口函数如下:

找到其中的常量跳转,即为跳往oep的指令:

动调程序,下硬件断点并跟进,到达oep:

设置好入口点,自动查找iat即可(如有错误项则删除):

dump修复好后,打开dump修复后文件,改变data(入口点所在段)属性为下图:

保存,即脱壳成功.

4.2.2 加密算法相关
假设有两个端点进行密钥交换,为加密端(器)和解密端(器).加密端存有黑客公钥,解密端存有黑客私钥.
加密端加密时候使用随机算法生成每个文件的文件私钥(经过一定处理的随机32bytes长字节串),根据文件私钥和32bytes的数字0x9进行标量乘法,计算出文件公钥写入被加密后的文件,使用文件私钥和黑客公钥生成共享密钥,使用共享密钥进行文件加密.
解密时,读取文件中的文件公钥,与解密器中的黑客私钥进行密钥交换得到与上文相同的共享密钥,然后使用共享密钥解密文件.

使用双线程加密,一个获取路径,一个加密路径对应的文件.


计算计数器的地方有一些干扰指令,但是动调能得出初始结果为1.

先获取随机密钥(32bytes,后作为文件块密钥),然后将其前[0,24]下标对应byte和[8,32]下标对应byte异或,存入新数组v179.
再次生成32bytes随机数,作为x25519的随机标量(文件私钥).
执行x25519标量乘法,即32bytes大数0x9和文件私钥相乘,与黑客公钥交换得到共享密钥v217.
自定义哈希结构体内容(开头部分代码和常数模仿sha512,具有一定迷惑性):

将字节串拼接(共享密钥+文件公钥),使用自定义哈希计算得到64bytes的结果,取前32bytes.
将前面取得的32bytes哈希再次以同样的方法哈希,取前24bytes.
使用得到的24bytes哈希初始化自定义的chacha20密钥ctx,使用自定义的初始化算法.

自定义chacha20结构体内包含数据如下:

和标准chacha20的密钥结构相同,此处使用的是8bytes counter和8bytes nonce这一标准.
然后加密该结构体.样本中算法与标准chacha20的区别就是此处有加密这64bytes数据.
密钥流生成时,key为一个32bytes字节串,拷贝加密后的ctx中的[0:16]字节到key的[0:16]下标处,再拷贝加密后的ctx中的[48:64]字节到key的[16:32]下标处,拷贝B的[16:24]字节,作为加密文件密钥的nonce传入密钥拓展函数.这些密钥数据用于chacha20-poly1305校验以及加密加密文件用的密钥.
//密钥流生成算法
int __usercall file_enc_or_gen_key@<eax>(
char *action@<edx>,
int output@<ecx>,
unsignedint input_len,
int key,
int nonce,
__int64 counter)
{
int i; // ebp
int v9; // eax
int j; // eax
char *v11; // eax
int k; // ecx
int v14[4]; // [esp+0h] [ebp-D0h] BYREF
char v15[32]; // [esp+10h] [ebp-C0h] BYREF
__int64 v16; // [esp+30h] [ebp-A0h]
char v17[8]; // [esp+38h] [ebp-98h] BYREF
int v18[16]; // [esp+40h] [ebp-90h] BYREF
int v19[20]; // [esp+80h] [ebp-50h] BYREF
cpy_dw((int)&unk_420498, (int)v14, 4); // 拷贝n个dwords
cpy_dw(key, (int)v15, 8);
cpy_dw(nonce, (int)v17, 2);
v16 = counter;
for ( i = 0; i != input_len >> 6; ++i )
{
chacha20_main(v18, v14); // 标准20轮chacha20算法操作
v9 = 0;
if ( action )
{
while ( v9 != 16 )
{
*(_DWORD *)(output + v9 * 4) = *(_DWORD *)&action[v9 * 4] ^ (v18[v9] + v14[v9]);
++v9;
}
action += 64;
output += 64;
}
else
{
while ( v9 != 16 )
{
*(_DWORD *)(output + v9 * 4) = v18[v9] + v14[v9];
++v9;
}
output += 64;
action = 0;
}
LODWORD(v16) = v16 + 1;
if ( !(_DWORD)v16 )
++HIDWORD(v16);
}
if ( (input_len & 63) != 0 )
{
chacha20_main(v18, v14);
for ( j = 0; j != 16; ++j )
v19[j] = v18[j] + v14[j];
v11 = a2;
if ( action )
v11 = action;
for ( k = 0; (input_len & 63) != k; ++k )
*(_BYTE *)(output + k) = *((_BYTE *)v19 + k) ^ v11[k];
zeroit((int)v19, 64); // 清零n个bytes
}
zeroit((int)v18, 64);
return zeroit((int)v14, 64);
}
使用chacha20-poly1305算法校验密钥,使用前面拓展的密钥流,输入文件公钥和加密文件的密钥,输出16字节校验码.

拷贝16bytes校验码,进行第二次校验,得到最终文件尾部附加信息,先行写入文件.
第二次校验,生成8bytes随机数,与常量字符串经过一系列运算得到12bytes字符串校验值,实际使用该校验值已经能够较精确地判断文件是否被加密.
第二次校验ida伪码如下:

第二次校验c语言代码如下:
bool is_file(BYTE* a2)
{
char* magic2="FBIsosite";//常量字符串值
BYTE v4 = a2[0];
BYTE v8 = a2[2] ^ v4 ^ 9;
char dst[10] = { 0 };
for (DWORD i = 0; i < 9; i++)
{
*(BYTE*)(a2 + i + 3) ^= v8;
*(BYTE*)(a2 + i + 3) -= v8;
*(BYTE*)(a2 + i + 3) ^= v4;
}
memcpy(dst, a2 + 3, 9);
if (!strcmp(dst, magic2))
{
returntrue;
}
returnfalse;
}

文件加密部分掺杂着一些干扰指令,不过不影响分析.

使用64位整数存储文件大小,保证能加密较大的文件.

对于小于1mb的文件,全部加密,对于大于1mb的文件,对如下区间作相应处理:
伪码变量定义:
block_sz = 9 * (file_size / 100) //加密块大小
gap_sz = ((file_size - 27 * (file_size / 100)) >> 1)//间隔大小
block_start = block_sz + gap_sz //一组(加密+不加密)数据大小
以下为加密区间:
[0, block_sz]
[block_start, block_sz]
[block_start * 2, file_size - block_start * 2]
以下为不加密区间:
[block_sz, gap_sz]
[block_start + block_sz, gap_sz]

使用chacha20分块加密写入文件,分块以避免加密时占用过多内存。
4.2.3 程序常规行为
4.2.3.1 获取api地址
样本采用多次hash获取api地址方法,大致上是先hash获取一次模块基址,再hash api名字获取api地址.
例子(调用NtProtectVirtualMemory):
4.2.3.2 hash算法
整个样本统一使用以下hash算法:

Hook ETW实现绕过保护.


解密一些字符串,包含chacha20常量(不再赘述) 和校验用字符串"FBIsosite".
解密勒索信.


根据键盘输入法代码检测是否是俄语输入法.


常规提权操作.


参数如下:(为程序的--help选项输出)
-m local:只加密本地文件
-m net:包含网络路径
-p <path>:加密指定路径
-f:强制加密,无视文件夹名限制
-k:不执行自删除
-q:静默模式,不输出
-nomutex:不创建互斥锁,即非单例运行.
原文如下:

使用api获取系统架构和版本.

读取pe头获取子系统版本.

该程序使用生产者-消费者模型.此处创建线程以及用于控制的信号量.

根据输入配置决定是否进行自删除.


调用wmi删除卷影备份.


改变文件索引方式.
初始化socket.

调用WSAIOctl获取异步客户端连接api ConnectEx.原因不再赘述.

获取本机地址.

初始化iocp.
遍历arp缓存中的所有ip.

创建ip遍历获取线程.


创建ip连接测试(扫描)线程.即iocp的完成包处理线程.


打开遍历服务对象.

枚举服务.


遍历结果中的服务名.使用前文所述hash算法比对服务名.

打开服务对象.

如果服务在运行,则发送停止控制码.

判断服务是否已停止.

未停止则再次尝试.

释放资源.

拷贝A-Z大写字母表.
遍历所有本地驱动器.





遍历网络驱动器.



判断驱动器类型.
为本地驱动器,立即释放信号量.


为网络驱动器,则进入队列.

为cd-rom则跳过.

等待加密信号量.

获得信号量后,开始加密.
先在每一个路径下写入前文所述勒索信.
再根据文件后缀白名单和目录白名单,获取要加密的文件目录及其中文件.

写入公用缓冲区,由加密线程加密.
文件后缀白名单如下:
[".exe", ".dll", ".sys"]
目录白名单如下:
["Temp", "$Recycle.Bin", "$RECYCLE.BIN","System Volume Information", "Boot", "Windows","WINDOWS"]



该勒索病毒样本采用自定义类SHA512哈希算法生成文件加密密钥,结合X25519椭圆曲线密钥交换算法生成共享密钥,进而派生出ChaCha20-Poly1305密钥流对目标文件进行分块加密;其加密策略对小于1MB的文件进行全量加密,对大文件则采用“9%加密+间隔跳过”的方式提升效率,且通过嵌入魔术字符串“FBIsosite”进行加密标识校验;整体流程涵盖自定义脱壳、API哈希解析、ETW绕过、勒索信写入、系统信息收集、服务停止、卷影删除、本地与网络驱动器遍历、445端口和RDP扫描等,形成一套集加密、传播、干扰、防逃逸于一体的完整攻击链,具备较高的工程化水平与防分析能力。