
x86、x64、またはAMD64+x86の位置独立型シェルコードを生成し、.NETアセンブリ、PEファイル、およびその他のWindowsペイロードをメモリから読み込んでパラメータ付きで実行します。

現在のバージョン: v1.1
Donut は、VBScript、JScript、EXE、DLL ファイル、および dotNET アセンブリのメモリ内実行を可能にする、位置独立コードです。Donut によって作成されたモジュールは、HTTP サーバーからステージングするか、ローダー自体に直接埋め込むことができます。モジュールはオプションで、Chaskey ブロック暗号と128ビットのランダム生成キーを使用して暗号化されます。ファイルがメモリにロードされ実行された後、元の参照は消去され、メモリスキャナーを妨害します。ジェネレーターとローダーは以下の機能をサポートしています。
Linux および Windows 向けの動的ライブラリと静的ライブラリがあり、独自のプロジェクトに統合できます。また、Python モジュールもあり、詳細は Python 拡張のビルドと使用 をご覧ください。
Donut には、サポートされている各ファイルタイプ用の個別のローダーが含まれています。dotNET EXE/DLL アセンブリの場合、Donut はアンマネージ CLR ホスティング API を使用して Common Language Runtime をロードします。CLR がホストプロセスにロードされると、新しいアプリケーションドメインが作成され、使い捨ての AppDomain でアセンブリを実行できるようにします。AppDomain の準備ができると、dotNET アセンブリは AppDomain.Load_3 メソッドを介してロードされます。最後に、ユーザーが指定した EXE のエントリポイントまたは DLL のパブリックメソッドが、追加のパラメーターとともに呼び出されます。アンマネージ CLR ホスティング API のドキュメントについては、MSDN (https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/clr-hosting-interfaces) を参照してください。CLR ホストのスタンドアロンの例については、こちらのコード を参照してください。
VBScript および JScript ファイルは、IActiveScript インターフェースを使用して実行されます。Windows Script Host (wscript/cscript) が提供する一部のメソッドの最小限のサポートもあります。スタンドアロンの例については、こちらのコード を参照してください。詳細な説明については、JavaScript、VBScript、JScript、XSL のメモリ内実行 をお読みください。
アンマネージまたはネイティブの EXE/DLL ファイルは、遅延インポート、TLS、コマンドラインのパッチ適用をサポートするカスタム PE ローダーを使用して実行されます。リロケーション情報があるファイルのみがサポートされています。詳細は DLL のメモリ内実行 をお読みください。
ローダーは、AMSI と WLDP を無効にして、メモリ内で実行される悪意のあるファイルの検出を回避するのに役立ちます。詳細については、レッドチームが .NET 動的コードの AMSI と WLDP をバイパスする方法 をお読みください。また、aPLib または RtlDecompressBuffer API を使用したメモリ内ファイルの解凍もサポートしています。詳細については、データ圧縮 をお読みください。
バージョン 1.0 以降、ETW もバイパスされます。AMSI/WLDP と同様に、これはモジュール式のシステムであり、デフォルトのバイパスを独自のものに交換できます。デフォルトのバイパスは XPN の研究に基づいています。詳細については、.NET の隠蔽 - ETW をお読みください。
デフォルトでは、ローダーはアンマネージ PE の PE ヘッダー(ベースアドレスから `IMAGE_OPTIONAL_HEADER.SizeOfHeaders` まで)を上書きします。デコイモジュールが使用されない場合(モジュールオーバーロード)、PE ヘッダーはゼロ埋めされます。デコイモジュールが使用される場合、デコイモジュールの PE ヘッダーがペイロードモジュールのものを上書きするために使用されます。これは、メモリ内のモジュールの PE ヘッダーをディスク上のファイルと比較する検出を防ぐためです。ユーザーは、すべての PE ヘッダーを元の状態のまま保持するように要求できます。これは、ペイロードモジュールが埋め込み PE リソースを検索する場合など、PE ヘッダーにアクセスする必要があるシナリオで役立ちます。
ジェネレーターの詳細なチュートリアルと、Donut がトレードクラフトにどのように影響するかについては、Donut - .NET アセンブリをシェルコードとしてインジェクトする をお読みください。ローダーの詳細については、.NET アセンブリをメモリからロードする をお読みください。
内部についてさらに詳しく知りたい方は、開発者向けノート を参照してください。
ビルドには2種類あります。Donut をデバッグしたい場合は、こちらのドキュメント を参照してください。そうでない場合は、リリースビルドについて以下をお読みください。
Windows コマンドプロンプトまたは Linux ターミナルから、リポジトリをクローンします。
git clone http://github.com/thewover/donut.git
次のステップは、使用するオペレーティングシステムとコンパイラによって異なります。現在、Donut のジェネレーターとローダーテンプレートは、Microsoft Visual Studio 2019 と MinGW-64 の両方で正常にコンパイルできます。独自の C/C++ プロジェクトでライブラリを使用するには、こちらにある例 を参照してください。
ローダーテンプレート、動的ライブラリ donut.dll、静的ライブラリ donut.lib、ジェネレーター donut.exe を生成するには、x64 の Microsoft Visual Studio 開発者コマンドプロンプトを起動し、Donut リポジトリをクローンしたディレクトリに移動して、以下を入力します。
nmake -f Makefile.msvc
Windows または Linux で MinGW-64 を使用して同様のことを行うには、Donut リポジトリをクローンしたディレクトリに移動し、以下を入力します。
make -f Makefile.mingw
動的ライブラリ donut.so、静的ライブラリ donut.a、ジェネレーター donut を生成するには、Donut リポジトリをクローンしたディレクトリに移動し、単に make と入力します。
Donut は Python モジュールとしてインストールして使用できます。ソースからインストールするには、Python3 用の pip が必要です。まず、古いバージョンの donut-shellcode がインストールされていないことを確認するために、Linux ターミナルまたは Microsoft Visual Studio コマンドプロンプトで次のコマンドを発行します。
pip3 uninstall donut-shellcode
古いバージョンがインストールされていないことを確認したら、次のコマンドを発行します。
pip3 install .
また、PyPi リポジトリから Donut を Python モジュールとしてインストールすることもできます。
pip3 install donut-shellcode
詳細については、Python 拡張のビルドと使用 を参照してください。
Docker コンテナのビルド。
docker build -t donut .
Donut の実行。
docker run -it --rm -v "${PWD}:/workdir" donut -h
Donut には、個別にビルドできる他のいくつかの実行可能ファイルが含まれています。これには、"hash.exe"、"encrypt.exe"、"inject.exe"、"inject_local.exe" が含まれます。最初の2つはシェルコード生成で使用されます。後者の2つは、donut シェルコードのテストを支援するために提供されています。"inject.exe" は、生のバイナリファイル(loader.bin)を PID またはプロセス名でプロセスにインジェクトします。"inject_local.exe" は、生のバイナリファイルを自身のプロセスにインジェクトします。
これらのサポート実行可能ファイルを個別にビルドするには、MSVC makefile を使用できます。たとえば、"inject_local.exe" をビルドして donut シェルコードをテストするには、次のように実行します。
nmake inject_local -f Makefile.msvc
Donut の各リリースバージョンには、コンパイルされた実行可能ファイルを含むタグが提供されています。
現在、他に2つのジェネレーターが利用可能です。
以下の表は、コマンドライン版のジェネレーターがサポートするスイッチを示しています。
Donut が正常にロードするために、ペイロードが満たす必要がある特定の要件があります。
Cygwin の実行可能ファイルは、ホストプロセスがディスクから実行されていることを期待する初期化ルーチンを使用します。メモリから実行する場合、ホストプロセスがクラッシュする可能性があります。
donut には4つのコンパニオンプロジェクトが用意されています。
より多くの種類のペイロードをサポートしたり、機能セットを変更したり、Donut を既存のツールに統合したい場合があります。開発者向けドキュメント を用意しています。追加機能は読者の課題として残されています。提案:
Donut に関する質問やコメントがある場合は、BloodHound Gang Slack の #Donut チャンネルに参加してください。
当方は、本ソフトウェアまたは技術の誤用について一切の責任を負いません。Donut は、CLR インジェクションとシェルコードを介したメモリ内ロードのデモンストレーションとして提供されており、レッドチームが敵対者をエミュレートし、防御側が分析と緩和策を構築するための基準を提供することを目的としています。これにより、マルウェア作成者や脅威アクターが悪用するリスクは避けられません。しかし、当方は、正味の利益がリスクを上回ると考えています。うまくいっていることを願っています。EDR や AV 製品がシグネチャや行動パターンを介して Donut を検出できる場合、当方はシグネチャや検出方法に対抗するために Donut を更新しません。気分を害されたくない場合は、お問い合わせしないでください。
| スイッチ | 引数 | 説明 |
|---|---|---|
| -a | arch | ローダーの対象アーキテクチャ: 1=x86, 2=amd64, 3=x86+amd64(デフォルト) |
| -b | level | AMSI/WLDP バイパスの動作: 1=なし, 2=失敗時に中止, 3=失敗時に継続(デフォルト) |
| -k | headers | PE ヘッダーの保持: 1=上書き(デフォルト), 2=すべて保持 |
| -j | decoy | モジュールオーバーロード用のデコイモジュールのパス(オプション) |
| -c | class | クラス名(オプション)。(.NET DLL には必須)名前空間も含めることができます: 例 namespace.class |
| -d | name | .NET 用に作成する AppDomain 名。エントロピーが有効な場合、ランダムに生成されます。 |
| -e | level | エントロピーレベル: 1=なし, 2=ランダム名を生成, 3=ランダム名を生成 + 対称暗号化を使用(デフォルト) |
| -f | format | ファイルに保存されるローダーの出力形式: 1=バイナリ(デフォルト), 2=Base64, 3=C, 4=Ruby, 5=Python, 6=PowerShell, 7=C#, 8=16進数 |
| -m | name | DLL のメソッドまたは関数名(オプション)。(.NET DLL にはメソッドが必要) |
| -n | name | HTTP ステージング用のモジュール名。エントロピーが有効な場合、ランダムに生成されます。 |
| -o | path | Donut がローダーを保存する場所を指定します。デフォルトはカレントディレクトリの "loader.bin" です。 |
| -p | parameters | DLL メソッド/関数または EXE 用の引用符で囲まれたオプションのパラメーター/コマンドライン。 |
| -r | version | CLR ランタイムバージョン。デフォルトでは MetaHeader が使用され、利用できない場合は v4.0.30319 が使用されます。 |
| -s | server | Donut モジュールをホストする HTTP サーバーの URL。次の形式で資格情報を指定できます: https://username:[email protected]/ |
| -t | アンマネージ/ネイティブ EXE のエントリポイントをスレッドとして実行し、スレッドが終了するのを待機します。 | |
| -w | コマンドラインが UNICODE 形式でアンマネージ DLL 関数に渡されます。(デフォルトは ANSI) | |
| -x | option | ローダーの終了方法を決定します: 1=スレッドを終了(デフォルト), 2=プロセスを終了, 3=終了またはクリーンアップせずに無期限にブロック |
| -y | addr | ローダー用に新しいスレッドを作成し、ホストプロセスの実行可能ファイルからの相対オフセットであるアドレスで実行を継続します。指定された値がオフセットです。このオプションは、donut の実行が完了した後、ホストプロセスの実行を再開したいローダーをサポートします。 |
| -z | engine | 入力ファイルのパック/圧縮: 1=なし, 2=aPLib, 3=LZNT1, 4=Xpress, 5=Xpress Huffman。現在、後の3つは Windows でのみサポートされています。 |
| ツール | 説明 |
|---|---|
| DemoCreateProcess | テスト用のサンプル .NET アセンブリ。それぞれが実行するプログラムを指定する2つのコマンドラインパラメーターを受け取ります。 |
| DonutTest | donut のテストに使用するシンプルな C# シェルコードインジェクター。シェルコードは base64 エンコードされ、文字列としてコピーされる必要があります。 |
| ModuleMonitor | Donut や Cobalt Strike の execute-assembly のようなツールが行う CLR インジェクションを検出する概念実証ツール。 |
| ProcessManager | 攻撃オペレーターがインジェクト先を決定し、防御オペレーターが実行中のプロセス、そのプロパティ、CLR がロードされているかどうかを判断するために使用できるプロセス発見ツール。 |