最近群晖大量用户都被勒索软件攻击,文件被恶意加密,并要求支付比特币赎金才能恢复数据。很不幸我的自建黑群晖NAS 也中招了,被勒索软件两次加密,其中一波的密钥永久丢失,还好我的磁盘格式是Btrfs,可以通过技术恢复。这篇只讲技术:攻击是怎么进来的,以及在没有密钥的前提下,数据凭什么还能回来。
这不是一篇「我用了什么工具」的清单,而是一条可以复用的推理链:从暴露面、注入方式、加密实现,一直到文件系统层面的恢复依据。
为控制信息量,文中不列具体规模、时间、主机与文件信息;所有结论都不依赖这些细节成立。
PART 01先看四个结论
| 01 · 入口管理面直接挂在公网自建穿透隧道把管理页、SSH 和一批应用端口一起映射出去,长期可被扫描。 | 02 · 手法加密器不原地覆盖它写出密文新块,再把文件索引指过去,原明文块并没有被抹掉。 |
|---|---|
| 03 · 转机旧数据块仍在盘上借助文件系统元数据定位旧块,按原偏移读出来就是明文,无需密钥。 | 04 · 纪律只读,且用三层证据恢复期间不往盘上写;验收不靠「能打开」,靠块校验、哈希与结构解码。 |
一句话结论: 这次恢复成立,不是因为拿到了密钥,而是因为加密器「写得不够彻底」,以及我们在动手之前先做到了「不往盘上再写一个字」。PART 02两波加密,两种命运
攻击者先后投了两次加密程序。两波的规模差着数量级,但真正影响恢复策略的,是密钥的两种结局。
| 维度 | 第一波 | 第二波 |
|---|---|---|
| 目标 | 照片、视频、文档等数据主区 | 系统日志、配置与崩溃转储 |
| 密钥 | 随进程死亡而丢失 | 进程存活时提取 |
| 恢复路线 | 文件系统旧块直读 / 拼装 / 雕复 | 密钥离线解密 |
| 技术意义 | 迫使整条恢复路线绕开密钥 | 解出日志,攻击链才得以闭环 |
第一波扫过数据主区,加密了几乎所有照片、视频和文档;第二波文件极少,却偏偏是日志、配置和崩溃转储——正是这些「不起眼」的文件,让整条攻击链最终能被还原。
第二波加密时进程还活着,密钥被完整提取;第一波进程早已死亡,密钥随进程内存一起永久释放。全量内存、交换区和崩溃转储都做过穷尽排查,确认没有残留——这条路必须放弃,转而向下找。
PART 03攻击链:五个环节,一条线
现场日志被同一波勒索加密,但用已掌握的那把密钥解开之后,攻击过程可以完整闭环。
STEP 1暴露面:自建隧道把 NAS 推到公网为了远程访问,用内网穿透工具把管理页、SSH 和十来个应用端口一并映射到公网,长期处于可被扫描的状态。STEP 2注入:登录接口的用户名字段在登录接口的用户名字段里塞入环境变量,借动态链接器的调试输出把内容写成文件——绕过了正常命令执行。STEP 3持久化:每分钟一次的定时任务注入产物落进系统定时任务目录,形成每分钟拉取远程脚本的入口,即使重启也能复活。STEP 4投放:远程脚本落地加密器定时任务拉取攻击者服务器上的脚本执行,下载并释放加密器与伴生文件。STEP 5加密与自清理:改名、写勒索信、删痕迹文件被追加统一后缀并写入勒索信,随后删除定时任务、投放文件与脚本本身。图 1 · 每个环节都有对应的日志证据,攻击链才能闭环。注入载荷(日志中的原始结构,已替换敏感字段)LD_PRELOAD=<占位> NOP
-
-
-
-
- root echo | base64 -d | sh
NOP PLUGIN_VALUE_END LD_DEBUG=libs
LD_DEBUG_OUTPUT=/etc/cron.d/<随机名>
- root echo | base64 -d | sh
-
-
-
这里的技术点值得单独说:动态链接器加载共享库时会读取环境变量,而调试输出选项可以把加载记录写到指定路径。攻击者把路径指向系统定时任务目录,于是「调试日志」直接变成了「定时任务文件」——不需要命令执行,也能落地持久化。
base64 解开后是一条拉取执行命令,指向攻击者服务器。所有连接都经隧道回源,日志里的来源看上去就来自内网——这是溯源初期最容易被误导的地方。
相对时间线(隐去具体日期)T-数月隧道开始对外暴露管理页、SSH、相册、密码库、下载器等端口长期可被公网访问,没有任何来源限制。D0 深夜第一波加密开始先扫数据副卷,随后向主数据区推进。D1 凌晨主数据区被加密,随后自清理先删定时任务,再启动主区加密,最后删除伴生文件——清理顺序本身就是证据。D1 上午加密进程被杀,密钥释放这一刀终结了加密,也终结了凭密钥解密的可能——这也是恢复策略必须转向的原因。D1 夜间SSH 暴力破解骤增失败尝试持续不断,说明攻击者始终在线,隧道并没有因为一次加密而收手。D2 清晨二次注入与第二波加密同样的注入手法再次奏效,这一波覆盖全部卷的日志、配置与崩溃转储。D2 午后冻结勒索进程,进入取证进程被挂起,全部线程保持停止,为后续内存取证保留现场——这是整轮恢复最关键的一步。D2 夜间 → D3密钥提取、旧块恢复、块雕复先用密钥解日志还原攻击链,再用文件系统旧块恢复媒体库,最后对不可达文件做块级雕复。
根因其实只有三点。
| 直接入口管理面与 SSH 直接暴露在公网,长期被扫描,没有来源限制,也没有强制双因素。 |
|---|
| 利用点登录接口的输入未经过滤,可以注入环境变量,进而写入系统级定时任务。 |
| 放大因素服务以高权限运行、没有独立离线备份、也没有出站白名单,一次入侵就能横扫全部数据。 |
PART 04为什么没有密钥也能恢复
关键在于文件系统的写时复制(CoW)。加密器并没有原地覆盖数据,而是写入新块,再修改文件索引指向新块。旧块在被回收之前一直躺在磁盘上,只是「没人指向它」。
图 2 · 加密只改写索引,旧数据块留在原处。
只要找到那块旧数据,按文件原本的偏移读出来,内容就是加密前的原文——不需要任何密钥。文件系统为每个数据块记录的 CRC32C 校验值,还能用来逐块验证读出来的字节是否正确。
图 3 · 形态决定可恢复比例:只有全文件加密没有旧块可用。旧块不是永久存在的。文件被改写、快照被清理、空间被复用,都会让旧块消失——所以恢复必须趁早,且全程只读,不能再往盘上写任何东西。
PART 05恢复是怎么一步步做成的
顺序很重要:先做小样本,验证「旧块真的能读出来」,再做全量只读预检,把每个文件判定成可恢复或不可恢复,最后分批执行、逐文件校验。整个过程没有向 NAS 写入任何字节。
① 试点: 用少量样张覆盖每种加密形态,全部通过才继续
② 全量预检: 逐文件枚举旧块,先分类,不动数据
③ 批量执行: 按类型分批,先小后大,边恢复边记账
④ 三层终验: 逐块校验 → 全文件哈希 → 格式结构解码图 4 · 分类先行,避免把不可恢复的文件反复重试。
顺带解释一个反直觉的现象:文件越大,越容易碎片化。大文件在盘上往往被拆成许多区块,加密时只有一部分被改写,于是旧块散落在不同位置,必须按窗口拼装。数据其实都在,只是读取逻辑复杂得多,这也是整轮恢复里最耗时的部分。
三层终验:不靠「能打开」下结论
| 第一层 · 逐块校验每个 4 KiB 数据块都与文件系统记录的 CRC32C 比对,块级不一致立即暴露。 |
|---|
| 第二层 · 全文件哈希文件写入独立外部盘后重新读取并计算 SHA256,排除传输与落盘阶段的损坏。 |
| 第三层 · 结构解码照片全图像素解码、视频容器结构走查、压缩包 CRC 解压、数据库完整性检查——确保不是「字节对了但文件废了」。 |
终验不是形式。正是第三层结构解码,让我们抓到过「哈希完全正确、但视频索引损坏」的情况——这类文件如果只看哈希,会被当成成功交付。
PART 06几个差点把人带偏的坑只看当前事务,会误判「没有旧块」文件系统的元数据分布在多个事务里,只比对当前事务的版本号,会把本来存在的旧块判成不存在。必须跨事务枚举。校验值对得上,不代表文件能用曾出现过哈希完全正确、但容器索引被破坏的文件。结构解码必须作为独立一层,不能合并进哈希校验。雕复时用错目标尺寸不同加密形态的原文长度算法不同,用错公式会让雕出来的文件「多出几十字节」,解码直接失败。容器长度字段的字节序视频容器内部的长度字段是大端,按小端解析会让整条结构链错位,看起来像「数据损坏」,其实只是读法错了。对齐巧合造成的假命中块雕复时,某些随机数据恰好能拼出合法的头部结构。必须追加身份交叉验证,否则会把垃圾当成果。扩展名不可信加密器统一加了后缀,恢复后不能按后缀直接还原类型,要按文件头与容器结构判定真实格式。一条硬规则:不输出纯零文件。 如果某个区间确实无法恢复,就明确标记为缺失并记录缺失长度,而不是用零填充假装完整——后者会让后续校验和业务判断全部失真。
PART 07哪些情况救不回来
写这篇的目的不是证明「总能恢复」,恰恰相反:这套方法有明确的失效边界。
| 全文件加密 | 没有留下任何明文段,旧块路线完全失效,只能靠密钥或整卷雕复。 |
|---|---|
| 旧块已被回收 | 加密之后继续使用、写入或触发快照清理,旧块会被逐步释放,窗口期就此关闭。 |
| 小文件被整体覆盖 | 文件本身小于被加密的固定长度时,等于全文件加密,没有可回收的明文段。 |
| 元数据损坏 | 连文件索引本身都被破坏时,就无法知道旧块属于哪个文件、处于哪个偏移,只剩下低概率的块雕复。 |
换一个角度说:这套方法本质上是在和「空间回收」抢时间。越早冻结、越早只读、越少写入,成功率越高。
另外要强调一句:数据恢复完成不等于事件闭环。当时暴露的公网隧道仍在运行,系统本身也没有重装——这两件事不解决,恢复出来的数据随时可能再次被加密。
如果重来一次,会按这个顺序做
| 立即切断公网暴露面,改全部凭据,封禁投放服务器,冻结勒索进程保住现场。 | 短期SSH 改公钥并关闭密码登录,管理面加白名单与双因素,开启自动封锁。 |
|---|---|
| 中期建立离线 / 异地备份并定期演练恢复;应用最小权限运行,配置出站白名单。 | 长期重装系统、留档攻击指纹、建立日志集中留存与异常告警。 |
PART 08三条值得记住的纪律一、先冻结,再排查。 勒索进程一旦被杀,内存里的密钥就没了;先停住它,取证和恢复才有退路。
二、只读优先。 恢复期间任何写操作都可能覆盖旧数据块,宁可慢,也不要往盘上写。
三、用三层证据说话。 块校验、全文件哈希、结构解码,缺一层都可能把损坏文件当成成功。如果只记一件事: 这次数据能回来,不是因为技术多高明,而是因为加密器没有覆盖原数据,而我们在动手前先做到了不往盘上写。运气只负责了一部分,纪律负责了剩下的。
最后提醒一句:这类恢复路线依赖文件系统的写时复制特性,不是所有系统都有同样的机会。真正的解法永远只有一个——可验证的离线备份。