EntropyReducer: ペイロードのエントロピーを低減し、シリアライズされたリンクリストで難読化する
仕組み
EntropyReducer アルゴリズムは BUFF_SIZE と NULL_BYTES の値によって決定されます。以下は、BUFF_SIZE を 4、NULL_BYTES を 2 に設定した場合に EntropyReducer がペイロードをどのように整理するかを示したものです。

難読化アルゴリズム
- EntropyReducer はまず、入力された生のペイロードのサイズが
BUFF_SIZE の倍数であるかを確認し、そうでない場合は倍数になるようにパディングします。
- 次に、ペイロードから
BUFF_SIZE ごとのチャンクを取り出し、InitializePayloadList 関数を使ってリンクリストのノードを作成し、ペイロードをリンクリストとして初期化します。
- 作成されたノードは、エントロピーを下げるために使用される
NULL_BYTES サイズの空のバッファを持ちます。
- この時点で、EntropyReducer はペイロードのエントロピーを下げるというタスクを完了していますが、ここで止まりません。続いて、リンクリスト内の各ノードの順序をランダム化し、生のペイロードの順序を崩します。このステップは、MergeSort 関数を通じて実装されたマージソートアルゴリズムによって行われます。
- ソートされたリンクリストはランダムな順序になります。これは、リンクリストがソートされる際の値が生のペイロードの最初の3バイトの XOR 値であり、この値が再編成されたリンクリスト内での位置を決定するためです。このステップはこちらで確認できます。
- リンクリストをファイルに保存することは、ポインタによって連結されているため不可能です。そのため、シリアライズする必要があります。
- 生成されたリンクリストのシリアライズは、こちらの
Obfuscate 関数によって行われます。
- その後、シリアライズされたデータは出力ファイルに書き込む準備が整います。
難読化解除アルゴリズム
難読化アルゴリズムの最後のステップがリンクリストのシリアライズであったため、ここで最初に行うべきことは、難読化されたペイロードをデシリアライズし、そこからリンクリストを生成することです。このステップは Deobfuscate 関数内のこちらで行われます。
- 次のステップは、ノードの Id を使用してリンクリストをソートすることです。これは、先ほどと同じマージソートアルゴリズムを使用して行われます。
- これで、リンクリストはペイロードのバイトを本来の形で再構築するための正しい順序になりました。そこで、こちらで行われるように、各ノードからペイロードの元のバイトを単純に取り出します。
- 最後のステップは、割り当てられたノードを解放することです。これはこちらで行われます。
使用方法
- EntropyReducer は単純にコマンドラインから生のペイロードファイルを読み取り、難読化されたバージョンを同じファイル名に ".ER" を付けた名前で書き出します。
- 最終的な難読化されたペイロードのサイズは、
BUFF_SIZE と NULL_BYTES の両方の値によって異なります。ただし、以下の式を使用して求めることができます。
FinalSize = ((OriginalSize + BUFF_SIZE - OriginalSize % BUFF_SIZE ) / BUFF_SIZE) * (BUFF_SIZE + NULL_BYTES + sizeof(INT))
このリポジトリの PoC プロジェクトは、例として生成された ".ER" ファイルを実行し、そのデシリアライズと難読化解除を行うために使用されます。
プロジェクトへの組み込み
必要な作業は、EntropyReducer.c と EntropyReducer.h ファイルをプロジェクトに追加し、Deobfuscate 関数を呼び出すだけです。参考として PoC/main.c を確認してください。
出力例
この例では、BUFF_SIZE は 3、NULL_BYTES は 1 に設定されています。
- 生のペイロード、最初のペイロードチャンク (
FC 48 83)

- 同じペイロードチャンクだが、異なるオフセットにあるもの

効果
- metasploit によって生成された x64 calc シェルコードはエントロピー
5.883 であり、pestudio で表示したものです。

- 同じファイルを AES で暗号化した場合、エントロピーは
7.110 になります。

- RC4 アルゴリズムでもほぼ同様の結果です。
7.210

- しかし EntropyReducer を使用すると、元の生のペイロードよりもさらに低いエントロピー
4.093 を記録します。
