首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
数据泄露防护加密文件恢复:进程名白名单与扩展名双条件解析
📅 2026/10/28 4:51:02
✍️ 爱科研究院
👁 阅读 3,247
简介这份docx文档面向需要处理易赛通数据泄露防护客户端加密文件的技术人员聚焦加密文件在未安装客户端环境中无法正常打开的排错与还原需求整理了一套可落地的解密分析思路。文档围绕主进程CDGRegedit、辅助进程EstVPN及Filelock.sys驱动展开说明驱动层Hook与应用层透明加解密的工作方式并归纳进程名与扩展名白名单组合下的加密判定规律。其价值在于结合程序结构与规律分析给出借名合法进程读取密文、另存为非受控扩展名并最终还原文件扩展名的验证思路便于读者理解防护机制并设计自己的文件还原工具。资源包仅含1个docx文档大小约29KB轻量易读适合安全研究、终端数据防护排错及敏感数据迁移场景参考。已有2082人学习具备一定实践参考热度。1. 被数据泄露防护客户端锁住的文件真正的开关不在驱动里去年有台工作机装着单位统一推下来的数据泄露防护客户端硬盘上近百个 .xlsx 和 .docx 全成了打不开的乱码文件。第一反应是逆向那个内核驱动翻了两个通宵的汇编最后真正解决问题的思路只用了不到三十行代码——因为决定一个文件加不加密的不是驱动本身而是它内部维护的两张名单一张进程名白名单一张扩展名列表。数据泄露防护这套机制的本质是进程名 扩展名双条件触发只有同时命中才提供加密和解密服务。这篇把整条链路拆开讲清楚怎么用对照实验反推名单边界、怎么用一次进程改名把明文借出来、工具落地时哪几个参数会让你翻车。新手能照着复现做过终端安全的同行能看到判断依据在哪。2. 摸清对手三个组件的分工与加密触发的真实边界动手之前得先知道自己在跟谁较劲。终端防护类产品看着神秘拆开看基本都是一个界面程序 一个守护程序 一个内核驱动的三段式结构真正干活的是最下面那层前面两个更多是策略和保活。我习惯先按位置和职责把组件列成一张表再决定哪些能碰、哪些碰了会出事。2.1 组件分工谁在拦谁在守谁在加密以我手上这个客户端下文统一称 D 客户端组件名按同类产品的常见命名做了脱敏为例装完之后落地的实体大概是这样组件类型典型文件名落地位置主要职责直接动它的后果主进程DGuard.exe / DGuard64.exe安装目录下的客户端子目录图形界面、策略拉取、用户登录态维护策略拉不下来登录态掉线但已加密文件不受影响守护进程DGuardSvc.exe / DGuardSvc64.exe与主进程同目录监视主进程存活杀掉后拉起会被反复重启且有日志上报内核驱动FltCrypt.sysC:\Windows\System32\drivers文件加解密、关键 API 拦截蓝屏风险且绕过驱动不属于常规恢复手段这张表最有用的一列是最后一列。很多人上来就想干掉主进程觉得界面没了加密就停了——实际完全相反主进程只是策略通道真正决定文件写下去是不是密文的是那个常驻内核的 FltCrypt.sys。你把界面进程结束掉驱动照样在过滤每一笔文件写入。所以正确的判断是主进程和守护进程都不是攻击面它们是干扰项真正要理解的是驱动的判定逻辑。2.2 驱动层拦截为什么让应用层手段全部失效这类产品的实现方式是在驱动层对文件相关 API 做过滤CreateFile、ReadFile、WriteFile 这一串调用在进入内核后会被拦一道判断当前进程和文件扩展名是否命中名单命中就在数据落盘前加密、读取时解密。这个过程对应用层是完全透明的你用记事本打开一个被加密的 .txt看到的是正常文字因为驱动在你读到数据之前已经帮你解好了你另存一份写完的字节在落盘瞬间又被加密回去。这就解释了几个常见的以为能行为什么不行。直接把文件拖到 U 盘复制动作由资源管理器发起这个进程大概率不在白名单里驱动不提供服务拷走的是原始密文插到另一台机器上当然是乱码。用十六进制编辑器打开看文件头看到的也是密文。哪怕是进程内 dump 内存也只能拿到当前进程已经申请过解密服务的那些数据换个进程就读不出来了。真正的突破口藏在时序里解密发生在读的瞬间明文确实在进程的内存缓冲区里存在过。只要能把这批明文写到一个不会被二次加密的位置事情就成了。这句话是整个思路的地基后面所有步骤都是围绕它展开的。2.3 用两组对照实验反推进程名与扩展名名单名单长什么样没人会告诉你但可以黑盒测出来。设计两组单变量对照实验就够了。实验 A 测进程维度。准备若干个可执行文件副本分别命名成常见办公软件、压缩软件的进程名再准备一个随便起的名字做对照组。让每一个都执行同一个动作读取同一个已被加密的 .docx把读到的内容原样写到一个冷门扩展名的文件里。写完逐个检查输出的文件头——.docx 本质是 zip 包正常明文的前四个字节是 PK\x03\x04十六进制 50 4B 03 04如果输出是这四个字节说明读取时驱动提供了服务这个进程名就在白名单里如果是别的字节说明它读到的是密文。实验 B 测扩展名维度。挑一个实验 A 里已经确认在白名单的进程名把同一段内容分别写成 .docx、.txt、.log、.temp、.abc 五种扩展名然后把输出文件拿到一台没装 D 客户端的机器上打开。打不开或乱码的说明落盘时被加密了扩展名在列表里能正常打开的说明没被加密。两组做完判定规则就出来了进程名在白名单目标扩展名在列表写入结果是是加密是否不加密否是不加密否否不加密这张表要注意一点读和写是同一套规则的两个方向。命中双条件时写加密、读解密不命中时读到的本来就是密文、写下去的也是原始字节。所以在实验 A 里只有白名单进程读到的是明文——这正是可以利用的地方。而实验 B 告诉我们白名单进程往冷门扩展名写东西落盘是不加密的。两个结论一拼路径就出来了。提示这类验证务必在自己有权处置的文件上做且优先确认单位是否提供管理员解密通道。技术思路用于应急恢复和理解机制不用于规避管控。3. 借刀杀人让白名单进程替你读让冷门扩展名替你存思路定下来之后实现反而简单。核心就一句话不跟驱动对抗借用它自己的规则。既然它只给名单内的进程提供服务那我们就变成名单内的进程既然它只对名单内的扩展名加密那我们就写到名单外的扩展名去。整个过程分五步每一步都有讲究。3.1 五步链路的完整拆解第一步把工具的可执行文件复制一份重命名成白名单里的进程名比如 winrar.exe。第二步运行这个副本用它去读目标加密文件——此刻驱动认得这个名字会正常解密进程拿到的是明文。第三步把明文写到一个冷门扩展名的文件里比如 .temp——这个扩展名不在列表里写入不会被加密。第四步换一个不在白名单里的进程把 .temp 改回原来的扩展名。第五步校验结果。关键判断在第三步和第四步之间解密其实在第三步就已经完成了第四步只是把扩展名改回去让系统认得出这是什么文件。但如果第四步的改名动作由白名单进程发起、且目标扩展名在列表内那这一下改名又可能触发一次加密判定——这是最容易翻车的地方后面会细说。所以第四步一定要换一个干净的进程来做资源管理器或者命令行都行只要确认它不在名单里。另外一个细节第三步为什么非得写冷门扩展名因为如果直接写成 .xlsx即便发起写入的是白名单进程也会命中双条件被加密回去等于白干。这一步是整个链路里最容易被忽略的环节。3.2 改进程名的三种做法与取舍把自己变成 winrar.exe听着玄实操上有三种路子难度和风险递增。最省事的是复制改名。Windows 判断进程名取的是映像文件名不含路径把 dlpdec.exe 复制一份叫 winrar.exe 放在别的目录里运行进程名就变了。原程序完全不动出问题删掉副本即可这是我在实际恢复里用的方式# 建一个与安装目录无关的独立工作目录避免误覆盖原程序 New-Item -ItemType Directory -Force -Path .\stage | Out-Null # 复制自身并改成白名单内的进程名进程名取映像文件名路径一般不影响判定 Copy-Item .\dlpdec.exe .\stage\winrar.exe -Force # 确认副本的映像名确实是目标名字再看它能否正常启动 Get-Item .\stage\winrar.exe | Select-Object Name, Length Start-Process .\stage\winrar.exe -ArgumentList --selftest这段的重点不在命令本身而在两个约束副本必须放在独立目录绝不能覆盖安装目录下的同名程序启动前先跑一次自检参数确认副本能正常起来——有些版本会校验文件签名或路径改名后的副本直接被拒绝启动这种情况就得回到第二种路子。第二种是改 PE 里的版本信息。用资源编辑类工具把可执行文件属性里的原始文件名、内部名称一并改掉让它在系统看来更像那个程序。这种做法在某些按版本信息比对的版本上有效但改坏了会启动失败属于一次性试验适合先在小文件上验证。第三种是注入或劫持理论上最正实际最不划算要处理位数匹配、会话隔离、权限提升还要跟守护进程的完整性检查抢时间稍有差池就是蓝屏或者被上报。我一般不建议往这个方向走投入产出比太差。3.3 第三步和第四步之间的那个坑前面说第三步写完 .temp 理论上就完事了但真正批量跑的时候第三步和第四步的衔接会出各种幺蛾子这里先把最典型的一个说透。假设你的工具本身就跑在 winrar.exe 这个名字下读完文件、写完 .temp 之后顺手在同一个进程里把 .temp 改名成 .xlsx。这一下改名操作会命中双条件——进程名在名单、目标扩展名也在名单——驱动很可能认为这是一次新建文件于是把内容加密了一遍。结果就是你打开了但内容是乱码还以为是解密失败回头去查驱动逻辑浪费一晚上。正确的做法是把读写临时文件和改回扩展名拆成两个进程、两个阶段中间用文件系统做交接。第一阶段跑在白名单进程里只负责产出明文 .temp第二阶段跑在一个确定不在名单里的进程里只做 rename。这两个阶段之间不需要任何 IPC落盘就是最好的通信方式。这也是我后来固化成流程的一点凡是涉及创建被管控扩展名的动作一律交给非白名单进程做。还有个小细节改名时优先用移动而不是复制。移动在同分卷下只是改目录项不搬运数据内容触发内容加密判定的可能性更低跨分卷复制则会真实读写一遍数据风险高得多。4. 落地实现把思路压成一个能跑的最小工具思路上理顺了工具本身不该复杂。我给自己定的规矩是单文件、无第三方依赖、能跑在任意一台装了客户端的机器上、出问题能靠日志定位。照这个标准做下来核心逻辑不到一百行。4.1 目录结构与参数设计工具的运行时分两个阶段对应两种进程身份所以目录也按阶段分开路径作用谁在里面跑stage\winrar.exe第一阶段副本负责读取密文并产出明文 .temp白名单进程身份out\明文临时文件与最终输出的落地区两个阶段共用log\每个文件的处理记录含哈希和文件头两个阶段共用参数上只保留四个多了记不住也用不上。--src 指定要处理的文件或目录--tmp-ext 指定临时文件扩展名默认 .tmpz--final-ext 指定还原后的扩展名默认沿用原扩展名--verify 打开校验开关处理完做文件头加哈希比对。这个参数设计的好处是第一阶段和第二阶段的命令行完全一致只是执行时换了进程身份脚本里不用写两套逻辑。4.2 核心代码读、写、改名三段工具内部按阶段拆成三个函数第一阶段调用前两个第二阶段只调用最后一个。import os import shutil import hashlib TMP_EXT .tmpz # 冷门扩展名必须确认不在扩展名列表内 CHUNK 4 * 1024 * 1024 # 分块大小大文件避免一次性读进内存 def read_plain(src_path): 第一阶段读取。此函数必须在白名单进程名下执行 驱动会在 ReadFile 返回前完成解密拿到的就是明文。 chunks [] with open(src_path, rb) as f: while True: buf f.read(CHUNK) if not buf: break chunks.append(buf) return b.join(chunks) def write_tmp(data, dst_dir, name): 第一阶段写入。目标扩展名必须冷门 落盘时不触发加密判定写下去的就是明文原始字节。 tmp_path os.path.join(dst_dir, name TMP_EXT) with open(tmp_path, wb) as f: f.write(data) f.flush() os.fsync(f.fileno()) # 强制刷盘避免缓存未落盘就进入第二阶段 return tmp_path def finalize(tmp_path, final_path): 第二阶段改名。此函数必须在非白名单进程名下执行 否则改名瞬间会被判定为新建被管控文件而重新加密。 shutil.move(tmp_path, final_path) return hashlib.sha256(open(final_path, rb).read()).hexdigest()三段代码看着平淡每一句都对应一个判断。read_plain 分块读是为了对付几十兆的表格文件一次性 read 在内存受限的办公机上容易把进程撑爆。write_tmp 里那句 fsync 是踩过坑之后加的——不强制刷盘操作系统缓存还没落盘你就进入第二阶段改名有可能拿到一个长度对但内容不全的文件。finalize 用 shutil.move 而不是 copy理由前面说过同分卷下它只改目录项。至于必须在什么进程名下执行这件事代码层面保证不了只能靠启动方式约束。我的做法是在程序入口读一次自身的映像名和配置里的目标名比对不匹配就直接退出并打日志防止有人在错误的进程身份下跑完全程还以为成功了。4.3 校验别用能打开当唯一标准批量处理上百个文件最怕的是看起来成功了其实坏了一半。校验我固定在三个层次上做跑完一轮就能定位是哪一步出的问题。第一层是文件头。.docx、.xlsx、.pptx 本质都是 zip 容器明文前四字节必是 50 4B 03 04PDF 是 25 50 44 46老式 .doc 是 D0 CF 11 E0。这一步能在不解压的情况下快速筛掉明显的密文。第二层是容器完整性用 zipfile 试着打开并列举条目条目数正常、没有 BadZipFile 异常基本可以确认结构完整。第三层是内容抽检随机抽几个文件用对应的库读一下正文或者直接比对第一阶段产出的临时文件和最终文件的哈希——两者必须一致不一致说明第二阶段被动过手脚。import zipfile def verify_office(path): with open(path, rb) as f: head f.read(4) if head ! bPK\x03\x04: return False, 文件头异常疑似仍为密文 try: with zipfile.ZipFile(path) as z: names z.namelist() return True, f容器正常条目数 {len(names)} except zipfile.BadZipFile: return False, zip 结构损坏可能在写入阶段被截断校验结果一定要写日志别只打在控制台上。批量跑的时候控制台滚得飞快出问题回头根本找不到是哪个文件。日志里至少留四列源路径、临时文件路径、最终路径、校验结论出问题时按结论过滤一眼能看出是哪一类失败。5. 避坑与常见问题五条用时间换来的经验这套流程跑通一次不难难的是稳定跑完一批。下面五条都是我实际翻车之后记下来的每条按现象、原因、解决三段说。5.1 复现阶段最容易翻车的三类现象现象一流程走完了打开还是乱码。原因多半是产出文件的扩展名仍在列表里落盘那一刻被二次加密看起来文件大小对、时间对内容全废。解决办法是把临时扩展名换成确定不在列表里的冷门后缀比如 .tmpz、.binx 这类先用实验 B 的方法验证一遍再批量跑。现象二副本程序刚启动就退出或者启动后读文件报权限错误。原因是有些版本不只比对进程名还会校验映像路径、数字签名甚至检查父进程链。解决办法是先在小文件上做单点试验确认副本能正常读出一个已知明文的文件如果不行退回到改 PE 版本信息的路子再不行就说明这个版本加了额外校验及时止损别在注入上耗时间。现象三处理到一半守护进程把工具副本删了或者改名了。原因是副本放的位置太显眼或者名字和安装目录里的真程序冲突触发了自保护逻辑。解决办法是把副本放到与安装目录完全无关的独立路径用完之后主动清理别长期留在机器上。5.2 结果校验阶段的两类误判现象四一批文件里有的能解、有的不能比例大概三七开。原因不是工具不稳定而是策略本身在变——不同部门、不同时间段下发的扩展名列表可能不一样还有些文件压根不是被加密的是别人用未加密通道另存出来的正常文件。解决办法是处理前先按扩展名分组抽样探测确认这一批到底哪些真被加密了别一股脑全塞进流程白白消耗时间还污染日志。现象五校验全部通过但某个表格打开提示内容有问题是否修复。原因通常是文件本身在被加密之前就已经有损坏或者第一阶段读取时遇到超长路径、文件被占用导致读取截断。解决办法是处理前先记录源文件的原始大小和修改时间处理后比对大小是否一致对提示修复的文件保留原件从备份重来一遍别在已损坏的文件上反复折腾。注意批量处理前务必确认工作目录所在分卷有足够空间临时文件和最终文件会同时存在一段时间空间不足导致的写入截断非常难排查。6. 把验证做在解密之前一个我后来雷打不动的习惯整套东西跑顺之后我最大的改变不是写工具变快了而是养成了一个近乎偏执的习惯动手解任何一批文件之前先造一个自己的试验品。具体做法很土。用白名单进程写一个小 .docx里面只放一行特征字符串比如某个随机生成的十六进制串写完之后先确认这个文件确实被加密了——拿到没装客户端的机器上打开应该是打不开或者乱码打不开才说明加密生效这一步是整个验证的基准。然后拿这个小文件走一遍完整的解密链路读、写临时文件、改名、校验最后比对特征字符串是否一字不差哈希是否和加密前一致。全链路通过才允许自己对真实数据动手任何一环失败就地停下来查绝不用真实文件去试错。这个习惯救过我两次。一次是某次客户端小版本更新之后白名单判定加了路径校验复制改名的副本还能启动但读出来的是密文——如果直接上真实数据那批文件的临时产物全是垃圾日志还会显示处理成功。另一次是临时扩展名恰好命中了新下发的策略写出来的东西被悄悄加密了也是靠那个特征字符串比对出来的。现在我把这个自检做成了工具的一个开关启动时先跑一遍通过才进入批量模式。整个过程不到十秒比事后从上百个文件里找哪个坏了要划算得多。做终端数据恢复这类活儿后悔药是没有的能提前做的只有把验证往前挪挪到动手之前。如果你手上也有类似的场景建议先别急着写代码把第 2 章那两组对照实验老老实实做一遍把名单边界摸清楚剩下的就是流水线活儿了。希望帮到你。本文还有配套的精品资源点击获取
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/28 4:51:02
五笔输入法学习路线:字根、拆字、识别码与盲打提速
2026/10/28 4:51:02
Agent-Reach:定义LLM智能体的真实可达能力边界
2026/10/28 4:51:02
impeccable如何正确使用?词源、近义词与搭配全解析
2026/10/28 5:51:08
从概念到工程落地:智能体自主迭代能力拆解与避坑指南
2026/10/28 5:51:08
C++继承中的访问权限控制:三大理解框架
2026/10/28 5:51:08
HTTPS页面混合内容拦截问题与6种解决方案
2026/10/28 5:51:08
数据结构课设:校园导航系统邻接矩阵+Floyd路径回溯
2026/10/28 5:51:08
千元级低成本视频监控系统:推流、录像与长期稳定运行
2026/10/28 5:46:07
C# Windows Forms学生选课系统开发实战
2026/10/28 0:00:12
Stable Diffusion文生图全解析:从CLIP到UNet的扩散模型原理与实战
2026/10/28 0:00:12
从 Notebook 到 Python 项目:如何重构量化行情获取代码?
2026/10/28 0:00:12
2026版人形机器人标准:具身智能与模块化设计解析
2026/10/27 11:41:45
全国计算机二级C语言真题PDF高效刷题指南
2026/10/27 9:24:40
requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南
2026/10/27 12:03:45
递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现
2026/10/25 22:15:16
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/26 11:29:48
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/25 12:42:56
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)