vincent's blog

Domptage de Firefox à l'aide de Chickenfoot

chickenfoot1

Lors d'un test d'intrusion, nous avons eu à faire une recherche exhaustive sur des comptes Webmail, plus précisément des identifiants valides, en laissant le minimum de traces dans les logs. Typiquement simuler une action humaine. Nous nous sommes orienté vers l'extension Firefox, Chickenfoot.

Chickenfoot (développée par le User Interface Design Group du MIT) est une interface qui permet de contrôler son navigateur au moyen de scripts.

Ses principaux atouts :

- Les scripts créés tournent dans l'espace chrome (au delà du DOM de la page, on est au niveau des extensions, on peut donc intéragir avec le code de Firefox).

- De nombreuses fonctions et bibliothèques extrêmement utiles sont fournies.

- C'est le juste milieu entre la macro de souris/clavier extrêmement imprécise (en particulier lorsqu'il s'agit de gérer les erreurs) et le script curl ou équivalent, détectable et limité (comportement non classique, non exécution du javascript, non téléchargement des images, etc.).

Chickenfoot permet donc d'automatiser un comportement utilisateur sans avoir à émuler un navigateur.

Nous nous sommes uniquement intéressés à l'aspect automatisation d'actions, mais il est à noter que ses fonctionnalités sont aussi orientées sur la présentation de contenu (la plupart des tutoriaux le présente d'ailleurs sous cet aspect).

chickenfoot2Comme un code source parle bien souvent plus qu'un long discours, vous trouverez - ici - un code exemple permettant le bruteforce d'un SquirrelMail français.

Deux blocs de fonctions, Utils et Squirrel, avec pour Utils :

Utils.Output pour la création de logs, qui donne un exemple de manipulation de fichiers (grâce à l'include fileio.js, jetez un oeil aux bibliothèques documentées, et n'hésitez pas à fouiller les sources de Chickenfoot pour trouver des petits trésors comme screenshot.js qui porte bien son nom).

Elle est suivie par Utils.CloseBoxWindow pour détruire toute forme de messages d'alerte (on notera ici la manipulation d'objets du navigateur).

Dans le bloc de fonctions Squirrel vous avez les exemples de base :

go(url);
retvalue = find("Identifiant:");
if (retvalue.count == 1) {
Util.Output("Init OK");
} else {
Util.Output("Can't verify if it's a good login page");
return (null);
}

go(url) envoie l'onglet courant sur la page url. Le find permet de faire de l'évènementiel, il sert de wait. Il attend que la page soit chargée, puis y cherche ensuite la chaine "Identifiant:". On peut ensuite effectuer un test dessus.

Par la suite, les identifiants et mots de passe sont extraits des fichiers sur le disque (un exemple d'expression régulière permettant de scinder le contenu de ces derniers).

On continue avec la fonction Squirrel.Check, appelée pour tester un couple d'identifiants :

enter("Identifiant :", login);
enter("Mot de passe :", pass);
click("Messagerie button");
retvalue = find("Utilisateur inconnu ou mot de passe incorrect.");
if (retvalue.count == 1) {
[...]
}

La simplicité de cette extension apparait très clairement sur cet exemple. On est loin du POST, du GET, des input type=hidden, des redirections de pages, des problèmes d'XMLHTTPRequest, etc. On demande simplement de remplir des champs, de cliquer sur un bouton, puis de regarder une fois la page chargée si une chaine est présente.

L'appel à sleep() qui suit, permet de temporiser, à noter que cette implémentation fait partie des fonctions fournies par l'extension, et souffre de problèmes sous certains systèmes exploitations (FreeBSD entre autre). Dans un soucis de portabilité, il est conseillé de rester sur les classiques rappels par setTimeout() bien connus des développeurs Javascript.

Je vous renvoie à la documentation officielle et à son wiki (courts et incomplets), au peu de posts tiers mais surtout aux sources (pour ceux qui souhaitent approfondir). Le mode record est à voir aussi, qui permet de générer très facilement les enter(xx,xx) et click(xx) (il suffit de cocher la case "Record actions").

Ce billet est une brève introduction de l'outil. Nous publierons prochainement une documentation plus avancée accompagnée de sources.

Détection de processus cachés

Nous avons développé lors d'une de nos missions un anti-rootkit pour Windows. Une des fonctionnalités kernel de ce dernier liée à la détection de processus cachés est détaillée dans ce présent billet.

Nous étudierons plus particulièrement une technique qui permet notamment de détecter le très célèbre Futo Enhanced. Pour rappel, ce rootkit va jusqu'à supprimer l'entrée du processus à cacher de la PspCidTable, table utilisée par le noyau Windows pour stocker threads et processus du système.

Détecter Futo Enhanced est très simple si l'on cherche sa signature en mémoire. C'est évidemment sans aucun intérêt puisque la méthodologie n'est pas générique. Nous avons donc préféré cumuler les techniques de récupération d'information et faire une corrélation de ces informations. La solution présentée ici permet de récupérer une liste de structures EPROCESS correspondant aux processus actifs sur le système.

Première étape: récupérer l'adresse de cette fameuse table. On analyse d'abord en mémoire la fonction PsLookupProcessByProcessId. Comme son nom l'indique, cette fonction retourne la structure EPROCESS correspondant au pid donné en argument (note intéressante, les pids sous Windows sont multiples de 4, car ils servent d'offset pour cette table).

Voici un extrait de cette fonction dans lequel on retrouve bien la valeur courante de la PspCidTable :

805c9446 8bff            mov     edi,edi
805c9448 55              push    ebp
805c9449 8bec            mov     ebp,esp
[...]
805c945e ff35e0a25580    push    dword ptr [nt!PspCidTable (8055a2e0)]

La PspCidTable contient la liste des EPROCESS, mais aussi la liste des ETHREAD, structures contenant des informations sur chacun des threads actifs du système d'exploitation.

Seconde étape: récupérer toutes les entrées "valides" de cette table (les entrées inutilisées ou en phase de suppression contiennent un "flag"). Les entrées sont de ce type :

typedef struct _TABLE_ENTRY {
        DWORD object;
        ACCESS_MASK security;
};

hide_cat2Il reste ensuite à différencier les ETHREAD des EPROCESS. Plusieurs solutions existent, la meilleure étant d'en implémenter le maximum (comme toutes les récupérations d'information). Une méthode très simple à mettre en place est de considérer la structure comme une structure ETHREAD, d'en sortir le champ correspondant à la service table, et de le comparer aux deux seules valeurs possibles, à savoir la service table classique et celle des GUI threads. Si la valeur ne correspond pas, il y a de fortes chances que ce soit une structure EPROCESS.

lkd> dt nt!_KTHREAD  88dc85e0
[...]
   +0x0e0 ServiceTable     : 0x80552fe0
[...]

Nous voila enfin avec une liste des structures pointant vers les threads actuellement actifs sur la machine. Ces threads étant liés à un processus, il suffit de rechercher dans la structure l'information suivante (l'offset est dépendant de la version du système, il est ici à titre informatif) :

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

Après avoir récupéré les pointeurs EPROCESS de ces structures, si un processus non présent dans les précédents listings apparait, il s'avère alors suspicieux.

C'est en cumulant des techniques de ce type qu'on parvient à détecter la plupart des codes malveillants. Le concept est simple, pousser plus loin que le créateur de rootkit.