
RunPEテクニックのVBA実装、またはアプリケーションホワイトリストを回避する方法。
VBA で RunPE テクニックをシンプルかつ効果的に実装したものです。このコードを使用すると、Word または Excel のメモリから実行可能ファイルを実行できます。Microsoft Office 2010 以降の 32 ビット版と 64 ビット版の両方に対応しています。
詳細はこちら:
https://itm4n.github.io/vba-runpe-part1/
https://itm4n.github.io/vba-runpe-part2/

Exploit プロシージャで、実行するファイルのパスを設定します。strSrcFile = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
/!\ 64 ビット OS で 32 ビット版の Microsoft Office を使用している場合は、32 ビットのバイナリを指定する必要があります。
strSrcFile = "C:\Windows\SysWOW64\cmd.exe"
strSrcFile = "C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe"
strArguments = "-exec Bypass"
これにより、次のコマンドラインと同等のものが形成されます。
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -exec Bypass
(オプション)実行ログとエラーログを確認するには、表示 > イミディエイトウィンドウ (Ctrl+G) を有効にします。
Exploit マクロを実行してください!
pe2vba.py を使用して PE ファイルを VBA に変換します。これにより、マクロに直接埋め込むことができます。user@host:~/Tools/VBA-RunPE$ ./pe2vba.py meterpreter.exe
[+] Created file 'meterpreter.exe.vba'.
.vba ファイルの内容に置き換えます。' ================================================================================
' ~~~ EMBEDDED PE ~~~
' ================================================================================
' CODE GENRATED BY PE2VBA
' ===== BEGIN PE2VBA =====
Private Function PE() As String
Dim strPE As String
strPE = ""
PE = strPE
End Function
' ===== END PE2VBA =====
(オプション)実行ログとエラーログを確認するには、表示 > イミディエイトウィンドウ (Ctrl+G) を有効にします。
Exploit マクロを実行してください!
/!\ 埋め込み PE を使用する場合、PE() メソッドが空でない文字列を返すため、マクロは自動的にこのモードに切り替わります。
GetThreadContext() がエラーコード 998 で失敗するこのマクロを 64 ビット版の Office から実行すると、このエラーが発生する可能性があります。回避策として、Word オブジェクト参照からではなく、コードを モジュール に移動してみてください。@joeminicucci さん、ヒントをありがとうございます。
================================================================================
[*] Source file: 'C:\Windows\System32\cmd.exe'
[*] Checking source PE...
[*] Creating new process in suspended state...
[*] Retrieving the context of the main thread...
|__ GetThreadContext() failed (Err: 998)
今のところ、この回避策がなぜ機能するのかわかりません。少し調査しましたが。 このエラーは、64 ビット版で CONTEXT 構造体が適切にアラインされていないことが原因と思われます。構造体のサイズも正しくないことに気付きました([VBA] LenB(CONTEXT) != [C++] sizeof(CONTEXT))が、32 ビット版では問題ありません。GetThreadContext() が正常に戻るようにする動作する解決策はありますが、実行の後半で別の部分が壊れてしまいます。
2019-12-15 編集: 64 ビット版の CONTEXT 構造体の定義は確かに間違っていましたが、これを修正してもバグは直りませんでした。そこで、64 ビット版の回避策を実装しました。GetThreadContext() と SetThreadContext() 関数の CONTEXT 構造体引数を、同じサイズの Byte 配列に置き換えました。
2019-12-17 編集: ついに問題が見つかりました。最初の推測は正しく、CONTEXT 構造体はメモリ上で 16 バイト境界にアラインされている必要があります。これは C では構造体の定義に align(16) を使用することで制御できますが、VBA では制御できません。そのため、GetThreadContext() と SetThreadContext() は「ランダムに」失敗する可能性があります。一方、Byte 配列は常に 16 バイト境界にアラインされているように見えるため、この回避策は有効ですが、VBA インタプリタ/コンパイラをリバースエンジニアリングして確認しない限り、保証はありません。
LongPtr - ユーザー定義型が定義されていませんこのエラーが発生した場合、Office の古いバージョン(<=2007)からマクロを実行していることを意味します。LongPtr 型は VBA7(Office 2010)で、64 ビット Windows API のサポートとともに導入されました。これは、アーキテクチャ(32 ビット/64 ビット)を気にせずにポインタを扱うのに非常に便利です。
回避策として、すべての LongPtr を Long(32 ビット)または LongLong(64 ビット)に置き換えることができます。お好みのテキストエディタで Ctrl+H を使用してください。
@hasherezade - 完全な RunPE 実装 (https://github.com/hasherezade/)
@Zer0Mem0ry - 32 ビット RunPE を C++ で記述 (https://github.com/Zer0Mem0ry/RunPE)
@DidierStevens - VBA への PE 埋め込み
このコードは以下のプラットフォームでテストされました:
Win32 と VBA の型対応表:
(*) LongPtr は「動的」型で、Office 32 ビットでは 4 バイト、Office 64 ビットでは 8 バイトです。 https://msdn.microsoft.com/fr-fr/library/office/ee691831(v=office.14).aspx
| C++ | VBA | アーキテクチャ |
|---|
| BYTE | Byte | 32 & 64 |
| WORD | Integer | 32 & 64 |
| DWORD, ULONG, LONG | Long | 32 & 64 |
| DWORD64 | LongLong | 64 |
| HANDLE | LongPtr(*) | 32 & 64 |
| LPSTR | String | 32 & 64 |
| LPBYTE | LongPtr(*) | 32 & 64 |