vincent's blog

HTML5, Websockets et cache poisoning

From the book "1000 Heads"Le concept de Websocket fait partie des fonctionnalités qui sont en train d'émerger avec HTML5, CSS3, les device events, etc. Elles servent principalement à remplacer les hacks utilisés par les développeurs web de la nouvelle génération (comprendre Web2 (attention aux allergiques)); ces hacks étant, pour faire simple, une solution au manque de canal de communication persistent, bidirectionnel et évènementiel (en Javascript, car Flash et Java possèdent déjà leur solution) entre le client et le serveur .

Les Websockets sont une des briques qui permettent (permettront) de transformer radicalement l'expérience web de tous les utilisateurs d'Internet (une fois encore).

 

Contexte

BookCinq chercheurs dont trois très reconnus dans le domaine ont publié / signé récemment un papier de recherche intitulé :

"Transparent Proxies: Threat or Menace?"

Ce papier fait état de deux vulnérabilités liées à l'utilisation de sockets binaires dans un environnement présentant des proxys HTTP transparents.

On y lit que les Websockets sont concernées, ainsi que Flash et Java. Une proposition de correction pour le draft Websocket est présentée.

Deux semaines plus tard, Firefox 4 et Opera décident de désactiver la fonctionnalité le temps qu'une nouvelle version soit proposée. Ce nouveau draft rendra toutes les implémentations clients/serveurs actuelles obsolètes.

 

Explication

Le papier décrit deux problemes, dont la source est commune :

Un proxy HTTP qui s'emmêle les pinceaux entre ip, host et vhost.

Les sockets binaires, qu'elles soient faites avec Flash, Java ou Javascript, ne sont qu'un vecteur permettant de forger la requête nécessaire à l'exploitation du proxy vulnérable.
Ce type de vulnérabilité n'a rien de nouveau et nous avons déjà eu l'occasion d'en tester quelques unes dans des scénarios externes (ce qui nous a permis d'accéder à des services internes).

Le premier problème se situe au niveau du routage, imaginez un scénario ou un navigateur établit une connexion vers un serveur 1.1.1.1, avec un header HTTP falsifié du serveur google.com "Host: google.com".
Il arrive qu'un proxy transparent, capturant la requête à l'insu de l'utilisateur et du serveur, se permette de rediriger la connection vers google.com (plutôt que sur le serveur 1.1.1.1). Nous ne nous intéresserons pas à ce cas dans ce billet.

Le deuxième problème concerne les fonctionnalités de cache de ces proxys, et cela semble bien plus intéressant.

Tout comme précédemment, imaginons le scénario durant lequel nous forçons un navigateur à se connecter à un serveur nous appartenant, en forgeant la requête afin de demander une ressource du vhost google.com ("Host: google.com"). Si notre serveur lui fournit une ressource malicieuse avec un header de cache de dix ans, alors un proxy invisible/transparent, analysant le flux à la volée, pourrait au milieu de cet échange prendre la décision de mettre cette ressource en cache.

Le souci est que comme vu précédemment (bien que le cas soit différent), ce proxy se contente de croire le header "Host:", en ignorant le "pinning" vhost-ip pourtant évident à des fonctionnalité de ce type. Il en résulte qu'à la prochaine requête (légitime cette fois) vers cette ressource de google.com (faite par un navigateur passant par le noeud où se trouve ce proxy), son cache sera invoqué et la ressource malicieuse chargée à la place de la légitime (Cache-poisoning).

Dans les scénarios réels évoqués, l'exemple du fichier javascript "ga.js" correspondant à google-analytics est révélateur, mais l'on pourrait tout aussi bien imaginer des attaques sur des webmails ciblés (étant donné que l'attaque nécessite de toutes façons une intervention extérieure derrière un proxy vulnérable).

 

Contenu

Ce papier contient une partie de description technique, une étude basée sur l'exploitation d'une masse de la population, et une proposition de solution pour les Websockets.
La proposition de draft pour les Websockets ne sera pas détaillée ici. Les lecteurs intéressés se réfèreront aux discussions de la mailing list associée.

Pour commencer, il n'apporte rien de nouveau d'un point de vue technique: d'un côté les premiers problèmes liés au pinning DNS (association forcée d'un domaine et d'une ip pour une session donnée) ont été rendus publics en 1996 (ils impliquaient les applets Java). Contrairement à ce qui est écrit dans le papier, ces problèmes ne sont pas récents, même les médias s'en sont emparés il y a trois ans, voire quatre pour certaines présentations (Collin Jackson et Adam Barth, deux des auteurs dont on parle, ayant même participé à un papier résumant le sujet en 2007).

De l'autre côté, les problématiques (évoquées plus haut) liées aux proxys transparents ont déjà été très longuement décrites en 2009, dans un papier de recherche de Robert Auger (PayPal) qui suivait un avis de l'US-CERT.

Les exploits développés sont en Flash et Java, et ils n'ont pas été rendus publics. Les chiffres de personnes vulnérables au cache poisoning (basé sur Java ou Flash) sont de moins de 50 sur 150000 (pour plus de détails reportez vous au papier). N'ayant pas la possibilité légale de reproduire les tests effectués par ces chercheurs (tests d'exploitation de masse sans consentement), nous ne pourrons les vérifier.

Néanmoins, nous avons reproduit une des attaques, et vous proposons de la tester de manière volontaire (Flash doit être activé, c'est compatible tous navigateurs, il suffit de cliquer sur le bouton bleu pour lancer le test qui prendra entre une et quinze secondes à s'effectuer):


Si vous obtenez une croix rouge à ce test, vous êtes vulnérable au cache poisoning. Nous sommes intéressés par vos retours, en particulier par le nom de l'équipement, version et configuration qui seraient mis en cause. N'hésitez pas à nous contacter: contact@atlab.fr.

 

A retenir

- Des chercheurs académiques se sont permis de tester et répertorier le taux d'expansion d'une vulnérabilité de manière mondiale au travers de l'achat d'un espace annonceur (probablement sans le consentement de l'annonceur, et surement sans celui des utilisateurs).

- La vulnérabilité est liée à des proxys transparents non à jour, les Websockets étant un vecteur d'exploitation.

- Aucun exploit en pur Javascript - WebSocket n'a été développé ou n'a été mentionné (les tests ont été effectués avec Java et Flash).

- Les exploits basés sur Flash ou Java seront toujours fonctionnels et le resteront très probablement aussi longtemps que ces plugins existeront.

- Le pourcentage de personnes vulnérables est très faible (de l'ordre de 0,03%) pour une attaque à tendance ciblée sur un proxy d'entreprise.

- Ce papier n'a rien apporté de nouveau d'un point de vue technique.

- Il est responsable de la refonte complète du handshake (qui devient beaucoup plus complexe), a rendu obsolète toutes les implementations courantes du protocole, et après médiatisation a fait désactiver la fonctionnalité dans Firefox4 et Safari.

 

L'équipe Atlab toute entière vous souhaite une bonne fin d'année.

(Pour les heureux possesseurs de Google Chrome et son V8, un joyeux noël en retard).

 

Pen-test Microsoft Surface - Sécurité des byte tags

Microsoft Surface est une table multitouch destinée à un usage multi-utilisateurs. La technologie innovante dans cette table est basée sur les caméras infrarouges disposées à l'interieur permettant la reconnaissance de formes telles qu'un doigt, une main ou un objet. Elle est capable de détecter jusqu'à 54 formes simultanément.

Dans les fonctionnalités offertes par l'API Microsoft Surface on notera la présence d'une sorte de qrcode "made in Microsoft". Disposés sous les objets (verres de cocktail, pièces de jeu d'échecs), ils permettent de déclencher des actions ou suivre un objet de manière plus précise. Microsoft les nomme "Surface tags", et ils existent en deux versions, respectivement byte tags et identity tags.

Les identity tags peuvent contenir 128 bits d'informations, tandis que les byte tags en contiennent 8. La chose intéressante ici est donc que les byte tags ne peuvent prendre que 256 valeurs différentes, ce qui est facilement bruteforceable.

Durant un test d'intrusion physique, il s'est avéré que les développeurs utilisaient une certaine valeur de byte tag dans leur application pour déclencher l'apparition d'un menu d'administration. Vous pouvez voir dans la photo ci-dessous le morceau de carton ayant le byte tag administrateur, ainsi qu'un menu d'administration (flouté) apparu grâce au tag :

Nous l'avons trouvé en testant toutes les valeurs de byte tags que nous avions au préalable imprimés (puis jetés sur la table Surface).

Un autre byte tag déclenchait une action, il s'agissait d'un lecteur vidéo commercial - nous avons supposé que les commerciaux de cette société le possédaient sur leur carte de visite et s'en servaient pour faire leurs présentations.

Tutorial / Documentation et codes d'exemples pour Chickenfoot

ChickenfootChickenfoot (développée par le User Interface Design Group du MIT) est une interface qui permet de contrôler son navigateur (Firefox) au moyen de scripts. Un précédent billet de blog en faisait son introduction, dans le cadre du développement d'une recherche de couples utilisateurs / mots de passe valides.

Nous travaillons actuellement sur de nouveaux outils de veille basés sur des sources publiques d'informations telles que les réseaux sociaux (Twitter, Facebook, Linkedin, Viadeo, ...), forums, news ou encore blog, et cette extension y prend une part importante.


Le document Chickenfoot contient une approche de cette extension au moyen d'exemples concrets.

 

N'hésitez pas à nous faire part de vos retours ou commentaires par mail sur contact  IatI  atlab.fr

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.