lundi 21 janvier 2008

Les apis de debugs, c'est plus fort que toi.

Bonsoir à vous,
c'est avec un peu de retard que je vous poste ce petit article de rien du tout.
Ne vous attendez pas à quelque chose d'exceptionnel, il ne s'agit juste d'une introduction aux apis de debugs.
Vous vous êtes jamais demandé, comment des désassembleurs/débuggeur tel que OllyDbg, fonctionnent-ils?
Bon bah justement c'est avec cette batterie d'apis qu'ils fonctionnent.
Je vais alors, vous expliquez le déroulement et l'utilisation de tels apis.

Tous d'abord, nous avons deux choix. En effet, soit l'on attache notre processus debuggé à notre programme (qui sera en faite le 'débuggeur') ; ou l'on
va créer directement notre processus (CreateProcess) avec les flags DEBUG_PROCESS ainsi que DEBUG_ONLY_THIS_PROCESS (afin de recevoir seulement les débugs évents relatif à notre processus et non à tous ses processus fils et co).
Une fois l'une de ces actions réalisée, notre programme devient le débuggeur
C'est à dire que grâce à la fonction WaitForDebugEvent, nous allons pouvoir stopper le ou les threads lorsqu'un 'debug évent' va être envoyé par le processus debuggé.
La liste des debugs évents est disponible ici : http://msdn2.microsoft.com/en-us/library/ms679308(VS.85).aspx.
Une fois le processus stoppé, libre à vous de modifier son contexte, à savoir ces registres ou encore de passer en mode 'single step', autrement dit 'pas à pas'.
Ceci dit, une fois fait vos petites magouilles, on relance l'attende de debug évents avec ContinueDebugEvent.
Voilà le fonctionnement du débuggeur.

Vous devez savoir aussi, que si vous avez des opérations de réécriture sur des registres, vous devez spécifié le flag CONTEXT_CONTROL dans le membre ContextFlags de la structure CONTEXT.
Si vous vous demandez de quoi est composé, la structure CONTEXT, la msdn me direz-vous, mais justement elle ne présente pas la structure c'est pour cela que je vous donne la déclaration tel quel, présente sur mon système.

typedef struct _CONTEXT {
DWORD ContextFlags;
DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;
FLOATING_SAVE_AREA FloatSave;
DWORD SegGs;
DWORD SegFs;
DWORD SegEs;
DWORD SegDs;
DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;
DWORD Ebp;
DWORD Eip;
DWORD SegCs;
DWORD EFlags;
DWORD Esp;
DWORD SegSs;
BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
} CONTEXT;


Je voulais vous parlez aussi de la réalisation du mode 'singe step'.
Celui-ci se réalise tout simplement en spécifiant un flag dans le membre EFlags, on appelle ce flag le 'Trap Bit'.
Grosso modo, vous allez faire un GetThreadContext, spécifiez le flag dans le bon membre, SetThreadContext et ContinueDebugEvent avec le flag DBG_CONTINUE.
Ensuite, à la prochaine instruction un nouveau debug évent va faire son apparition : EXCEPTION_SINGLE_STEP, si vous voulez continuer en mode pas à pas, vous re-spécifiez le flag et ainsi de suite.
Voilà pour ce qui est de la théorie, place aux screenshots :

Trouver l'adresse de la fonction à appeler :



Rewrite de l'eip



Et maintenant les codes :

DebugSingleStep.c.
RewriteEIP.c.
Cible.c.

A présent, vous êtes apte à patcher un crackme en mémoire par exemple :)).
Plus serieusement, l'outil "iinjj" developpé par Baboon utilise en partie ces apis, allez faire un tour sur son blog : http://baboon.ringzero.fr/.
Voilà en espérant que ça pourra servir à quelques d'entres vous, sur ce bonne soirée et désolé du retard.

PS: Vous pouvez aussi biensure posez vos breakpoints, en modifiant la mémoire avec WriteProcessMemory, et y posez une int 3, libre à votre immagination.

samedi 12 janvier 2008

Close a remote handle file.

Bonjour à tous,
me revoilà après un petit peu d'absence ,tout cela par la faute des vacances scolaires et des fêtes bien sure.
Trêve de plaisanterie ,en cette nouvelle année je reprend mon petit régime hebdomadaire.
Aujourd'hui c'est un post de Ivanlef0u qui attire mon attention : Playing with windows handle.
Dans ce post il explique comment récupérer le type d'un handle ainsi que son nom.
Bien sure on utilise encore une fois la belle api windows ainsi que quelques fonctions ,venues tout droit de ntdll.
Ceci dis j'ai voulus moi même tenter l'expérience ,en codant exactement ce qu'il avait déjà réalisé.
Cela permet de mettre des petites choses au point ,être sois même confronté aux problèmes éventuels et j'en passe.
Cependant j'ai décidé d'utilisé ce petit code afin de m'amuser avec les handles de type file.
Notre but ,va donc être de fermer un handle file d'un processus !

Comme vous le savez peut être ,chaque processus possèdent des handles ouvert sur des objets qui peuvent être :

- des files
- des events
- des mutexs
- des pipes et j'en passe
Allez voir par ici ,notre fabuleuse msdn : http://msdn2.microsoft.com/en-us/library/ms724251.aspx.

Je vais donc vous expliquez comment on va opérer :

- Tous d'abord ,on doit récupérer des informations sur tous les handles ouvert sur le système ,on utilisera ntQuerySystemInformation avec l'argument SystemHandleInformation.
- Ensuite on doit trier les structures ,afin de garder seulement celles qui concernent notre processus ,on compare donc le membre de la struct spécifiant le PID avec le PID de notre processus.
- A présent on doit retrouver le type de handle auquel nous avons a faire ,on duplique notre handle afin de query des informations dessus ,duplicateHandle donc.
- Une fois dupliqué nous pouvons utiliser NtQueryObject afin d'obtenir son type.
- A présent ,si vous lisez le post Ivanlef0u il parle d'un bug au niveau des types files : et bien en effet on est obligé d'implanter une petite astuce permettant de savoir si oui ou non notre fonction est bloquante.
On lance donc des threads qui s'occupe de récupérer le nom du handle ,seulement si il dépasse le timeout on les close.
Le thread va donc s'occuper de remplir notre structure ,que nous traiterons dans la fonction qui l'appel.
- On compare le nom avec le fichier que nous voulons fermer ,et on lance notre fonction CloseHandle.

Cette fonction utilise un système que l'on a largement travaillé ,au fil de se blog : l'exécution de code bien sure.
On créer un thread dans notre processus cible sur la fonction CloseHandle ,on lui passe un pointeur sur notre handle et BIM closed.

Voilà en gros le petit code.
Celui-ci est peut être assez 'velus' à lire ,des structures en pagailles et tous cela dans un seul fichier.
Tous cela pour dire que n'hésiter pas à utiliser les headers et compagnie.
Pour tester ce petit programme ,j'ai codé un petit fopen ,qui se charge de garder le fichier ouvert ,on peut alors lancer le close de notre handle.

Place au concret ,voici un petit screenshot :



et un petit dernier :



Maintenant le principale ,les codes :

-CloseAFuckingFileHandle.c.
-HandleOpen.c.

Voici quelques liens intéréssants :

-Je vous conseille de telecharger le SDK ,elle contient de la doc concernant certaines apis natives.
-ZwQueryInformationFile -> http://www.osronline.com/DDKx/kmarch/k111_9pyq.htm.
-Playing with windows Handles -> http://www.ivanlef0u.tuxfamily.org/?p=13.

PS : un petit merci à wizardman pour sa générosité concernant le futur dns :) ainsi que Nam_K .
PS2 : merci à blackclowns pour son zine ,vraiment technique un grand merci.
PS3 : Le blog est actuellement disponible avec l'adresse suivant : www.0vercl0k.fr