Pentest d’une instance Yunohost #3 – Audit en Black Box

PUBLISHED ON AUG 26, 2016 — SECURITY, SYSADMIN

Scanning

Ports et services

Yunohost installe avec lui divers services comme Nginx, Postfix, Dovecot ou encore Jabber. Un rapide scan nmap nous permet de récupérer une liste des ports ouverts sur le serveur et, par conséquent, des services disponibles.

$ sudo nmap -sS -sU myyunohost.local
Starting Nmap 6.40 ( http://nmap.org ) at 2016-07-11 13:19 CEST
Nmap scan report for myyunohost.local (192.168.1.28)
Host is up (0.00037s latency).
Not shown: 998 open|filtered ports, 990 filtered ports
PORT     STATE SERVICE
22/tcp   open  ssh
25/tcp   open  smtp
53/tcp   open  domain
80/tcp   open  http
443/tcp  open  https
465/tcp  open  smtps
587/tcp  open  submission
993/tcp  open  imaps
5222/tcp open  xmpp-client
5269/tcp open  xmpp-server
53/udp   open  domain
5353/udp open  zeroconf

On voit qu’il y a, par défaut, de nombreux ports ouverts et notamment le port 22 correspondant au serveur SSH (Yunohost recommande de changer ce port : https://yunohost.org/#/security_fr).

SSH

De la même manière, un scan détaillé du service SSH nous donne des résultats intéressants :

$ nmap -A -p 22 myyunohost.local
[...]
22/tcp   open  ssh      OpenSSH 6.7p1 Debian 5+deb8u2 (protocol 2.0)

La version d’OpenSSH semble être 6.7p1 et celle-ci présente deux vulnérabilités.

SMTP

Dans un scan plus précis, on peut voir que le serveur SMTP laisse accessible une commande intéressante : VRFY.

$ nmap -A -p 25,465,587 myyunohost.local
[...]
25/tcp   open  smtp     Postfix smtpd
|_smtp-commands: myyunohost.local, PIPELINING, SIZE 26214400, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, 
| ssl-cert: Subject: commonName=myyunohost.local
| Not valid before: 2016-07-03T15:58:48+00:00
|_Not valid after:  2026-07-01T15:58:48+00:00
|_ssl-date: 2022-02-07T07:07:20+00:00; +5y198d16h33m34s from local time.
465/tcp  open  ssl/smtp Postfix smtpd
|_smtp-commands: myyunohost.local, PIPELINING, SIZE 26214400, VRFY, ETRN, AUTH PLAIN LOGIN, AUTH=PLAIN LOGIN, ENHANCEDSTATUSCODES, 8BITMIME, DSN, 
| ssl-cert: Subject: commonName=myyunohost.local
| Not valid before: 2016-07-03T15:58:48+00:00
|_Not valid after:  2026-07-01T15:58:48+00:00
|_ssl-date: 2044-10-27T06:53:41+00:00; +28y107d19h29m50s from local time.
587/tcp  open  smtp     Postfix smtpd
|_smtp-commands: myyunohost.local, PIPELINING, SIZE 26214400, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, 
| ssl-cert: Subject: commonName=myyunohost.local
| Not valid before: 2016-07-03T15:58:48+00:00
|_Not valid after:  2026-07-01T15:58:48+00:00
|_ssl-date: 2100-01-01T21:03:18+00:00; +83y174d9h39m27s from local time.

Cette commande permet de vérifier l’existence d’une adresse email sur le serveur. Pour l’utiliser, on se connecte sur l’un des ports ouverts par Postfix et on lance la commande VRFY [adresse email].

Sur les ports 587 et 465, la réponse est toujours “Client host rejected: Access denied”. Cependant, la réponse sur le port 25 est différente :

VRFY admin@myyunohost.local
252 2.0.0 admin@myyunohost.local
VRFY toto@myyunohost.local
550 5.1.1 <toto@myyunohost.local>: Recipient address rejected: User unknown in virtual mailbox table

On peut donc voir que l’adresse admin@myyunohost.local existe mais pas toto@myyunohost.local.

Afin de récupérer quelques noms d’utilisateurs, j’ai écrit un script permettant d’énumérer les utilisateurs présent sur le serveur mais mon IP s’est fait bannir après quelques secondes … Il est donc probable qu’un service type Fail2Ban soit installé par défaut.

DNS

Bien que le numéro de version d’Nginx n’est pas disponible, ce n’est pas le cas du serveur DNS installé en même temps que Yunohost.

$ nmap -A -p 53 myyunohost.local
[...]
53/tcp   open  domain   dnsmasq 2.72
| dns-nsid:
|_  bind.version: dnsmasq-2.72

On voit ici que le serveur est dnsmasq version 2.72. Or, cette version contient, au moins, une vulnérabilité de type “Déni de service”.

HTTP/HTTPS

Comme on a pu le remarquer sur le résultat du scan Nmap, un serveur web tourne sur le serveur et si l’on fait un scan plus poussé, on remarque plusieurs choses :

$ nmap -A -p 80,443 myyunohost.local
[...]
80/tcp   open  http     nginx
|_http-methods: No Allow or Public header in OPTIONS response (status code 302)
|_http-title: Did not follow redirect to https://myyunohost.local/yunohost/sso/?r=aHR0cDovL215eXVub2hvc3QubG9jYWwv
443/tcp  open  http     nginx
|_http-methods: No Allow or Public header in OPTIONS response (status code 400)
|_http-title: 400 The plain HTTP request was sent to HTTPS port
| ssl-cert: Subject: commonName=myyunohost.local
| Not valid before: 2016-07-03T15:58:48+00:00
|_Not valid after:  2026-07-01T15:58:48+00:00
|_ssl-date: 2052-10-13T03:02:01+00:00; +36y81d3h07m40s from local time.
| tls-nextprotoneg: 
|_  http/1.1
  • Deux ports sont ouverts : 80 pour le protocole HTTP et 443 pour sa version sécurisée.
  • Le serveur web est Nginx.
  • Un requête en HTTP est automatiquement redirigée vers la version sécurisée du site.

Le numéro de version d’Nginx n’apparaît pas et, d’après les différents types de scans, il n’y a pas de fuite d’information importante.

Concernant la configuration SSL/TLS, pas de défaut majeur mis à part le certificat auto-signé qui, je crois, sera remplacé par Let’s Encrypt dans les prochains versions. La configuration automatique de Yunohost est correct et ne pose pas de problème de sécurité.

Un scan nikto nous présente d’autres résultats :

$ nikto -h myyunohost.local -p 443 -ssl
[...]
+ Server: nginx
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ Uncommon header 'x-sso-wat' found, with contents: You've just been SSOed
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Root page / redirects to: https://myyunohost.local/yunohost/sso/?r=aHR0cDovL215eXVub2hvc3QubG9jYWwv

On y voit notamment que le header ‘x-sso-wat’ est présent ce qui indique probablement que nous sommes sur une page gérée par l’outil SSOwat. Cela signifie, par conséquent, que l’authentification réalisée sur cette page utilisera le protocole LDAP. Une injection LDAP pourrait-elle être présente ? Cela n’est pas impossible car lorsque l’on utilise l’identifiant toto@myyunohost.local) et le mot de passe toto, nous obtenons une belle erreur : 500 Internal Server Error.

Le scan nous montre aussi d’autres choses :

  • il n’y a pas de header ‘X-XSS-Protection’ permettant d’utiliser les filtres anti-xss des navigateurs.
  • il n’y a pas de header ‘X-Frame-Options’ permettant d’empêcher le “clickjacking”.
  • il n’y a pas de header ‘X-Content-Type-Options’ permettant d’empêcher le rendu des fichiers dont le type MIME n’est pas le même que celui attendu.

Après une session de fuzzing sur les headers HTTP, rien ne semble mettre à mal la sécurité de Yunohost.

Concernant Dokuwiki, le numéro de version est disponible via l’URL /dokuwiki/VERSION. Chez moi, il s’agit de la version 2015-08-10a “Detritus”.

Pour WordPress, c’est plus délicat. En effet, la version 2.4 du Yunohost ne permet pas de l’installer depuis son interface classique. Par conséquent, j’ai installé WordPress via la ligne de commande :

$ yunohost app install -l wordpress https://github.com/YunoHost-Apps/wordpress_ynh

Les défauts de configuration sont basiques :

  • Présence du numéro de version ()
  • Présence du fichier readme.txt

Les plus gros problèmes se situent dans la version téléchargée (4.5.2) qui contient plusieurs vulnérabilités. Dans le cadre de ce pentest, j’ai décidé de ne m’attarder que sur les failles de configuration de Yunohost ou sur les parties développées dans le cadre du projet et je vais considérer que ces failles ne rentrent pas dans ce cadre.

Autres services

Les serveurs IMAP, XMPP et MDNS ne semble pas présenter d’informations intéressantes.

Scan de vulnérabilités

Pour terminer, j’ai lancé un scan de vulnérabilités OpenVAS mais celui-ci n’a rien reporté d’intéressant.

Exploitation

SSH

La version d’OpenSSH présente sur mon instance Yunohost présente deux vulnérabilités CVE-2016-0778 et CVE-2016-0777. Celles-ci ont un défaut pour l’attaquant car il doit être authentifié sur le serveur pour pouvoir les exploiter.

Je rappelle qu’un brute-force est impossible car le serveur banni mon IP après quelques tentatives.

DNS

Comme nous l’avons vu précédemment, la vulnérabilité présente dans la version 2.72 de dnsmasq est de type “Déni de service” (CVE-2015-3294). Il n’existe pas d’exploit publique et les informations disponibles ne sont pas très détaillées.

HTTP/HTTPS

Lors de la phase de scanning, nous avons pu voir que l’utilisateur est toujours renvoyé vers la page d’authentification des utilisateurs de Yunohost.

Celle-ci utilise donc le système SSOwat qui paraissait faillible lors de la première phase. Une erreur 500 nous était retourné lorsque l’on tentait une injection LDAP. J’ai multiplié les tentatives d’injection sans parvenir à un résultat concluant. Voulant en savoir plus, j’ai décidé de pousser plus loin l’audit en allant regarder le code source de cette partie. Je sais que cela ne rentre pas dans le cadre du pentest mais la sensibilité de cette partie est trop importante pour passer outre.

SSOwat

Le fonctionnement du système d’authentification est très simple (https://github.com/YunoHost/SSOwat/blob/unstable/helpers.lua#L228).

Le programme vérifie si le nom d’utilisateur contenant un arobase et si c’est le cas, SSOwat considère que c’est une adresse email. Une connexion anonyme s’ouvre alors avec le serveur LDAP pour rechercher un nom d’utilisateur correspondant à l’adresse email entrée.

Une fois que SSOwat a récupéré un nom d’utilisateur, il tente d’ouvrir une connexion LDAP.

On a pu voir que l’erreur 500 n’apparaît que quand nous utilisons un arobase ce qui semble signifier qu’un injection LDAP est probablement présente dans la fonction search. Au contraire, malgré mes divers tests, la fonction qui permet d’ouvrir une connexion LDAP nominative semble résister.

L’impact de cette “faille” est limitée car elle n’affiche rien. Si, par exemple, nous l’exploitons pour retrouver toutes les adresses emails enregistrés, elle ne seront jamais affichées. Une faille au niveau de la fonction d’authentification d’LDAP serait catastrophique car, bien exploitée, elle conduirait à l’authentification de l’attaquant en tant qu’administrateur sans avoir besoin de renseigner un mot de passe.

Ce problème ne provient pas de SSOwat à proprement parlé mais de lualdap qui n’est pas écrit par l’équipe de Yunohost.

Conclusion

J’ai été très étonné par la qualité de Yunohost. Tant au niveau de la sécurité qu’au niveau de l’interface et de la simplicité. C’est typiquement le genre de système qui pourrait aider les gens un peu geek à s’auto-héberger de manière ludique. En plus d’être ludique, simple et agréable à utiliser, Yunohost semble très bien sécurisé. Évidemment, il a plusieurs raisons à cela, la première étant que l’interface à proprement parlé ne représente pas une grande surface d’attaque. Le point critique de Yunohost est bien sûr la base de données LDAP mais ce n’est pas celle-ci qui sera attaquée frontalement. Le plus gros risque réside dans les applications tierces installées par les utilisateurs.

Imaginons un monde merveilleux où le cœur de Yunohost sera sans faille, un WordPress mal configuré ou un Dokuwiki qui n’est pas à jour peut réduire à néant la sécurité du serveur et permettre à un attaquant de prendre le contrôle du système. La simplicité de l’interface ne doit pas faire oublier à l’administrateur que chaque service installé est une nouvelle chose à surveiller. La meilleure sécurité reste de faire les mise à jour au moment où celles-ci sont disponibles car les exploits se répandent très rapidement et un simple oubli peut se révéler catastrophique.

Mon pentest n’est pas encore terminé car il reste la partie en boite grise mais à l’issue de ce premier audit, je serais prêt à conseiller, sans hésiter, cet outil à tout apprenti administrateur système. Je voulais dire aussi un grand bravo aux personnes qui travaillent sur Yunohost et également un grand merci.