════════════════════════════════════╦═══
╔═╦═╗ ╔═╗ ╔═╗ ╔═╗ ╔═╦═╗ ╔═╗ ╔══╔═╗ ╠═╗
═╩ ╩ ╩═╚═╝═╩ ╩═╚═╝═╩ ╩ ╩═╚═╝═╩ ╠═╝═╩ ╩═
════════════════════════════════╩═══════
作者 Retr0id
═══ MD5-Monomorphic Shellcode Packer ═══
使い方: python3 monomorph.py input_file output_file [payload_file]
最大4KBの圧縮シェルコードを実行可能バイナリに、ほぼ瞬時にパックします。出力ファイルのMD5ハッシュは 常に 同じ値 3cebbe60d91ce760409bbe513593e401 になります。
現在、Linux x86-64のみがサポートされています。この手法を他のプラットフォームに移植するのは簡単ですが、各バージョンのMD5は異なります。また、APE のようなマルチプラットフォームのポリグロットファイルを使用することも可能です。
使用例:
$ python3 monomorph.py bin/monomorph.linux.x86-64.benign bin/monomorph.linux.x86-64.meterpreter sample_payloads/bin/linux.x64.meterpreter.bind_tcp.bin
これまでにも、単一の衝突を使ってバイナリを「善玉」と「悪玉」モードで切り替える手法がありました。Monomorphはこの概念をさらに一歩進めます。
今でも、私には理解できない様々な理由で、ファイルサンプルの参照にMD5を使い続ける人々がいます。もし彼らの誰かがMonomorphでパックされたコードを調査することになれば、大いに混乱するでしょう。
エンコードしたいビットごとに、FastColl を使用して衝突するMD5ブロックを事前計算しています。こちらに要約されているように、各衝突によって、全体のMD5ハッシュを変えずに交換できるブロックのペアが得られます。ローダーは実行時にどのブロックが選ばれたかをチェックし、ビットをデコードします。
4KBのデータをエンコードするには、4 * 1024 * 8 個の衝突を生成する必要があります(数時間かかります)。最終的なファイル内で4MBのスペースを占有します。
これを高速化するために、FastCollに小さな調整を加え、実際の処理をさらに高速化し、並列実行を可能にしました。よりスマートな並列化方法は確かにあるでしょうが、私の単純なアプローチは、N個のインスタンスを同時に起動し、最初に完了したものを待ってから他のすべてを強制終了するというものです。
事前計算は既に行っているため、ペイロードの再構成はほぼ瞬時に行えます。事前計算されたブロックの状態を入れ替えるには、Ange Albertini によって実装された手法を使用します。
はい。非常にステルス性が高いわけではなく、そのように意図されてもいません。detectcoll を使用して衝突ブロックを検出できます。