mardi 11 décembre 2007

h0l0c4ust ou l'illustration d'une technique utilisée dans les rootkits ring3.

Bonsoir à tous,
Comme chaque semaine ,je vais vous exposer mon petit article et un petit code dans le but d'illustrer le tout.
Après ces plusieurs posts ,j'ai décidé de faire un petit truc plutôt intéréssant pour celui-ci.
En effet il met en action de l'injection de dll ,l'utilisation d'api native ,du hook ( en modifiant l'iat ).
Mon but a donc été de montrer un code pouvant être intégré dans un rootkit ring 3.
Celui-ci va cacher un dossier au processus cible.
Bon à présent je vous expose la technique :

- Tous d'abord ,nous allons injecter notre dll dans un processus. ( à l'aide d'un d'injecteur )
- Ensuite ,notre dll va allez corrompre l'iat de kernel32.dll ,afin de détourner l'api native ( exporté par ntdll.dll ) NtQueryDirectoryFile.
- Et enfin le plus complexe ,est de réaliser une fonction capable de cacher notre dossier.

Voilà donc le mode opératoire.
Normalement si vous avez suivis les précédents post ,vous n'aurez aucun problème à injecter la dll ,et corrompre l'iat de kernel32.dll.
Ce qui peut poser problème en revanche,c'est l'élaboration de la fonction qui va cacher notre dossier.
J'ai décidé de ne pas l'expliquer ,car c'est plutôt complexe à expliquer et je vous conseil de faire énormement de test ,de tattonner le tout.
Je vais par contre vous renvoyez vers de la documentation française sur le "Comment faire ?" de la chose ( en fin de page ).
Comme je parlais de rootkit userland ,ce code est loin d'en être un ,tout d'abord le code ne prend en aucun cas le contrôle de l'userland.
Il va s'injecter dans un seul processus donc ,cependant il serait facilement réalisable d'injecter tous les processus lancés au moment de l'éxécution de l'injection.
Mais un petit problème resterait le cas des nouveaux processus : eux ne seraient pas injecter par notre dll.
Enfin bref tout cela pour susciter votre curiosité à vous de jouer à présent.
Un petit screenshot ,injection du notepad.exe :



Et un second screen ,cette fois-ci plus intéréssant : explorer.exe :



Les codes : h0l0c4ust's injector.c
h0l0c4ust.c (dll)

Les documents : - http://ivanlef0u.free.fr/repo/windoz/hidingfr.txt -> article sur lequel j'ai basé l'élaboration de ma fonction.
- http://www.rit.edu/~jrk9185/rootkit/6-7/rootkit.c -> une source trouvée ,qui peut aider je pense.

Voilà en espérant que vous allez bien assimilez la technique.
Bonne fin de soirée à vous cya.

PS : désolé pour le retard du post ,je suis en pleine période d'examen blanc.
PS2 : j'ai finalement commenté le code de la dll un petit peu .

8 commentaires:

Anonyme a dit…

Sympa comme article, il suffit d'injecter la dll dans tous les process et on a un jouli rk en ring3. :)

Anonyme a dit…

tres sympa ton article " Overclok"

Anonyme a dit…

Salut
Pour commencer je trouve que c'est un super article, et je te remercie d'avoir fourni le code source.
Ensuite je m'en suis un peu servi pour faire mumuse, et je me suis dis que si non pouvais le faire avec des fichiers y'a pas de raison qu'avec des processus se soit different.
Alors ni une ni deux je m'y suis mis.
Je fini tranquillement, je suis content, je teste et la a ma grande surprise ca ne fonctionne pas !
Je regarde mes debugs, j'ai essayer d'injecter dans process explorer (procexp.exe) sur mes debugs je vois qu'il n'utilise pas NtQuerySystemInformation pour lister des fichiers (soit SystemInformationClass == 5) mais uniquement avec SystemInformationClass == 2 (je ne sais pas a quoi ca correspond).
Je teste alors avec le task manager de windows (Taskmgr.exe), lui n'utilise meme pas pour SystemInformationClass == 2, donc aucun apelle a ma fonction.
Je supose qu'ils doivent loader l'API directement depuis la DLL mais je n'en suis pas du tout sur.
Si tu as une quelquonque explication (voir meme solution) elle serait la bien venue.
Merci encore ^^
`Z`

0vercl0k a dit…

Encore merci à toi,
Je pense que la source que je donne en fin de source peut t'aider.
Elle inclus un module de hide de processus, et bien évidemment c'est le même principe qu'avec les fichiers oui.
Je te recommande aussi le post d'ivanlef0u "SSDT Hooking Reinvented".
Bonne chance à toi, en espérant t'avoir apporté de l'aide.

x00.null AT gmail.com a dit…

Iop,

en cherchant à faire un hook IAT sur firefox (ou chrome), sur la fonction send(), je me suis rendu compte que ws2_32.dll ou wsock32.dll sont loadées non pas par l'exécutable firefox.exe ou chrome.exe, mais par certaines de leurs dll.
(docu hook iat, pour exemple [url]http://0vercl0k.blogspot.com/2007/12/bonsoir-tous-comme-chaque-semaine-je.html[/url] )
Bref, les codes "normaux" ne peuvent donc pas aller directement dans l'IAT du processus direct changer ce qu'on veut.

Du coup, j'ai bouclé récursivement sur les entry directory, en les prenant comme modules (plutot que faire un getModuleHandle(0), je fais un getModuleHandle, et je parcoure normalement/récursivement, comme si c'était l'exécutable).

Sauf que là, j'ai deux hics. Primo, boucle infinie sur les modules (même si je spécifie bien que faut pas prendre les ntdll, et compagnie).

Bon, qu'à cela ne tienne, en attendant, j'ai limité la récursivité au seul cas de nspr4.dll de firefox, qui importe tout ce qui est ws2_32.dll et wsock32.dll. Ce qui m'amène au secundo, sous firefox: j'arrive bien à trouver la fonction send (de wsock32.dll). Mais quand je la remplace par ma valeur, cette dernière est re-changée par une autre valeur alakon, d'où le méga plantage quand un send apparaît.
Or, à un moment, j'avais pas traité le type de dwReason de ma dll, du coup je hookais aussi quand je détachait la dll, ce qui m'a permis de voir que mon hook était correct (bonne adresse de ma dll à la place de wsock32.dll:send). Ce qui signifie qu'après mon 1er hook (qui était donc correct), ce blaireau de firefox m'en a fait une belle. Why??? T'as déjà traité ce cas où l'import est fait par une dll importée?

Tchaw!

x00.null AT gmail.com a dit…

@Z: au passage, si ça peut aider, même si ça date grave:
SystemInformationClass == 2 c'est SYSTEM_PROCESSOR_INFORMATION

La structure est dispo sur le net, même si ça ressemble surtout à des infos sur le processeur... A mon avis, ça n'a rien à voir avec le listing de processus.

x00.null AT gmail.com a dit…

Ah tant que j'y suis, en fait mon problème vient probablement du fait que ma dll est unloadée trop tôt, ce qui fait que l'adresse que j'ai foutu dans l'iat n'est plus valide... Une idée du pourquoi du comment, par hasard? Sioupli? ? :)

0vercl0k a dit…

Salut à toi,
Je viens de t'envoyer un e-mail afin de tenter de résoudre ton problème ; c'est plus pratique pour discuter =).
Cordialement, 0vercl0k.