
発表
Shoggothは、C++とasmjitライブラリに基づくオープンソースプロジェクトで、与えられたシェルコード、PEファイル、COFFファイルをポリモーフィックに暗号化するために使用されます。
Shoggothは、ペイロードと対応するローダーを難読化された形式で保存した出力ファイルを生成します。出力の内容は位置独立コードであるため、シェルコードとして直接実行できます。ペイロードの実行中は、実行時に自身を復号化します。暗号化ルーチンに加えて、Shoggothはルーチン間に何も変更しないガベージ命令を追加します。
私は、さまざまな動的な命令生成手法、アセンブリの実践、シグネチャ検出を研究するためにこのプロジェクトの開発を始めました。新しい学びを得るたびにリポジトリを定期的に更新する予定です。
現在の機能は以下の通りです:
入力ファイルに対するShoggothの一般的な実行フローは以下の画像で確認できます。デフォルト設定でこのフローを観察できます。
基本的に、Shoggothはまず選択されたモード(COFFまたはPEファイル)に従ってプリコンパイルされたローダーシェルコードと入力ファイルをマージします。次に、このマージされたペイロードに生成した複数のガベージ命令を追加します。ローダー、ガベージ命令、ペイロードを含むスタブは、最初にRC4暗号化で暗号化され、次に対応する復号化ルーチンを結合したランダム生成のブロック暗号で暗号化されます。最後に、結果のブロックにガベージ命令を追加します。
Shoggothがガベージスタブや暗号化ルーチンの命令をランダムに生成する際には、AsmJitライブラリを使用します。
AsmJitは、C++言語で書かれたマシンコード生成のための軽量ライブラリです。X86、X86_64、AArch64アーキテクチャのマシンコードを生成でき、ベースライン命令と最近の拡張機能をすべてサポートしています。AsmJitでは、オペコード、レジスタ、即値オペランド、コールラベルを指定したり、コード内の任意のオフセットに任意の値を埋め込んだりできます。AsmJitを使用してアセンブリ命令を生成するには、Assemblerクラスから必要なアセンブリ操作に対応するAPI関数をアセンブリオペランド値とともに呼び出すだけで十分です。API呼び出しごとに、AsmJitはコードと再配置情報を内部のCodeHolder構造体に保持します。生成するすべてのアセンブリ命令のAPI関数を呼び出した後、JitRuntimeクラスを使用して、CodeHolderから実行可能権限を持つメモリにコードをコピーし、再配置できます。
コード生成ライブラリを探していたときにAsmJitに出会い、多くの人気プロジェクトで広く使われていることを知りました。そのため、自分のニーズに合わせて使うことにしました。ShoggothがRed Teamの文脈でAsmJitを使用した最初のプロジェクトかどうかはわかりませんが、将来の実装の参考になることを願っています。
Shoggothは、与えられたPEファイルやCOFFファイルを暗号化するために使用でき、プリコンパイルされた位置独立ローダーのおかげで、両方をシェルコードとして実行できます。私は単純に C to Shellcode メソッドを使用して、以前のプロジェクトで修正した有名なPEおよびCOFFローダーのPICバージョンを取得しました。コンパイルには、PIC形式のLSASSダンパーであるHandleKatzプロジェクトのMakefileを使用しました。
基本的に、C to Shellcodeテクニックでシェルコードを取得するために、ローダーソースコード内のすべてのグローバル変数を削除し、すべての文字列をスタックに格納し、実行時に必要なDLLをロードしてパースすることでWindows API関数のアドレスを解決しました。その後、リンカスクリプトでエントリポイントを決定し、MinGWを使用して様々なコンパイルフラグでコードをコンパイルしました。生成された実行可能ファイルの.textセクションを抽出し、ローダーシェルコードを取得しました。上記のようにコードを編集した後の実行可能ファイルは.textセクション以外のセクションを含まないため、このセクションのコードを位置独立として使用できます。
これらのソースコードはCOFFLoaderおよびPELoaderディレクトリで確認および編集できます。また、これらのソースコードのコンパイル済みバージョンはstubディレクトリにあります。現時点では、これらのローダーを編集または変更したい場合は、シグネチャを遵守し、stubディレクトリからプリコンパイル済みバイナリを置き換える必要があります。
BOFに引数を渡すには、'--coff-arg'オプションを使用します。Shoggothは、TrustedSecのbeacon_generate.pyスクリプトを使用して作成できる、パックされた引数を含む事前フォーマットされた16進文字列を期待します。このスクリプトのコピーがCOFFArgGenerator/beacon_generate.pyとして含まれています(@Octoberfest7に多大なる感謝を)。
Shoggothはまず、ストリーム暗号の1つであるRC4アルゴリズムを使用して、取得したペイロードを暗号化します。ここで使用する鍵をランダムに生成した後、その鍵でペイロードを暗号化します。実行時にペイロードを復号する復号化スタブは、AsmJitを使用して動的に作成およびアセンブルされます。スタブで使用されるレジスタは、サンプルごとにランダムに選択されます。
Shoggothで使用したRC4アルゴリズムの実装については、Nayukiのコードを参考にしました。
最初の暗号化の後、Shoggothはランダムに生成されたブロック暗号である2番目の暗号化を使用します。2番目の暗号化では、RC4復号化ルーチンと、オプションでペイロード、ガベージ命令、RC4で暗号化されたローダーを含むスタブの両方を暗号化します。暗号化するチャンクを8バイトのブロックに分割し、各ブロックに対してランダムに生成された命令を使用します。これらの命令には、ADD、SUB、XOR、NOT、NEG、INC、DEC、ROL、RORが含まれます。これらの命令のオペランドもランダムに選択されます。
生成されるガベージ命令ロジックは、Ege Balci氏の素晴らしいSGNプロジェクトに大きく影響を受けています。Shoggothは、ランダムバイトをスキップするジャンプ、副作用のない命令、偽の関数呼び出し、副作用はあるが初期値を保持する命令に基づいてガベージ命令を選択できます。これらの命令はすべてランダムに選択され、AsmJitライブラリの対応するAPI関数を呼び出して生成されます。また、サイズと異なる組み合わせを増やすために、これらの生成関数は再帰的に呼び出されます。
Shoggothの最初のバージョンでは、ガベージ命令を配置できる場所が多数あります。例えば、ブロック暗号命令やRC4暗号命令の間にガベージ命令を配置できます。ただし、デモンストレーションの目的で、生成されるペイロードの複雑さが増すのを避けるため、これらの配置は以降のバージョンに残しています。
メインプロジェクトはコンパイルしていません。そのため、自分でコンパイルする必要があります。オプションとして、PEローダーまたはCOFFローダーのソースコードを編集したい場合は、提供されているMakefileを使用してコンパイルするために、マシンにMinGWがインストールされている必要があります。
______ _ _
/ _____) | _ | |
( (____ | |__ ___ ____ ____ ___ _| |_| |__
\____ \| _ \ / _ \ / _ |/ _ |/ _ (_ _) _ \
_____) ) | | | |_| ( (_| ( (_| | |_| || |_| | | |
(______/|_| |_|\___/ \___ |\___ |\___/ \__)_| |_|
(_____(_____|
by @R0h1rr1m
"Tekeli-li! Tekeli-li!"
Usage of Shoggoth.exe:
-h | --help ヘルプメッセージを表示します。
-v | --verbose 詳細な出力を有効にします。
-i | --input <入力パス> 暗号化するペイロードの入力パス。(必須)
-o | --output <出力パス> 暗号化された入力の出力パス。(必須)
-s | --seed <値> ランダム化のためのシード値を設定します。
-m | --mode <モード値> ペイロード暗号化モードを設定します。利用可能なモードは次の通りです:(必須)
[*] raw - Shoggothはローダースタブを追加しません。(デフォルトモード)
[*] pe - ShoggothはPEローダースタブを追加します。入力は有効なx64 PEである必要があります。
[*] coff - ShoggothはCOFFローダースタブを追加します。入力は有効なx64 COFFである必要があります。
--coff-arg <引数> COFFローダーの引数を設定します。COFFArgGenerator/beacon_generate.pyを使用してこの文字列を生成してください。
例:--coff-arg 0a0000000600000068656c6c6f00
COFFローダーモードでのみ使用されます。(@Octoberfest7に感謝)
-k | --key <暗号化キー> ランダムキーの代わりに最初の暗号化キーを設定します。
--dont-do-first-encryption 最初の(ストリーム暗号)暗号化を行いません。
--dont-do-second-encryption 2番目の(ブロック暗号)暗号化を行いません。
--encrypt-only-decryptor 2番目の暗号化で復号化スタブのみを暗号化します。
「それは恐ろしく、言葉にできないもので、地下鉄の列車よりも巨大でした。形のない原形質の泡の集まりで、かすかに自発光し、無数の一時的な目が、緑色の光の膿疱のようにトンネルを埋め尽くす前面全体に形成され、そして消えていきました。それは私たちに迫り、狂ったペンギンを押しつぶし、その仲間がすべてのゴミを邪悪に一掃した輝く床の上を滑りながら進みました。」 〜 H・P・ラヴクラフト『狂気の山脈にて』
ショゴス(Shoggoth)は、クトゥルフ神話に登場する架空の怪物です。この存在はH・P・ラヴクラフトのソネット連作『ユゴスからの真菌』(1929–30年)でほのめかされ、後に中編小説『狂気の山脈にて』(1931年)で詳細に描写されました。彼らは、その時々に必要な器官や付属肢を形成することができますが、通常の状態はうごめく目、口、もつれる触手の塊です。
これらの生物は、ラヴクラフトの描写では自己形成するゼラチン質の肉塊のような知覚を持ち、固定された形状を持たないため、この名前をポリモーフィック暗号化ツールに付けたいと思いました。🙂
許可されたセキュリティテスト専用です。明示的な許可なくシステムに対してこのツールを悪用することは違法です。