Bring Your Own Land (BYOL) – 新しいレッドチームのテクニック

序章

高度な攻撃作戦における最近の最も重要な進展の 1 つは、攻撃者による「Living off the Land」(LotL) 技術の使用です。これらの手法は、攻撃を実行するために、PowerShell スクリプト言語など、システムに存在する正当なツールを利用します。攻撃ツールとしての PowerShell の人気は、Empire やPowerSploitなど、PowerShell に基づいた Red Team フレームワーク全体の開発で最高潮に達しました。さらに、PowerShell の実行は、「 Invoke-Obfuscation 」などのツールを使用して難読化することができます。これに対応して、防御側は正当なアプリケーションの悪意のある使用に対する検出を開発しました。これらの検出には、疑わしい親子プロセスの関係、疑わしいプロセスのコマンド ライン引数、さらにはスクリプト ブロック ロギングを使用した悪意のある PowerShell スクリプトの難読化が含まれます。

このブログ投稿では、現在の LotL 手法に代わる方法について説明します。 Cobalt Strike の最新ビルド (バージョン 3.11) では、「execute-assembly」コマンドを使用して、.NET アセンブリ全体をメモリ内で実行できるようになりました。 C# ベースのカスタム アセンブリを開発することにより、攻撃者はターゲット システムに存在するツールに依存する必要がなくなります。代わりに、独自のツールを作成して配信することができます。これは、私が BYOL (Bring Your Own Land) と呼んでいる手法です。 PowerSploit プロジェクトの機能の一部を複製するカスタム .NET アセンブリを使用して、この手法を説明します。また、BYOL 手法を中心に検出を開発する方法についても説明します。

バックグラウンド

昨年の DerbyCon で、Cobalt Strike Remote Access Tool (RAT) の開発者である Raphael Mudge に会うことができました。議論の中で、「powershell-import」コマンドを使用して PowerShell スクリプトをインポートする方法と同様に、.NET アセンブリを Cobalt Strike ビーコンにロードできることがいかに有用であるかについて言及しました。私が関与していた以前のレッド チームの関与では、ターゲット環境内のホスト マシンに存在するエンドポイントの検出と応答 (EDR) エージェントによって、PowerShell の使用が妨げられていました。当時の私のレッド チームの方法論の多くは、さまざまな PowerShell スクリプトの使用に基づいていたため、これは重大な問題でした。たとえば、 PowerViewスクリプトの「Get-NetUser」コマンドレットを使用すると、Active Directory 環境内のドメイン ユーザーを列挙できます。 PowerShell の使用はオプションではありませんでしたが、ターゲットの環境内のホストでアプリケーション ベースのホワイトリスト登録が行われていないことがわかりました。そのため、PowerShell 機能を C# コードに変換し、アセンブリをポータブル実行可能 (PE) ファイルとしてローカルでコンパイルし、PE ファイルをターゲット マシンにアップロードして実行する作業を開始しました。この戦術は成功し、これらのカスタム アセンブリを使用して、ターゲット環境内で権限をドメイン管理者に昇格させることができました。

Raphael は、Cobalt Strike ビーコンを使用してメモリ内にこれらのアセンブリをロードする機能が役立つことに同意し、約 8 か月後、この機能は「execute-assembly」コマンドを介して Cobalt Strike バージョン 3.11 に組み込まれました。

「execute-assembly」デモンストレーション

このデモでは、「get-users」という名前のカスタム C# .NET アセンブリが使用されました。このアセンブリは、PowerView の「Get-NetUser」コマンドレットの機能の一部を複製しています。現在のすべてのドメイン アカウントのリストについて、指定されたドメインのドメイン コントローラに問い合わせました。得られた情報には、各アカウントの「SAMAccountName」、「UserGivenName」、および「UserSurname」プロパティが含まれていました。ドメインはその FQDN を引数として渡すことによって指定され、結果は stdout に送信されます。 Cobalt Strike ビーコン内で実行されているアセンブリを次に示します。図1。

 

Cobalt Strike ビーコン内で「execute-assembly」コマンドを使用する。

図 1: Cobalt Strike ビーコン内で「execute-assembly」コマンドを使用。

簡単なことですが、この手法が内部でどのように機能するかを見てみましょう。

「execute-assembly」の仕組み

「execute-assembly」コマンドがどのように機能するかをさらに理解するために、図 1 で実行された実行がProcMonを実行しているホストで繰り返されました。実行後の ProcMon からのプロセス ツリーの結果を次に示します。図 2.

 

「execute-assembly」コマンドを実行した後の ProcMon からのプロセス ツリー。

図 2: 「execute-assembly」コマンドを実行した後の ProcMon からのプロセス ツリー。

図 2 では、「powershell.exe (2792)」プロセスにビーコンが含まれていますが、「rundll32.exe (2708)」プロセスは「get-users」アセンブリの読み込みと実行に使用されています。 Cobalt Strike ビーコンは PowerShell ワンライナーを使用して起動されたため、この例では「rundll32.exe」の親プロセスとして「powershell.exe」が示されていることに注意してください。ただし、さまざまなプロセス移行手法を活用することで、ほぼすべてのプロセスを使用してビーコンをホストできます。この情報から、「execute-assembly」コマンドが他のCobalt Strike のポストエクスプロイト ジョブに類似していると判断できます。 Cobalt Strike では、ビーコンの安定性を確保するために、一部の機能が新しいプロセスにオフロードされます。 rundll32.exe Windows バイナリがデフォルトで使用されますが、この設定は変更できます。必要なコードを新しいプロセスに移行するために、 CreateRemoteThread関数を使用します。この機能が利用されていることは、「execute-assembly」コマンドの実行中にSysmonでホストを監視することで確認できます。 CreateRemoteThread 関数を使用して生成されたイベントを図 3 に示します。

 

CreateRemoteThread 「execute-assembly」コマンドの実行後に作成される Sysmon イベント。

図 3: CreateRemoteThread Sysmon イベント。「execute-assembly」コマンドの実行後に作成されます。

このイベントの詳細については、図 4 を参照してください。

 

図 3 に示す Sysmon CreateRemoteThread イベントに関する詳細情報。

図 4: 図 3 に示した Sysmon CreateRemoteThread イベントの詳細情報。

提供されたアセンブリを実行するには、新しく作成されたプロセスに共通言語ランタイム (CLR) を読み込む必要があります。 ProcMon ログから、この手順で読み込まれた正確な DLL を特定できます。これらの DLL の一部を図 5 に示します。

 

CLR をホストするために rundll32 に読み込まれる DLL の例。

図 5: CLR をホストするために rundll32 に読み込まれた DLL の例。

さらに、rundll32 プロセスにロードされる DLL には、LDAP 通信や Kerberos 認証用の DLL など、get-users アセンブリに必要な DLL が含まれています。これらの DLL の一部を図 6 に示します。

 

Kerberos 認証のために rundll32 にロードされた DLL の例。

図 6: Kerberos 認証のために rundll32 に読み込まれた DLL の例。

ProcMon ログは、提供されたアセンブリがディスクに書き込まれないことを確認しており、「execute-assembly」コマンドは完全にインメモリ攻撃になっています。

「execute-assembly」の検出と防止

「execute-assembly」コマンドから保護するには、いくつかの方法があります。前に詳述したように、この手法は Cobalt Strike の悪用後のジョブであるため、EDR ソリューションで一般的に検出される CreateRemoteThread 関数を使用します。ただし、BYOL 手法の他の実装では、CreateRemoteThread 関数を使用する必要がない可能性があります。

「execute-assembly」手法は、提供されたアセンブリをロードするために、ネイティブの LoadImage 関数を利用します。 CLRGuardプロジェクトは、この関数の使用にフックし、その実行を防ぎます。 「execute-assembly」コマンドの実行を防止する CLRGuard の例を図 7 に示します。

 

「execute-assembly」手法の実行をブロックする CLRGuard。

図 7: 「execute-assembly」手法の実行をブロックする CLRGuard。

Cobalt Strike チームサーバーで発生したエラーを図 8 に示します。

 

「execute-assembly」が CLRGuard によってブロックされている場合、Cobalt Strike でエラーが表示されます。

図 8: 「execute-assembly」が CLRGuard によってブロックされている場合に Cobalt Strike に表示されるエラー。

CLRGuard は、「execute-assembly」コマンドやその他の BYOL 手法を防ぐのに効果的ですが、システムで LoadImage 関数のすべての使用をブロックすると、他の無害なアプリケーションに悪影響を与える可能性が高く、運用環境にはお勧めできません。

ほとんどすべてのセキュリティ問題と同様に、ベースラインと相関関係は、この手法を検出する最も効果的な手段です。関連付けが必要な疑わしいイベントには、通常は使用しないプロセスによる LoadImage 関数の使用や、異常な DLL のプロセスへのロードなどがあります。

BYOLの利点

巧妙な攻撃者による PowerShell スクリプトの一般的な使用により、悪意のある PowerShell アクティビティの検出が現在の検出方法の主な焦点になっています。特に、PowerShell のバージョン 5 では、難読化手法に関係なく、システムによって実行された PowerShell スクリプトを正確に記録できるScript Block Loggingを使用できます。さらに、制約付き言語モードを使用して、PowerShell の機能を制限できます。 PowerShell ダウングレード攻撃など、これらの保護にはバイパスが存在しますが、攻撃者が試行する各バイパスは、防御側がトリガーできる別のイベントです。 BYOL では、PowerShell ベースの潜在的なすべてのアラートを完全に回避しながら、通常は PowerShell スクリプトによって実行される攻撃を実行できます。

防御側が悪意のある使用を追跡しているネイティブ バイナリは、PowerShell だけではありません。アラートを生成できるその他の一般的なバイナリには、WMIC、schtasks/at、reg などがあります。これらすべてのツールの機能は、C# コードの柔軟性により、カスタム .NET アセンブリ内で複製できます。これらのツールを使用しなくても、これらのツールと同じ機能を実行できるため、悪意のある使用に基づくアラートは無効になります。

最後に、リフレクティブ ロードを使用することで、ディスクへの書き込みを必要とせずに、BYOL 手法を完全にメモリ内で実行できます。

結論

BYOL は、交戦中にレッド チームが検出されないようにするための強力な新しいテクニックを提供し、Cobalt Strike の「execute-assembly」コマンドで簡単に使用できます。さらに、C# アセンブリを使用すると、攻撃者は同様の PowerShell スクリプトよりも柔軟に対応できます。アセンブリをリフレクティブにロードするために使用される関数のフックなど、CLR ベースの手法の検出は、防御手法に組み込む必要があります。これらの攻撃は、LotL 手法の検出が成熟するにつれてより一般的になる可能性が高いためです。

了承

この手法を活用する C# アセンブリの開発で緊密に協力してきた Casey Erikson に、このブログへの貢献に特に感謝します。

参照: https://www.mandiant.com/resources/blog/bring-your-own-land-novel-red-teaming-technique

Comments

Copied title and URL