分割統治(Divide and Conquer)は、複雑な問題を多くのより単純な部分問題に分割することで解決するためにプログラミングで一般的に適用されるアルゴリズムです。私たちはこのアプローチを、異なる目標を持ってオフェンシブセキュリティに適用できます。それは、EDRを混乱させて私たちの活動を見失わせ、アラートを発生させないようにすることです。これは、最近の実環境におけるほとんどすべてのフィッシングキャンペーンで見られるものと似ています。最終ペイロードを直接実行する代わりに、複数のファイルを段階的に実行する長い感染チェーン(例:.url -> .one -> .js -> .bat -> .dll)です。実行される各ファイルは、単独では悪意のあるものとしてタグ付けするのが難しい単純なタスク(別のファイルのダウンロード、レジストリの変更、ディレクトリ間でのファイルの移動、ファイル名や拡張子の変更など)を実行し、最終的な実行のための環境を準備します。
私はこのシンプルなアイデアを、別の何か、この場合はリモートプロセスインジェクションに適用してテストすることにしました。このリポジトリで紹介されているコードは何も新しいものではありません。それどころか、リモートプロセスにシェルコードを注入するための最も一般的で率直な方法の1つでしょう。NtOpenProcess、NtAllocateVirtualMemory、NtWriteVirtualMemory、NtProtectVirtualMemory、NtCreateThreadEx を使用するというものです。唯一の違いは、これらの各呼び出しの後に NtCreateUserProcess を使用してプロセスをフォークしていることです。フォークされたプロセスは RIP + 1 から実行を継続し、メモリは親から完全にコピーされるため、5つの異なるプロセスを使用してリモートプロセスインジェクションを実行できます。その際、後続のAPI呼び出しに必要なハンドルが適切に継承されるようにする必要があります。
このようにして、シェルコードインジェクションの手順をより単純なタスクに分割し、それぞれを分離されたコンテキスト(プロセス)で実行します。
私はこのPoCを、現在最も一般的な3つのEDR(MDE、CrowdStrike、SentinelOne)に対してテストしました。結果は明白です。フォークなしでPoCを実行した場合、3つのうち2つのEDRがリモートプロセスインジェクションのアラートを発生させました。対照的に、フォークメカニズムを導入すると、どのEDRもアラートを発生させませんでした。
もちろん、フォークメカニズムを使用しても、生のテレメトリではプロセス作成、スレッド作成、そしてすべてのクロスプロセス動作に対応するイベントを確認できます。しかし、EDRがその活動を悪意のあるものとしてタグ付けするには十分ではないようで、このPoCの趣旨を証明しています。悪意のある動作をより単純なタスクに分割し、それぞれを異なるプロセスから実行することで、EDRを混乱させ、アラートを発生させるのを防ぐことができます。
同じ結果は別の方法でも達成できたかもしれませんが、私はコードを簡素化し、クロスプロセスアクティビティを減らすためにフォークメカニズムを使用しました。
自分でテストしたい場合は、fork() 関数の呼び出しを含む場合と含まない場合の両方でコードをコンパイルし、対象のEDRが動作する環境で両方のペイロードを実行してください。
文字列リテラルを難読化するために LITCRYPT プラグインを使用しているため(Dinvoke_rs コードのみ)、コードをコンパイルする前に環境変数 LITCRYPT_ENCRYPT_KEY を設定する必要があります:
C:\Users\User\Desktop\Split> set LITCRYPT_ENCRYPT_KEY="yoursupersecretkey"
その後、コードをコンパイルしてツールを実行するだけです:
C:\Users\User\Desktop\Split> cargo build --release
C:\Users\User\Desktop\Split\target\release> split.exe -h
このテクニック単体ではEDRをバイパスするのに十分ではありません。コードがまったくOPSECを考慮していない場合、おそらくいずれにせよ検出されるでしょう。これは特効薬ではなく、ツールに追加できるもう1つの回避レイヤーにすぎません。それでも、このリポジトリで紹介されているコードは、とりわけ以下の理由からまったくOPSEC対応ではありません:
一方、私はこのアプローチを前述のEDRに対してのみテストしたため、他のEDRも同様にバイパスできるかどうかはわかりません。自分でテストして、結果を教えてください ;)