dimanche 28 septembre 2008

L'Union Fait la Force.

Voici une archive contenant deux articles qui sont le résultats d'un travail en commun avec Overclok, le fruit d'une entraide conséquente à renouveler puisque plutôt efficace :). En effet depuis quelques temps nous travaillons sur deux sujets : les buffer overflows sous php et les TLS Callbacks.
0vercl0k nous a mijoté une jolie classe toute propre pour gérer l'implémentation de TLS Callbacks le tout en expliquant le fonctionnement de ceux-ci.
Il met en pratique le tout en montrant comment détecter un debugger avant même que celui-ci n'est eu le temps de breaker l'entry point.
Il continue avec un exemple d'HotPatching reprennant le principe de l'inline hooking. Encore un sujet que mon camarade mène avec brio en montrant comment rendre très discret un anti-debugger qui ne l'est pas.
Tout ceci étant bien évidemment accompagné de codes, screenshots, schémas, dumps et explications.
Je ne vous en dis pas plus, à vous de découvrir la suite :).
Pour ma part j'aborde les buffers overflows sous php. Je débute en créant un fuzzer me permettant de trouver des fonctions faillibles. Au total 8 sont détectées. J'entame alors une analyse de PHP.exe pour essayer de localise les failles ainsi que de comprendre pourquoi celles-ci ont lieu d'être. L'exploitation est basée sur la réécriture de SEH et aboutie à deux exploits, l'un pour PHP 5.x et l'autre pour Apache 2.x.

Je vous souhaite donc une bonne lecture.
A bientôt.

L'archive est disponible ici.

Les codes/exploits/binaires de mon paper sont également dispo ici.

Un petit coucou à Freespirit qui revient parmi nous :).

2 commentaires:

Anonyme a dit…

Coucou !
Je vins de lire ton article et je me pose plusieurs questions :
- Dans ton fuzzer, pourquoi avoir pris 999 comme taille de buffer ?
- Ne peut-on pas avoir une erreur du au nombre d'arguments de la fonction qui nous ferait croire que la fonction est vulnerable ?
- Je n'ai pas compris "De cette façon l'instruction qui va copier les données va vouloir écrire en dehors des limites de la
pile et et de ce fait l'exception Access Violation immédiatement et non au RET." quand tu passes de 1000 à 2000...
- Quel intérêt d'avoir des BOF dans des fonctions qui ne prennent de toutes façons (quasiment) jamais d'argument venant d'un utilisateur ?

lilxam a dit…

Salut !
Désolé pour le temps que j'ai mis à répondre, mais la semaine je suis pas chez moi.
Pour ta première question j'ai pris 999 au hasard, j'aurais très bien pu prendre 1000 ou 800...
Ensuite pour reconnaitre si il s'agit d'un BoF je me base sur l'erreur obtenue, si l'EIP est en partie ou totalement réécrit c'est qu'il s'agit bien d'un BoF. Le nombre d'argument est lui géré par php, si il y en a pas le bon nombre il affiche juste un message d'erreur sans conséquences.
En ce qui concerne ta troisième question, imagine la pile comme suit :

DWORD ret_address = adress_de_retour_originale
...
DWORD Pointer to Next SEH = une_adresse
DWORD SEH Handler = une_adresse
...
Fin de la pile

Si je met 1000 caractères elle va être écrasée comme ceci :

DWORD ret_address = 0x41414141
0x41...
DWORD Pointer to Next SEH = une_adresse
DWORD SEH Handler = une_adresse
...
Fin de la pile

Dans ce cas lorsqu'on va arriver au RET de la fonction courrante l'EIP va prendre la valeur 0x41414141 et l'exception Access Violation saura générée.
Maintenant si je met 2000 caractères, lorsque l'instruction à l'origine du problème va être exécutée celle-ci va copier le buffer dans la pile jusqu'à arriver à la fin de la pile et vouloir continuer à écrire. Donc si la fin de la pile est en 0x22FFFF elle va vouloir écrire en 0x230000 et là l'Access violation va être généré dessuite et non au RET. Je peux donc identifier facilement l'instruction qui provoque le bug.

Ensuite l'intérêt c'est tout d'abord de voir comment tout ça fonctionne puis ensuite imagine que tu est hébergé sur un serveur où une fonction faillible est activée, tu pourrais en avoir le contrôle. Enfin mon but à moi est surtout didactique.

Voilà en espérant avoir été clair.
Bonne continuation.