
KeePassプロセスにインジェクションされると、データベースを平文でエクスポートするスタンドアロンDLLです。
素晴らしい KeeFarce や KeeThief、KeePassHax プロジェクトから多大な影響を受けています。
数年前、@denandz は、KeePassデータベースを平文で抽出するように設計された最初の攻撃用ツールである KeeFarce を公開しました。これは実行中のプロセスにDLLをインジェクションし、ClrMD を使ってヒープを走査して必要なオブジェクトを見つけ、リフレクションを使用してKeePassの組み込みエクスポートメソッドを呼び出します。当時の唯一の欠点は、ターゲットに複数のファイル(抽出DLL + ClrMD DLL + インジェクター + ブートストラップDLL)をドロップする必要があったことです。
1年後、@tifkin_ と @harmj0y は、KeePassを標的とした攻撃手法に関する詳細なレビューを公開しました(harmj0yのブログでは現在入手できませんが、記事はWayback Machineで見つけることができます: パート1、パート2)。その結果、代替認証方法が使用されている場合も含めてKeePassのマスターキーを復号できるツール KeeThief がリリースされました。これは非常に効果的だったため、KeePass開発者はこの手法を緩和するためのパラメータを追加しました(ユーザーが十分な権限を持っている場合(これはかなり一般的です)、KeePassの設定ファイルを編集することで無効にできます)。
これらのツールは、ペネトレーションテスト中にすぐに私の定番となりましたが、そのインジェクション手法(すなわち、有名なWin32 API群である VirtualAllocEx、WriteProcessMemory、CreateRemoteThread、WriteProcessMemory など)が現在では即座に検知をトリガーするため、すぐに時代遅れになりました。@snovvcrash は、D/Invokeを使用してインジェクション機構を改善するためにKeeThiefをフォークし(現在はプライベートリポジトリにありますが、こちらからアクセス可能です)、彼が辿ったプロセスを詳述した素晴らしい記事を執筆してこの問題に取り組みました。これはKeeThiefの維持が実現可能であることを示しましたが、KeeThiefのコードはインジェクターと密接に結びついているため、新しいインジェクション手法を定期的に実装することは難しいと感じています。
@holly-cracker は KeePassHax もリリースしました。これは単一のDLLとして提供され、リフレクションのみを使用してKeePassのマスターキーを復号します。この作品に触発され、私はKeeFarceでも同じことを行い、以下の機能を持つ独自のKeePass抽出ツールを書くことにしました:
KeeFarce Rebornは、インジェクターを煩わせることなくKeePass自身にインジェクションを行わせるKeePassプラグインDLLも提供します。
コードは外部依存関係のない.NET Frameworkのみに依存しているため、Visual Studio 2015以降で簡単にコンパイルできるはずです。
KeeFarce Rebornには、KeePassプロセスにDLLをロードするためのインジェクターは含まれていません。 これは意図的なもので、インジェクターは数ヶ月ごとに時代遅れになるため、独自のものを使用する必要があります。以下のパートでは、インジェクションを実行する2つの典型的な方法を示します。
前提条件: 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がすでに実行中の場合は、インジェクションが発生するまで次の再起動を待つ必要があります(または自分で再起動を強制します)。
⚠️ プラグインがロードされると、KeePassが閉じられるまでDLLファイルは書き込み保護されます。評価中に悪意のあるプラグインを残さないように、この点に注意してください。
KeePassプラグインディレクトリへの書き込みアクセス権がない場合は、Quarkslabの記事 を参照してください。プラグインキャッシュを介してより少ない権限でプラグインをロードする方法が示されています。
前提条件: KeePassが実行中 + ユーザーがデータベースのロックを解除している + KeePassプロセスにインジェクションするための十分な権限がある。
リモートプロセスにDLLを注入するよりもシェルコードをステルスに注入する方が個人的に簡単だと感じているため、通常最初に行うのは、DLLから位置非依存のシェルコードを生成することです。@odzhan と @TheWover の donut プロジェクトが私たちのニーズに完全に適合しているようです!
devブランチのコミットからdonutをコンパイルします。これは、デフォルトドメインでのリフレクションの実行を妨げるアプリケーションドメイン管理の issue を修正しているためです。
git clone https://github.com/TheWover/donut/
cd donut
git checkout 9d781d8da571eb1499122fc0e2d6e89e5a43603c
Visual Studioの x64 Native Tools Command Prompt から nmake ユーティリティを使用して簡単にビルドできます:
nmake -f Makefile.msvc
シェルコードの生成は次のように簡単です:
.\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/HEAD/: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
これで、お気に入りの手法でインジェクションできるペイロードが用意できました。次に何をすればよいかわからない場合は、ired.team Code & Process Injection page を確認して概念に慣れることをお勧めします。@SEKTOR7 のマルウェア開発コースは、費用を負担できるなら素晴らしい学びでいっぱいです。
例として、D/Invokeを使用する snovvcrash のVeraCryptThiefコード(それ自体がSEKTOR7コースに触発されています)を使ってペイロードを注入してみましょう。デモのために、彼のプロジェクトを SampleInjector フォルダーにコピーしました。圧縮したシェルコードを貼り付けて、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抽出ツールの検知に関する主な問題はインジェクターですが、メモリ内スキャンはシェルコードやプラグインDLLを分析する際にアラートをトリガーする可能性もあります。インジェクターで使用するために、シェルコードを難読化および/または暗号化する必要があるかもしれません。
プラグインDLLが最終的に静的解析で検出される場合でも、KeePassの PLGXプラグインフォーマット を使用して検出を回避できます。
DISM.exe を使用して手動でセットアップできます。Pull requestは歓迎します。遠慮なくissueを開くか、TwitterでDMを送って改善を提案してください。
コードの一部は KeeFarce、KeeThief、KeePassHax プロジェクトから取られました。
サンプルのインジェクション機構は、snovvcrash のプロジェクトから直接取られました。