samedi 27 juin 2009

Attaques sur la mémoire vive; antiphishing chez firefox

La RAM est un vecteur de divulgation d'information intéressant. L'ensemble des opérations effectuées par le système est enregistrée par celle-ci, aussi est elle un bon candidat pour lire des données. Que ce soit des documents, des clés de chiffrement, des clés de sessions ou tout autre information. Je citerai entre autre l'attaque Cold-boot, ingénieuse et spectaculaire qui permet de retrouver des clés de chiffrement de disque durs.

Je propose un article sur une étude rapide de la mémoire vive d'un système linux (le mien, en l'occurence). Cette étude se base en deux étapes, la première consiste sur le meilleur moyen d'accéder à cette mémoire, la seconde sur un cas concret d'analyse de données nous menant sur les mécanismes d'antiphishing de firefox 2.

1/
Comment accéder à la RAM d'une machine.
La mémoire sous linux est directement accessible via /dev/mem. C'est un fichier spécial de type caractère, le tout premier:
$ ls -l /dev/mem
crw-r----- 1 root kmem 1, 1 2008-12-31 17:31 /dev/mem
Ce fichier représente la mémoire complète physique du système. Un autre fichier important est le /proc/iomem indiquant l'état du découpage de la mémoire:
$ cat /proc/iomem
00000000-0000ffff : reserved
00010000-0009ffff : System RAM
000a0000-000bffff : Video RAM area
000c0000-000c7fff : Video ROM
000f0000-000fffff : reserved
000f0000-000fffff : System ROM
00100000-07fbffff : System RAM
00100000-00432e07 : Kernel code
00432e08-00586313 : Kernel data
005d3000-005fc51b : Kernel bss
01101000-01101fff : Local APIC
efffb000-efffb0ff : 0000:00:14.0
efffb000-efffb0ff : 8139too
efffc000-efffc0ff : 0000:00:13.0
efffc000-efffc0ff : 8139too
efffd000-efffd0ff : 0000:00:12.0
efffd000-efffd0ff : 8139too
ffff0000-ffffffff : reserved
On peut voir que mon système possède 07fbffff octets de RAM, soit 128Mo, ce qui est effectivement le cas.

Se pose maintenant la question d'accès à ces données. La première méthode consiste à passer root puis à dumper le fichier périphérique /dev/mem dans un fichier local et à l'analyser. Cette méthode permet d'obtenir une image statique de la mémoire pour analyse future.
Les outils classiques d'analyse de contenu sont utilisables, comme strings suivi de grep pour rechercher des motifs textes, ou des outils comme ceux de cgsecurity (photorec et tesdisk).

A titre d'exemple encore une fois, sur mes 128Mo de RAM analysées, photorec me trouve 283 fichiers, dont plusieurs scripts shells et programmes elf ( ce qui semble logique).

Un seconde méthode permettant d'analyser la RAM, beaucoup plus longue consiste à utiliser hexdump. En effet, hexdump -C /dev/mem fournit le contenu de la RAM sous forme hexadécimale, bien plus lisible.

C'est d'ailleurs en consultant ce fichier dump hexa que j'ai découvert une série de messages uggc:// ce qui m'a mis intrigué, du fait de a ressemblance avec http:// (aux caractères près). La deuxième partie de ce post donne l'explication de ces URL encodées.

2/
Pour ceux qui ne connaisse pas le rot13, uggc correspond à un décalage de 13 lettres dans l'alphabet du mot http://. Or donc, je trouvai dans la RAM d'une machine une grande quantité de lien http encodés en rot13.
De plus, les domaines considérés ressemblaient tous à des domaines de phishing, de faux sites bancaires ou autres sites à la légalité douteuse. Enfin, la majorité des sites étaient fermés.

Une analyse de la machine montra qu'elle n'était pas infectée, ni vérolée, néanmoins, la provenance de ces URL était intriguante. Lors du dump de la mémoire rien de spécifique n'était lancé sur cette machine, si ce n'était firefox v2.

Et firefox propose une extension appelée "safe browsing".

Cette extension pour firefox v2 est un service proposé par google http://sb.google.com/safebrowsing/update qui donne les dernières mises à jour d'une liste de sites web contrefaits, de malfaçons, ou de site référencés comme phisher. La syntaxe est la suivante: http://sb.google.com/safebrowsing/update?version=goog-white-domain:1:1 pour avoir la liste des domaines whitelistés par google depuis le numéro 1.
Firefox2 télécharge et stocke cette liste de sites dans le fichier urlclassifier2.sqlite, situé dans le profil de l'user. Ce profil est effectivement (comme son nom l'indique) une base de données sqlite:
$ sqlite3 urlclassifier2.sqlite
SQLite version 3.5.6
Enter ".help" for instructions
sqlite> .schema
CREATE TABLE 'goog_black_enchash' (key TEXT PRIMARY KEY, value TEXT);
CREATE TABLE 'goog_black_url' (key TEXT PRIMARY KEY, value TEXT);
CREATE TABLE 'goog_white_domain' (key TEXT PRIMARY KEY, value TEXT);
CREATE TABLE 'goog_white_url' (key TEXT PRIMARY KEY, value TEXT);
sqlite> select key from goog_white_domain limit 3;
02onapbec.pbz
163.pbz/cubgbf
1fg-naancbyvf.pbz
sqlite> .quit
Nous retrouvons bien la liste des URL ROT13-encodées.
J'ai de fait ma réponse sur la raison d'être de trouver dans la mémoire d'une machine une quantité extrêmement grande d'URL encodées en ROT13.

Suite a ces information, une question reste: pourquoi donc ces URL sont-elles codées en ROT13?
Une rapide recherche à l'aide de google codesearch amène à un fichier source appelé nsUrlClassifierDBService.cpp, dont un commentaire attire l'attention:
// We use ROT13 versions of keys to avoid antivirus utilities from
// flagging us as a virus.
nsCString keyROT13(key);
Rot13Line(keyROT13);
Ainsi, firefox2 utilise une simple rotation de 13 caractères pour que leurs listes d'URL ne se fassent pas détecter par des antivirus, ce qui semble surprenant de premier abord.

Firefox 2 n'est plus vraiment utilisé de nos jours. Qu'en est il de firefox 3?

Firefox 3 utilise la nouvelle version de la spec google disponible à l'adresse http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec
Ainsi, firefox utilise un fichier urlclassifier3.sqlite et un fichier de clé urlclassifier3key.txt. Cette méthode semble plus sûre pour éviter de se faire détecter par des antivirus. Seul les hashs sont calculés et comparés. Les détails de l'implémentation antiphishing sont présentés chez mozilla.


CONCLUSION/
Une simple analyse de RAM nous a emmenés très loin de la recherche initiale, sur les mécanismes d'antiphishing de firefox; ceci restant intéressant, j'ai axé la seconde partie de l'article sur ce point.

Cette analyse de RAM apprend beaucoup de choses sur le fonctionnement de la machine, notamment sur les caches utilisés. J'ai été surpris de retrouver certains documents toujours en RAM quelques jours après utilisation.
Pour éviter les accès à cette RAM, il faudrait que je me penche sans doute sur les outils existants permettant soit de flusher l'intégralité des caches RAM, ce qui pourrait être improductif, soit de flusher les caches RAM d'une application particulière lors de sa fermeture.

jeudi 25 juin 2009

Tor sans Privoxy?

Tor est un logiciel permettant d'utiliser les services internet de manière anonyme.
Cet anonymat repose sur l'adresse IP source présentée aux services visités et uniquement cette IP source.

Tor est basé sur un nuage de noeuds Tor, dans lequel la communication client entre, effectue un certain nombre d'opérations de routage, puis s'extrait par un noeud de sortie.
Le destinataire ne connaît donc que l'IP du noeud de sortie Tor, et tor est construit de façon à ce que même le possesseur du noeud de sortie ne puisse pas reconstruire le chemin menant à l'IP source réelle.

Ceci dit, un internaute laisse énormément plus d'informations personnelles qu'une simple IP source. La nature même du trafic peut renseigner sur l'identité de l'internaute (consultation de sa messagerie. Message laissé sur un forum, etc..) Les outils réseaux comme un navigateur web fournissent de plus un grand nombre d'informations au site distant: plateforme utilisé, version, encodage utilisé. Ces informations peuvent être alors utilisées pour tracer l'internaute.
Il existe de nombreux autres problèmes concernant le surf sur le web ou l'insertion judicieuse de scripts javascripts ou d'enregistrement DNS permettent de tracer l'IP source réelle naviguant sur des pages web.
Consulter la FAQ de Tor à ce sujet sur https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ

Pour le surf internet, Tor recommande Privoxy. Nous verrons que privoxy n'est en aucun cas incontournable. Tout d'abord nous verrons succintement comment fonctionne privoxy, ensuite comment l'utiliser sans privoxy tout en conservant un niveau d'anonymat acceptable.
Les recommandations faites pour les clients web seront vraies pour tout type de client internet.

1/
Le fonctionnement de Tor.
Tor n'est pas un proxy HTTP. Toute tentative d'utilisation de Tor comme proxy HTTP se solde par un message:
tor@exploitability:~$ export http_proxy=127.0.0.1:9050
tor@exploitability:~$ wget http://www.google.fr
--2009-06-25 16:24:01-- http://www.google.fr/
Connexion vers 127.0.0.1:9050...connecté.
requête Proxy transmise, en attente de la réponse...
Jun 25 16:24:01.771 [warn] Socks version 71 not recognized. (Tor is
not an http proxy.)
501 Tor is not an HTTP Proxy
2009-06-25 16:24:01 ERREUR 501: Tor is not an HTTP Proxy.

tor@exploitability:~$

(Le message d'erreur vient de tor et non de wget)

Privoxy est un proxy HTTP pouvant se chaîner sur un proxy socks. Ainsi, la chaîne complète est:

Firefox -> privoxy -> Tor -> routage Tor -> Destination

Le destinataire ne peut pas remonter jusqu'à la source. Privoxy propose aussi de nombreuses extensions permettant d'anonymiser également les informations envoyées par le navigateur. La conjonction de ces deux facteurs, anonymat de Tor au niveau IP et anonymat de privoxy au niveau client, justifie cet usage.
Ceci dit, nous pouvons nous en passer.

2/
Un proxy HTTP permet d'effectuer des requêtes HTTP sans réaliser des requêtes DNS préalables. Pour se passer de privoxy, il faudra donc utiliser le proxy socks, faire attention aux requêtes DNS et faire attention aux informations envoyées par les clients.

Firefox permet d'utiliser un proxy internet socks:


Concernant les autres logiciels, il suffit de les paramétrer pour utiliser socks.

A titre d'exemple, wget ne sait pas utiliser un proxy socks, mais curl le peut:

tor@exploitability:~$ curl --socks5 127.0.0.1:9050 -o /dev/null http://www.google.fr
Jun 25 17:06:26.540 [warn] Your application (using socks5 to port 80) is
giving Tor only an IP address. Applications that do DNS resolves themselves
may leak information. Consider using Socks4A (e.g. via privoxy or socat)
instead. For more information, please see
http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#SOCKSAndDNS.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5319 0 5319 0 0 340 0 --:--:-- 0:00:15 --:--:-- 1674
tor@exploitability:~$
On peut par ailleurs noter que l'utilisation de tor entraîne un certain ralentissement du débit internet; 15s pour télécharger la page google.

Ce message d'erreur sera indiqué également lorsque firefox sera utilisé. Ce message est bénin tant que le risque pris par le téléchargement est fait à partir d'adresses IP connues ou que le DNS utilisé est sûr et fiable, ce qui n'est pas forcément toujours le cas.
Pour éviter ce message, deux possibilités sont offertes:

A/
Utiliser un paramétrage de l'outil. Concernant firefox, il suffit de taper about:config dans la barre d'adresse, chercher la clé network.proxy.socks_remote_dns et la mettre à true. Pour curl, utiliser le flag --socks5-hostname:

tor@exploitability:~$ curl --socks5-hostname 127.0.0.1:9050 -o /dev/null http://www.google.fr
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5319 0 5319 0 0 514 0 --:--:-- 0:00:10 --:--:-- 1270
tor@exploitability:~$


B/
Une autre méthode consiste à utiliser le proxy DNS que peut mettre en oeuvre tor. Une règle iptables suffira pour rediriger toutes les requêtes DNS vers ce service tor

Cette directive tor est indiquée par:

DNSPort PORT
If non-zero, Tor listens for UDP DNS requests on this port and
resolves them anonymously. (Default: 0).

Donc une solution consiste à ajouter une ligne:

tor@exploitability:~$ grep DNSPort /usr/local/etc/tor/torrc
DNSPort 5353


Puis à rediriger les requêtes provenant de chaque client vers ce circuit tor; par exemple pour le client se présentant à partir de 192.168.1.1:

iptables -t nat -A PREROUTING -s 192.168.1.1 -p udp --dport 53 -j REDIRECT --to-ports 5353


Bien entendu, ce n'est pas suffisant. Il faut de plus interdire toute autre communication DNS afin d'éviter qu'une requête puisse sortir.

Enfin, concernant les informations renvoyées par les clients, il est également possible de limiter ou de limiter cette fuite. Firefox permet également de modifier son user-agent, et d'autres informations. Il faut de plus faire attention aux extensions ajoutées pouvant elles aussi divulguer de l'information.
curl permet de modifier son User-agent ou tout autre champ d'entêtes web.

CONCLUSION/
Donc, en paramétrant finement son client web, en utilisant des règles de filtrage iptables il est parfaitement possible de surfer à l'aide de tor sans privoxy tout en conservant un niveau d'anonymat aussi haut que celui offert par tor+privoxy.
Privoxy n'est donc qu'une facilité de configuration pour les utilisateurs.

Bien entendu je ne déconseille pas l'utilisation de privoxy. Cet article pointe juste du doigt les raisons d'usage de privoxy. Il est bien plus simple d'utiliser privoxy pour tout client HTTP 'lourd' comme firefox. Mais dans d'autres usages, il est tout aussi rapide d'utiliser curl en mode socks5-hostname.

Pour aller un peu plus loin/

Pour tous les autres services (SMTP, IRC, autres...), il est possible d'utiliser la méthode proxy Socks + redirection DNS vers DNSPort.
Pour les services ne sachant pas utiliser un proxy socks, il faut alors employer un hack comme tor+socat, ou bien utiliser d'autre méthode indiquée sur cette même page.
https://wiki.torproject.org/noreply/TheOnionRouter/TorifyHOWTO#Socat

dimanche 21 juin 2009

Attaques réseaux lentes

Dernièrement sont parues deux attaques réseaux qui se ressemblent; leur but est identique, réaliser un DOS, et leur méthode également puisque la principe consiste à émettre lentement des données afin d'empêcher le fonctionnement normal du service visé.
La première vient de phrack et concerne TCP 1/ Phrack: Exploiting TCP and the Persist Timer Infiniteness, la seconde de ha.ckers.org 2/ ha.ckers.org: Slowloris HTTP DoS.

1/
TCP est un protocole à timers et débits adaptatif. Il permet ainsi d'assurer des connexions dans des contextes variés. L'attaque présentée par phrack concerne une adaptation aux variations de débits constatées sur les lignes internet.
TCP possède une fenêtre d'envoi, ou taille maximale d'octets pouvant être envoyée sans acquittement par la source. L'émetteur ou le destinataire peuvent décider de la taille de cette fenêtre.

Le destinataire peut donc choisir d'augmenter ou diminuer cette fenêtre, la réduire, voire même la rendre nulle en cas d'incapacité de traitement local ou de surcharge réseau détectée.
La source ne peut donc plus envoyer aucune données tant que cette fenêtre est nulle. TCP va donc attendre que la fenêtre d'envoi de données grandisse avant de renvoyer des données.
La connexion reste ouverte tant qu'elle n'est pas terminée. Le code source de linux précise à ce sujet (conserver ou tuer la connexion):
It is not killed only because window stays zero
for some time, window may be zero until armageddon
and even later.
Donc la connexion peut rester ouverte tant que l'autre partie continue d'émettre des paquets TCP continuant de préciser que la fenêtre est de zéro. Il est de plus tout à fait possible de jouer sur le timer TCP permettant de détecter un temps de parcours lent. Plus on répond avec du délai, plus le timer TCP de la source peut conserver la connexion ouverte sans envoi ni réception de paquets.

L'attaque est donc basée sur ce principe
a) on ouvre une connexion
b) on demande un fichier
c) on indique une fenêtre de zéro octets, et on avertit régulièrement la source que la fenêtre est toujours de zéro. La consommation de ressource côté attaquant est minime.
d) L'hôte visé conserve le nombre de connexions ouvertes, et la quantité de mémoire correspondant aux paquets non envoyés.
e) on boucle sur a) un certain nombre de fois.

L'émetteur va donc devoir conserver au niveau applicatif des fichiers ouverts, et au niveau noyau des connexions TCP ouvertes.
Conclusion: DOS.
L'article contient de plus un code source (nkiller2.c) permettant de prouver cette attaque.

La puissance de cette attaque repose sur un des mécanismes de base de TCP. Et c'est bien à ce sujet qu'elle est redoutable. Les failles protocolaires sont les plus difficiles à contrer. Ce n'est pas une erreur de programmation que l'on peut patcher, ce n'est pas une faille de paramétrage. Cette faille fait intrinsèquement partie de TCP, il va être difficile de la corriger.

Ceci dit, j'émettrai deux réserves.
La première concerne la mise en pratique de cette attaque. Il est bien entendu nécessaire que l'hôte visé soit serveur. Mais pas n'importe quel serveur. En imaginant un serveur ssh, la quantité de mémoire consommée risque d'être faible; en effet la réponse d'un serveur ssh tient en quelques octets. A ce sujet, il est éclairant de voir que le PoC vise explicitement un serveur web. nkiller2 réalise une requête GET, puis pose la fenêtre TCP à zéro.
La seconde concerne l'attaque en elle-même. Elle impose une connexion TCP complète, et maintenue dans le temps. L'attaquant voit donc immédiatement quelle est l'IP source de l'attaquant. Il est donc possible de prendre des contremesures.

Enfin, je testerai bien cette attaque contre un proxy HTTP. L'attaquant requete un gros fichier au proxy, mettons une image ISO de DVD, puis envoie des fenêtres TCP à zéro. Je pense que la connexion TCP entre le proxy et le site final ne sera pas de zéro, obligeant ainsi le relais à conserver en mémoire l'intégralité du fichier. Une extension de l'attaque qui pourrait être intéressante.

2/
ha.ckers.org
Cette attaque cible précisément les serveurs HTTP. Comme le dit son auteur, c'est le principe du TCP SynFlood adapté au protocole HTTP.
Le principe consiste à ouvrir presque complètement, mais pas totalement, une session HTTP et à ne rien faire, sauf à la conserver dans cet état. Par exemple en envoyant octet après octet, en prenant garde à ne jamais dépasser le timeout d serveur web:
GET / HTTP/1.1
X-header : une ligne longue (répetition d'une centaine de caractères)
X-header2 : encore une autre ligne
(...)
etc...
Le serveur web va donc utiliser unt hread pour lire cette requête et conserver ce thread ouvert tant que cette requête n'est pas servie. Comme elle peut mettre très longtemps à arriver, le thread ne pourra pas servir à autre chose...
Le serveur web va donc rapidement consumer ses ressources disponibles et ne plus avoir un unique thread de libre pour servir des requêtes légitimes.
Tant que l'attaquant maintient un grand nombre de connexions ouvertes (supérieure aux nombre de threads alloués pour ce site particulier), alors le site est inaccessible.

Cette attaque est pleine de finesse car elle peut faire tomber un unique site web sans toucher aux autres services de la même machine. De plus, comme la connexion n'est pas entièrement ouverte, les logs n'affichent rien (bien entendu, dès que l'attaque termine, les logs se rempliront). Enfin, si le pirate a préalablement ouvert une connexion de type keep-alive, il pourra alors continuer à interroger le serveur alors que toute nouvelle connexion est impossible.

Encore une fois, la même réserve est abordée. L'adresse IP source de l'attaquant est immédiatement connue, et donc filtrable. Il suffit d'interdire à plus d'une adresse IP un maximum de thread, et l'attaque devient inopérante. Deux méthodes sont fournis permettant de contrer cette attaque, toute les deux basées sur ce principe; la première au niveau système en comptant via netstat le nombre d'IP identiques, la seconde au niveau serveur apache directement.

Par ailleurs, ce site web présente un lien vers un message de security focus .
Ce message propose une autre méthode pour attaquer un serveur web. Elle consiste à utilier plusieurs fois l'option Range:
Range: bytes=0-,0-,0-,0-,0-...
le serveur va donc renvoyer autant de fois le fichier que demandé. Ce comportement pourrait être intéressant, encore une fois contre un proxy.

Conclusion:
Les attaques réseaux lentes sont une manière élégante de faire du DOS. Généralement, le DOS implique une énorme connexion, ou une énorme quantité de données à envoyer. Ces deux méthodes montrent qu'il est possible de faire des DoS efficace en envoyant très peu de données.
Je n'ai pas eu le temps de tester contre un proxy, mais je pense que l'expérience serait efficace.

samedi 20 juin 2009

Premier message

Réalisé à des fins de tests.
Plusieurs mots; lorem ipsum, lorem ipsum.

Un mot souligné.