Retex : sécurisation Drupal

Je me suis fait hacker sur l’un de mes sites Drupal en production, sur le serveur qui était mal protégé.

L’alerte

Tout commence par OVH qui bloque l’envoies d’email parce que le serveur est repéré comme spammeur :

Bonjour,

Notre protection Anti-Spam a détecté un envoi important de spam à partir d'une de vos IP: 
92.XX.XX.XXX

Afin d'assurer la sécurité de notre réseau le trafic sortant de votre serveur vers les
ports 25 a été suspendu.

Afin que vous puissiez effectuer les vérifications voici un échantillon des emails bloqués:

Destination IP: 217.69.139.150 - Message-ID: <span id="OBJ_PREFIX_DWT169_com_zimbra_email" class="Object"><span id="OBJ_PREFIX_DWT170_com_zimbra_email" class="Object">20160325090323.E07981XXXXX@vpsXXXXX.ovh.net</span></span> - Spam score: 9999
Destination IP: 66.102.1.27 - Message-ID: <span id="OBJ_PREFIX_DWT171_com_zimbra_email" class="Object"><span id="OBJ_PREFIX_DWT172_com_zimbra_email" class="Object">20160325090402.E91EE1XXXXX@vpsXXXXX.ovh.net</span></span> - Spam score: 9999
Destination IP: 194.186.47.93 - Message-ID: <span id="OBJ_PREFIX_DWT173_com_zimbra_email" class="Object"><span id="OBJ_PREFIX_DWT174_com_zimbra_email" class="Object">20160325090343.81C801XXXXX@vpsXXXXX.ovh.net</span></span> - Spam score: 9999
Destination IP: 94.100.180.150 - Message-ID: <span id="OBJ_PREFIX_DWT175_com_zimbra_email" class="Object"><span id="OBJ_PREFIX_DWT176_com_zimbra_email" class="Object">20160325090422.973121XXXXX@vpsXXXXX.ovh.net</span></span> - Spam score: 9999
Destination IP: 94.100.180.150 - Message-ID: <span id="OBJ_PREFIX_DWT177_com_zimbra_email" class="Object"><span id="OBJ_PREFIX_DWT178_com_zimbra_email" class="Object">20160325090441.E3F061XXXXX@vpsXXXXX.ovh.net</span></span> - Spam score: 9999

Merci de consulter attentivement ce guide:

    <span id="OBJ_PREFIX_DWT179_com_zimbra_url" class="Object"><span id="OBJ_PREFIX_DWT180_com_zimbra_url" class="Object"><a href="http://guide.ovh.net/AntiSpamBestPratice" target="_blank">http://guide.ovh.net/AntiSpamBestPratice</a></span></span>

Si vous avez identifié et résolu la cause du blocage, vous pouvez débloquer votre IP
depuis le manager, en vous rendant à cette adresse :

    <span id="OBJ_PREFIX_DWT181_com_zimbra_url" class="Object"><span id="OBJ_PREFIX_DWT182_com_zimbra_url" class="Object"><a href="https://www.ovh.com/manager/#/configuration/ip?action=antispam&amp;ip=92.XX.XX.XX&amp;ipSpamming=92.XX.XX.XX" target="_blank">https://www.ovh.com/manager/#/configuration/ip?action=antispam&amp;ip=92.XX.XX.XX&amp;ipSpamming=92.XX.XX.XX</a></span></span>

C’est une IP Russe qui envoies des emails (probablement du SPAM) vers les Chinois. Ce qui signifie que nous avons été hacké.

A partir de la, j’ai fait appel à un sysadmin pour découvrir la faille et protéger le site correctement.

L’audit

L’expert sécurité repère vite l’apparition d’un nouveau thème “fusion core” qui n’a rien à faire la. D’ailleurs git lui même nous le dit :

/var/www/prod/sites/all/themes/fusion/fusion_core/system_ml.php

Après que son robot ai repéré le site, et se soit loggué (l’inscription peut se faire de manière automatique), il passe par le authorise.php pour demander l’installation d’un “theme” qui contient des scripts tels que “shell.php” qui permet ensuite de prendre le contrôle de la machine.
Voici un extrait des logs d’apache :

/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT407_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT408_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:48:12 +0100] "GET / HTTP/1.1" 200 34864 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari
/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT409_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT410_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:48:12 +0100] "POST / HTTP/1.0" 302 680 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/
537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT411_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT412_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:48:13 +0100] "POST /?destination=node/323 HTTP/1.0" 200 193793 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chr
ome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT413_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT414_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:48:20 +0100] "GET /admin/modules HTTP/1.1" 200 68620 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2
454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT415_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT416_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:48:30 +0100] "POST /admin/modules HTTP/1.0" 200 740266 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0
.2454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT417_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT418_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:49:21 +0100] "GET /admin/appearance/install HTTP/1.1" 200 147306 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) C
hrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT419_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT420_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:49:22 +0100] "POST /admin/appearance/install HTTP/1.0" 302 465 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chr
ome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT421_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT422_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:49:23 +0100] "POST /authorize.php?batch=1&amp;amp;op=start&amp;amp;id=1901 HTTP/1.0" 200 245 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, l
ike Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT423_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT424_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:49:24 +0100] "POST /authorize.php?batch=1&amp;amp;id=1901&amp;amp;op=do HTTP/1.0" 200 312 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like
  Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT425_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT426_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:49:25 +0100] "GET /authorize.php?batch=1&amp;amp;id=1901&amp;amp;op=finished HTTP/1.1" 302 297 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML,
  like Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT427_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT428_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:49:26 +0100] "GET /authorize.php HTTP/1.1" 200 3699 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.24
54.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT429_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT430_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:49:27 +0100] "GET /admin/modules HTTP/1.1" 200 68620 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2
454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT431_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT432_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:49:38 +0100] "POST /admin/modules HTTP/1.0" 200 739926 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0
.2454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT433_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT434_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:19:50:18 +0100] "GET /sites/all/themes/fusion/fusion_core/shell.php HTTP/1.1" 200 368 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KH
TML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.45"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT435_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT437_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:20:05:06 +0100] "POST /sites/all/themes/fusion/fusion_core/shell.php HTTP/1.0" 200 23488 "&lt;span id="OBJ_PREFIX_DWT436_com_zimbra_url" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT438_com_zimbra_url" class="Object"&gt;&lt;a href="http://www.emindhub.com/sites/all/themes/fusion/fusi" target="_blank"&gt;http://www.emindhub.com/sites/all/themes/fusion/fusi&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;
on_core/shell.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.9.168 Version/11.50"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT439_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT441_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:20:05:06 +0100] "POST /sites/all/themes/fusion/fusion_core/shell.php HTTP/1.0" 200 24083 "&lt;span id="OBJ_PREFIX_DWT440_com_zimbra_url" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT442_com_zimbra_url" class="Object"&gt;&lt;a href="http://www.emindhub.com/sites/all/themes/fusion/fusi" target="_blank"&gt;http://www.emindhub.com/sites/all/themes/fusion/fusi&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;
on_core/shell.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.9.168 Version/11.50"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT443_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT444_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:20:05:06 +0100] "GET /sites/all/themes/fusion/fusion_core/shell.php HTTP/1.0" 200 24073 "-" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.9.168
  Version/11.50"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT445_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT446_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:20:15:41 +0100] "POST /sites/all/themes/fusion/fusion_core/system_ml.php HTTP/1.1" 200 1126 "-" "Mozilla/5.0 (Windows NT 6.1; rv:38.0) Gecko/2
0100101 Firefox/38.0"
/var/log/apache2/access-prod.log.1:52.29.249.200 - - [14/&lt;span id="OBJ_PREFIX_DWT447_com_zimbra_date" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT449_com_zimbra_date" class="Object"&gt;Mar&lt;/span&gt;&lt;/span&gt;/2016:20:15:41 +0100] "POST /sites/all/themes/fusion/fusion_core/system_ml.php HTTP/1.1" 200 1080 "&lt;span id="OBJ_PREFIX_DWT448_com_zimbra_url" class="Object"&gt;&lt;span id="OBJ_PREFIX_DWT450_com_zimbra_url" class="Object"&gt;&lt;a href="http://www.emindhub.com/sites/all/themes/fusion/f" target="_blank"&gt;http://www.emindhub.com/sites/all/themes/fusion/f&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;
usion_core/system_ml.php" "Mozilla/5.0 (Windows NT 6.1; rv:38.0) Gecko/20100101 Firefox/38.0"

Un nslookup nous indique que l’attaque est lancée depuis un serveur amazon (difficile donc d’aller plus loin) :

nslookup 52.29.249.200
Server:        212.27.40.240
Address:    212.27.40.240#53

Non-authoritative answer:
200.249.29.52.in-addr.arpa    name = ec2-52-29-249-200.eu-central-1.compute.amazonaws.com.

Authoritative answers can be found from:
29.52.in-addr.arpa    nameserver = pdns1.ultradns.net.
29.52.in-addr.arpa    nameserver = x1.amazonaws.com.
29.52.in-addr.arpa    nameserver = x3.amazonaws.org.
29.52.in-addr.arpa    nameserver = x4.amazonaws.org.
29.52.in-addr.arpa    nameserver = x2.amazonaws.com.

Veuillez noter le passage par :

/admin/appearance/install
/authorize.php?batch=1&amp;op=start&amp;id=1901
/sites/all/themes/fusion/fusion_core/shell.php

Du coup l’expert a testé le XSS par acquis de conscience :

First Name : guest<script>alert('attacked')</script>
Last Name : <h1>guest<h1>

En effet, il manquait des “check_plain” sur l’affichage des profils utilisateurs.

Mais ce fût loin d’être terminé :

  • répertoires de tests behat et de deploy dans le root drupal qui pouvaient donner accès à des informations importantes sur le site
  • un adminer.php à la racine du VPS, bien pratique pour développer, mais aurais du être à minima derrière un htpasswd
  • sites de dev non protégés derrière un htpasswd (et pour cause, ça empêche les tests behat de fonctionner)
  • une seule VM pour la prod et les devs : du temporaire qui dure.

Actions menées

  • Migration vers un serveur de prod séparé du serveur de dev
  • déplacement de la racine drupal dans ${GITROOT}/www
  • déplacement du répertoire bdd, deploy et autres répertoires non drupal à la racine
  • sécurisation de la conf apache (intégration du htaccess directement dedans + protection accrue des répertoires)
  • accès interdit aux scripts drupal dangereux : install.php, authorize.php
  • répertoire tmp public private
  • mise en place du ssl
  • passage du script “fix perm” sur la racine drupal afin de s’assurer qu’il n’y a pas de répertoires qui sont trop ouverts (ou inaccessibles)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Time limit is exhausted. Please reload CAPTCHA.

Protected by WP Anti Spam