
ここ数日、AppDomain manager injection テクニックを試してきましたが、以前のレッドチーム活動で特定のEDRに対してある程度の成功を収めました。これは初期アクセスベクターとして非常に優れていますが、シェルコードを他の場所に隠すのに役立つPOCを公開したいと思いました。もうシェルコードを埋め込んだDLLファイルは必要ありません!
このテクニックは単独で使用する場合には優れていますが、ISO/ZIP/VHD/VHDXファイル内にC# ClickOnceを送信するような配信テクニックと組み合わせると問題が生じます。本当の問題は、10回のうち1回の頻度で、appdomain用のDLLがAV/EDRのAI/MLヒューリスティクスによって検出されることです。これは、appdomainを初期化する前にDLLファイルをディスク上にドロップする必要があるためです。今のところリモートDLLロード(.config内のUNCパス)は無視しますが、appdomain用のDLLにはシェルコードが含まれることになり、これが静的検出の原因である可能性が高いと強く感じました。なぜなら、残りのコード(WINAPI呼び出し)は動的に解決でき、かなり難読化できるからです。
私は、DLLが最初に保持するものを最小限に抑えるという点で、このテクニックを強化したいと考えました。最初は暗号化されたシェルコードをインジェクターDLLと一緒に別ファイルとしてディスクにドロップすることから始めましたが、その後、CheckpointによるZloaderのキャンペーンに関する素晴らしいブログを見つけました。
TLDR: ファイルの署名を壊さない方法で、PE内の特定のフィールドに任意のデータを埋め込むことができます。そのため、データは埋め込まれ、exeはデジタル署名されたままになります。
そこで、Zloaderマルウェアのように、暗号化されたシェルコードスタブを既知の署名付き実行可能ファイルに埋め込み、署名を維持するというアイデアです。これにより、AppDomain Manager DLLはシェルコードを内部に含まなくなり、代わりに、それをロードするPEバイナリからシェルコードを解析し、復号して別スレッドとして実行するロジックだけを持ちます。これにより、DLLの静的検出率が低下し、シェルコードは署名付きバイナリ内にきれいに配置されます。
私は、VirusTotalから入手したZLoaderサンプルを手動で改変することでこれを実現しようとしましたが、後にこれらのテクニックをすべて非常によく実装したプロジェクト、Sigflip を見つけました。このPOCでは、AppDomain DLLを構築するためにSigFlipのローダーコードを活用し、暗号化されたシェルコードをC# exeに埋め込むためにSigFlipインジェクターを使用しました。
Cobalt StrikeのStagelessシェルコードのような大きなシェルコードの塊は、使用される難読化/エンコード手法に関係なく、ディスク上の署名なしDLLに存在しなくなります。DLLはよりクリーンで、より小さく、よりステルスになり、コードが最小限になるため、検出の可能性が減少します。
SigFlip.exe -i "Z:\ZLoader\CasPol.exe" "Z:\ZLoader\x64-stageless.bin" "Z:\ZLoader\update.exe" "S3cretK3y"update.exe という名前の(Windows署名された?)バイナリが作成されます。これは、暗号化されたシェルコードが埋め込まれたデジタル署名PEになります。csc /target:library /out:test.dll test.csこのPOCは、私と他のレッドチームメンバーが、より優れた初期実行ペイロードを構築するのに役立つ、2つのまったく異なる防御回避テクニックを組み合わせるというアイデアに基づいています。このプロジェクトではAppDomain Manager Injectionを例として使用していますが、このアイデアはDLLサイドローディングやDLLハイジャックなどの他のインジェクションテクニックにも適用可能です。
med0x2e に全面的なクレジットを捧げます。このPOCは彼のSigFlipプロジェクトに基づいて構築されています。