Archive for février 1st, 2007

NtSystemDebugControl Demystified

Yopla, en direct de la planète RE, en ce moment ce déroule une magnifique rencontre opposant Ivan et son désassembleur, ,le match promet d’être sérré, à la clé, la gloire les filles et l’argent ! L’API NtSystemDebugControl résiste bien mais après avoir été sur des boards chinois et demandé à Alex plein d’infos, Ivan a finit par l’avoir.

L’API Native NtSystemDebugControl permet comme son nom l’indique de réaliser des opérations de débuggage directement au niveau du noyau. Son utilisation requiert l’activation du privilège SeDebugPrivilege. En fait le tout petit ennuit c’est quelle n’est pas documentée :( Enfin pas toutes ses possibilitées…
Son prototype est le suivant :

NtSystemDebugControl(
DEBUG_CONTROL_CODE ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnLength
);

Le champ ControlCode permet de spécifié ce qu’on veut faire, une partie est documenté dans le « Windows 2000 Native API Reference » :

typedef enum _DEBUG_CONTROL_CODE {
DebugGetTraceInformation = 1,
DebugSetInternalBreakpoint,
DebugSetSpecialCall,
DebugClearSpecialCalls,
DebugQuerySpecialCalls,
DebugDbgBreakPoint
} DEBUG_CONTROL_CODE;

Par contre sous IDA, on remarque qu’il y à bien plus que 6 ControlCode possible, voyez plutot :
http://ivanlef0u.fr/repo/NtSystemDebugControl.html
(regardez les ‘case’ du switch)

Après donc avoir chercher un peu partout sur le net et avec l’aide de IDA j’ai pu réunir les 20 possibilitées de cette fonction :

typedef enum _DEBUG_CONTROL_CODE {
DebugSysGetTraceInformation=1,
DebugSysSetInternalBreakpoint,
DebugSysSetSpecialCall,
DebugSysClerSpecialCalls,
DebugSysQuerySpecialCalls,
DebugSysBreakpointWithStatus,
DebugSysGetVersion,
DebugSysReadVirtual,
DebugSysWriteVirtual,
DebugSysReadPhysical,
DebugSysWritePhysical,
DebugSysReadControlSpace,
DebugSysWriteControlSpace,
DebugSysReadIoSpace,
DebugSysSysWriteIoSpace,
DebugSysReadMsr,
DebugSysWriteMsr,
DebugSysReadBusData,
DebugSysWriteBusData,
DebugSysCheckLowMemory,
} DEBUG_CONTROL_CODE;

Pour l’instant j’ai pas encore tout étudié, je me suis intéressé à DebugSysReadVirtual et DebugSysWriteVirtual. Nous permettant de lire et d’écrire partout en mémoire !!!!  W00T
On doit pour cela passer à la fonction pour les utiliser une structure SYSDBG_VIRTUAL.

typedef struct _SYSDBG_VIRTUAL {
PVOID Address; //Adresse ou l’on souhaire lire/écrire
PVOID Buffer; //Buffer source ou destination
ULONG Request; //Taille à lire/écrire
} SYSDBG_VIRTUAL, *PSYSDBG_VIRTUAL;

Petit rappel, l’espace mémoire est divisé en 2 grandes zones :
- de 0×00000000 à 0x7FFFFFFF le UserLand, unique à chaque process, diposant ainsi de 2 GO allouable pour chacun.
- de 0×80000000 à 0xFFFFFFFF le KerneLand, la zone ou se situe le noyau et les drivers.

Ainsi j’ai pu codé un petit memory dumper permettant de voir partout partout partout, à noter que si on dump une zone userland, on verra celle du process courant. Un petit exemple sur le KernelBase qui chez moi vaut 0x804D7000 :

C:\\ProgHack\\c\\native>kdump 0x804D7000 150
4d 5a 90 00 03 00 00 00  04 00 00 00 ff ff 00 00  | MZ..............
b8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  | ........@.......
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  | ................
00 00 00 00 00 00 00 00  00 00 00 00 e8 00 00 00  | ................
0e 1f ba 0e 00 b4 09 cd  21 b8 01 4c cd 21 54 68  | ........!..L.!Th
69 73 20 70 72 6f 67 72  61 6d 20 63 61 6e 6e 6f  | is program canno
74 20 62 65 20 72 75 6e  20 69 6e 20 44 4f 53 20  | t be run in DOS
6d 6f 64 65 2e 0d 0d 0a  24 00 00 00 00 00 00 00  | mode....$.......
ce 0d 2d e1 8a 6c 43 b2  8a 6c 43 b2 8a 6c 43 b2  | ..-..lC..lC..lC.
49 63 1e b2 8d 6c                                 | Ic...l

Tient le PE Header de Ntoskrnl.exe ;)
Après libre à vous d’être curieux et d’aller voir ce que vous voulez ;) Peut-être que Billou vous montrera son cul :]

Cependant la possibilitée la plus intéressante est certainement d’écrire ce que l’on veut dans le noyau :] Pour illustrer rien ne valant un bon exemple, je me suis codé un petit tool qui réalise du DKOM (Direct Kernel Object Manipulation) sur les structures EPROCESS contenant plein d’infos sur les process.

En se basant sur une adresse référence, fs:[0]=0xffdff000, constante qui est en fait le début du KPCR (Kernel Processor Control Region) on peut retrouver la structure EPROCESS courante, celles-ci étant doublement chainée entre elles, il suffit de modifer les pointeurs pour faire croire à sa disparition et donc de son process !!

Le programme s’appel KFist (ouais inspiré hein!) et demande juste le nom du process que vous voulez dégager, exemple avec mon xchat.exe :

C:\\ProgHack\\c\\native>tasklist

Nom de l'image              PID  Nom de la sessio Numéro d Utilisation
========================= ====== ================ ======== ============
System Idle Process            0                         0        16 Ko
System                         4                         0       212 Ko
smss.exe                     512                         0       392 Ko
csrss.exe                    800                         0     4 888 Ko
winlogon.exe                 824                         0     3 816 Ko
services.exe                 868                         0     4 424 Ko
winamp.exe                   280                         0     7 728 Ko
uedit32.exe                 1696                         0    13 616 Ko
cmd.exe                     2036                         0        64 Ko
cmd.exe                     1744                         0       876 Ko
xchat.exe                   1684                         0    12 940 Ko
wish.exe                    1688                         0    26 644 Ko
firefox.exe                 1792                         0    44 412 Ko
FoxitReader.exe             1584                         0    10 132 Ko
hh.exe                      1380                         0    12 016 Ko
tasklist.exe                 636                         0     4 052 Ko
wmiprvse.exe                1340                         0     5 488 Ko

C:\\ProgHack\\c\\native>kfist xchat.exe
KFist : UserLand DKOM Process Hider (xp only)
By Ivanlef0u
BE MAD!
Current ETHREAD : 0x818e1da8
Current EPROCESS : 0x81571da0
Process Name : KFist.exe
EPROCESS : 0x80560450
Process Name :
EPROCESS : 0x81bcb9c8
Process Name : System
EPROCESS : 0x81942da0
Process Name : smss.exe
EPROCESS : 0x818dbda0
Process Name : csrss.exe
EPROCESS : 0x818edd78
Process Name : winlogon.exe
EPROCESS : 0x818b9670
Process Name : services.exe
EPROCESS : 0x818983c0
Process Name : winamp.exe
EPROCESS : 0x8166ea08
Process Name : uedit32.exe
EPROCESS : 0x818c2da0
Process Name : cmd.exe
EPROCESS : 0x81986da0
Process Name : cmd.exe
EPROCESS : 0x818d6da0
Process Name : xchat.exe
Process Found ! Now hiding it...
Prev EPROCESS : 0x818bada0
Next EPROCESS : 0x819bf650
Hiding done, have fun!
EPROCESS : 0x819bf650
Process Name : wish.exe
EPROCESS : 0x8187f3c0
Process Name : firefox.exe
EPROCESS : 0x81aba3c0
Process Name : FoxitReader.exe
EPROCESS : 0x8162ea88
Process Name : hh.exe
EPROCESS : 0x816f8750
Process Name : wmiprvse.exe
EPROCESS : 0x81571da0

C:\\ProgHack\\c\\native>tasklist

Nom de l'image              PID  Nom de la sessio Numéro d Utilisation
========================= ====== ================ ======== ============
System Idle Process            0                         0        16 Ko
System                         4                         0       212 Ko
smss.exe                     512                         0       392 Ko
csrss.exe                    800                         0     4 908 Ko
winlogon.exe                 824                         0     3 816 Ko
services.exe                 868                         0     4 432 Ko
winamp.exe                   280                         0     7 728 Ko
uedit32.exe                 1696                         0    13 616 Ko
cmd.exe                     2036                         0        76 Ko
cmd.exe                     1744                         0       800 Ko
wish.exe                    1688                         0    26 644 Ko
firefox.exe                 1792                         0    44 404 Ko
FoxitReader.exe             1584                         0    10 132 Ko
hh.exe                      1380                         0    12 016 Ko
tasklist.exe                1040                         0     4 052 Ko
wmiprvse.exe                 408                         0     5 488 Ko

Voilà mon xchat n’apparaît plus dans la liste des process courant ;)
Il existe tout de même une facon de le retrouver mais shuuuuut !
Remarque aussi, le fait de virer une structure noyau peut gravement nuire à la santé de votre OS, ainsi si celui-ci tente d’acceder à la structure sans la trouver il risque de mal le prendre et de BSOD …

L’avantage c’est qu’on à plus besoin de loader un driver pour manipuler le KernelSpace, l’inconvénient c’est que c’est plus compliqué car il faut lire la mémoire de facon indirecte en appelant à chaque fois l’API NtSystemeDebugControl.

Ceci n’est qun ‘avant goût des possibilitées de cette fonction, j’essayerais d’explorer les autres plus tard.

En attendant je vous donne le code soure et les binaires :
http://ivanlef0u.fr/repo/DebugControl.rar

Enjoy !

9 comments février 1st, 2007


Calendar

février 2007
L Ma Me J V S D
« jan   mar »
 1234
567891011
12131415161718
19202122232425
262728  

Posts by Month

Posts by Category