Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
SysWhispers2 — AV/EDR回避:直接システムコールによる回避。 | Kitploit
ツール/GitHubGitHub/jthuraisamy/syswhispers2
防御ツールIDS/IPS回避シェルコードレッドチーミングペイロード開発バイナリエクスプロイト
GitHubjthuraisamy/syswhispers2

SysWhispers2

AV/EDR回避:直接システムコールによる回避。

リポジトリを見る
1.8k2653年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

SysWhispers2

SysWhispersは、直接システムコールを行うためのヘッダー/ASMファイルを生成することで、回避策(エビデンション)を支援します。

すべての主要なシステムコールがサポートされており、生成されたファイルの例は example-output/ フォルダにあります。

SysWhispers 1 と 2 の違い

使用方法は SysWhispers1 とほぼ同じですが、サポートするWindowsのバージョンを指定する必要はありません。変更点のほとんどは内部的なものです。これはもはや @j00ru の syscall tables に依存せず、代わりに @modexpblog によって普及した「システムコールアドレスによるソート」という手法を使用しています。これにより、システムコールスタブのサイズが大幅に削減されます。

SysWhispers2における具体的な実装は、@modexpblogのコードの変形です。違いの一つは、関数名のハッシュが生成のたびにランダム化されることです。この手法を以前に 公開 した @ElephantSe4l は、C++17ベースの別の実装も行っており、こちらも確認する価値があります。

元のSysWhispersリポジトリはまだ存在していますが、将来的に非推奨になる可能性があります。

はじめに

さまざまなセキュリティ製品は、ユーザーモードAPI関数にフックを仕掛け、実行フローを自社のエンジンにリダイレクトして不審な動作を検出できるようにしています。ntdll.dll内のシステムコールを行う関数は、わずか数個のアセンブリ命令で構成されているため、それらを自身のインプラント内で再実装することで、それらのセキュリティ製品のフックをトリガーするのを回避できます。この手法は @Cn33liz によって広められ、彼の ブログ記事 には、さらに詳しい技術的詳細が記載されています。

SysWhispersは、レッドチームメンバーがカーネルイメージ(ntoskrnl.exe)内の任意のシステムコールに対してヘッダー/ASMのペアを生成できるようにします。ヘッダーには必要な型定義も含まれます。

インストール

root@kitploit:~
> git clone https://github.com/jthuraisamy/SysWhispers2.git
> cd SysWhispers2
> py .\syswhispers.py --help

使用方法と例

コマンドライン

root@kitploit:~
# サポートされているすべてのWindowsバージョンと互換性のあるすべての関数をエクスポート(example-output/ 参照)。
py .\syswhispers.py --preset all -o syscalls_all

# 共通関数のみをエクスポート(以下のリスト参照)。
py .\syswhispers.py --preset common -o syscalls_common

# NtProtectVirtualMemory と NtWriteVirtualMemory をすべてのバージョンと互換性を持たせてエクスポート。
py .\syswhispers.py --functions NtProtectVirtualMemory,NtWriteVirtualMemory -o syscalls_mem

スクリプトの出力

root@kitploit:~
PS C:\Projects\SysWhispers2> py .\syswhispers.py --preset common --out-file syscalls_common

python syswhispers.py -p all -a all -l all -o example-output/Syscalls

                  .                         ,--.
,-. . . ,-. . , , |-. o ,-. ,-. ,-. ,-. ,-.    /
`-. | | `-. |/|/  | | | `-. | | |-' |   `-. ,-'
`-' `-| `-' ' '   ' ' ' `-' |-' `-' '   `-' `---
     /|                     |  @Jackson_T
    `-'                     '  @modexpblog, 2021

SysWhispers2: Why call the kernel when you can whisper?

すべての関数が選択されました。

完了!ファイルは以下に書き込まれました:
        example-output/Syscalls.h
        example-output/Syscalls.c
        example-output/SyscallsStubs.std.x86.asm
        example-output/SyscallsStubs.rnd.x86.asm
        example-output/SyscallsStubs.std.x86.nasm
        example-output/SyscallsStubs.rnd.x86.nasm
        example-output/SyscallsStubs.std.x86.s
        example-output/SyscallsStubs.rnd.x86.s
        example-output/SyscallsInline.std.x86.h
        example-output/SyscallsInline.rnd.x86.h
        example-output/SyscallsStubs.std.x64.asm
        example-output/SyscallsStubs.rnd.x64.asm
        example-output/SyscallsStubs.std.x64.nasm
        example-output/SyscallsStubs.rnd.x64.nasm
        example-output/SyscallsStubs.std.x64.s
        example-output/SyscallsStubs.rnd.x64.s
        example-output/SyscallsInline.std.x64.h
        example-output/SyscallsInline.rnd.x64.h

従来の CreateRemoteThread DLLインジェクションのBefore/After例

root@kitploit:~
py .\syswhispers.py -f NtAllocateVirtualMemory,NtWriteVirtualMemory,NtCreateThreadEx -o syscalls
root@kitploit:~
#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);
}
root@kitploit:~
#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のペアが作成されます:

関数リストを展開するにはクリック
  • NtCreateProcess (CreateProcess)
  • NtCreateThreadEx (CreateRemoteThread)
  • NtOpenProcess (OpenProcess)
  • NtOpenThread (OpenThread)
  • NtSuspendProcess
  • NtSuspendThread (SuspendThread)
  • NtResumeProcess
  • NtResumeThread (ResumeThread)
  • NtGetContextThread (GetThreadContext)
  • NtSetContextThread (SetThreadContext)
  • NtClose (CloseHandle)
  • NtReadVirtualMemory (ReadProcessMemory)
  • NtWriteVirtualMemory (WriteProcessMemory)
  • NtAllocateVirtualMemory (VirtualAllocEx)
  • NtProtectVirtualMemory (VirtualProtectEx)
  • NtFreeVirtualMemory (VirtualFreeEx)
  • NtQuerySystemInformation (GetSystemInfo)
  • NtQueryDirectoryFile
  • NtQueryInformationFile
  • NtQueryInformationProcess
  • NtQueryInformationThread
  • NtCreateSection (CreateFileMapping)
  • NtOpenSection
  • NtMapViewOfSection
  • NtUnmapViewOfSection
  • NtAdjustPrivilegesToken (AdjustTokenPrivileges)
  • NtDeviceIoControlFile (DeviceIoControl)
  • NtQueueApcThread (QueueUserAPC)
  • NtWaitForMultipleObjects (WaitForMultipleObjectsEx)

Visual Studio へのインポート

  1. 生成された H/C/ASM ファイルをプロジェクトフォルダにコピーします。
  2. Visual Studio で、プロジェクト → ビルドのカスタマイズ... に移動し、MASM を有効にします。
  3. ソリューションエクスプローラー で、.h ファイルと .c/.asm ファイルをそれぞれヘッダーファイル、ソースファイルとしてプロジェクトに追加します。
  4. x86 ASM ファイルのプロパティに移動します。
  5. 構成 ドロップダウンから すべての構成 を選択します。
  6. プラットフォーム ドロップダウンから Win32 を選択します。
  7. 以下のオプションを設定します:
    • ビルドから除外 = いいえ
    • コンテンツ = はい
    • 項目の種類 = Microsoft Macro Assembler
  8. 適用 をクリックします。
  9. プラットフォーム ドロップダウンから x64 を選択します。
  10. 以下のオプションを設定します:
    • ビルドから除外 = はい
    • コンテンツ = はい
    • 項目の種類 = Microsoft Macro Assembler
  11. 適用 をクリックし、OK をクリックします。
  12. x64 ASM ファイルのプロパティに移動します。
  13. 構成 ドロップダウンから すべての構成 を選択します。
  14. プラットフォーム ドロップダウンから Win32 を選択します。
  15. 以下のオプションを設定します:
    • ビルドから除外 = はい
    • コンテンツ = はい
    • 項目の種類 = Microsoft Macro Assembler
  16. 適用 をクリックします。
  17. プラットフォーム ドロップダウンから x64 を選択します。
  18. 以下のオプションを設定します:
    • ビルドから除外 = いいえ
    • コンテンツ = はい
    • 項目の種類 = Microsoft Macro Assembler
  19. 適用 をクリックし、OK をクリックします。

MinGW と NASM を使用したコンパイル

以下の例は、MinGW と NASM アセンブラを使用して上述のサンプルプログラムを EXE および DLL としてコンパイルする方法を示しています:

x86 EXE の例

root@kitploit:~
i686-w64-mingw32-gcc -c main.c syscalls.c -Wall -shared
nasm -f win32 -o syscallsstubs.std.x86.o syscallsstubs.std.x86.nasm
i686-w64-mingw32-gcc *.o -o temp.exe
i686-w64-mingw32-strip -s temp.exe -o example.exe
rm -rf *.o temp.exe

x86 DLL の例(エクスポート付き)

root@kitploit:~
i686-w64-mingw32-gcc -c dllmain.c syscalls.c -Wall -shared
nasm -f win32 -o syscallsstubs.std.x86.o syscallsstubs.std.x86.nasm
i686-w64-mingw32-dllwrap --def dllmain.def *.o -o temp.dll
i686-w64-mingw32-strip -s temp.dll -o example.dll
rm -rf *.o temp.dll

x64 EXE の例

root@kitploit:~
x86_64-w64-mingw32-gcc -m64 -c main.c syscalls.c -Wall -shared
nasm -f win64 -o syscallsstubs.std.x64.o syscallsstubs.std.x64.nasm
x86_64-w64-mingw32-gcc *.o -o temp.exe
x86_64-w64-mingw32-strip -s temp.exe -o example.exe
rm -rf *.o temp.exe

x64 DLL の例(エクスポート付き)

root@kitploit:~
x86_64-w64-mingw32-gcc -m64 -c dllmain.c syscalls.c -Wall -shared
nasm -f win64 -o syscallsstubs.std.x64.o syscallsstubs.std.x64.nasm
x86_64-w64-mingw32-gcc-dllwrap --def dllmain.def *.o -o temp.dll
x86_64-w64-mingw32-strip -s temp.dll -o example.dll
rm -rf *.o temp.dll

MinGW と GNU アセンブラ (GAS) を使用したコンパイル

x86 EXE の例

root@kitploit:~
i686-w64-mingw32-gcc -m32 -Wall -c main.c syscalls.c syscallsstubs.std.x86.s -o temp.exe
i686-w64-mingw32-strip -s temp.exe -o example.exe

x86 DLL の例(エクスポート付き)

root@kitploit:~
i686-w64-mingw32-gcc -m32 -Wall -c dllmain.c syscalls.c syscallsstubs.std.x86.s -o temp.dll
i686-w64-mingw32-dllwrap --def dllmain.def *.o -o temp.dll
i686-w64-mingw32-strip -s temp.dll -o example.dll

x64 EXE の例

root@kitploit:~
x86_64-w64-mingw32-gcc -m64 -Wall -c main.c syscalls.c syscallsstubs.std.x64.s -o temp.exe
x86_64-w64-mingw32-strip -s temp.exe -o example.exe

x64 DLL の例(エクスポート付き)

root@kitploit:~
x86_64-w64-mingw32-gcc -m64 -Wall -c dllmain.c syscalls.c syscallsstubs.std.x64.s -o temp.dll
x86_64-w64-mingw32-dllwrap --def dllmain.def *.o -o temp.dll
x86_64-w64-mingw32-strip -s temp.dll -o example.dll

LLVM/Clang での使用

SysWhispers2 は、clang 互換の ASM スタブを含む .s ファイルを出力します。これは llvm を使用してコードをコンパイルする際に使用できます。例えば、上記の CreateRemoteThread DLL インジェクションの例では:

root@kitploit:~
clang -D nullptr=NULL main.c syscall.c syscallstubs.std.x64.s -o test.exe

インライン ヘッダー オンリー

inlinegas 出力オプションを使用すると、BOF のコンパイルで使用できる Syswhispers2 のヘッダーのみのバージョンが生成されます。プロジェクトにそのヘッダーをインクルードするだけです。

ランダム システムコール ジャンプ

ランダム システムコール ジャンプルーチンを使用することで、「システムコールのマーク」を回避することが可能です。アセンブリスタブは、新しい関数 SW__GetRandomSyscallAddress を呼び出します。この関数は ntdll.dll 内のクリーンなシステムコール命令を検索して選択します。これにより、ユーザーランドのシステムコール命令もトリガーされないようにできます。

ランダム システムコール ジャンプを使用するには、プログラムのコンパイル時に RANDSYSCALL を定義し、SysWhispers2 の出力の rnd バージョンを使用する必要があります。以下の例は、GNU アセンブラスタブを使用したものです。

x86 EXE の例 - ランダム システムコール ジャンプ使用

root@kitploit:~
i686-w64-mingw32-gcc main.c syscalls.c syscallsstubs.rnd.x86.s -DRANDSYSCALL -Wall -o example.exe

x64 EXE の例 - ランダム システムコール ジャンプ使用

root@kitploit:~
x86_64-w64-mingw32-gcc main.c syscalls.c syscallsstubs.rnd.x64.s -DRANDSYSCALL -Wall -o example.exe

注意点と制限事項

  • グラフィカルサブシステム (win32k.sys) のシステムコールはサポートされていません。
  • Visual Studio 2019 (v142) と Windows 10 SDK でテストされています。

トラブルシューティング

  • 型の再定義エラー:syscalls.h 内の typedef がすでに定義されている場合、プロジェクトがコンパイルできないことがあります。
    • 必要な関数のみが含まれていることを確認してください(つまり、--preset all はほとんど必要ありません)。
    • 他の使用中のヘッダーですでに typedef が定義されている場合は、syscalls.h から削除できます。

クレジット

@Jackson_T と @modexpblog によって開発されましたが、多くの他の作業者の研究に基づいています:

  • @FoxHex0ne - 多くの関数プロトタイプと typedef を機械可読形式でカタログ化。
  • @PetrBenes、NTInternals.net team、MSDN - 追加のプロトタイプと typedef。
  • @Cn33liz - 初期の Dumpert POC 実装。

関連記事とプロジェクト

  • @modexpblog: Bypassing User-Mode Hooks and Direct Invocation of System Calls for Red Teams
  • @hodg87: Malware Mitigation when Direct System Calls are Used
  • @Cn33liz: Combining Direct System Calls and sRDI to bypass AV/EDR (Code)
  • @0x00dtm: Userland API Monitoring and Code Injection Detection
  • @0x00dtm: Defeating Userland Hooks (ft. Bitdefender) (Code)
  • @mrgretzky: Defeating Antivirus Real-time Protection From The Inside
  • @SpecialHoang: Bypass EDR’s memory protection, introduction to hooking (Code)
  • @xpn and @domchell: Silencing Cylance: A Case Study in Modern EDRs
  • @mrjefftang: Universal Unhooking: Blinding Security Software ()

SysWhispers への参照

  • @JFaust_: Process Injection Part 1, Part 2, および Alaris loader プロジェクト (Code)
  • @0xPat: Malware Development Part 2
  • @brsn76945860: Implementing Syscalls In The CobaltStrike Artifact Kit
  • @Cn33liz and @_DaWouw: Direct Syscalls in Beacon Object Files (Code)

ライセンス

このプロジェクトは Apache License 2.0 の下でライセンスされています。

ツールをダウンロード
Code
  • @spotheplanet: Full DLL Unhooking with C++
  • @hasherezade: Floki Bot and the stealthy dropper
  • @hodg87: Latest Trickbot Variant has New Tricks Up Its Sleeve