标题: MSDN系列(52)--U盘反病毒抢救数据 创建: 2026-10-27 11:08 更新: 2026-10-29 15:03 链接: https://scz.617.cn/windows/202610271108.txt https://mp.weixin.qq.com/s/K9ZH0Leb5A09c5xwYm_FWg https://mp.weixin.qq.com/s/dGmtl4OLJOzAJQEPG65N4w -------------------------------------------------------------------------- 目录: ☆ 场景介绍 ☆ 抢救数据 1) cmd内部命令dir 2) attrib.exe 3) PowerShell ☆ 畸形/恶意目录、文件名 ☆ 畸形/恶意Unicode字符 1) 在线不可见字符查看工具 2) U盘病毒实例 ☆ fstest ☆ fsexplorer -------------------------------------------------------------------------- ☆ 场景介绍 前段时间给张三处理过一次U盘病毒,Windows Defender报了两个高危 Trojan:Win32/Fragtor.ARA!MTB Backdoor:Win64/ToneShell.A!dha 报警界面中出现两个DLL,其中一个是 X:\\\\$WinUpdate\RBGUIFramework.dll 另一个当时没记下来。 这种只看路径,就知道异常。正常情况下,路径中不可能出现连续反斜杠,视觉上出 现这种效果时,路径中必含不可见的零宽Unicode字符。 资源管理器去X盘根目录,看不到异常子目录。从Windows Defender复制上述路径, 粘贴到资源管理器中,回车,可进入$WinUpdate子目录,下面一堆EXE、DLL。恶意代 码主要集中在被报警的两个DLL中,其余EXE算载体。 这款U盘病毒感染U盘后,将U盘上原始数据转移到名字畸形、多层嵌套的目录里;沿 线各级目录均带系统、隐藏双属性,目录名携带不同零宽Unicode字符;只在X盘根目 录留一个文件,名为 USB Disk(117 GB).exe 若资源管理器未设置成始终显示扩展名、文件类型,那此文件看起来是 USB Disk(117 GB) 其图标被精心构造过,看不出是EXE。张三看到这枚U盘时,以为自己未打开U盘,对 之双击或右键打开,殊不知实际执行了EXE,将加载恶意DLL。 追溯U盘动向,张三曾在自己之外的多台不可控电脑上插入过该枚U盘。由于不具备技 术背景,他完全无法有效回忆,已然说不清最早在哪台电脑上染毒,溯源失败。 此EXE除了加载恶意DLL,另有一主要功能,自动打开U盘原始数据被迁移后的目录, 让普通用户以为双击此EXE就是打开U盘。张三正是深陷此种骗局而不自知,多次双击 此EXE,四处传播病毒。 此U盘病毒并非高度定向,张三属于范围感染者之一,病毒特征早已位于各大杀软特 征库中。现代Windows默认自带Windows Defender并启用中,因此张三莽撞之际,万 幸在某台电脑上被拦截,出现前述高危报警,但张三并未意识到。后来张三找我,谈 及每次都要双击前述EXE才能看到U盘内容,觉得有点奇怪,病毒这才彻底暴露。 简单看了一下$WinUpdate目录下的其他PE,明显带远控、文件传输等功能。不知张三 实际受损情况几何?不幸中的万幸是,此病毒以窃取数据为主要目的,可能并不疯狂 感染其他PE。手工处置时,这种病毒算是最"友好"的。若是勒索软件,上来二话不说 就加密本地文件,请来神仙也没招,交钱还得看对方讲不讲究,大概率不讲究。 在特定单位、特定人群中,会存在未自带Windows Defender的老旧操作系统,即使自 带,也未必能联网更新病毒特征库,它们亦未禁止"可移动介质自动执行"功能, autorun.inf仍有机会。这些电脑是U盘病毒极佳宿主,特别利于横向传播。至少在相 当一段时间内,U盘病毒并未远去,它们只是在等待机会。 另一方面,自己电脑处于高防状态,架不住要与低防电脑共用U盘。我的建议是,对 外始终用一枚容量不大的专用U盘,务必不将高价值数据置于这种对外交换U盘中。只 要它在其他电脑上插过,回到自己电脑时,先用杀软过一遍,甭管你觉得里面是空与 否。有条件的话,资源管理器设置成始终显示扩展名、文件类型,养成打开文件前看 一眼"文件类型"列的习惯。若非绝对必要,这枚U盘只对外提供数据,不从外部回收 数据。取回U盘后,上下文允许时,直接快速格式化,简单粗暴但有效。万一这些做 不到,至少要做到另一条,意识到异常后,不抱任何侥幸心理,第一时间封存,找懂 行之人协助处置。 ☆ 抢救数据 遭遇这类U盘病毒,除了杀毒,可能还需要抢救U盘数据。若按我前述建议,就不会面 临此困境,但有些人会。 抢救数据的基本操作是 a. 找出存放U盘原始数据的隐藏目录,可用dir或PowerShell b. 卸掉系统、隐藏双属性,可用attrib或PowerShell c. 对含有畸形Unicode字符的目录、文件重命名,可用ren或PowerShell 上述操作均为命令行形式,不要在资源管理器中干这些事,阻碍太多。 1) cmd内部命令dir dir /a /r /q /t:a X:\ 检查X盘根目录是否含隐藏项,注意最后一次访问时间 dir /a /r /q /t:a /s X:\*.exe 在整个X盘遍历查找exe,可换dll等其他扩展名 dir /a:sh /r /q /t:a /s X:\ 病毒一般会创建带系统、隐藏双属性的目录、文件,找出它们 本文不讨论NTFS流,参看 《MSDN系列(48)--NTFS Alternate Data Streams简介》 https://scz.617.cn/windows/202203171121.txt 2) attrib.exe attrib /d /l X:\*.* 检查X盘根目录所有项的属性 attrib /s /d /l X:\*.* 在整个X盘遍历,显示目录、文件的属性 attrib -s -h -r /s /d /l X:\*.* 在整个X盘遍历,卸掉系统、隐藏、只读属性 3) PowerShell 可用PowerShell脚本完成dir、attrib、ren的工作,下面是分步示例,实战时让AI写 个整合版。 -------------------------------------------------------------------------- # 指定目标路径,比如X盘根目录 $target = 'X:\' $items = @(Get-ChildItem -LiteralPath $target -Force -ErrorAction Stop) $report = for ($i = 0; $i -lt $items.Count; $i++) { $item = $items[$i] $units = ( $item.Name.ToCharArray() | ForEach-Object { '{0:X4}' -f [int]$_ } ) -join ' ' [pscustomobject]@{ Index = $i Type = if ($item.PSIsContainer) { 'Directory' } else { 'File' } VisibleName = '[' + $item.Name + ']' UTF16 = $units Attributes = $item.Attributes # 反引号续行 VisibleFullName ` = '[' + $item.FullName + ']' } } $report | Format-List -------------------------------------------------------------------------- -Force 同时枚举隐藏项和系统项 -LiteralPath 将输入路径按字面值处理,不把其中的*、?当作通配符 -Recurse 递归遍历 -------------------------------------------------------------------------- 注意VisibleName、UTF16、VisibleFullName,是否包含恶意Unicode字符,比如零宽 空格。 -------------------------------------------------------------------------- # 从前述脚本得到的 $items 中选择目标,指定目标项的索引,比如2 $entry = $items[2] $longPath = '\\?\' + $entry.FullName $attrs = [System.IO.File]::GetAttributes($longPath) $attrs # 示例输出 # ReadOnly, Hidden, System, Directory -------------------------------------------------------------------------- $mask = [int]( [System.IO.FileAttributes]::System -bor [System.IO.FileAttributes]::Hidden -bor [System.IO.FileAttributes]::ReadOnly ) $newAttrs = [System.IO.FileAttributes]( [int]$attrs -band (-bnot $mask) ) [System.IO.File]::SetAttributes($longPath, $newAttrs) -------------------------------------------------------------------------- 上述脚本相当于"attrib -s -h -r"指定项。后续操作均假设目标项已卸掉SHR属性。 -------------------------------------------------------------------------- # 可能含恶意Unicode字符 $oldPath = '\\?\' + $entry.FullName $parent = $entry.FullName.Substring( 0, $entry.FullName.Length - $entry.Name.Length ) # 指定只含普通字符的名字 $newPath = '\\?\' + $parent + 'recovered_001' if ([System.IO.File]::Exists($newPath) -or [System.IO.Directory]::Exists($newPath)) { throw 'New name already exists, try another one.' } if ($entry.PSIsContainer) { [System.IO.Directory]::Move($oldPath, $newPath) } else { [System.IO.File]::Move($oldPath, $newPath) } -------------------------------------------------------------------------- 假设$items[2]名字含恶意Unicode字符,无法正常操作,上段代码将$items[2]重命 名为"recovered_001"。 ☆ 畸形/恶意目录、文件名 资源管理器中创建、修改item name,结尾不会出现空格、点号,这是explorer.exe 自己加的限制,不是底层文件系统的限制。通过适当的Win32 API可生成这种畸形 item name,在资源管理器中无法对之进行有效操作,经常报"找不到"。多年来,U盘 病毒、恶意软件常利用这点阻止用户访问、删除它们。 只用Windows自带工具处理这种item name时,需利用\\?\前缀,比如 ren "\\?\X:\path\taildot." foo.bar 但是,rename目录名时,源目录不支持"\\?\"语法,所以ren可修正异常文件名,无 法修正异常目录名。 更多细节参看 -------------------------------------------------------------------------- CreateFileA function https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea File Streams (Local File Systems) https://learn.microsoft.com/en-us/windows/win32/fileio/file-streams Naming Files, Paths, and Namespaces https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file Path prefixes \??\ and \\?\ - Eryk Sun [2017-09-03] https://stackoverflow.com/questions/23041983/path-prefixes-and 《"文件名或扩展名太长"导致的文件删除失败》 https://scz.617.cn/windows/202006182000.txt 《MSDN系列(48)--NTFS Alternate Data Streams简介》 https://scz.617.cn/windows/202203171121.txt 《MSDN系列(51)--regedit的冷门知识》 https://scz.617.cn/windows/202310181035.txt -------------------------------------------------------------------------- ☆ 畸形/恶意Unicode字符 常用恶意字符 U+200B ZWSP (Zero Width Space) 零宽空格 U+200C 零宽 U+200D 零宽 U+202E RLO (Right-to-Left Override) 从右到左强制覆盖 U+202C PDF (Pop Directional Formatting) 终止符 这些恶意字符零宽、不可见,在资源管理器中肉眼无法察觉其存在,甚至产生误导性 视觉效果。比如"U+202E",导致其后所有字符整体反序显示,于是 ann[U+202E]txt.exe 产生视效 annexe.txt 你以为这是个TXT,双击实际执行EXE。 cmd dir倒是可以发现异常,但不够直观。可用PowerShell脚本处理这些情形。 1) 在线不可见字符查看工具 https://sosec.io/tools/text-inspector https://originality.ai/blog/invisible-text-detector-remover 在cmd或资源管理器中F2复制item name,贴到上述网页,可查看item name中不可见 Unicode字符。这对抢救数据没有帮助,只是让你死得明白。 2) U盘病毒实例 用在线工具查看前面那个路径 X:\\\\$WinUpdate\RBGUIFramework.dll 显示 X:\[U+200D]\[U+200D]\[U+200C]\$WinUpdate\RBGUIFramework.dll 其中三级目录的名字均是单个零宽Unicode字符,同时这些目录带有系统、隐藏属性。 ☆ fstest fstest是款Windows文件系统测试工具,用于测试Win32 API及底层文件系统对路径名 的支持情况,集成attrib、dir、ren的部分功能。 fstest用"WorkBuddy + Step-5-Preview"生成。 ☆ fsexplorer fsexplorer是fstest的GUI版本,用"WorkBuddy + Step-5-Preview + Hy4 preview" 生成。在GUI界面中直接显示所有item,包括带有系统、隐藏属性的item,透明利用 \\?\前缀尽最大可能操作item name,对异常Unicode字符进行[U+...]占位显示。 fstest、fsexplorer是为U盘反病毒抢救数据场景而生。 https://scz.617.cn/windows/fsexplorer.7z size 275952 sha256 e1f48245ac9a5edf2150ded8c4a29eeb886b374c291b6a3445d7ec61b5ba91ac