FreshRSS

🔒
❌ À propos de FreshRSS
Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.
À partir d’avant-hierFlux principal

Comment auditer un site WordPress avec WPScan ?

12 janvier 2022 à 13:00

I. Présentation

Dans ce tutoriel, nous allons voir comment réaliser un audit de sécurité sur un site WordPress à l'aide de l'outil WPScan, afin d'identifier les failles de sécurité, mais aussi les défauts de configuration.

Afin de réaliser un audit de sécurité d'un site Web, il existe divers outils de sécurité : Nikto, Wapiti, WPScan, etc... Aujourd'hui, nous allons nous intéresser à WPScan, un outil spécifique dédié à l'analyse de sites WordPress.

WordPress étant un CMS utilisé par des millions de sites, il attire forcément le regard des pirates informatiques qui vont chercher à trouver des vulnérabilités au sein du CMS en lui-même, mais aussi dans les extensions et thèmes populaires.

WPScan peut être utile pour auditer son propre site afin d'identifier d'éventuelles faiblesses connues, avant que quelqu'un le fasse avant vous. Cet outil est intéressant en complément des opérations de maintenance effectuées régulièrement, notamment pour maintenir à jour les différents éléments (WordPress, les thèmes et les plugins).

Par ailleurs, WPScan peut-être utilisée dans le cadre de prestation d'audit afin d'analyser le site d'un client. Je ne vais pas vous le cacher et vous l'avez surement deviné, ce type d'outil peut aussi être utilisé à des fins malveillantes.

Attention : n'utilisez pas ce genre d'outil sur des sites web qui ne vous appartiennent pas, à moins d'avoir eu le consentement du propriétaire au préalable.

II. Les fonctionnalités de WPScan

WPScan intègre différentes fonctionnalités que l'on va pouvoir activer ou non en fonction des paramètres utilisés au moment d'exécuter l'outil. Voici quelques-unes des fonctionnalités de WPScan :

  • Récupération du Header HTTP
  • Détection de la possibilité de s'inscrire ou non sur le site
  • Détection de la version de WordPress
  • Analyse du fichier d'exploration robots.txt
  • Récupération d'informations sur le thème, notamment le nom
  • Récupération d'informations sur les extensions
  • Identification de vulnérabilités au sein des extensions détectées
  • Détection de fichiers de configuration de sauvegarde
  • Etc.

Certaines fonctionnalités sont soumises à l'utilisation de l'API WPScan. Les requêtes à destination de cette API sont limitées dans la version gratuite : 25 requêtes par jour sur l'API, tout en sachant qu'une analyse d'un site nécessite généralement plusieurs appels vers l'API WPScan. En fonction des besoins et du nombre d'analyses à effectuer, il faudra peut-être songer à prendre un abonnement payant.

Les différents abonnements de l'API WPscan
Les différents abonnements de l'API WPScan

Avant d'aller plus loin, sachez que WPScan est développé en Ruby et que c'est un projet soutenu par Automattic, l'entreprise propriétaire de WordPress.

III. Installation de WPScan

Pour suivre ce tutoriel, vous avez besoin d'une machine avec Kali Linux puisque WPScan est préinstallé sur cette distribution Linux orientée sécurité.

Pour l'installer sur une autre distribution Linux, je vous invite à vous référer au GitHub du projet : WPScan - GitHub.

Si vous envisagez d'utiliser l'API WPScan (même en version gratuite), vous devez créer un compte sur leur site officiel : WPScan. La création d'un compte ne nécessite pas d'enregistrer une carte bancaire, ce qui est une bonne nouvelle.

IV. Utilisation de WPScan

Sur Kali Linux, l'outil WPScan est un binaire disponible dans "/usr/bin" alors il suffira de l'appeler par son petit nom dans un terminal Linux. Pour afficher l'aide complète de WPScan, la commande suivante doit être utilisée :

wpscan --hh

À partir de là, toutes les options seront affichées à l'écran. Voyons quelques exemples d'utilisation de WPScan.

La première à chose à savoir, c'est qu'il faut inclure le paramètre "--url" pour spécifier le nom de domaine du site à analyser.

wpscan --url www.domaine.fr

Sans aucun autre paramètre, WPScan va effectuer une analyse rapide du site et retourner quelques éléments : header HTTP, contenu du fichier robots.txt, état de la fonction d'inscription du site, détection de la version de WordPress, identification de certains plugins, etc.

Ensuite, il y a une option qui est particulièrement intéressante, c'est l'option "--enumerate" (ou "-e") puisqu'elle permet de spécifier ce qu'il faut analyser (dans le cas d'une analyse ciblée). Par exemple, la valeur "vp" permet de détecter les plugins vulnérables, tandis que la valeur "vt" recherchera la présence d'un thème vulnérable. On peut préciser plusieurs valeurs (mais certaines sont incompatibles entre elles ; voir l'aide), comme ceci :

wpscan --url www.domaine.fr --enumerate vp,vt

Pour que le résultat de cette commande soit complet et pertinent, il faut que l'on utilise l'API de WPScan. En effet, les informations liées aux vulnérabilités sont obtenues après sollicitation de l'API. Sans cela, WPScan va analyser le site distant, récupérer le maximum d'information au sujet des plugins et thèmes, mais il ne vous donnera pas d'informations sur les vulnérabilités détectées.

À partir de votre compte WPScan, vous devez récupérer votre "API Token" afin de l'utiliser avec votre instance WPScan.

Récupérer le jeton d'accès à l'API WPScan
Récupérer le jeton d'accès à l'API WPScan

Comment préciser le token de l'API au sein de la commande WPScan ? Pour cela, il y a deux possibilités : soit dans la commande directement via le paramètre "--api-token" suivi de la valeur, ou dans un fichier de configuration. La première option me semble préférable dans le cas de l'utilisation gratuite pour gérer au mieux ses 25 requêtes quotidiennes.

Ainsi, dans une requête cela donne :

wpscan --url www.domaine.fr --enumerate vp,vt --api-token VotreJetonAPI

Si vous souhaitez stocker ce jeton d'API dans un fichier de configuration pour ne pas avoir à le préciser à chaque fois, créez ce fichier :

nano ~/.wpscan/scan.yml

Précisez le contenu suivant (en modifiant le jeton) :

cli_options:
  api_token: VotreJetonAPI

Il suffit ensuite d'enregistrer le fichier. Si vous ne précisez pas de jeton d'API en utilisant WPScan, celui-ci sera utilisé systématiquement, sinon si vous précisez un jeton dans la ligne de commande, il sera utilisé à la place de celui dans le fichier de configuration. C'est bon à savoir.

Suite à l'analyse effectuée, vous pouvez voir s'il y a des vulnérabilités ou non au sein des plugins détectés sur le site. Néanmoins, il se peut que certains plugins ne soient pas détectés. Voici un exemple :

WPScan : découverte de vulnérabilités dans les plugins WordPress
WPScan : découverte de vulnérabilités dans les plugins WordPress

Sur la copie d'écran ci-dessus, on peut voir le plugin "NextScripts: Social Networks Auto-Poster". En recherchant sur le site de WordPress, on peut voir qu'il s'agit d'une extension qui permet de publier les nouveaux articles automatiquement sur les réseaux sociaux. C'est également précisé qu'il y a 6 vulnérabilités détectées, avec à chaque fois des informations.

Néanmoins, il faut prêter attention à une ligne en particulier : "The version could not be determined". Cela signifie que WPScan a détecté le plugin mais qu'il n'a pas pu récupérer la version installée. En fait, les vulnérabilités listées sont celles connues pour ce plugin, mais cela ne veut pas dire que le site analysé est vulnérable : tout dépend de la version installée.

À la fin de chaque analyse, plusieurs statistiques sont indiquées, notamment l'état de l'API. Sur l'exemple ci-dessous, on peut voir que cette analyse a consommé 8 requêtes d'API, et qu'il m'en reste 17 à consommer.

WPScan : statistiques sur l'analyse
WPScan : statistiques sur l'analyse

Par défaut, le mode de détection est défini sur "mixed", cela signifie qu'en fonction des éléments à détecter, le scan sera plus ou moins agressif (et donc visible). Pour passer en mode agressif (ou tout en mode passif ; "passive"), on peut utiliser l'option "--detection-mode" :

wpscan --url www.domaine.fr --detection-mode aggressive

Terminons l'utilisation de WPScan en prenant un exemple : l'énumération des utilisateurs WordPress.

L'outil WPScan permet d'énumérer les utilisateurs existants sur un site WordPress, et il faut savoir que par défaut WordPress autorise l'énumération des utilisateurs. Pour énumérer les utilisateurs, il y a plusieurs possibilités : à partir des permaliens via les pages auteur, à partir de l'API REST de WordPress (active par défaut) ou encore du flux RSS. Les comptes associés au flux RSS et aux pages liées aux auteurs sont visibles un peu par tout le monde de par leur visibilité sur les articles d'un site. Par contre, l'API REST de WordPress peut-être très bavarde si elle n'est pas bloquée et réellement donner une liste de comptes, ce qui est dangereux.

Cette énumération des utilisateurs s'effectue seulement avec la valeur "u" de l'option "--enumerate", comme ceci :

wpscan --url www.domaine.fr --enumerate u
WPScan : énumération des utilisateurs WordPress
WPScan : énumération des utilisateurs WordPress

Grâce à ces quelques exemples, vous avez connaissance des options basiques de WPScan. Libre à vous d'explorer l'aide pour aller plus loin dans l'utilisation de cet outil.

V. Conclusion

Une analyse de votre propre site web WordPress avec l'outil WPScan va peut-être vous faire prendre connaissance de certains défauts de configuration.

En complément d'un bon suivi des mises à jour, vous devez mettre en place des mécanismes de protection sur votre site WordPress. Certains plugins de sécurité permettent de vous guider en ce sens, notamment pour masquer des informations sensibles, désactiver l'accès à l'API REST, etc. Pour gérer spécifiquement l'accès à l'API REST, il y a le plugin "Disable JSON API" qui permet une gestion avancée.

Dernièrement, j'ai publié deux articles qui peuvent vous aider à renforcer la sécurité de votre site WordPress :

Si vous avez une question liée à la sécurité de WordPress, n'hésitez pas à laisser un commentaire sur cet article.

The post Comment auditer un site WordPress avec WPScan ? first appeared on IT-Connect.

Forensic – PearlArmor : analyse de journaux et d’une image disque

10 janvier 2022 à 10:00

I. Présentation

Nous continuons notre suite d'articles sur le CTF du FIC 2021 proposé par l'école EPITA afin de découvrir certains outils et méthodes de forensic (investigation numérique). Dans cet article nous allons nous pencher sur l'analyse de journaux d'évènements d'un service web et d'une image disque.

Cette enquête est découpée en 5 articles, voici la liste des articles :

II. Contexte : Panic on board - PearlArmor

Le contexte de l'incident sur lequel nous intervenons est le suivant : un bateau de croisière de la compagnie maritime ArMor a subi une panne et se retrouve bloqué en pleine mer.

Nous savons à présent qu'à la suite d'un phishing, l'attaquant est parvenu à dérober les identifiants VPN d'un utilisateur puis à mener une attaque sur les automates du bateau afin de les arrêter. Le cinquième et dernier contexte de cette analyse est le suivant : 

Avant chaque appareillage, l’ordinateur de maintenance présent à bord met à jour sa documentation depuis le serveur de fichiers interne. Le PDF qui a infecté le SeaCastle a donc été téléchargé depuis ce serveur, pourtant situé dans les locaux d’ArMor ! Il ne reste plus qu’à trouver comment le fichier qui a infecté le SeaCastle a été uploadé sur le serveur de documentation !

Deux fichiers nous sont ici fournis :

  • Droits Serveur Doc.pdf
  • FIC-SERVEUR-DOC.ova.gz
  • Utilisateurs Serveur Doc.pdf

Nous devons répondre aux questions suivantes pour compléter cette dernière étape de l'analyse :

  • La date vraisemblable d'intrusion ;
  • Le nom du fichier ayant exploité la faille Apache ;
  • La commande ayant été exécutée en root.

N'oublions pas de vérifier l'intégrité des éléments récupérés (le hash BLAKE2 est fourni avec les fichiers sur le site du challenge) :

$ b2sum Droits Serveur Doc.pdf
6c768bfa48b48a576788b9466e0157f8fd6b2aeb653f6dee11aae31c95412c00fb1abef13d62b0d2a2b3925406fb045f889eadb19738c11c9e28eaaf5e9aef84 Droits Serveur Doc.pdf

$ b2sum FIC-SERVEUR-DOC.ova.gz
c513de9149a9eb85837a8fe9f939f3fa9a1d685514daec1d00a93d35ef2a43214d7f672a9cce58e3cb1840eb8d614e81e8f531fe72b5767e3688df7f294fb344 FIC-SERVEUR-DOC.ova.gz

$ b2sum Utilisateurs Serveur Doc.pdf
64b8a397f26b523a9b75fca277eb5ef0f27c4e1657f5c18e46c058982e989a92e2d3419a9e11b2a237e4d8d5ab471c8563eca5877c1b2004086c4d8df60a4fda Utilisateurs Serveur Doc.pdf

Vous trouverez le challenge en question et les fichiers utilisés dans cet article ici : Panic On Board - PearlArmor 

Les deux documents PDF ne sont pas des preuves, mais des informations fournies à l'analyste. Dans un cas réel, ce genre d'information peut être obtenue par un échange direct avec les responsables du périmètre étudié. Ils nous informent sur les utilisateurs légitimes et la matrice de droit en place.

III. Gestion des preuves

L'un des principes importants lorsque l'on manipule les preuves (objets analysés) en forensic est de s'assurer de leur intégrité comme nous l'avons vu. En cela, il peut arriver que la simple lecture d'un fichier puisse altérer son contenu. Prenons par exemple le cas de notre image disque : nous pouvons tenter de monter cet OVA dans Vmware/VirtualBox puis de parcourir manuellement le contenu du serveur. Cependant, cette action entrainera de fait une modification du contenu de la preuve (écritures d'évènements de démarrage dans les journaux, de tentative d'authentification, etc.). Voire pire, l'attaquant a très bien pu installer un code de destruction qui s'activera au prochain démarrage.

Nous allons donc commencer par effectuer une copie de tous les éléments que nous comptons étudier, nous travaillerons alors sur cette copie et non sur le fichier récupéré.

IV. Analyse d'une image disque

Nous avons donc sous la main un fichier OVA.

Le format OVA (Open Virtual Machine Format) est un format d'archivage des données d'une machine virtuelle (disque & configuration) permettant de facilement les exporter et les importer d'un hyperviseur à un autre (changement de système ou de technologie). Plus simplement, il s'agit d'une archive .tar dont le contenu est défini par le format OVA.

$ file FIC-SERVEUR-DOC.ova
FIC-SERVEUR-DOC.ova: POSIX tar archive

$ tar -xvf FIC-SERVEUR-DOC.ova

FIC-SERVEUR-DOC.ovf
FIC-SERVEUR-DOC-disk001.vmdk
FIC-SERVEURit-DOC.mf

Le fichier OVF permet d'obtenir des informations sur la machine virtuelle, ce fichier est normalement lu par l'hyperviseur pour construire une VM avec les bonnes ressources (RAM, périphériques, etc.).  Au passage, on remarque la présence d'une mauvaise pratique, probablement mise ici pour faciliter la résolution du challenge :

$ grep -i "description" FIC-SERVEUR-DOC.ovf
<Description>root = Root2021

Un autre fichier intéressant dans cette archive OVA est le fichier FIC-SERVEUR-DOC-disk001.vmdk.

VMDK (Virtual Machine Disk) est un format de fichier ouvert (à la base créé par VmWare) permettant de simuler un disque dur virtuel pour les machines virtuelles telles que VMware ou Virtualbox.

Le problème rencontré ici est que les outils d'analyse d'image disque ne sont pas tous accoutumés au format VMDK, nous devons donc convertir ce format VMDK en format raw (image disque brute). Cela à l'aide de la commande suivante : 

$ qemu-img convert FIC-SERVEUR-DOC-disk001.vmdk -m 16 -O raw image.disk

À noter que dès lors, nous pouvons présumer que des preuves sont peut-être écrasées ou perdues par cette manipulation, d'où l'intérêt de travailler sur une copie de la preuve et non sur la preuve reçue directement. Cela nous permettra de revenir sur un fichier sain si nous pensons avoir supprimé quelque chose ou pour valider un constat par une autre technique. Nous nous retrouvons donc avec un fichier de 50Go, soit la taille du disque défini lorsque la machine a été créée :

$ ls -alh
-rwxrwxrwx 1 mdy mdy 2,6G déc. 12 2020 FIC-SERVEUR-DOC-disk001.vmdk
-rwxrwxrwx 1 mdy mdy 50G janv. 5 20:10 image.disk

Une fois cela fait, nous pouvons utiliser l'utilitaire fdisk pour déterminer les différentes partitions présentes dans notre disque :

$ fdisk -l image.disk
Disque image.disk : 50 GiB, 53687091200 octets, 104857600 secteurs
Unités : secteur de 1 × 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 512 octets
taille d'E/S (minimale / optimale) : 512 octets / 512 octets
Type d'étiquette de disque : gpt
Identifiant de disque : 17D2441A-D62C-427F-BC1C-8B694294086E

Périphérique Début Fin Secteurs Taille Type
image.disk1 2048 4095 2048 1M Amorçage BIOS
image.disk2 4096 104855551 104851456 50G Système de fichiers Linux

Nous voyons ici que notre image disque comporte deux partitions, une partition d'amorçage BIOS, et une contenant un système de fichier Linux (très probablement ext4). Tentons à présent de monter cette partition pour pouvoir parcourir son contenu : 

$ sudo mkdir /mnt/m
$ sudo mount -t ext4 -o loop,offset=2097152 image.disk /mnt/m

Étant donné que notre image disque contient deux partitions, nous sommes obligés ici d'indiquer l'offset de début de notre partition dans le fichier transmis à mount. Celui-ci est obtenu en multipliant l'offset de début indiqué par fdisk pour la partition ciblée (4096) à la taille d'un secteur sur le disque (512), ce qui donne 2 097 152 .

Puis nous pouvons parcourir librement le contenu de la partition montée :

$ cd /mnt/m
[email protected]: /mnt/m
$ ls -al
total 4038784
drwxr-xr-x 24 root root 4096 déc. 11 2020 .
drwxr-xr-x 19 root root 4096 déc. 8 16:33 ..
drwxr-xr-x 2 root root 4096 déc. 5 2020 bin
drwxr-xr-x 3 root root 4096 déc. 11 2020 boot
drwxr-xr-x 2 root root 4096 déc. 5 2020 cdrom
drwxr-xr-x 4 root root 4096 févr. 3 2020 dev

Gardez cependant à l'esprit que le simple fait de lire un fichier modifiera des informations à propos de celui-ci, par exemple :

$ stat /etc./hosts
Fichier : hosts
Taille : 224 Blocs : 8 Blocs d'E/S : 4096 fichier
Périphérique : 713h/1811d Inœud : 1835722 Liens : 1
Accès : (0644/-rw-r--r--) UID : ( 0/ root) GID : ( 0/ root)
Accès : 2020-12-11 16:15:40.996000000 +0000
Modif. : 2020-12-05 08:36:46.450157258 +0000
Changt : 2020-12-05 08:36:46.450157258 +0000
Créé : -

$ cat /etc/hosts
127.0.0.1 localhost
[...]

$ stat /etc/hosts

Fichier : hosts
Taille : 224 Blocs : 8 Blocs d'E/S : 4096 fichier
Périphérique : 713h/1811d Inœud : 1835722 Liens : 1
Accès : (0644/-rw-r--r--) UID : ( 0/ root) GID : ( 0/ root)
Accès : 2022-01-05 20:22:21.025011907 +0000
Modif. : 2020-12-05 08:36:46.450157258 +0000
Changt : 2020-12-05 08:36:46.450157258 +0000
Créé : -

La date d'accès du fichier, qui fait partie des attributs des fichiers dans le système de fichier ext4, a été modifiée par notre accès en lecture. Nous ne pouvons ici plus savoir si ce fichier a été lu dans le cadre de l'attaque menée sur le système.

Pour palier à cela, nous pouvons monter le disque en lecture seule (read-only) :

$ sudo mount -t ext4 -o ro,loop,offset=2097152 "/media/mdy/Disque exte/image.disk" /mnt/
$ stat /etc./timezone

Fichier : timezone
Taille : 8 Blocs : 8 Blocs d'E/S : 4096 fichier
Périphérique : 713h/1811d Inœud : 1835770 Liens : 1
Accès : (0644/-rw-r--r--) UID : ( 0/ root) GID : ( 0/ root)
Accès : 2020-12-05 08:52:36.770945118 +0000
Modif. : 2020-12-05 08:52:36.774945114 +0000
Changt : 2020-12-05 08:52:36.774945114 +0000
Créé : -

$ cat /etc/timezone
Etc/UTC

$ stat /etc./timezone
Fichier : timezone
Taille : 8 Blocs : 8 Blocs d'E/S : 4096 fichier
Périphérique : 713h/1811d Inœud : 1835770 Liens : 1
Accès : (0644/-rw-r--r--) UID : ( 0/ root) GID : ( 0/ root)
Accès : 2020-12-05 08:52:36.770945118 +0000
Modif. : 2020-12-05 08:52:36.774945114 +0000
Changt : 2020-12-05 08:52:36.774945114 +0000
Créé :

Nous apprendrons plus loin dans cet article que l'attaque a eu lieu à une date ultérieure à la date d'accès du fichier /etc/timezone. Nous pouvons donc ici être relativement sûr que l'attaquant n'a pas consulté ce fichier. Cette information ne sert à rien ici, mais c'est un exemple pour montrer l'intérêt de conserver une trace dans son état d'origine autant que possible, et d'être conscient du fonctionnement de nos outils pour savoir quelles données risquent d'être modifiées par nos actions.

V. Étude des journaux d'évènements

Maintenant que nous avons un accès au disque dur, nous pouvons parcourir celui-ci et tenter de savoir ce qu'il s'est passé. Le fichier /etc./init.d/apache2.4.29 nous renseigne sur l'emplacement des configurations apache :

[email protected]:/mnt/m/etc/init.d# cat apache2.4.29 
[...]
HTTPD='/usr/local/apache2/bin/httpd'
#
# pick up any necessary environment variables
if test -f /usr/local/apache2/bin/envvars; then
. /usr/local/apache2/bin/envvars
fi

Les journaux du service web apache2 (/usr/local/apache2/logs/access.log) sont notamment intéressant :

Constat de l'absence de journaux pour le 14/08 et le 15/08
Constat de l'absence de journaux pour le 14/08 et le 15/08

On peut constater qu'il y a un trou au niveau des dates de journalisation. Cela peut être dû à une suppression intentionnelle de l'attaquant qui a souhaité effacer ses traces. Ce type d'action est référencé par la T1070.002 - Indicator Removal on Host: Clear Linux or Mac System Logs dans le framework MITRE ATT&CK.

Également, la configuration Apache nous apprend que le répertoire /home/ de l'utilisation deloin_c était exposé sur le service web :

[email protected]:/mnt/m/usr/local/apache2/conf# grep "deloin_c" -A 5 httpd.conf
Alias "/log" "/home/deloin_c"
<Directory "/home/deloin_c">
Options Indexes FollowSymLinks
Require all granted
</Directory>

L'attaquant ayant compromis ce compte a donc pu s'en servir pour exposer des fichiers sur le service web, sans avoir besoin des droits du compte de service apache2. Intéressons nous maintenant à l'activité des comptes utilisateur, par exemple en regardant le contenu du fichier .bash_history des utilisateurs du système.

Sur les systèmes Linux, un fichier .bash_history est situé dans le /home/ de chaque utilisateur et contient l'historique des commandes saisies dans le terminal. Il n'a pas pour vocation première la journalisation dans un but d'investigation numérique puisqu'il peut être supprimé ou désactivé par l'utilisateur. Il est plus fréquemment utile lorsque l'on souhaite retrouver une commande saisie par le passé (Ctrl+R).

Le contenu du fichier /home/deloin_c/.bash_history est suspect :

[email protected]:/mnt/m/home/deloin_c# cat .bash_history 
[...]
echo hello >> test.txt
ls
cat test.txt
cp test.txt /usr/local/apache2/htdocs/Siemes/
vim /usr/local/var/log/carpediem.php
ls
ls -lha /usr/local/apache2/htdocs/Siemes/
ls -lh /usr/local/apache2/htdocs/Siemes/
ls -lh /usr/local/var/log/
chmod 777 /usr/local/var/log/carpediem.php
ls -lh /usr/local/var/log/
wget http://192.168.2.10/log
cat log
rm log
ls
ls -lh /usr/local/apache2/htdocs/Siemes/
ls -lh /usr/local/var/log/
ls
pwd
cp /home/deloin_c/test.txt /usr/local/apache2/htdocs/Siemes/
curl http://192.168.2.10/log/carpediem.php?cmd=cp+/home/deloin_c/test.txt+/usr/local/apache2/htdocs/Siemens
ls -lh /usr/local/apache2/htdocs/Siemes/
cat /proc/self/map
cat /proc/self/maps
cat /usr/local/apache2/logs/httpd.pid
cat /usr/local/apache2/logs/access_log
curl http://192.168.2.10/log/carpediem.php?cmd=/bin/bash
service apache2.4.29 graceful
logout
touch hello.txt
vim hello.txt
cat hello.txt
rm hello.txt

On remarque notamment différentes commandes visant à télécharger des fichiers (wget, curl) et à écrire ou modifier des fichiers dans le répertoire de travail d'apache2. Deux commandes nous interpellent plus particulièrement :

vim /usr/local/var/log/carpediem.php
curl http://192.168.2.10/log/carpediem.php?cmd=cp+/home/deloin_c/test.txt+/usr/local/apache2/htdocs/Siemens

On retrouve ici un élément caractéristique des webshells, l'utilisation d'un paramètre (cmd) contenant une commande système. Nous pouvons donc fortement supposer que le fichier PHP créé (carpediem.php) contienne du code PHP permettant d'exécuter des commandes système. Le nom du fichier carpediem.php est aussi peu commun, une rapide recherche sur internet nous oriente vers un exploit concernant une élévation de privilège locale sur Apache :

Code d'exploitation de la CVE-2019-0211 nommée "Carpe diem"
Code d'exploitation de la CVE-2019-0211 nommée "Carpe diem"

Si l'on regarde la date de dernière édition du fichier /home/deloin_c/.bash_history, on retrouve la date du 15/08/2020 :

[email protected]:/mnt/m/home/deloin_c# ls -al
-rw------- 1 1012 1012 1284 août 15 2020 .bash_history

Ces différents constats nous permettent de répondre à la première question :

  • La date vraisemblable d'intrusion : 15/08/2020

Un autre fichier intéressant est le fichier .viminfo :

[email protected]:/mnt/m/home/deloin_c# cat .viminfo
# Marques dans le fichier :
'0 9 6 /usr/local/var/log/hello.html
|4,48,9,6,1607621460,"/usr/local/var/log/hello.html"
'1 52 0 /usr/local/var/log/carpediem.php
|4,49,52,0,1597511166,"/usr/local/var/log/carpediem.php"
'2 9 6 /usr/local/var/log/hello.html
|4,50,9,6,1607621460,"/usr/local/var/log/hello.html"
'3 536 25 /usr/local/apache2/conf/httpd.conf
|4,51,536,25,1597497150,"/usr/local/apache2/conf/httpd.conf"
'4 9 6 /usr/local/var/log/hello.html
|4,52,9,6,1607621460,"/usr/local/var/log/hello.html"

Le fichier .viminfo est créé automatiquement dans le /home/ de chaque utilisateur et permet d'historiser certains éléments comme les commandes saisies dans vim, les recherches faites dans les fichiers, les marques, etc. 

Dans notre cas, on obtient le chemin absolu des fichiers modifiés par Mr Deloin (ou l'attaquant ayant compromis son compte) :

# Historique des marques dans les fichiers (les plus récentes en premier) :
/usr/local/var/log/hello.html
/usr/local/var/log/carpediem.php
/usr/local/apache2/conf/httpd.conf
~/index.php
/usr/local/var/log/index.php
~/hello.txt

L'attaquant semble avoir créé des fichiers dans /usr/local/var/log/ ainsi que dans le répertoire /home/ de l'utilisateur, or nous savons que le home de l'utilisateur était exposé sur le web, les fichiers PHP créés pouvaient donc y être interprétés par le service web. Avec les éléments recueillis, nous pouvons nous répondre à ces questions : 

  • Le nom du fichier ayant exploité la faille Apache : index.php
  • Le dossier ayant servi de point d'entrée à l'attaquant : /home/deloin_c

Au passage, l'utilisation d'un exploit sur un système ou une application en vue d'élever ses privilèges est référencée par la T1068 - Exploitation for Privilege Escalation dans le framework MITRE ATT&CK.

VI. Récupération d'une preuve supprimée

Problème, lorsque l'on tente de lire ces fichiers, ils n'existent plus. Il semble donc que l'attaquant ayant utilisé ce compte utilisateur ait pris le soin de supprimer certaines informations. Nous allons tenter d'utiliser un outil de File Carving pour récupérer ces fichiers.

Le File Carving est le processus consistant à essayer de récupérer des fichiers en l'absence de leurs métadonnées (fichiers supprimés de la table de référence). Cela se fait en analysant les données brutes et en identifiant de quel format il peut s'agir (texte, exécutable, png, mp3, etc.). Cela peut être fait de différentes manières, mais la plus simple est de rechercher la signature de fichier ou les magic number qui marquent le début et/ou la fin d'un type de fichier particulier (lecture du contenu du disque en hexadécimal et marquage du début d'un fichier lorsque l'on rencontre un magic number). Nous avons déjà abordé les magics numbers dans l'article de cette même série : Forensic – SteerOnSomewhere : analyse de PDF et EXE malveillants

Nous utiliserons ici photorec :

Choix du média à analyser par photorec
Choix du média à analyser par photorec

Il nous faut ensuite sélectionner la partition à analyser dans l'image disque. Mais avant cela, nous allons faire un tour dans le paramètre File Opt (en bas) : 

Selection de la partition à analyser et des options d'analyse
Sélection de la partition à analyser et des options d'analyse

Ici nous allons pouvoir préciser à photorec quels sont les types de fichiers qui nous intéressent, nous sélectionnerons txt (qui comprend les extensions web) :

Choix des extensions et type de fichier à chercher
Choix des extensions et types de fichiers à chercher

Pour faciliter le travail de photorec, nous lui précisons quel système de fichier est utilisé :

Précision du système de fichier de la partition analysée
Précision du système de fichier de la partition analysée

Et enfin, le dossier de sortie dans lequel positionner les fichiers retrouvés :

Sélection de dossier dans lequel seront positionnés les fichiers retrouvés
Sélection du dossier dans lequel seront positionnés les fichiers retrouvés

Après une vingtaine de minutes d'exécution, photorec a retrouvé plus de 60 000 fichiers, cela fait beaucoup trop pour une recherche manuelle. Mais l'on se souvient avoir observé cette commande : 

curl http://192.168.2.10/log/carpediem.php?cmd=cp+/home/deloin_c/test.txt+/usr/local/apache2/htdocs/Siemens

Celle-ci nous a menés vers un exploit dont le code peut être trouvé ici. On sait donc que notre fichier contient au moins le mot CARPE par exemple. Utilisons à présent grep :

$ grep -ril "carpe" * 
recup_dir.125/f92709184.php:o('CARPE (DIEM) ~ CVE-2019-0211');
recup_dir.125/f92709264.php:o('CARPE (DIEM) ~ CVE-2019-0211');
recup_dir.125/f92713296.php:o('CARPE (DIEM) ~ CVE-2019-0211');
recup_dir.14/f17105536.php:o('CARPE (DIEM) ~ CVE-2019-0211');

Nous avons identifié plusieurs fichiers parmi les 60 000 fichiers retrouvés par photorec. Une exploration de leur contenu nous en apprend plus sur ce qu'ils font et nous permet de répondre à notre dernière question :

$ grep "cmd" recup_dir.14/f17105536.php -C 5
$bucket = isset($_REQUEST['cmd']) ?
$_REQUEST['cmd'] :
"cp ./S7-300.pdf /usr/local/apache2/htdocs/Siemens/S7-300.pdf";

if(strlen($bucket) > $size_worker_score - 112)
{
o(
  • La commande ayant été exécutée en root : cp ./S7-300.pdf /usr/local/apache2/htdocs/Siemens/S7-300.pdf

VII. Conclusion

Cette série d'articles sur le challenge Panic On Board proposé par le FIC/l'école EPITA est maintenant terminée. Comme dans toute analyse forensic, il est maintenant temps de résumer les différentes TTP (Tactics, techniques and procedures) utilisées par l'attaquant et identifiées dans notre analyse :

Phase ATT&CK Nom
Initial Access T1566.01 Phishing : Spearphishing attachment
Execution T1059.003 Command and Scripting Interpreter: Windows Command Shell
Credential Access T1552.001 Unsecured Credentials: Credentials In Files
Persistence T1078 Valid Accounts
Impact T0826 Loss of Availability
Discovery T1046 Network Service Scanning
Execution T1204.002 User Execution: Malicious File
Defense Evasion T1497.003 Virtualization/Sandbox Evasion: Time Based Evasion
Defense Evasion T1070.002 Indicator Removal on Host: Clear Linux or Mac System Logs
Privilege Escalation T1068 Exploitation for Privilege Escalation

Le résumé des TTP a plusieurs objectifs, il permet notamment de pouvoir rapidement corréler deux attaques en constatant que leur TTP sont similaires, ce qui peut être utile pour l'attribution d'une attaque ou simplement pour noter qu'il est probable que deux attaques aient été opérées par un même attaquant.

Dans les rapports d'analyse forensic, il est aussi courant de trouver un ensemble d'IOC (Indicator of Compromission) qui peuvent être des URL, domaines, IP, noms d'exécutable, de services, etc. La synthèse de ces IOC permet elle aussi de pouvoir faire une corrélation entre différentes attaques pour lesquelles on retrouverait les mêmes IOC. Ils permettent également de mettre à jour les systèmes de détection et de prévention (ex : mettre en blacklist une adresse IP, ajouter une alerte de détection pour un certains nom d'exécutable sur les solutions antivirales) ou d'effectuer des recherches ciblées sur les journaux d'évènements du SI (qui sont centralisés bien évidemment 🙂 ).

J'espère que cette suite d'articles vous a plu, il existe encore de nombreux challenges de ce type disponibles sur le site de l'EPITA et je ne peux que vous conseiller d'aller y jeter un œil :). C'est par ici : Challenges Forensic

The post Forensic – PearlArmor : analyse de journaux et d’une image disque first appeared on IT-Connect.

PowerShell : activer la journalisation des commandes et scripts

4 janvier 2022 à 09:00

I. Présentation

L'utilisation de Windows PowerShell par les attaquants et les malwares est désormais chose commune, la puissance de ce moteur et ce langage est utilisée depuis plusieurs années (nous vous en parlions déjà sur IT-Connect en 2014). Il faut savoir que par défaut, PowerShell ne laisse pas beaucoup de traces de son exécution dans la plupart des environnements Windows.

Cette tendance doit mener à une vigilance accrue des équipes de sécurité qui doivent impérativement se mettre à surveiller l'exécution de commandes PowerShell sur les systèmes protégés. Dans cet article, nous allons voir comment activer la journalisation des commandes et scripts PowerShell exécutés sur un système Windows. Il existe trois moyens différents d'activer la journalisation des commandes PowerShell.

II. PowerShell et Transcript

Le transcript (littéralement transcription) est une méthode historique utilisée pour journaliser l'exécution de commandes PowerShell. Cette méthode comporte des manquements, mais c'est toujours mieux que de ne rien journaliser :).

La transcription crée un enregistrement unique de chaque session PowerShell comprenant toutes les entrées et sorties, exactement telles qu'elles apparaissent dans le terminal PowerShell. Les transcriptions sont écrites dans des fichiers texte, un fichier par utilisateur et par session, comme ceci : 

Deux fichiers Transcript enregistrés, correspondans à deux session Poweshell d'un utilisateur
Deux fichiers Transcript enregistrés correspondant à deux sessions PowerShell d'un utilisateur

Les transcriptions contiennent également des horodatages et des métadonnées pour chaque commande afin de faciliter l'analyse. Voici un exemple du contenu d'un fichier de transcription PowerShell :

Exemple de commandes et sorties enregistrées par les Transcripts
Exemple de commandes et sorties enregistrées par les transcriptions

Cependant, la transcription n'enregistre que ce qui apparaît dans le terminal PowerShell, ce qui n'inclura pas le contenu des scripts exécutés ou la sortie écrite vers d'autres destinations tel que le système de fichiers. Pour l'activer localement et pour une session donnée, nous pouvons utiliser la commande start-transcript :

PS C:\Users\admin> Start-Transcript
Transcription démarrée, le fichier de sortie est C:\Users\admin\Documents\PowerShell_transcript.DESKTOP-DBSUD32.g32CqxMk.20211227184120.txt
PS C:\Users\admin> write-host "Hello"
Hello
PS C:\Users\admin> Stop-Transcript
Transcription arrêtée, le fichier de sortie est C:\Users\admin\Documents\PowerShell_transcript.DESKTOP-DBSUD32.g32CqxMk.20211227184120.txt
PS C:\Users\admin>

Bien sûr, cela n'a aucun intérêt de tenter de surveiller l'activité d'un attaquant sur un système si il doit lui-même activer la journalisation. C'est pourquoi nous pouvons passer par les GPO pour l'activation de la transcription.

Pour activer la transcription au niveau GPO, il faut se rendre dans Configuration ordinateur -> Modèles d'administration -> Composants Windows -> Windows PowerShell. Il faut ensuite passer le paramètre Activer la transcription PowerShell à Activé :

Activation des Transcripts PowerShell
Activation des Transcripts PowerShell

Par défaut, les transcriptions sont écrites dans le dossier Documents de l'utilisateur, mais cette configuration peut être modifiée vers n'importe quel emplacement accessible sur le système local ou sur le réseau. Il faut être conscient qu'un système de journalisation a peu de valeur s'il peut être supprimé ou désactivé par l'utilisateur lui-même et peut même s'avérer dangereux si des données sensibles peuvent y être consultées (par exemple : mots de passe saisis dans le terminal).

Dans l'idéal, la meilleure pratique consiste à externaliser les transcriptions du système et les envoyer sur un serveur de fichier. Ce répertoire distant doit être un partage réseau restreint en écriture seule (seule l'équipe de sécurité pourra y accéder en lecture par exemple). Attention tout de même, dans l'éventualité où un répertoire distant non accessible serait indiqué, les transcriptions ne seront plus enregistrées.

Pour modifier le répertoire d'écriture, il faut utiliser l'option correspondante dans le paramètre précédemment modifié :

Indication d'un répertoire distant pour l'écriture des Transcripts PowerShell
Indication d'un répertoire distant pour l'écriture des transcriptions PowerShell

Il est également conseillé de cocher l'option Inclure les en-têtes de l'appel. Cela permet simplement l'horodatage de chaque commande :

Effet de l'activation de l'horodatage individuel des commades
Effet de l'activation de l'horodatage individuel des commandes

Pour activer ce même paramétrage au niveau de la base de registre, il faut modifier les registres suivants :

HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\Transcription : EnableTranscripting = 1
HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\Transcription : EnableInvocationHeader = 1
HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\Transcription : OutputDirectory = ""

Faisons à présent un test. Je suis un utilisateur et j'ouvre PowerShell pour télécharger un exécutable malveillant :

> Invoke-WebRequest -Uri https://www.it-connect.fr/wp-content-itc/uploads/2017/06/IT-Connect_Flat_072017_Small_v2.png -OutFile logo-ITConnect.png

Voici la trace laissée dans la transcription :

Transcript d'une commande Powershell classique
Transcription d'une commande PowerShell classique

Grâce aux transcriptions, je peux affirmer que l'utilisateur admin a téléchargé un fichier à 11h36 le 29/12/2021. À présent j'exécute un script PowerShell qui fait la même opération, sans aucune sortie dans le terminal. Voici la trace laissée dans la transcription :

Transcript de l'exécution d'un Script PowerShell
Transcription de l'exécution d'un Script PowerShell


Comme indiqué précédemment, la faiblesse de cette solution est qu'elle ne journalise que les entrées/sorties du terminal, l'utilisation d'un script est donc un moyen de contourner la journalisation par la transcription. Dans le cadre d'une activité malveillante, on peut facilement imaginer que le script utilisé ait été supprimé à la suite de son utilisation, nous n'avons alors aucune trace de ce qu'il s'est passé. Heureusement, d'autres solutions existent :).

III. PowerShell et Script Block Logging

Le script block logging enregistre les blocs de code au fur et à mesure qu'ils sont exécutés par le moteur PowerShell, capturant ainsi l'intégralité du contenu du code exécuté par un attaquant, y compris les scripts et les commandes.

Il enregistre notamment le code "désobfusqué" au fur et à mesure de son exécution. Par exemple, en plus d'enregistrer le code obfusqué d'origine, le script block logging enregistre les commandes décodées passées avec l'argument -EncodedCommand de PowerShell, ainsi que celles obfusquées avec XOR, Base64, ROT13, etc, en plus du code obfusqué d'origine. Le script block logging n'enregistrera cependant pas la sortie du code exécuté. Ces évènements seront journalisés dans la console de journalisation classique Windows et porteront l'ID d'évènement 4104. Les blocs de code dépassant la longueur maximale d'un message de journal d'évènements sont fragmentés en plusieurs entrées.

Il faut cependant savoir qu'à partir de PowerShell 5.0, le système enregistre automatiquement les blocs de code si leur contenu correspond à une liste de commandes ou de techniques de script suspectes, même si le script block logging n'est pas activé. Ces blocs suspects sont enregistrés au niveau avertissement dans l'ID d'évènement 4104, à moins que le script block logging ne soit explicitement désactivé. Cette fonctionnalité garantit que certaines informations nécessaires aux investigations (forensic) sont enregistrées pour une activité suspecte connue, même si la journalisation n'est pas activée.

L'activation du script block logging capturera toutes les activités, pas seulement les commandes considérées comme suspectes par le processus PowerShell. Cela permet d'identifier toute l'étendue de l'activité de l'attaquant. Les blocs qui ne sont pas considérés comme suspects seront également enregistrés dans l'ID d'évènement 4104, mais avec des niveaux verbose ou information.

Pour activer le script block logging au niveau GPO, il faut se rendre dans Configuration ordinateur -> Modèles d'administration -> Composants Windows -> Windows PowerShell. Il faut ensuite passer le paramètre Activer la journalisation de blocs de scripts PowerShell à Activé :

Activation de la fonctionnalité Script Block Logging
Activation de la fonctionnalité Script Block Logging

Pour activer ce même paramétrage au niveau de la base de registre, il faut modifier le registre suivant :

HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging : EnableScriptBlockLogging = 1

Faisons à présent le même test que tout à l'heure. J'exécute une commande de téléchargement de fichier :

> Invoke-WebRequest -Uri https://www.it-connect.fr/wp-content-itc/uploads/2017/06/IT-Connect_Flat_072017_Small_v2.png -OutFile logo-ITConnect.png

Les évènements journalisés peuvent être trouvés localement dans l'Observateur d'évènements -> Journaux des applications et des services -> Microsoft -> Windows -> PowerShell -> Operationnal :

Journalisation d'une commande PowerShell sous l'ID d'évènement 4104
Journalisation d'une commande PowerShell sous l'ID d'évènement 4104

Cette commande est journalisée dans l'ID d'évènement 4104. Si j'exécute un script contenant cette commande, voilà ce que l'on pourra voir dans l'observateur d'évènements :

Journalisation des commandes exécutées par un script PowerShell
Journalisation des commandes exécutées par un script PowerShell

Nous avons bien ici notre commande de lancement du script, puis dans l'évènement suivant, la ligne de commande exécutée par le script, dont on retrouve par ailleurs le nom dans "Chemin d'accès :".

Nous allons maintenant passer à un cas un peu plus complexe qui est le cas d'un script contenant une commande encodée. L'encodage en base64 est la manière la plus basique de "dissimuler" une commande en PowerShell, cela permettra par exemple de ne pas faire apparaitre en clair la directive Invoke-WebRequest, qui permet de faire une requête HTTP, dans un script ou un terminal.

Pour ce faire, j'encode une première fois ma commande PowerShell en base64 :

>> [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("Invoke-WebRequest -Uri https://www.it-connect.fr/wp-content-itc/uploads/2017/06/IT-Connect_Flat_072017_Small_v2.png -OutFile logo-ITConnect.png"))
CgBJAG4AdgBvAGsAZQAtAFcAZQBiAFIAZQBxAHUAZQBzAHQAIAAtAFUAcgBpACAAaAB0AHQAcABzADoALwAvAHcAdwB3AC4AaQB0AC0AYwBvAG4AbgBlAGMAdAAuAGYAcgAvAHcAcAAtAGMAbwBuAHQAZQBuAHQALQBpAHQAYwAvAHUAcABsAG8AYQBkAHMALwAyADAAMQA3AC8AMAA2AC8ASQBUAC0AQwBvAG4AbgBlAGMAdABfAEYAbABhAHQAXwAwADcAMgAwADEANwBfAFMAbQBhAGwAbABfAHYAMgAuAHAAbgBnACAALQBPAHUAdABGAGkAbABlACAAIABsAG8AZwBvAC0ASQBUAEMAbwBuAG4AZQBjAHQALgBwAG4AZwA=

Puis une deuxième fois : 

>> [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("powershell -e CgBJAG4AdgBvAGsAZQAtAFcAZQBiAFIAZQBxAHUAZQBzAHQAIAAtAFUAcgBpACAAaAB0AHQAcABzADoALwAvAHcAdwB3AC4AaQB0AC0AYwBvAG4AbgBlAGMAdAAuAGYAcgAvAHcAcAAtAGMAbwBuAHQAZQBuAHQALQBpAHQAYwAvAHUAcABsAG8AYQBkAHMALwAyADAAMQA3AC8AMAA2AC8ASQBUAC0AQwBvAG4AbgBlAGMAdABfAEYAbABhAHQAXwAwADcAMgAwADEANwBfAFMAbQBhAGwAbABfAHYAMgAuAHAAbgBnACAALQBPAHUAdABGAGkAbABlACAAIABsAG8AZwBvAC0ASQBUAEMAbwBuAG4AZQBjAHQALgBwAG4AZwA="))
cABvAHcAZQByAHMAaABlAGwAbAAgAC0AZQAgAEMAZwBCAEoAQQBHADQAQQBkAGcAQgB2AEEARwBzAEEAWgBRAEEAdABBAEYAYwBBAFoAUQBCAGkAQQBGAEkAQQBaAFEAQgB4AEEASABVAEEAWgBRAEIAegBBAEgAUQBBAEkAQQBBAHQAQQBGAFUAQQBjAGcAQgBwAEEAQwBBAEEAYQBBAEIAMABBAEgAUQBBAGMAQQBCAHoAQQBEAG8AQQBMAHcAQQB2AEEASABjAEEAZAB3AEIAMwBBAEMANABBAGEAUQBCADAAQQBDADAAQQBZAHcAQgB2AEEARwA0AEEAYgBnAEIAbABBAEcATQBBAGQAQQBBAHUAQQBHAFkAQQBjAGcAQQB2AEEASABjAEEAYwBBAEEAdABBAEcATQBBAGIAdwBCAHUAQQBIAFEAQQBaAFEAQgB1AEEASABRAEEATABRAEIAcABBAEgAUQBBAFkAdwBBAHYAQQBIAFUAQQBjAEEAQgBzAEEARwA4AEEAWQBRAEIAawBBAEgATQBBAEwAdwBBAHkAQQBEAEEAQQBNAFEAQQAzAEEAQwA4AEEATQBBAEEAMgBBAEMAOABBAFMAUQBCAFUAQQBDADAAQQBRAHcAQgB2AEEARwA0AEEAYgBnAEIAbABBAEcATQBBAGQAQQBCAGYAQQBFAFkAQQBiAEEAQgBoAEEASABRAEEAWAB3AEEAdwBBAEQAYwBBAE0AZwBBAHcAQQBEAEUAQQBOAHcAQgBmAEEARgBNAEEAYgBRAEIAaABBAEcAdwBBAGIAQQBCAGYAQQBIAFkAQQBNAGcAQQB1AEEASABBAEEAYgBnAEIAbgBBAEMAQQBBAEwAUQBCAFAAQQBIAFUAQQBkAEEAQgBHAEEARwBrAEEAYgBBAEIAbABBAEMAQQBBAEkAQQBCAHMAQQBHADgAQQBaAHcAQgB2AEEAQwAwAEEAUwBRAEIAVQBBAEUATQBBAGIAdwBCAHUAQQBHADQAQQBaAFEAQgBqAEEASABRAEEATABnAEIAdwBBAEcANABBAFoAdwBBAD0A

J'exécute enfin ma commande en spécifiant -encodedcommand (ou -e), ce qui indique à PowerShell qu'il va devoir décoder la commande avant de l'exécuter, la commande qu'il obtiendra contiendra encore une fois un -encodedcommand, et la troisième commande qu'il obtiendra exécutera enfin une requête pour télécharger un fichier via HTTP.

powershell -EncodedCommand  cABvAHcAZQByAHMAaABlAGwAbAAgAC0AZQAgAEMAZwBCAEoAQQBHADQAQQBkAGcAQgB2AEEARwBzAEEAWgBRAEEAdABBAEYAYwBBAFoAUQBCAGkAQQBGAEkAQQBaAFEAQgB4AEEASABVAEEAWgBRAEIAegBBAEgAUQBBAEkAQQBBAHQAQQBGAFUAQQBjAGcAQgBwAEEAQwBBAEEAYQBBAEIAMABBAEgAUQBBAGMAQQBCAHoAQQBEAG8AQQBMAHcAQQB2AEEASABjAEEAZAB3AEIAMwBBAEMANABBAGEAUQBCADAAQQBDADAAQQBZAHcAQgB2AEEARwA0AEEAYgBnAEIAbABBAEcATQBBAGQAQQBBAHUAQQBHAFkAQQBjAGcAQQB2AEEASABjAEEAYwBBAEEAdABBAEcATQBBAGIAdwBCAHUAQQBIAFEAQQBaAFEAQgB1AEEASABRAEEATABRAEIAcABBAEgAUQBBAFkAdwBBAHYAQQBIAFUAQQBjAEEAQgBzAEEARwA4AEEAWQBRAEIAawBBAEgATQBBAEwAdwBBAHkAQQBEAEEAQQBNAFEAQQAzAEEAQwA4AEEATQBBAEEAMgBBAEMAOABBAFMAUQBCAFUAQQBDADAAQQBRAHcAQgB2AEEARwA0AEEAYgBnAEIAbABBAEcATQBBAGQAQQBCAGYAQQBFAFkAQQBiAEEAQgBoAEEASABRAEEAWAB3AEEAdwBBAEQAYwBBAE0AZwBBAHcAQQBEAEUAQQBOAHcAQgBmAEEARgBNAEEAYgBRAEIAaABBAEcAdwBBAGIAQQBCAGYAQQBIAFkAQQBNAGcAQQB1AEEASABBAEEAYgBnAEIAbgBBAEMAQQBBAEwAUQBCAFAAQQBIAFUAQQBkAEEAQgBHAEEARwBrAEEAYgBBAEIAbABBAEMAQQBBAEkAQQBCAHMAQQBHADgAQQBaAHcAQgB2AEEAQwAwAEEAUwBRAEIAVQBBAEUATQBBAGIAdwBCAHUAQQBHADQAQQBaAFEAQgBqAEEASABRAEEATABnAEIAdwBBAEcANABBAFoAdwBBAD0A

Lors de son exécution, voici les différentes entrées portant l'ID d'évènement 4104 que l'on peut trouver dans l'observateur d'évènements :

Journalisation des différentes étapes de décodage de la commande PowerShell
Journalisation des différentes étapes de décodage de la commande PowerShell

On voit ici que les différentes étapes de l'exécution de ma commande apparaissent, on voit notamment les deux résultats du décodage base64, ce qui nous permet de voir la commande finale exécutée (contenant le Invoke-WebRequest) dans l'évènement journalisé.

Cas plus complexe où l'on peut vraiment parler d'obfuscation. Voici la même commande Invoke-WebRequest obfusquée grâce à l'outil Invoke-Obfuscation :

((("{40}{112}{104}{88}{46}{20}{24}{77}{41}{13}{76}{35}{33}{31}{34}{79}{51}{27}{101}{48}{9}{85}{47}{7}{28}{32}{60}{63}{15}{114}{97}{42}{65}{86}{5}{23}{18}{82}{83}{75}{110}{116}{96}{30}{29}{94}{8}{16}{66}{61}{84}{2}{62}{11}{78}{80}{69}{4}{74}{91}{39}{10}{103}{53}{58}{70}{36}{22}{3}{90}{1}{44}{109}{6}{50}{115}{52}{25}{117}{102}{45}{107}{17}{14}{72}{73}{106}{64}{49}{105}{38}{108}{68}{98}{57}{89}{12}{56}{111}{55}{93}{26}{0}{21}{71}{95}{43}{19}{92}{99}{67}{54}{113}{37}{81}{100}{59}{87}" -f'T+','dbT2db','con','bT7db','ds/db','onnedb','017dbT+d','ps:/','T+d','T+d','/IT-','t','Fid','ebR','bT+','Tw','b','_d','dbT','b','bTndbT+dbTvo','dbT logo-IT','_0dbT+d','T+','ke','bT+dbTSmald','db','ues','/','dbT/','bT+','dbT','ww','e','+','+dbT','at','T+',' ','017/06',' iex((d','W','db','d','T+db','b','+d','T -Uri htt','db','d','bT','bTqdbT+dbT','d','dbT','dbTt','l','b','+','_','))','dbT+d','-dbT+d','tent-i','b','n','Tidb','Tp','necdbT+','O','ploa','FdbT+dbTl','Co','dbTv','dbT+d','T+dbT','T+d','dbT','-','c/','d','udbT+dbT','dbT.pngd','ct','.db','bT','b','T+dbTt-c',' ','IdbT','dbTt','T+','2','T','e','wdb','dbT+','d','T+','udbT','n','bT','t','dbTld','ConndbT+dbTectdbT+','T','bT+dbTg','bT2.p','T+dbT','-','T','bTf','T+dbT','b','db','.db','_','r','bT+'))-rEplaCE ([char]100+[char]98+[char]84),[char]39)|InvOKE-EXprESSIOn

Ça fait mal aux yeux n'est-ce pas ? :p Sachez que c'est sur ce format de commande que travaillent la plupart des analystes en investigation numérique. Ce résultat est très difficilement compréhensible par l'homme et pose également problème aux systèmes de détection automatique. La commande est pourtant générée par un script trouvé sur internet en quelques secondes et elle fonctionne à merveille. Pour information, voici quelques-unes des techniques d'obfuscation utilisées ici :

  • Reordering : l'opérateur de formatage -f est utilisé afin de reconstituer une chaine de caractère ayant été divisée en plusieurs parties, ordonnée dans un sens qui rend complexe sa compréhension.
    • "{1}{0}"-f 'x','IE'
  • Replacing: Consiste à écrire une commande incorrecte ou mal formatée, puis à remplacer certains caractères au dernier moment pour qu'elle retrouve une structure correcte pour son exécution.
    • +dbT','-','T','bTf','T+dbT','b','db','.db','_','r','bT+'))-rEplaCE ('dbT','')|
  • Escaping character: Consiste à positionner des caractères ` au milieu d'une chaine de caractères afin de complexifier la compréhension de la commande par l'analyste.
    • Dans notre cas, les ` ([char]39) apparaissent après la phase de remplacement et sont positionnés à la place des dbT ([char]100+[char]98+[char]84)
  • Up/Lower case : Écriture de commande ou mot-clé détectable en alternance de minuscule/majuscule afin de tromper des expressions régulières qui ne prendraient pas la casse en compte.
    • InvOKE-EXprESSIOn

Si vous êtes toujours là, voici la journalisation obtenue lors de l'exécution de cette commande :

Journalisation des étapes de reconstruction d'une commande obfusquée
Journalisation des étapes de reconstruction d'une commande obfusquée

Voilà qui est intéressant, trois évènements journalisés reconstituent la commande à chaque étape de sa reconstruction, et nous voyons à nouveau la commande exécutée en clair.

IV. PowerShell et le module Logging

Le module logging enregistre les détails de l'exécution au fur et à mesure de l'exécution, y compris l'initialisation des variables et les appels de commande. Le module logging enregistrera des portions de script, du code désobfusqué et des données de sortie. Cette journalisation capturera certains détails manqués par d'autres sources de journalisation PowerShell, bien qu'elle puisse ne pas capturer de manière fiable l'intégralité des commandes exécutées. Les événements de journalisation du module sont écrits dans l'ID d'événement (EID) 4103 et s'orientent sur l'utilisation de modules plutôt que le suivi de l'exécution d'une commande ou d'un script de A à Z.

Voici par exemple la journalisation générée par l'exécution de notre commande obfusquée :

Journalisation de l'exécution d'une commande obfusquée
Journalisation de l'exécution d'une commande obfusquée

On voit ici que trois évènements (EID 4013) ont été journalisés, chacun faisant apparaitre une étape de notre commande, correspondant à l'utilisation d'un module précis : Invoke-Expression, Invoke-WebRequest, Out-Default (la sortie). Le module ciblé par l'évènement est spécifié en première ligne (CommandInvocation) alors que les données utiles à un analyste sont dans la partie Contexte. 

Pour activer le module logging au niveau GPO, il faut se rendre dans Configuration ordinateur -> Modèles d'administration -> Composants Windows -> Windows Powershell. Il faut ensuite passer le paramètre Activer l'enregistrement des modules à Activé :

Activation du module Logging Powershell
Activation du module Logging PowerShell

Il ne faut pas oublier ici d'activer le module logging pour tous les modules (en fonction de ce que l'on souhaite) en positionnant un wildcard (*) dans Noms des modules. On peut se servir de cette option pour journaliser uniquement l'utilisation de certains modules, mais cela n'est pas recommandé, car il est presque impossible d'anticiper toutes les possibilités qu'utilisera un attaquant.

Pour activer ce même paramétrage au niveau de la base de registre, il faut modifier le registre suivant :

HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging : EnableModuleLogging = 1
HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging \ModuleNames : * = *

IV. Pour aller plus loin : centralisation et corrélation

Nous voyons donc que ces trois méthodes de journalisation sont complémentaires, la transcription présente des manquements qui peuvent être problématiques pour mener à bien une investigation numérique ou pour de la surveillance des évènements de sécurité. Le script block logging et le module logging apparaissent comme des sources d'information pertinentes aussi bien pour de l'analyse forensic que pour l'envoi des journaux à un SIEM qui tentera ensuite d'y détecter des activités suspectes ou malveillantes.

Dans tous les cas, l'externalisation des journaux hors du système qui les produit et leur centralisation pour mener à bien des opérations de corrélation d'évènements et de détection des activités suspectes est clairement recommandée une fois que la journalisation des commandes PowerShell est activée. Je vous oriente vers cet article pour aller plus loin sur ce sujet : Centralisation des logs, un outil pour la sécurité.

Pour rappel, il s'agit d'un point non négligeable du guide d'hygiène informatique de l'ANSSI

Directive 36 : Activer et configurer les journaux des composants
Si toutes les actions précédentes ont été mises en œuvre, une centralisation des journaux sur un dispositif dédié pourra être envisagée. Cela permet de faciliter la recherche automatisée d’évènements suspects, d’archiver les journaux sur une longue durée et d’empêcher un attaquant d’effacer d’éventuelles traces de son passage sur les équipements qu’il a compromis.

N'hésitez pas à partager vos expériences et vos avis dans les commentaires de cet article 🙂

The post PowerShell : activer la journalisation des commandes et scripts first appeared on IT-Connect.

Forensic – SteerOnSomewhere : analyse de PDF et EXE malveillants

3 janvier 2022 à 10:00

I. Présentation

Nous continuons notre suite d'articles sur le CTF du FIC 2021 proposé par l'école EPITA afin de découvrir certains outils et méthodes de forensic (investigation numérique). Dans cet article nous allons nous pencher sur l'analyse de fichiers PDF et exécutables contenant des objets ou du code malveillant.

II. Contexte : Panic on board - SteerOnSomewhere

Le contexte de l'incident sur lequel nous intervenons est le suivant : Un bateau de croisière de la compagnie maritime ArMor a subi une panne et se retrouve bloqué en pleine mer.

Nous savons à présent qu'à la suite d'un phishing, l'attaquant est parvenu à dérober les identifiants VPN d'un utilisateur puis à mener une attaque sur les automates du bateau afin de les arrêter. Le contexte de cette quatrième étape de l'analyse est le suivant :

L’analyse du logiciel d’IHM (auquel seul le technicien a accès) n’a rien révélé de probant. Sur le point d’abandonner, vous tombez sur quelques fichiers de documentation anodins… Ou pas ? Découvrez comment les ordres d’arrêter les machines ont été donnés.

Deux fichiers nous sont ici fournis :

  • s7-300_IHB_f.pdf 
  • stopAutomatesProp.exe

Nous devons répondre aux questions suivantes pour compléter cette quatrième étape de l'analyse :

  • Le fichier PDF cache du contenu ;
  • La fonction de décodage utilisée pour désobfusquer la charge utile ;
  • La charge utile est... ;
  • Vous avez extrait le fichier embarqué. En quel langage le programme est-il écrit ;
  • Le temps en secondes que le script passe à dormir.

N'oublions pas de vérifier l'intégrité des éléments récupérés (le hash BLAKE2 est fourni avec les fichiers sur le site du challenge) :

$ b2sum s7-300_IHB_f.pdf 
f5d2ef2e841e24731187d310677312c2a78d58b540eeabff69832625a508fc84f8147c7891eafedfbc76fc99ae880c4dc3858280bf28b4fa512d75c2bbcaf5f2 s7-300_IHB_f.pdf

$ b2sum stopAutomatesProp.exe
30ff3011c25368fa1d4e09632874c0781199aa62d4ad57b47a99ae39bff6480fff2639a70dbe498f93b6aa263cf86d49a5f66a2d7bf3cdfc38f3f15903e22186 stopAutomatesProp.exe

Vous trouverez le challenge en question et les fichiers utilisés dans cet article ici : Panic On Board - SteerOnSomewhere 

III. Analyse d'un PDF 

Comme je l'ai indiqué dans l'article Forensic – PhishingBoat : analyse de fichiers Mbox et PDF, les fichiers PDF peuvent être utilisés de façon malveillante afin de transporter d'autres objets, parfois chiffrés ou encodés, et déclencher des actions à leur ouverture. Pour décortiquer ce fichier PDF, nous allons commencer par utiliser le script pdfid.py de Dider Stevens :

$ pdfid.py s7-300_IHB_f.pdf 
PDFiD 0.2.1 s7-300_IHB_f.pdf
PDF Header: %PDF-1.4
obj 3253
endobj 3253
stream 295
endstream 295
xref 3
trailer 3
startxref 3
/Page 245
/Encrypt 0
/ObjStm 0
/JS 1
/JavaScript 1
/AA 1
/OpenAction 2
/AcroForm 0
/JBIG2Decode 0
/RichMedia 0
/Launch 1
/EmbeddedFile 0
/XFA 0
/Colors > 2^24 0

pdfid.py n'est pas un parser PDF, mais il analysera un PDF pour rechercher certains mots-clés permettant d'identifier les documents PDF contenant (par exemple) du JavaScript ou d'exécuter une action lorsqu'ils sont ouverts. 

Ici, celui-ci nous indique que le fichier fait 245 pages et contient du code Javascript (/JS, /Javascript) ainsi que des éléments permettant l'exécution d'instructions à l'ouverture (/AA, /OpenAction, /Launch).  Nous pouvons compléter notre analyse avec l'utilisation de l'outil pdfdetach, qui vient de la suite d'outil origami :

$ pdfdetach s7-300_IHB_f.pdf -list
Syntax Warning: Illegal URI-type link
Syntax Warning: Illegal URI-type link
1 embedded files
1: s7-300_IHB_f.pdf

Contrairement à pdfid.py, pdfdetach détecte un fichier embarqué dans le PDF, tentons d'en savoir plus avec pdf-parser et utilisons l'option --search, qui permet d'effectuer un filtre sur un mot précis :

$ pdf-parser.py --search embedded s7-300_IHB_f.pdf 
obj 3246 0
Type:
Referencing: 3247 0 R

<<
/EmbeddedFiles 3247 0 R
>>

Un PDF est composé de multiples objets de différents types qui sont numérotés de façon unique et référencés dans la XREF table (cross reference table). Ici, nous voyons que l'objet 3246 0 référence l'objet 3247 0 en tant que fichier embarqué, nous pouvons ici utiliser l'option --object pour afficher directement le contenu de cet objet :

$ pdf-parser.py s7-300_IHB_f.pdf --object 3247
obj 3247 0
Type:
Referencing: 3248 0 R

$ pdf-parser.py s7-300_IHB_f.pdf --object 3248
obj 3248 0
Type: /Filespec
Referencing: 3249 0 R

Nous arrivons enfin à l'objet 3249 0 pour lequel nous devons ajouter les options --filter et --raw pour avoir une sortie brute de son contenu. Celui-ci étant un stream, pdf-parser n'affiche pas son contenu par défaut (un stream peut être très volumineux) :

$ pdf-parser.py s7-300_IHB_f.pdf --object 3249 --filter --raw
obj 3249 0
Type:
Referencing:
Contains stream

b'MZ\x90\x00[...]

Dans un fichier PDF, les streams sont des séquences d'octets qui peuvent être de longueur illimitée et peuvent être compressés ou encodés. En tant que tels, ils constituent le type d'objet utilisé pour stocker de gros blocs de données (blob) qui sont dans un autre format standardisé, (XML , image, police, etc.).

Et justement, nous voyons ici le début du contenu du blob dans ce stream et il commence par MZ, il s'agit du magic byte caractéristique des fichiers exécutables Windows.

Les magic bytes, ou signatures de fichier, sont simplement les premiers octets composant un fichier et indiquant son format, on peut les considérer comme un "en-tête" qui va ensuite indiquer au système quels programmes peuvent les ouvrir, puis aux programmes comment ils sont composés (un peu à l'image d'un paquet pour Wireshark et ses dissecteurs). Ainsi un fichier PNG commencera toujours par 89 50 4E 47 0D 0A 1A 0A, un fichier PDF par 25 50 44 46 2D et un fichier exécutable par 4D 5A, soit MZ en conversion ASCII.

C'est notamment sur ces éléments que se basent les outils de File Carving ou de récupération de fichiers supprimés qui permettent de trouver les fichiers contenus dans un autre fichier ou un espace disque donné (image disque, firmware, PDF, etc.). On peut notamment citer foremost, binwalk, bulk_extractor, etc. Voici une liste des magics bytes par format de fichier : List of file signatures

Nous pouvons donc affirmer ici que notre fichier PDF embarque un fichier exécutable Windows, ce qui est des plus suspect. Nous pouvons ici citer la T1204.002 User Execution: Malicious File du MITRE ATT&CK.

Nous pouvons également utiliser l'outil PeePDF pour avoir une synthèse des informations sur cet objet spécifique :

PPDF> info 3249
Offset: 3608903
Size: 7423903
MD5: 8057276523631af3456969a2372971f9
Object: stream
Subtype: /application/pdf
Stream MD5: c53391adcd8cb8b2ad4995c78c13aca7
Raw Stream MD5: acbe518d8f95f884467b4c42cea1598c
Length: 7423727
Encoded: Yes
Filters: /FlateDecode
Filter Parameters: No
Decoding errors: No
References: []

Nous voyons ici une notion importante lors de l'analyse d'objet dans un PDF : Filters: /FlateDecode. Dans un PDF, les Filters sont le moyen utilisé pour encoder un objet. Le fait d'indiquer en clair ce Filter permet ensuite aux lecteurs PDF de les décoder facilement. Cela nous permet de répondre à la question suivante :

  • La fonction de décodage utilisée pour désobfusquer la charge utile : FlateDecode
  • La charge utile est... : PE Executable

Je note au passage qu'il existe une multitude d'outils pour analyser un PDF, certains très anciens (avant 2010) qui fonctionnent encore et d'autres plus récents. Lorsque l'on aborde ce domaine, il n'est pas évident de s'orienter sur un outil spécifique (aucun ne semble contenir à lui seul toutes les fonctions utiles) ou au contraire de jongler entre les différents outils (commandes, syntaxes et sorties différentes à chaque fois). PeePDF me parait cependant assez dynamique, l'analyse interactive apparait comme un plus, par exemple pour suivre les objets qui se référencent entre eux. Voici la synthèse des outils utilisés dans cet article :

L'ANSSI a également sorti un outil d'analyse de PDF qui ne semble plus maintenu aujourd'hui et que je n'ai pas du tout réussi à installer 🙁 : Caradoc

IV. Analyse basique d'un exécutable

Un binaire, ou exécutable, peut être étudié de différentes façons, souvent complémentaires :

  • l'analyse statique : elle consiste à récupérer certains éléments tels que les hashs (empreinte numérique et unique du fichier), l'analyse antivirus, l'analyse d'un dump mémoire, la détection des packers, etc. Ce fichier binaire peut ensuite faire l'objet d'un reverse engineering à l'aide d'un désassembleur pour convertir le code machine en code assembleur afin de le rendre "lisible" par l'homme. 
  • l'analyse dynamique : elle consiste à analyser le comportement des binaires malveillants dans un environnement sandbox (bac à sable) afin qu'ils n'affectent pas les autres systèmes. Différentes "sondes", métriques et autres éléments de détection et de surveillance sont alors utilisés pour capturer et analyser le comportement du malware à son exécution (fichiers ouverts, connexion réseau, API systèmes utilisées, etc.)

Lors de la réalisation d'une analyse statique de base, nous n'exécutons pas directement le code du binaire malveillant analysé ni n'ouvrons de désassembleur pour tenter de disséquer ce binaire. La première étape est d'obtenir un aperçu rapide de la structure de l'exécutable et d'identifier les premiers éléments d'analyse. Commençons par un simple strings sur le binaire fourni dans le cadre du challenge :

strings stopAutomatesProp.exe 
bpython38.dll
bselect.pyd
bstopAutomatesProp.exe.manifest
bucrtbase.dll
bunicodedata.pyd
opyi-windows-manifest-filename stopAutomatesProp.exe.manifest
xInclude\pyconfig.h
xbase_library.zip
zPYZ-00.pyz
&python38.dll

La commande Linux strings est utilisée pour détecter et afficher les chaines de caractères présentes dans des fichiers. Elle se concentre principalement sur la détermination du contenu et l'extraction du texte des fichiers binaires (fichier non texte).

On retrouve ici plusieurs lignes contenant le mot python ou python38. Il s'agirait donc d'un exécutable contenant du Python. Ce qui est inhabituel, c'est que l'on ne produit habituellement pas de .exe en Python étant donné qu'il s'agit d'un langage interprété et non compilé. Il existe néanmoins une solution permettant de faire cela : Transformer un script Python en exécutable avec PyInstaller

Après quelques recherches, je remarque qu'il est possible de faire l'opération inverse lorsque l'on a sous la main un exécutable produit via Python : https://github.com/extremecoders-re/pyinstxtractor

$ python3.8 pyinstxtractor.py ../stopAutomatesProp.exe 
[+] Processing ../stopAutomatesProp.exe
[+] Pyinstaller version: 2.1+
[+] Python version: 38
[+] Length of package: 7298295 bytes
[+] Found 71 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: pyi_rth_multiprocessing.pyc
[+] Possible entry point: pyi_rth_pkgres.pyc
[+] Possible entry point: stopAutomatesProp.pyc
[+] Found 254 files in PYZ archive
[+] Successfully extracted pyinstaller archive: ../stopAutomatesProp.exe

You can now use a python decompiler on the pyc files within the extracted directory

PyInstaller Extractor est un script Python permettant d'extraire le contenu d'un fichier exécutable Windows généré par PyInstaller. Le contenu du fichier (généralement des fichiers .pyc) est présent dans l'exécutable est également extrait. Et oui, lorsque PyInstaller génère l'exécutable à partir du code python, celui-ci positionne le bytecode dans l'exécutable, ce qui facilite sa récupération. Vous trouverez plus d'informations sur le fonctionnement de PyInstaller ici : What PyInstaller Does and How It Does It

Nous nous retrouvons donc avec un ensemble de fichiers .dll et .pyc (entre autres) :

Ensemble de fichiers récupérés après extraction de l'exécutable
Ensemble de fichiers récupérés après extraction de l'exécutable

Les fichiers .pyc sont des fichiers Python compilés. Mais si Python est un langage interprété, pourquoi existe-t-il des formats de fichiers compilés ?

Les fichiers .pyc sont une version pré-compilée du code d'un fichier .py (script en texte clair). Il s'y trouve un code en format bytecode, ce qui permet de gagner du temps lors de l'exécution, car le système n'aura pas à faire lui-même cette conversion. Lorsque l'on dispose du fichier .pyc, le code en clair (fichier .py) n'est plus nécessaire à l'exécution.

Le format de fichier .pyc est donc du bytecode, il s'agit d'un format de code intermédiaire entre les instructions-machine et le code source, qui n'est pas directement exécutable. Il ne s'agit pas d'une mesure d'obfuscation et l'opération inverse (bytecode vers code source) peut elle aussi être réalisée, à l'aide de uncompyle6 notamment :

Récupération du code source Python à partir d'un fichier PYC
Récupération du code source Python à partir d'un fichier PYC

Nous récupérons ici le code source en clair de notre exécutable malveillant, ce qui est bien plus simple à étudier qu'une analyse en assembleur :). On remarque notamment une fonction stop_plc et une fonction scan_port, ce qui correspond aux éléments observés lors des précédentes étapes de notre analyse. En fin de script, on remarque la fonction suivante :

else:
time.sleep(36000)
scan_ports(available_ips, [80, 445, 443, 25, 110, 139, 23, 21, 3389, 22, 102])
time.sleep(1231)
stop_plc(available_ips)

Notre script fait 2 pauses à l'aide de l'instruction time.sleep.  Il s'agit d'un comportement visant à espacer les scans de port et les actions d’arrêt du PLC dans le temps, notamment afin de tromper des systèmes de détection (IPS, sondes de détection, antivirus) qui pourraient baser leur analyse sur le nombre d’occurrences d'un évènement dans le temps.

Cela nous permet de répondre aux dernières questions de notre analyse :

  • Vous avez extrait le fichier embarqué. En quel langage le programme est-il écrit : Python
  • Le temps en secondes que le script passe à dormir : 37231

Lorsqu'un antivirus exécute un programme en sandbox (bac à sable) avant de le considérer comme sûr, celui-ci ne peut se permettre de faire durer son analyse plusieurs minutes (ce serait désagréable pour l'utilisateur), il est donc courant qu'un programme malveillant profite de ce comportement afin de n'exécuter son action malveillante qu'après un temps d'attente. L'antivirus n'ayant pas la patience d'attendre ce temps va souvent arrêter son analyse au bout d'un certain temps et ne jamais exécuter le code malveillant, qui ne sera alors pas détecté. Cette mesure est décrite dans la T1497.003 Virtualization/Sandbox Evasion: Time Based Evasion du MITRE ATT&CK.

Nous avons vu dans cet article qu'un PDF peut cacher bien des choses et notamment un exécutable Windows. Différents outils ont été utilisés ici, mais nous sommes loin de l'exhaustivité. Nous sommes tout de même parvenus à retrouver, via le code source, l'exécutable responsable des activités identifiées au niveau des traces réseau dans les articles précédents. Cela nous donne donc un bon aperçu de comment quelques lignes de code peuvent avoir un impact très important sur un système d'information.

Le prochain article, et dernier de cette série sur le scénario de l'attaque du SI d'un navire, portera sur l'analyse de journaux d'évènements, de fichiers supprimés, d'une image OVA et d'une image disque :).

The post Forensic – SteerOnSomewhere : analyse de PDF et EXE malveillants first appeared on IT-Connect.

Forensic – EngineX : scan réseau et protocole industriel

30 décembre 2021 à 10:00

I. Présentation

Nous continuons notre suite d'articles sur le CTF du FIC 2021 proposé par l'école EPITA afin de découvrir certains outils et méthodes de forensic (investigation numérique). Dans cet article, nous allons nous pencher sur l'analyse de traces réseau contenant un protocole propriétaire permettant de gérer des automates industriels.

Nous allons à nouveau utiliser logiciel Wireshark et quelques-unes de ses fonctionnalités.

II. Contexte : Panic on board - EngineX

Le contexte de l'incident sur lequel nous intervenons est le suivant : Un bateau de croisière de la compagnie maritime ArMor a subi une panne et se retrouve bloqué en pleine mer.

Dans la phase précédente, nous avons identifié dans différentes traces réseau le fait que l'attaquant ait mis la main sur les éléments d'authentification VPN d'un utilisateur légitime. Le contexte de cette troisième étape de l'analyse est le suivant : 

Bienvenue à bord à vous et à votre équipe ! Pour déterminer la cause de l’arrêt soudain des moteurs, vous disposez à présent d’une capture réseau réalisée sur le SeaCastle. À vous de trouver les actions louches sur le réseau interne du fleuron de la flotte d’ArMor !

Ici, une trace réseau nous est fournie :

  • SeaCastle_suspect.pcap

 Nous devons répondre aux questions suivantes afin de compléter cette troisième étape de l'analyse :

N'oublions pas de vérifier l'intégrité de la trace récupérée (le hash BLAKE2 est fourni avec le fichier sur le site du challenge) :

$ b2sum SeaCastle_suspect.pcap
ce16940ae28744b6eb2179c2cfc6974581234403407602b3835bf4c7496e967e78f602208d907900100250946a052490d2385636553dd8d680317ba8d8e2447c SeaCastle_suspect.pcap

Vous trouverez le challenge en question et les fichiers utilisés dans cet article ici : Panic On Board - EngineX

III. Détecter un scan réseau dans un PCAP

Notre premier objectif est ici de détecter un scan réseau et de retrouver l'adresse IP du poste émetteur de ce scan. Pour cela, il faut comprendre ce qu'est un scan réseau.

Un scan réseau est une action menée afin de découvrir les hôtes actifs d'un réseau et les services qu'ils hébergent, il peut aller jusqu'à chercher à identifier ses services (technologies, versions, faiblesses de configuration). L'outil le plus utilisé pour la réalisation d'un scan réseau est le fameux nmap, bien que de nombreux autres existent aujourd'hui (masscan, ping, nessus, etc.). Dans les cas les plus classiques, une adresse IP va donc chercher à savoir si d'autres adresses IP sur le même réseau local sont actives, par l'intermédiaire d'un simple ping ou l'envoi d'un paquet sur les services les plus communs (TCP/22, TCP/445, TCP/80 par exemple).

Lorsqu'une adresse IP est détectée comme valide par l'outil de scan, celui-ci va ensuite chercher à énumérer tous les services hébergés par cette adresse IP.

Maintenant que nous avons une meilleure vue sur ce qu'est un scan réseau, il est temps de "traduire" cela en comportement réseau pouvant être présent dans notre capture. Nous allons dans un premier temps tenter d'identifier qui a le plus "parlé" au sein de cette capture réseau.

Notre capture réseau contient plus de 196 000 paquets, l'analyse de ces derniers à la main via un scrolling furieux n'est donc pas une option. Comme dans l'article précédent, nous allons utiliser la fonction Endpoints de Wireshark :

Utilisation de la fonction endpoints de Wireshark
Utilisation de la fonction Endpoints de Wireshark

L'adresse IP 192.168.101.31 sort un peu du lot, et elle est première toutes catégories confondues (nombre de paquets émis/reçus, volumétrie des échanges, etc). Il s'agit d'un indice intéressant, mais trop faible pour affirmer avec certitude que c'est cette adresse IP qui est la source d'un scan réseau. L'accès à la fonction Statistiques - IPv4 Statistics - Source and Destination nous confirme ce constat, l'adresse 192.168.101.31 est concernée par 94% (la majorité) des échanges contenus dans cette capture réseau : 

Accès à la fonction Statistics IPv4 - All Addresses de Wireshark
Accès à la fonction Statistics IPv4 - All Addresses de Wireshark

Une autre option nous permet de détecter clairement qu'un scan réseau a eu lieu sans avoir à parcourir manuellement les paquets : Statistiques - IPv4 Statistics - Destinations and ports :

Utilisation de la fonction Statitics - Destinations and Ports
Utilisation de la fonction Statistics - Destinations and Ports

Ici, nous voyons que sur plusieurs adresses IP du même sous-réseau, des échanges très brefs (1 ou 2 paquets) ont été réalisés systématiquement sur les mêmes ports, ce qui est exactement le comportement qu'adoptent les outils de scan réseau pour tester la présence d'un service sur un ensemble d'adresses IP. Terminons cette section avec la fonction Statistiques - Conversations, qui va nous permettre de visualiser l'ensemble des échanges émis par adresse source, destination et port :

Utilisation de la fonction Conversations de Wireshark
Utilisation de la fonction Conversations de Wireshark

En se rendant sur l'onglet TCP puis en regardant les colonnes Address A (IP source) et Port B (port destination), on se rend compte que l'adresse IP 192.168.101.19 a communiqué avec un grand nombre d'hôtes, systématiquement sur les mêmes ports. Nous pouvons donc affirmer que l'adresse IP source du scan réseau est donc celle-ci et non 192.168.101.31, qui est l'adresse IP la plus bavarde, mais qui n'a échangé qu'avec 5 hôtes différents :

Utilisation de la fonction Statistiques - Conversations avec l'application d'un filtre par IP
Utilisation de la fonction Statistiques - Conversations avec l'application d'un filtre par IP

Dans la capture ci-dessus, le fait de cocher la case Limiter au Filtre d'Affichage permet d'avoir une vue des conversations concernant uniquement l'adresse IP choisie.

Sans avoir parcouru aucun paquet et uniquement via les fonctions statistiques de Wireshark, nous pouvons donc affirmer qu'un scan réseau a eu lieu et identifier l'adresse IP source de ce scan réseau : 192.168.101.19.

Dans le framework MITRE ATT&CK, la technique du scan réseau est référencé T1046 Network Service Scanning.

Il est ici intéressant de retenir, en plus des différentes fonctions de statistique très utiles de Wireshark, le fait qu'un scan réseau n'est pas forcément l'échange le plus verbeux sur une trace réseau. L'échange d'un fichier de 100 Mo réalisé en même temps que la capture du scan réseau suffira à semer le trouble si l'on analyse uniquement la volumétrie des échanges.

IV. Analyse d'échanges SIEMENS S7

La prochaine étape de l'investigation consiste à étudier ce qu'a fait l'attaquant à la suite de ce scan réseau. Pour cela, nous utiliserons la même trace réseau. Nous devons chercher dans un premier temps le protocole utilisé pour effectuer l'attaque. À nouveau, la fonction Conversations va nous aider à cibler nos recherches, au-delà du scan réseau émis par l'adresse IP 192.168.101.19, il se passe clairement quelque chose à destination des ports TCP/102 des systèmes présents sur le réseau :

Nous pouvons donc appliquer un filtre dans Wireshark sur les paquets qui ont pour source ou destination ce port, et qui concernent l'adresse IP 192.168.101.19.

ip.src==192.168.101.19 && tcp.port==102
Filtre sur le port relatif aux communications S7COMM (Port TCP/102)
Filtre sur le port relatif aux communications S7COMM (Port TCP/102)

Nous nous retrouvons alors avec 374 paquets, ce qui devient plus gérable pour une analyse manuelle :). Nous voyons notamment apparaitre le protocole S7COMM

Le protocole S7COMM est, d'après cette source, utilisé pour le contrôle à distance d'automates de la famille S7-300/400 de la marque Siemens. Dans le monde industriel, un automate peut également être appelé PLC (programmable logic controllers). Il s'agit donc dans notre contexte de systèmes pouvant recevoir des ordres par le réseau TCP/IP et qui ont également une action physique dans la vie réelle, principe même des systèmes industriels (gestion d'un bras mécanique, d'une porte automatique, etc.).

Mais comment Wireshark détermine-t-il un protocole ?

Wireshark utilise des dissecteurs pour déterminer et "décoder" correctement le contenu d'un paquet. Il s'agit simplement de parsers de protocoles qui permettent d'identifier son contenu et de l'afficher correctement dans l'interface graphique, les paquets des couches 2, 3 et 4 intègrent directement une indication sur le protocole de niveau supérieur qu'ils contiennent :

Indication des protocles de niveaux supérieur pour les couches 2, 3 et 4
Indication des protocoles de niveaux supérieurs pour les couches 2, 3 et 4

Pour déterminer quel protocole est utilisé au-delà de la couche 4 (TCP/UDP) : cela se complique un peu et sachez que Wireshark peut ici faire des erreurs, car il essaye de deviner le protocole utilisé à partir de plusieurs critères comme des champs caractéristiques, le numéro de port source ou destination, etc... (Source : 11.4. Control Protocol dissection).

Une fois qu'un protocole a été identifié par Wireshark, celui-ci utilise le dissecteur associé qui va "traduire" le format hexadécimal que vous voyez en bas de votre fenêtre en sections lisibles. Si l'on s'intéresse aux paquets qui utilisent le protocole S7COMM, nous pouvons voir que Wireshark a déjà ordonné le contenu du paquet dans différentes sections en utilisant d'ailleurs un dissecteur documenté sur son site officiel :

Dissection du protocole S7COMM par Wireshark
Dissection du protocole S7COMM par Wireshark

Lorsque Wireshark trouve une valeur hexadécimale à cet endroit précis d'un paquet identifié comme utilisant le protocole S7COMM, il sait que cette valeur sert à déterminer la fonction (l'ordre) envoyée par le paquet, c'est le dissecteur qui permet de faire cette "catégorisation/rangement" des valeurs hexadécimales.

Vous pouvez d'ailleurs ajouter votre propre dissecteur dans Wireshark dans le cas où vous tombez sur un protocole non encore pris en charge ou spécifique à votre contexte. On remarque notamment la partie Function qui contient l'instruction 0x29, soit PCL Stop. Cela nous permet de répondre aux questions suivantes :

Si l'on souhaite effectuer un filtre très précis sur tous les paquets du protocole S7COMM qui contiennent cette instruction, nous pouvons tenter de manuellement trouver les bons champs à indiquer dans le filtre, ou simplement faire un Clic droit -> Appliquer comme Filtre -> Sélectionné sur le champ Function d'un paquet contenant l'instruction PLC Stop :

Application d'un filtre depuis le chmap du protocole s7COMM disséqué
Application d'un filtre depuis le champ du protocole s7COMM disséqué

Wireshark appliquera alors automatiquement le filtre suivant : 

s7comm.param.func == 0x29

Nous aurons alors la liste des paquets contenant cette instruction et nous pourrons avoir une liste toute jolie des adresses IP ciblées avec la fonction Endpoints que vous connaissez bien à présent (n'oubliez pas de cocher la case Limiter au Filtre d'Affichage 🙂 ) :

Affichage de la liste des adresse IP concernées par le filtre appliqué
Affichage de la liste des adresses IP concernées par le filtre appliqué

En excluant l'adresse IP de l'attaquant, nous pouvons donc répondre à notre dernière question :

L'attaquant vise donc ici clairement l'arrêt des automates présents sur le réseau, dans le framework MITRE, qui possède un déclinaison spécifique au monde industriel, il s'agit de la T0826 Loss of Availability.

Nous avons vu dans cette section que les dissecteurs intégrés à Wireshark nous permettent de comprendre un protocole industriel que ne nous ne connaissions pas du tout avant, la dissection des paquets (format hexadécimal vers un format plus ordonné et textuel) et l'une des forces de Wireshark. Les dissecteurs actifs peuvent être visualisés dans la fonction Analyser -> Protocoles activés de Wireshark :

Liste des dissecteurs activés sur Wireshark
Liste des dissecteurs activés sur Wireshark

Il faut cependant garder en tête que Wireshark peut se tromper dans la détermination d'un protocole pour un paquet, il est alors possible d'indiquer à Wireshark quel dissecteur utiliser pour quel port dans la section Analyser -> Décoder comme...

Indication d'une liaison entre un port et un dissecteur dans Wireshark
Indication d'une liaison entre un port et un dissecteur dans Wireshark

Dans cet exemple, j'indique à Wireshark de décoder les paquets sur les ports TCP/4000 comme de l'HTTP

J'espère que cet article vous aura intéressé et qu'au-delà du scénario de forensic proposé par le challenge du FIC, vous aurez appris quelques astuces sur le fonctionnement et l'utilisation de Wireshark :). Le prochain article portera sur l'analyse plus approfondie d'un PDF embarquant un exécutable malveillant.

The post Forensic – EngineX : scan réseau et protocole industriel first appeared on IT-Connect.

Recherchez tous les comptes correspondants à un pseudo avec Sherlock

28 décembre 2021 à 10:00

I. Présentation

Si je vous dis "Sherlock", vous allez me répondre "Holmes". Et bien, on pourrait dire que l'outil "Sherlock" aurait pu servir au célèbre détective privé Sherlock Holmes si ses histoires avaient eu lieu à l'époque d'Internet et des réseaux sociaux.

Sherlock est un outil développé en Python qui va analyser de nombreux sites Internet à la recherche d'un pseudonyme spécifique. Autrement dit, vous précisez un pseudonyme et il va trouver tous les comptes correspondants à ce pseudo sur un ensemble de sites (323 sites à l'heure actuelle) : GitHub, Spotify, Twitter, Pinterest, Gravatar, Facebook, Reddit, Mastodon, WordPress.org, JeuxVideo.com, Bitwarden Forum, Flickr, Nextcloud Forum, TikTok, VirusTotal, Wikipédia, Steam, etc.

C'est un outil à classer directement dans la catégorie "OSINT" (Open Source Intelligence) puisqu'il s'appuie uniquement sur des informations accessibles publiquement.

Pourquoi utiliser Sherlock ou un outil similaire ? Je vois deux raisons pour lesquelles on peut souhaiter utiliser cet outil :

  • Surveiller l'utilisation d'une marque, de son nom, de son pseudo

En recherchant le nom de votre site Web, de votre marque, votre pseudo ou encore votre nom, vous pouvez identifier les faux comptes éventuels qui utilisent vos informations. On parlera alors de cybersquattage. Même si vous n'êtes peut-être pas le seul à utiliser votre pseudonyme et qu'il y a peut-être d'autres personnes qui ont le même nom et le même prénom que vous, cette recherche automatisée avec Sherlock est intéressante.

  • Préparer une attaque informatique ciblée

Afin de préparer une cyberattaque, un attaquant peut avoir besoin de Sherlock dans sa trousse d'outils notamment pour se renseigner sur sa cible. Cela peut également donner des indications sur les solutions utilisées au sein de l'entreprise de la cible : si l'on sait que l'utilisateur avec le pseudo "hello123" est l'administrateur système de l'entreprise XYZ et que l'on voit qu'il a un compte sur le forum de NextCloud, cela peut vouloir dire qu'il utilise NextCloud dans son entreprise (ou sur son NAS à la maison). Une information qui peut avoir de l'importance.

Avec Sherlock, on se rend compte assez rapidement que pour rester furtif sur Internet et essayer de respecter au maximum sa vie privée, il vaut mieux diversifier les pseudos utilisés sur les différents sites. Sinon, on peut réussir à collecter des informations au sujet d'un individu à partir de différentes sources.

Le projet Sherlock est sous licence MIT et il est disponible sur GitHub à cette adresse : GitHub - Sherlock

Note : pour la suite de ce tutoriel, je vais utiliser Kali Linux 2021.4 mais vous pouvez utiliser une autre distribution.

II. Installation de Sherlock

Afin d'utiliser Sherlock sur notre machine, nous allons cloner le projet avec Git. Si besoin, vous pouvez installer Git avec la commande suivante :

sudo apt-get update
sudo apt-get install -y git

Une fois que c'est fait, je vous invite à cloner Sherlock :

git clone https://github.com/sherlock-project/sherlock.git

Cloner le projet Sherlock depuis Git
Cloner le projet Sherlock depuis Git

Vous allez obtenir un répertoire nommé "sherlock" au sein de votre dossier actuel. Nous allons nous déplacer dans ce dossier :

cd sherlock/

À l'aide de Python et du gestionnaire de paquets Pip, nous allons installer Sherlock (et ses prérequis). Avant cela, vous devez installer Python 3 et Pip sur votre machine, si ce n'est pas déjà fait. Voici les commandes à exécuter :

sudo apt-get install -y python3 pip

Une fois que c'est fait, on va déclencher l'installation avec cette commande :

python3 -m pip install -r requirements.txt

Installation de Sherlock
Installation de Sherlock

Voilà, nous pouvons passer à l'utilisation de Sherlock.

III. Utilisation de Sherlock

Commençons par afficher l'aide de Sherlock. Pour cela, il suffit d'exécuter la commande suivante :

python3 sherlock --help

Afficher l'aide de l'outil Sherlock
Afficher l'aide de l'outil Sherlock

Pour utiliser Sherlock de façon simple, il n'y a pas trop à chercher puisqu'il suffit de préciser le pseudo à rechercher. Par exemple, si l'on imagine que l'on souhaite rechercher le pseudo "florian", on exécute :

python3 sherlock florian

Le script va travailler pour nous et l'analyse va durer plusieurs minutes. Soyez patient si vous désirez un résultat complet. Voici un exemple pour le pseudo "florian" qui est bien trop générique pour être précis mais c'est un exemple (ce n'est pas mon pseudo, je tiens à le préciser, ahah).

Note : l'option --tor vous permet d'effectuer la recherche en utilisant le réseau Tor mais cela nécessite que Tor soit installé sur votre machine.

Au final, on obtient une liste des sites pour lesquels Sherlock a trouvé une correspondance et à chaque fois il y a le lien vers le profil.

Recherche d'un pseudo avec Sherlock
Recherche d'un pseudo avec Sherlock

Si vous souhaitez rechercher plusieurs pseudos, vous pouvez les ajouter les uns à la suite des autres, par exemple :

python3 sherlock florian1 florian2

Sachez qu'en plus de la sortie dans la console, un fichier TXT par pseudo sera créé dans le dossier de "Sherlock", ce qui vous permet de consulter les résultats ultérieurement.

Pour finir, nous allons voir quelques options de l'outil Sherlock. Pour réaliser un export CSV plutôt qu'au format TXT, il faut ajouter cette option :

python3 sherlock florian --csv

Vous allez obtenir un fichier CSV avec le format suivant :

username,name,url_main,url_user,exists,http_status,response_time_s
florian,WordPress,https://wordpress.com,https://florian.wordpress.com/,Claimed,200,0.363991595000698

Si vous souhaitez afficher toute la liste des sites sur lesquels Sherlock a effectué la recherche, y compris les sites où il n'a rien trouvé, vous devez ajouter l'option suivante :

python3 sherlock florian --print-all

Enfin, pour effectuer une recherche uniquement sur un site, vous pouvez utiliser l'option "--site" de cette façon :

python3 sherlock florian --site WordPress

Le résultat retourné correspondra uniquement à ce site, de quoi faire une requête ciblée rapidement. La liste des sites est accessible dans le fichier "sites.md" situé dans le répertoire de Sherlock.

Alors, dites-moi tout, qui va effectuer une recherche sur son pseudo ou son nom ?

The post Recherchez tous les comptes correspondants à un pseudo avec Sherlock first appeared on IT-Connect.

Forensic – FloatingCredentials : analyse d’une capture WireShark

22 décembre 2021 à 10:00

I. Présentation

Nous continuons notre suite d'articles sur le CTF du FIC 2021 proposé par l'école EPITA afin de découvrir certains outils et méthodes de forensic (investigation numérique). Dans cet article nous allons nous pencher sur l'analyse de traces réseau afin de déterminer les actions menées par un attaquant.

Nous allons notamment utiliser le logiciel Wireshark et explorer quelques-unes de ses nombreuses fonctionnalités, notamment celles permettant de comprendre et d'analyser une trace réseau comprenant un grand nombre de paquets et d'échanges différents.

II. Contexte : Panic on board - FloatingCredentials

Le contexte de l'incident sur lequel nous intervenons est le suivant : Un bateau de croisière de la compagnie maritime ArMor a subi une panne et se retrouve bloqué en pleine mer.

Nous avons, dans le premier article de cette série, identifié que l'attaquant a envoyé un mail de phishing contenant une pièce jointe malveillante. Le contexte de cette seconde étape de l'analyse est le suivant :

M.Deloin affirme avoir cliqué sur la pièce jointe malveillante dès sa lecture, soit le lundi 03/08 à 9h00. Aussi, selon Armor, la seule connexion à leur VPN depuis le poste de Christian Deloin pendant le mois d’août a eu lieu le 05/08 à 13h. Récoltez des preuves permettant d’affirmer que l’attaquant s’est servi de la machine de M.Deloin pour se connecter au VPN d’Armor.

Comme dans toute analyse forensic, les éléments de contexte sont importants à prendre en compte et permettent d'orienter nos recherches. Ici, deux traces réseau nous sont fournies :

  • deloin_03_08_09_00.pcapng : date d'ouverture de la pièce jointe malveillante par l'utilisateur ;
  • deloin_05_08_13_00.pcapng : date d'une connexion VPN établie depuis le poste de Mr Deloin.

Ces deux traces réseau correspondent aux éléments de contexte indiqué.  Nous devons fournir les éléments suivants pour compléter cette deuxième étape de l'analyse :

  • IP de l'attaquant;
  • Identifiants du VPN;
  • IP du VPN;
  • Commande complète utilisée pour se connecter chez Armor.

N'oublions pas de vérifier l'intégrité des éléments récupérés (le hash BLAKE2 est fourni avec les fichiers sur le site du challenge) :

$ b2sum deloin_03_08_09_00.pcapng 
72891fe777ccc13f29ab0b4a62ddaa644d68ab7a82ee52b3e29025de971504257c04578f27c3a9cd2aee3145fa35c21df7f59e8df898b64ed17e11d264f0163c deloin_03_08_09_00.pcapng

$ b2sum deloin_05_08_13_00.pcapng
f1af4b121e62f9137f571b00023501530bf8c6f12aa797d858a39d5afe9dd7d15bad86092f5152175ff8fbd7c3b6d711e7071313d5a456ac89caf5b69d24fcb3 deloin_05_08_13_00.pcapng

Vous trouverez le challenge en question et les fichiers utilisés dans cet article ici : Panic On Board - FloatingCredentials 

III. Analyse d'une trace réseau avec WireShark

Les traces réseau reçues contiennent un grand nombre de paquets, l'analyse manuelle des paquets un à un n'est donc pas une méthodologie viable dans notre cas. Heureusement, Wireshark propose de nombreuses fonctionnalités de filtre, de tri, de statistique et de catégorisation des échanges qui vont nous être utiles.

A. Identifier l'adresse IP du poste d'écoute

Commençons par l'analyse du fichier deloin_03_08_09_00.pcapng qui contient plus de 90 000 paquets.  Pour rappel, la pièce jointe malveillante analysée dans la première étape était un PDF exécutant des commandes système dès son ouverture (voir cet article Forensic – PhishingBoat : analyse de fichiers Mbox et PDF). On peut donc penser que cette activité a laissé une trace réseau.

Afin d'avoir une bonne compréhension des échanges, il nous faut déterminer l'adresse IP du poste ayant été utilisé pour l'enregistrement des traces réseau, nous pourrons ainsi plus facilement mettre un sens sur les paquets analysés.

Dans Wireshark, il n'existe pas de moyen fiable à 100% de déterminer cette information : mettre une interface en mode promiscious et réaliser l'écoute réseau depuis un actif réseau en mode mirroring font partie des cas de figure qu'il nous sera difficile de caractériser.

Nous pouvons simplement tenter de déduire cette information à partir de différentes sources. L'utilisation de la fonction Conversations dans le menu Statistiques est une source possible : 

Accès au menu statistiques - conversations de Wireshark
Accès au menu statistiques - conversations de Wireshark

Dans Wireshark, une conversation réseau est un trafic entre deux points de terminaison spécifiques qui peuvent être caractérisés par adresses Ethernet (MAC), IPv4, IPv6, UDP ou TCP. Ce que l'on remarque rapidement dans les onglets IPv4 et TCP, c'est que l'adresse 192.168.0.12 est la plus présente en adresse source et destination :

Identification de l'adresse IP potentielle du poste d'écoute
Identification de l'adresse IP potentielle du poste d'écoute

C'est un indicateur intéressant, car si la capture réseau a été faite sur le poste lui-même, la grande majorité des paquets aura pour adresse source ou destination celle du poste en question, hormis les paquets multicast et broacast (et les paquets non IP).

Nous pouvons à présent utiliser les filtres Wireshark pour faire un filtre sur l'adresse IP 192.168.0.12 : 

ip.src==192.168.0.12 || ip.dst ==192.168.0.12

Nous utilisons ici l'opérateur || qui permet d'indiquer un OU : soit l'adresse IP source est 192.168.0.12 , soit l'adresse IP destination est 192.168.0.12. Information intéressante, lorsque nous utilisons un filtre sur Wireshark, celui-ci nous indique (discrètement) le pourcentage de paquets affichés à la suite de l'application de ce filtre :

Affichage du pourcentage de paquet affichés à la suite de l'application du filtre.
Affichage du pourcentage de paquets affichés à la suite de l'application du filtre.

Nous savons donc que 99,9% des paquets ont pour adresse source ou destination l'adresse IP ciblée par le filtre, un autre indicateur qui confirme notre choix. Enfin, nous pouvons utiliser la fonction Endpoint du menu Statistiques de Wireshark : 

Accès àa la fonction Endpoints de Wireshark
Accès à la fonction Endpoints de Wireshark

Cette fonctionnalité va lister de manière unitaire les points de terminaison présents dans la capture réseau, l'équivalent d'un sort -u pour les Linuxiens. À nouveau, différents onglets sont proposés : Ethernet, IPv4, IPv6, TCP et UDP. En se rendant sur IPv4, on remarque à nouveau que les valeurs des colonnes Tx packets (Transmitter) et Rx Packets(Receiver) pour la ligne de l'adresse 192.168.0.12 sont les plus élevées, ce qui va dans le même sens que nos constats précédents :

Visualisation des endpoints IPv4 dans Wireshark
Visualisation des endpoints IPv4 dans Wireshark

Nous venons de voir dans cette section comment utiliser certaines fonctionnalités de Wireshark pour identifier une adresse IP pouvant correspondre à celle du poste sur laquelle a été réalisée la capture réseau. Ces fonctions peuvent également servir à identifier des exceptions et des comportements qui sortent de l'ordinaire.

B. Identifier un trafic anormal

Pour rappeler notre mission principale, nous devons identifier un trafic anormal au sein de cette capture ainsi que l'adresse IP de l'attaquant. Nous allons ici lister les différents ports TCP présents dans la capture réseau à l'aide de la fonction Endpoints, plus précisément dans l'onglet TCP :

Liste des échanges par port TCP via la focntion Endpoint
Liste des échanges par port TCP via la fonction Endpoint

Pour l'instant, rien de très parlant. Nous voyons des échanges sur les ports HTTP et HTTPS classiques. Nous cherchons dans un premier temps des comportements anormaux concernant l'adresse IP 192.168.0.12. Nous pouvons utiliser un filtre pour inclure ou exclure certains paquets, par exemple :

 (ip.dst == 192.168.0.12 || ip.src==192.168.0.12) && (!tcp.port==80 && !tcp.port == 443)

Ainsi, nous excluons les paquets qui ne concernent pas l'adresse 192.168.0.12 et qui sont des échanges sur les ports 80 ou 443. Nous pouvons ensuite retourner dans la fonction Endpoint. Une petite astuce ici consiste à appliquer le filtre Wireshark sur les données présentées par cette fonction :

Application du filtre sur les résultats de la fonction Endpoints
Application du filtre sur les résultats de la fonction Endpoints

Voilà qui est un peu plus clair. Nous nous retrouvons avec une liste plus réduite de cas "anormaux" et pouvons maintenant investiguer sur ces cas un à un. Notamment en utilisant un filtre comme celui-ci pour le port 1723 (première ligne sur l'image ci-dessus) :  

(ip.dst == 192.168.0.12 || ip.src==192.168.0.12) && tcp.port==1723

C. Suivre une connexion TCP

Pour chaque filtre appliqué, nous nous retrouvons à nouveau avec une dizaine ou une centaine de paquets à analyser, nous pouvons ici utiliser la fonction Suivre de Wireshark en faisant un clic droit sur l'un des paquets :

Sélection de l'option "Suivre" sur un paquet
Sélection de l'option "Suivre" sur un paquet

Ici, rien de très parlant, mais cette fonction peut être très utile pour certains protocoles puisqu'elle permet de visualiser, dans une seule fenêtre, les échanges entre le serveur (en bleu) et le client (en rouge), c'est notamment le cas pour les protocoles non chiffrés. Faisons la même opération pour le port TCP/5000 :

Suivi d'échanges TCP sur un protocole en clair
Suivi d'échanges TCP sur un protocole en clair

Voilà qui est plus intéressant, cela ressemble fortement à un shell PowerShell distant, typiquement le type d'outils et de méthodes utilisés dans le cadre d'un accès distant par un attaquant. Nous pouvons donc obtenir, grâce à ce filtre, l'adresse IP de notre attaquant : 93.29.253.182.

Nous pouvons donc affirmer ici que l'attaquant a utilisé la technique T1059.003 Command and Scripting Interpreter: Windows Command Shell référencée dans le framework MITRE ATT&CK :

Description de la technique T1059.003 dans le framework MITRE ATT&CK
Description de la technique T1059.003 dans le framework MITRE ATT&CK

Un peu plus bas dans cette même conversation, nous remarquons que l'attaquant était à la recherche d'identifiants VPN, qu'il a fini par trouver :

Affichage des identifiants VPN par l'attaquant
Affichage des identifiants VPN par l'attaquant

Nous sommes donc en mesure de dire, grâce à ces éléments, que l'attaquant a bien mis la main sur ces identifiants. Cela nous amène à notre deuxième capture réseau, qui concerne une connexion VPN établie avec le compte de Mr Deloin peu après cette première capture réseau.

Le vol d'éléments d'identification sur un système compromis est décrit dans la technique T1552.001 Unsecured Credentials: Credentials In Files du framework MITRE ATT&CK.

Description de la technique T1552.001 dans le framework MITRE ATT&CK
Description de la technique T1552.001 dans le framework MITRE ATT&CK

Nous ouvrons donc la capture réseau deloin_05_08_13_00.pcapng et appliquons dans un premier temps le même filtre que précédemment :

(ip.dst == 192.168.0.12 || ip.src==192.168.0.12) && tcp.port==5000

À nouveau en faisant un suivi de connexion TCP sur ces échanges, nous obtenons une vue en clair des commandes exécutées par l'attaquant et des réponses obtenues :

Affichage des commandes saisies et de leurs résultats
Affichage des commandes saisies et de leurs résultats

Ce qui nous permet de répondre aux deux dernières questions :

  • IP du VPN : 90.70.74.155
  • Commande complète utilisée pour se connecter chez Armor : Invoke-Expression "rasdial.exe RH-ARMOR christian.deloin Chr123delo!"

L'attaquant a donc utilisé les identifiants volés afin d'obtenir un accès VPN valide au SI ciblé, cette technique T1078 Valid Accounts est également décrite dans le framework MITRE ATT&CK. Cette action peut être vue comme un moyen d'accès initial ou de persistance.

Description de la technique T1078 dans le framework MITRE ATT&CK
Description de la technique T1078 dans le framework MITRE ATT&CK

Les choses auraient bien sûr été plus complexes si l'attaquant avait utilisé un protocole chiffré ainsi qu'un échange sur un port commun (80 ou 443). Gardons à l'esprit qu'il s'agit d'un exercice et non d'un cas 100% réel :). Cela nous a cependant permis de nous familiariser avec différentes fonctionnalités de Wireshark et d'avoir un aperçu de l'état d'esprit qu'il faut avoir en matière d'investigation. Nous avons également vu dans cet article que nous sommes en capacité d'associer une technique du framework MITRE ATT&CK à chaque action de l'attaquant. Cela nous permettra par la suite de tenter d'en savoir plus sur ses intentions, sur les recommandations et moyens de détection à mettre en place à la suite de cette attaque, et très éventuellement de tenter d'assigner cette attaque à une entité connue (APT).

Le prochain article de cette série portera sur une analyse réseau également, nous étudierons quelques fonctions de filtre supplémentaires ainsi que l'analyse d'un protocole industriel.

The post Forensic – FloatingCredentials : analyse d’une capture WireShark first appeared on IT-Connect.

Comment protéger son site WordPress avec CrowdSec ?

20 décembre 2021 à 11:30

I. Présentation

Dans ce tutoriel, nous allons voir comment protéger un site WordPress avec l'outil CrowdSec afin de bannir les adresses IP malveillantes.

Grâce à CrowdSec, on va pouvoir protéger notre site WordPress contre toutes les attaques courantes, notamment les scans avec des outils de sécurité, mais aussi les attaques par brute force sur le formulaire de connexion de WordPress.

Afin de pousser un peu plus loin la configuration de l'extension CrowdSec, je vais utiliser un site WordPress derrière un reverse proxy HAProxy. Si vous n'utilisez pas de reverse proxy et que votre site Web est publié directement sur Internet (ou via un NAT), vous pouvez aussi utiliser l'extension CrowdSec (et ce sera encore plus rapide).

Le site WordPress "it-connect.tech" sera mon cobaye pour cette démonstration. Je vais manipuler le serveur Web où est déployé le site WordPress afin de mettre en place CrowdSec et le "PC de l'attaquant" présent sur le schéma ci-dessous.

Je ne vais pas détailler l'installation de mon serveur Web (LAMP - Linux Apache MariaDB PHP) ni l'installation de WordPress dans ce tutoriel. Si besoin, je vous oriente vers ces deux tutoriels existants :

II. Installation de CrowdSec sur le serveur

Sur mon serveur web sous Debian 11, je vais installer CrowdSec directement à partir des dépôts officiels.

sudo apt-get update
sudo apt-get install -y crowdsec

Le cas échéant, si le paquet n'est pas disponible (sur une version Linux plus ancienne, par exemple), vous devez utiliser cette méthode pour réaliser l'installation :

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash 
sudo apt install crowdsec

Lors de l'installation, CrowdSec va analyser votre machine afin de détecter les services présents et de télécharger les collections associées. Ces composants vont permettre à CrowdSec de détecter les attaques (sans les bloquer).

On peut lister les collections avec la commande suivante :

sudo cscli collections list

On peut voir que la collection "WordPress" est automatiquement installée : CrowdSec a détecté la présence du CMS. En complément, on retrouve d'autres collections, dont "base-http-scenarios", ce qui va nous permettre d'être protégé contre les attaques Web courantes, y compris sur notre site WordPress.

Suite à l'installation, il est préférable d'effectuer une mise à jour des collections pour être certain de bénéficier des dernières versions et de tous les scénarios de détection. Voici les deux commandes à saisir :

sudo cscli hub update
sudo cscli hub upgrade

III. Mise en place du Bouncer CrowdSec dans WordPress

A. Installation et configuration de l'extension CrowdSec

À partir de l'interface d'administration de WordPress, cliquez sur le lien "Ajouter" du menu "Extensions".

Grâce à la zone de recherche, vous pouvez trouver facilement l'extension "CrowdSec". Ensuite, il suffit de cliquer sur le bouton "Installer maintenant".

Dans la foulée de l'installation, cliquez sur le bouton "Activer" pour activer l'extension. Cela n'aura pas d'impact sur votre site, car il faut lier le Bouncer CrowdSec à notre instance locale CrowdSec pour que cela fonctionne.

À ce sujet, accédez à la console de votre serveur Web et saisissez la commande ci-dessous pour générer une clé d'API pour notre Bouncer. Il faudra copier cette valeur.

sudo cscli bouncers add wordpress-bouncer

Ensuite, retournez sur WordPress et cliquez à gauche sur "CrowdSec" dans le menu afin d'accéder à la configuration de l'extension. Il va falloir renseigner plusieurs options :

  • LAPI URL : indiquez "http://localhost:8080", car CrowdSec est installé sur le même serveur que WordPress.
  • Bouncer API Key : collez la clé d'API générée précédemment
  • Bouncing level : en mode "Normal bouncing", CrowdSec va bannir ou présenter le Captcha aux clients malveillants selon la configuration, tandis qu'en mode "Flex bouncing", le blocage sera toujours effectué via un Captcha. Enfin, le mode "Bouncing disabled" permet à CrowdSec d'être transparent donc il ne bloquera plus personne, y compris les pirates. Prenons le mode "Normal bouncing" pour le moment.
  • Public website only : désactivez cette option afin de protéger la partie publique du site, mais aussi l'espace d'administration (wp-admin). Si cette option est active, CrowdSec protège seulement la partie publique du site (front office).

Validez en cliquant sur le bouton "Enregistrer les modifications".

À partir de la ligne de commande de votre serveur, exécutez la commande suivante pour lister les bouncers actifs :

cscli bouncers list

On constate que le bouncer WordPress est bien présent et valide ! Bonne nouvelle !

B. Un reverse proxy ? Configurez le module remoteip

Pour fonctionner, le bouncer WordPress va s'appuyer sur les journaux du serveur Web notamment pour identifier le client source par son adresse IP.

Dans le cas où vous utilisez un reverse proxy ou un CDN comme CloudFlare, c'est l'adresse IP du proxy qui est visible dans les journaux puisque c'est lui qui communique en direct avec le serveur Web. Cela ne joue pas en notre faveur, mais heureusement on peut ajuster la configuration d'Apache pour récupérer l'adresse IP d'origine du client.

Note : en amont, il faut configurer le reverse proxy pour qu'il ajoute le champ "X-Forwarded-For" à l'en-tête des requêtes HTTP afin de transmettre l'adresse IP du client au serveur Web.

Pour configurer Apache, il faut activer le module "remoteip" (normalement installé par défaut) :

a2enmod remoteip

Ensuite, il faut modifier le fichier de configuration d'Apache :

nano /etc/apache2/apache2.conf

Il faut modifier le format des logs et plus particulièrement la ligne qui termine par "combined". Il faut remplacer "%h" par "%a" pour spécifier dans les logs l'adresse IP du client d'origine plutôt que l'adresse IP de l'hôte qui contact le serveur Web directement.

Ce qui donne :

Enfin, on va ajouter à Apache que le champ "X-Forwarded-For" contiendra l'adresse IP du client d'origine au sein de l'en-tête HTTP. Pour cela, on utilise l'option RemoteIPHeader du module remoteip. Ajoutez la ligne suivante au fichier apache2.conf :

RemoteIPHeader X-Forwarded-For

Il ne reste plus qu'à sauvegarder le fichier et redémarrer Apache :

systemctl restart apache2

Nous verrons dans la suite de ce tutoriel l'impact de cette modification sur les logs d'Apache. La configuration de CrowdSec étant prête, nous allons pouvoir attaquer notre site WordPress.

IV. Tester le bon fonctionnement

Pour simuler une attaque contre un site Web, en l'occurrence ici un site WordPress, il y a plusieurs façons de faire. On peut utiliser Nikto, Wapiti, WPScan ou tout simplement Curl avec un user-agent suspect.

C'est d'ailleurs Curl que je vais utiliser, car ce que j'aime bien quand il s'agit de faire une démo, c'est que l'on voit en direct le code de retour HTTP : 200 quand la page se charge correctement, et il passe à 403 ou 401 une fois que CrowdSec est intervenu (le code dépend de la décision : bannir ou captcha).

On va contacter notre site en utilisant le user-agent OpenVAS (un outil de sécurité), ce qui ne devrait pas plaire à CrowdSec, car il est dans la liste des "bad user agent". Ce qui donne la commande :

curl -I https://it-connect.tech -H "User-Agent: OpenVAS"

Sur la copie d'écran ci-dessous, on peut voir qu'au début le serveur Web me répond bien, avec un code HTTP 200 donc j'accède au site. Ensuite, j'obtiens une réponse "403 Forbidden", ce qui correspond à un accès refusé. On va aller voir avec un navigateur ce qu'il se passe...

À partir du navigateur, si je tente d'accéder à l'espace d'administration de mon site WordPress ou au site en lui-même, j'obtiens un message qui m'indique je suis actuellement banni par le système ! Nous verrons dans la suite de ce tutoriel comment personnaliser cette page.

À partir de la ligne de commande, on peut lister les décisions actives dans CrowdSec et on peut voir la présence de notre adresse IP publique. L'action "BAN" montre bien que l'adresse IP est bannie pour une raison claire "http-bad-user-agent", ce qui montre clairement que CrowdSec n'a pas aimé que je me présente avec le user-agent OpenVAS.

sudo cscli decisions list

Si l'on regarde les journaux d'Apache, on peut voir la ligne avec le code HTTP 403, et cette même ligne commence bien par l'adresse IP publique utilisée par le PC de l'attaquant. Toutes les autres lignes visibles sur l'image ci-dessous correspondent aux différents "check alive" effectué par le reverse proxy pour vérifier si le serveur Web est opérationnel (d'où l'adresse IP du reverse proxy qui apparaît toutes les secondes).

J'ai l'avantage d'être à la fois l'attaquant et l'admin du site WordPress alors je vais débloquer mon adresse IP (via un autre accès sur le serveur) :

sudo cscli decisions delete --ip X.X.X.X

On va tester d'une seconde façon l'efficacité de CrowdSec : en s'attaquant au formulaire de connexion de WordPress, accessible via la page wp-login.php.

Brute force WordPress : comment va réagir CrowdSec ?
Brute force WordPress : comment va réagir CrowdSec ?

Si on liste les décisions actives, comme nous avons fait précédemment, on peut voir que cette fois-ci la raison du blocage est différente : http-fb-wordpress_bf. CrowdSec a bien détecté que j'étais en train d'effectuer un brute force sur la page de connexion !

Notre site WordPress est protégé par CrowdSec, mais pour finir je vous propose de voir quelques options supplémentaires du Bouncer WordPress.

V. Optimiser la configuration du Bouncer WordPress

A. Les options avancées du Bouncer WordPress

Dans l'interface d'administration de WordPress, à gauche sous le menu CrowdSec cliquez sur "Advanced".

Cette partie permet d'accéder à quelques options supplémentaires, dont l'option "Trust these CDN IPs (or Load Balancer, HTTP Proxy)". Cette option va permettre de préciser les adresses IP correspondantes au CDN que vous utilisez, par exemple CloudFlare, ou alors l'adresse IP de votre reverse proxy, comme dans mon cas. C'est pour cette raison que je spécifie l'adresse IP "192.168.100.1".

Ensuite, vous pouvez activer l'option "Hide CrowdSec mentions", cela va permettre d'éviter d'afficher sur la page de blocage que c'est CrowdSec qui sécurise le site. Même si CrowdSec c'est génial, ce n'est pas la peine d'afficher le nom de l'outil publiquement. 😉

Vous pouvez sauvegarder les changements.

Au sein de la section de configuration globale de CrowdSec, nous avons choisi le mode "Normal bouncing" pour bannir les adresses IP lorsque c'est utile. Si vous choisissez le mode "Flex bouncing", un captcha sera présenté. À titre d'information, voici ce que ça donne côté utilisateur via le navigateur :

B. Personnaliser la page de blocage CrowdSec

La page de blocage qui s'affiche lorsque l'on est banni ou la page du captcha sont toutes les deux en anglais. Sachez qu'il est possible de les configurer totalement via l'extension CrowdSec de WordPress. Cette fois-ci, sous le menu "CrowdSec", choisissez "Theme customization".

Vous allez pouvoir modifier le texte des deux pages, mais aussi jouer sur les couleurs, ainsi que sur le style CSS de la page ! De cette façon, la page de blocage présentée par CrowdSec pourra respecter la charte graphique de votre site.

Voici un exemple :

Ce qui donne en production :

C. Brute force WordPress : modifier le seuil de blocage

En listant les scénarios via la ligne de commande (cscli scenarios list), on peut voir que le fichier de configuration du scénario "http-bf-wordpress_bf" est situé à cet emplacement :

/etc/crowdsec/scenarios/http-bf-wordpress_bf.yaml

Pour ajuster le comportement de ce scénario, notamment le seuil de blocage, il faut modifier ce fichier. On obtient le contenu suivant :

Il y a deux paramètres ajustables :

  • capacity: 5
  • leakspeed: "10s"

Il faut interpréter cette configuration par défaut de cette façon : nous avons un sceau (bucket) d'une capacité de 5 unités au maximum (capacity: 5) et une unité de ce sceau est retirée toutes les 10 secondes (leakspeed: "10s"). À chaque fois que j’effectue une tentative en erreur sur la page de login, une unité est ajoutée dans le sceau et à la 6ème unité, le sceau déborde donc je dois être banni (ou avoir un captcha). Vous pouvez ajuster ces deux valeurs en fonction de vos besoins.

Note : à cause de la mise en cache des informations via PHP, il peut y avoir une certaine latence entre le moment où l'action se produit et le moment où la décision est appliquée.

Avec toutes ces informations, vous êtes désormais en mesure de déployer CrowdSec sur votre serveur Web afin de protéger votre site WordPress des attaques informatiques.

VI. CrowdSec : les autres épisodes

Avant de vous laisser, je tenais à vous rappeler que j'ai déjà publié deux épisodes sur l'installation et la configuration de CrowdSec correspondant à deux autres cas de figure. Voici les liens :

Je profite de cet article et de l'actualité du moment liée à la faille de sécurité critique "Log4Shell" pour vous informer que CrowdSec a publié un scénario afin de détecter et bloquer cette attaque. Grâce aux différentes instances de la communauté CrowdSec, plus de 1 100 adresses IP ont déjà été bloquées pour avoir tenté d'exploiter la vulnérabilité Log4Shell. Vous pouvez accéder à cette liste d'IP gratuitement ici.

En complément, vous pouvez accéder à une carte qui permet de voir en temps réel les adresses IP à l'origine d'attaques cherchant à exploiter cette faille de sécurité : Log4j - Carte temps réel CrowdSec.

The post Comment protéger son site WordPress avec CrowdSec ? first appeared on IT-Connect.

Forensic – PhishingBoat : analyse de fichiers Mbox et PDF

16 décembre 2021 à 10:00

I .Présentation

Dans cette suite d'articles, je vous propose de suivre les exercices du CTF du FIC 2021 proposés par l'école EPITA afin de découvrir certains outils et méthodes de forensic (investigation numérique). Ces éléments peuvent être utilisés dans un grand nombre de contextes pour effectuer des recherches sur des évènements du quotidien, mais aussi afin de sensibiliser sur les bonnes et mauvaises pratiques, tant en matière de sécurité que de réponse à incident.

Je profile de ce premier article pour remercier les personnes qui ont crées ces challenges qui permettent de travailler sur des contextes d'attaques réalistes, ce qui est un vrai plus lorsque l'on aborde ce domaine.

II. Contexte : Panic on board - PhishingBoat

Le contexte de l'incident sur lequel nous intervenons est le suivant : Un bateau de croisière de la compagnie maritime ArMor, a subi une panne et se retrouve bloqué en pleine mer.

Le 30 août 2020, lors d’une traversée reliant Marseille à Pointe-à-Pitre, le ‘Sea Castle’, navire pouvant embarquer jusqu’à 8030 passagers, a subi une avarie de propulsion et s’est retrouvé bloqué à plus de 150 kilomètres de sa destination. Après avoir effectué des vérifications mécaniques et matérielles, l’équipage pense que la panne provient de l’informatique. Dans le doute, des investigations préalables sont menées chez RH Pro, un contractant offrant une solution de gestion RH.

La première simulation du challenge est la suivante : PhishingBoat -  Le poste de Christian Deloin, consultant junior fraîchement arrivé chez RH Pro, est peut-être compromis. Passez au peigne fin la boîte de réception de Monsieur Deloin afin de déterminer si elle constitue le point d’entrée d’une attaque.

Le challenge nous propose de mener une investigation afin de répondre aux questions suivantes :

  • date de réception du mail;
  • adresse source de l'email malveillant;
  • la CVE qui semble être utilisée.

Pour investiguer, deux fichiers nous sont fournis :

  • boite_de_reception.mbox
    • b2sum : 5fb763e2194378582f31ed2ea2274943c121511fa813b787cab548a5a374e0b3a2a779602e32e70334389f9b1b6e3e05962539fd11344cdf6817196fd4393314
  • documents.zip
    • b2sum : bff804323f4803665ad9f020a2a57a1cc26781f1627cc6eec57feb764efe6214cb639d43e0ef11c3f768619fb0139a6264a621b0ab16a36a40cfb64083fe86ce

Un hash est une empreinte numérique unique d'un fichier. Les hashs sont systématiquement utilisés en forensic afin de s'assurer qu'un fichier n'a pas été altéré entre le moment de son acquisition et le moment de son analyse. Cette vérification permet de s'assurer de l'intégrité des objets contenant les preuves récoltées. Ce qui évite que les conclusions de l'investigation ne soient remises en cause.

On commence donc par vérifier l'intégrité des fichiers récupérés à l'aide de la commande b2sum qui utilise l'algorithme de hachage BLAKE2  :

$ b2sum boite_de_reception.mbox 
5fb763e2194378582f31ed2ea2274943c121511fa813b787cab548a5a374e0b3a2a779602e32e70334389f9b1b6e3e05962539fd11344cdf6817196fd4393314 boite_de_reception.mbox

$ b2sum documents.zip
bff804323f4803665ad9f020a2a57a1cc26781f1627cc6eec57feb764efe6214cb639d43e0ef11c3f768619fb0139a6264a621b0ab16a36a40cfb64083fe86ce documents.zip

Maintenant que nous sommes sûrs de travailler sur des fichiers non altérés, nous pouvons continuer notre investigation.

Une seconde phase importante est la récolte et la compréhension des éléments de contexte, qui sont utiles pour orienter nos recherches et notre méthodologie. Ici, on nous indique qu'un navire de croisière a subi une attaque informatique, visiblement par l'intermédiaire d'une solution de gestion RH et de la boite mail d'un certain Mr Deloin. Les fichiers PDF fournis dans l'archive documents.zip nous permettent d'ailleurs de comprendre l'organisation de l'entreprise ainsi que d'obtenir la liste des adresses mail des utilisateurs.

III. Analyse de la boite mail

Dans un premier temps, nous allons nous intéresser à la boite mail fournie. Le format du fichier (.mbox) n'est qu'un simple fichier texte.

La boite mail contenant plusieurs dizaines de mails avec chacun leurs en-têtes, contenus et pièces jointes, cela rend la recherche peu agréable. D'après cette source, il est possible d'utiliser Thunderbird pour interpréter ce fichier .mbox, puis de parcourir les mails de l'utilisateur de façon un peu plus visuelle.

Il faut pour cela créer un nouveau profil dans Thunderbird, puis déposer dans le répertoire /home/<user>/.thunderbird/<profileID>.default-release/Mail/Local Folders notre fichier .mbox, et enfin redémarrer Thunderbird. Suivre cette procédure pour plus détails. Au redémarrage, un fichier local contiendra nos mails :

Affichage des mails du fichier .mbox dans ThunderBird
Affichage des mails du fichier .mbox dans Thunderbird

La difficulté principale ici est de différencier les mails légitimes, des mails suspects. Nous pouvons, dans un premier temps, regarder les adresses émettrices des mails. À première vue, rien ne saute aux yeux, pas de [email protected] ;). Pour trouver des idées d'attaques et d'éléments sur lesquels investiguer, nous pouvons nous pencher sur la matrice ATT&CK du MITRE, qui contient une section sur les attaques par phishing (technique T1566.01) :

Extrait de la technique T1566.01 du MITRE ATT&CK
Extrait de la technique T1566.01 du MITRE ATT&CK


La matrice ATT&CK du MITRE est une base de connaissance reconnue et utilisée pour référencer les techniques d'attaques, décrire ces techniques ainsi que les moyens de détection et de protections associées. Il s'agit d'une source d'information très intéressante pour un grand nombre de métiers (informatique/cybersécurité), que l'on soit du côté "attaquant" ou du côté "défense". La matrice est maintenue à jour en fonction des attaques et scénarios réels observés et contient notamment des références, pour chaque technique présentée, de cas réels d'utilisation, par exemple :

Exemples de cas réels d'attaque par des APT utilisant des techniques de phishing
Exemples de cas réels d'attaque par des APT utilisant des techniques de phishing

Nous pouvons dans un premier temps effectuer une recherche sur les e-mails contenant une pièce jointe, principal vecteur d'intrusion :

Visualisation des mails contenants une pièce jointe
Visualisation des mails contenant une pièce jointe

L'une des recommandations présentées dans le MITRE ATT&CK concerne le fait de former les utilisateurs à reconnaitre des mails de phishing :

Section "Mitigations" contre les techniques d'attaque par Phishing proposées par le MITRE
Section "Mitigations" contre les techniques d'attaque par Phishing proposées par le MITRE

Je m'oriente donc sur une lecture plus fine des adresses émettrices. On peut notamment partir à la recherche des noms de domaine de type homoglyphe (description dans cet article: Protéger son domaine contre le Phishing : techniques basées sur l’OSINT) c'est-à-dire les noms de domaine qui remplacent une lettre par une autre afin de tromper la vigilance de l'utilisateur (www.it-comnect.fr au lieu de www.it-connect.fr).

Pour cela, je décide de récupérer tous les noms de domaine des adresses émettrices et de comparer leurs hashs, ce qui sera bien plus fiable qu'une lecture à l'œil nu par un cerveau pouvant être berné :), j'utilise pour cela ce petit script fait pour l'occasion :

#!/bin/bash

for domain in `cat boite_de_reception.mbox |grep "From:" | cut -d "@" -f 2 | sort -u`; do
echo "- $domain"
domain_hash=$(echo $domain |md5sum |cut -d " " -f 1)
echo -e "\t$domain_hash"
done

Lors de son exécution, j'obtiens la sortie suivante :

$ ./domain_hash.sh 
- armor.com
4ea5e9ee234d4420dadc3c3f28eca790
- arnor.com
565f995d816506104313e12fbccea1fe
- delivrou.fr
fb0f6649ac0210437cd01594892328d3
- gmail.com
d3f00fb2602559aa8dbe7d7877a9532b
- labriseventee.fr
e69367e71948378d23bbd44bc329aca1
- rhpro.fr
6121b72d7433512bff4df25c82ffda5c
- xtramuscle.fr
815e32e51b2a182e8db879e3093b8a01

Nous détectons ici un nom de domaine qui diffère des autres, bien que visuellement similaire, je ne l'avais en effet pas vu lors de la vérification sous Thunderbird : arnor.com. Il semble donc que l'émetteur ait ici souhaité tromper sa cible avec un nom de domaine homoglyphe, ce qui semble suspect dans notre contexte. Nous avons mis la main sur un vecteur d'intrusion probable.

$ grep "arnor.com" -C 4 boite_de_reception.mbox 
X-Mozilla-Status: 0009
X-Mozilla-Status2: 00000000
Content-Type: multipart/mixed; boundary="===============8406457186411689544=="
MIME-Version: 1.0
From: [email protected]
To: [email protected]
Subject: Support VPN
cc:
Date: Thu, 30 Jul 2020 18:32:00 -0000

Nous pouvons répondre aux deux premières questions :

  • Date de réception du mail : 30/07/2020
  • Adresse source de l'email malveillant : [email protected]

IV. Analyse d'une pièce jointe malveillante

Nous avons identifié un vecteur d'intrusion, il nous faut maintenant déterminer sa charge utile. Nous allons à présent nous intéresser à la pièce jointe de ce mail, il s'agit d'un fichier PDF semblant être une documentation relative à un VPN : 

Pièce jointe du mail suspect identifié
Pièce jointe du mail suspect identifié

Les fichiers PDF ont un format structuré simple (venant du PostScript) mais peuvent intégrer de nombreux autres types de fichiers, langages et fonctionnalités (JavaScript, fichiers exécutables, actions à l'ouverture du fichier, chiffrement, etc.), le tout pouvant rendre leur analyse complexe.

Nous allons utiliser différents outils et commandes afin de tenter d'évaluer la dangerosité de ce fichier PDF, voire d'y trouver du contenu malveillant. À commencer par l'outil pdfid.py, qui va nous donner un aperçu des objets contenus dans ce fichier PDF.  

Analayse des objets contenus dans un fichier PDF par pdfid.py
Analyse des objets contenus dans un fichier PDF par pdfid.py

Nous voyons ici plusieurs éléments qui peuvent nous alerter. Le fichier PDF semble contenir du JavaScript (/JavaScript, /JS) ainsi que des instructions permettant le lancement d'actions à l'ouverture du fichier (/OpenAction, /Launch et /AA).  L'outil pdf-parser.py nous permettra de lire et décomposer le contenu du fichier PDF.

$ pdf-parser.py doc_vpn.pdf 

En parcourant le contenu du fichier PDF, on remarque l'objet portant l'identifiant 279 : 

Celui-ci tente de lancer un cmd.exe. Dans le cadre du challenge, plusieurs CVE sont proposés et nous devons indiquer laquelle est exploitée par ce fichier PDF. Dans le cas présent, seule la CVE-2010-1240 concerne les fichiers PDF. La question est donc vite répondue 🙂

Cette vulnérabilité concerne Acrobat 9.x avant la version 9.3.3, et 8.x avant la version 8.2.3, elle est due à un manque de restriction concernant un champ texte de la boite de dialogue d'avertissement : CVE-2010-1240

J'espère que ce premier article vous aura mis l'eau à la bouche, je compte bien continuer cette série afin d'explorer avec vous d'autres attaques, méthodologies et outils permettant d'investiguer des cas d'attaques que tout le monde peut croiser. Le prochain article portera sur l'analyse d'une trace réseau afin de déterminer l'activité d'un attaquant.

Je vous invite en attendant à vous rendre sur le site du MITRE afin de découvrir la matrice ATT&CK : https://attack.mitre.org/

The post Forensic – PhishingBoat : analyse de fichiers Mbox et PDF first appeared on IT-Connect.

Comment durcir la configuration de son serveur SSH ?

9 décembre 2021 à 10:00

I. Présentation

Dans ce tutoriel, nous allons voir comment sécuriser le service SSH sous Linux, en respectant quelques best practices en matière de configuration d'un serveur SSH.

Le protocole SSH est recommandé pour la connexion à distance, la réalisation de sauvegardes, le transfert de fichiers à distance via scp ou sftp, et bien plus encore. SSH est parfait pour préserver la confidentialité et l'intégrité des données échangées entre deux machines situées sur des réseaux différents, ou sur le même réseau. Son principal avantage est l'authentification du serveur, grâce à l'utilisation de la cryptographie à clé publique pour l'authentification. (aussi appelée SSH password-less). Sous Linux (et Windows), l'implémentation de ce protocole se fait par le biais du packet OpenSSH.

Depuis quelques années, au grès des mises à jour, OpenSSH a vu sa sécurité durcie, notamment en ce qui concerne les messages d'erreurs (trop verbeux) au départ. Ce guide ne sera pas très long étant donné que les développeurs ont fait un gros effort afin d'éviter que la configuration d'OpenSSH ne soit trop permissive par défaut.

Environnement :

  • Client SSH : Kali Linux (2021.3) - 192.168.175.128
  • Serveur SSH : Ubuntu 20.04.1 LTS - 192.168.175.129 - Deux utilisateurs : tintin, haddock

Toutes les commandes ci-dessous seront exécutées par l'intermédiaire de l'utilisateur root. 

Avant de commencer, installez SSH sur votre serveur :

sudo apt install openssh-server
# apt utilise aussi l'alias ssh, pour identifier le paquet openssh-server

II. Sécurisation générale de SSH

Quelle que soit la méthode de connexion au serveur SSH, il y a certaines règles communes à respecter afin de brouiller les pistes pour un attaquant :

  • Modifier le port et l'interface réseau d'écoute par défaut
  • Fixer un Idle timeout pour ne pas avoir de sessions SSH qui restent actives
  • Empêcher la connexion de l'utilisateur root (sur les distributions Linux récentes, cette fonctionnalité est désactivée par défaut)
  • etc.

Pour cela, nous allons modifier le fichier "/etc/ssh/sshd_config" de notre serveur SSH. Editez ce fichier avec votre éditeur préféré :

sudo nano /etc/ssh/sshd_config

A. Modifier le port et l'interface réseau d'écoute par défaut

Par défaut, le port d'écoute SSH est 22, changez-le afin de brouiller les pistes. Pour cela, modifiez le paramètre "Port" du fichier de configuration :

Port 2021

L'interface d'écoute du protocole SSH est par défaut "Toutes les interfaces" : 0.0.0.0/0. Changez ce paramètre, afin que votre serveur SSH accepte seulement les connexions sur votre interface principale. Si vous n'avez pas plusieurs interfaces réseau (j'entends par la carte réseau) et adresses IP sur votre serveur, vous pouvez vous passer de cette modification.

Pour que SSH écoute seulement sur l'adresse IP "192.168.175.129", voici la configuration :

ListenAddress 192.168.175.129

Puis, redémarrez le service :

systemctl restart ssh

B. Configurer le timeout des sessions SSH

Pour cette troisième modification, nous allons définir un temps maximal d'inactivité pour une session SSH, afin d'éviter que certaines connexions SSH restent actives indéfiniment.

Dans ce cas précis, si le service SSH ne détecte aucune activité sur le flux de connexion (en bref, si aucune commande n'est saisie pendant un laps de temps), alors il terminera automatiquement la connexion.

Si vous souhaitez que le client SSH se ferme (timeout) automatiquement après 10 minutes (600 secondes), modifiez le fichier sshd_config et définissez les deux paramètres suivants comme indiqué ci-dessous.

  • ClientAliveInterval - ceci indique le délai d'attente en secondes. Après x secondes, le serveur SSH enverra un message au client demandant une réponse.
  • ClientAliveCountMax - ceci indique le nombre total de messages de vérification envoyés par le serveur SSH sans obtenir de réponse du client SSH.

Nous en avons fini avec cette partie. Quelle que soit votre configuration, respectez ces règles. Pour valider ces changements, redémarrez le service SSH :

systemctl restart ssh

Si vous avez modifié le port SSH, il faudra vous reconnecter en utilisant le nouveau port.

C. Empêcher la connexion de l'utilisateur root en SSH

Même si depuis bien des années maintenant, la connexion de l'utilisateur root est désactivée par défaut dans la configuration SSH, il se peut que sur certaines vieilles bécanes, le processus d'authentification du super-utilisateur soit actif. Pour cela, recherchez la ligne suivante, et affectez lui la valeur No :

PermitRootLogin No

III. Sécuriser l'authentification par mot de passe classique

Depuis que l'authentification par clé publique/privée existe, cette méthode est de moins en moins utilisée et déconseillée (car trop sensible aux attaques par brute force si le service SSH est mal configuré).

Toutefois, dans certains cas pour des serveurs n'étant pas hautement stratégiques, et non atteignables depuis internet, nous pouvons garder la méthode d'authentification classique. Dans cette partie, nous allons voir comment sécuriser cette méthode d'authentification.

A. Autoriser seulement la connexion pour un ou plusieurs utilisateurs.

Dans mon cas, j'ai créé deux utilisateurs en amont :

  • tintin
  • haddock
sudo nano /etc/ssh/sshd_config

Je vais autoriser seulement tintin à se connecter en SSH sur mon serveur. Ajoutez cette ligne :

AllowUsers tintin

Sauvegardez les changements, et redémarrer votre service SSH.

systemctl restart ssh

Tentez une connexion SSH depuis votre machine cliente en précisant l'utilisateur haddock :

Comme l'utilisateur haddock n'est pas présent dans la liste, il se verra automatiquement refuser la connexion.

Vous préférez spécifier un groupe pour l'autorisation de connexion en SSH ? Ajoutez vos utilisateurs à un groupe, et spécifiez celui-ci dans la configuration de SSH. Par exemple :

AllowGroups MonGroupeSSH

IV. Authentification par clés publique/privée

Comme dit précédemment, il est recommandé d'utiliser une authentification basée sur un couple de clés. Pour ce faire, créez la paire de clés en utilisant la commande suivante (à partir de votre machine cliente) :

ssh-keygen -b 8192

Puis, entrez la commande suivante, afin de copier votre clé publique vers le serveur SSH (en écoute sur le port 2021) depuis votre machine cliente :

ssh-copy-id -p 2021 [email protected]

Bien sûr, l'utilisateur tintin devra s'authentifier afin de pouvoir déposer sa clé SSH. Afin de vérifier que votre clé est bien arrivée sur le serveur SSH, exécutez la commande suivante (vous ne devez plus entrer de mot de passe) :

ssh -p 2021 [email protected]

A. Désactivez l'authentification par mot de passe classique

Afin de durcir la sécurité de notre serveur SSH, nous allons autoriser seulement la connexion par clé publique/privée. Décommentez la ligne suivante dans le fichier et changer la valeur du paramètre "PasswordAuthentication" de yes à no :

sudo nano /etc/ssh/sshd_config
PasswordAuthentication no

Puis, redémarrez le service SSH.

sudo systemctl restart ssh

Si vous tentez de vous connecter sans fournir une clé privée, pour le processus d'authentification, une erreur sera retournée. Pour réaliser ce test, je bascule en root sur la machine cliente Kali, et j'essaie de me connecter :

Note : dans certains cas d'utilisation, il se peut que vous deviez mettre en place une authentification 2FA (double authentification). Je vous laisse consulter l'article suivant (en anglais) : SSH - Authentification à deux facteurs.

V. Pour aller plus loin :

Pour aller plus loin, et notamment lutter contre les attaques brutes à destination du service SSH, vous pouvez miser sur Fail2ban ou CrowdSec pour protéger le service. Voici deux tutoriels qui devraient vous aider :

Et si vraiment SSH est un sujet qui vous intéresse et que vous souhaitez apprendre à le configurer plus précisément, je vous invite à lire notre cours sur le SSH : Cours gratuit SSH.

The post Comment durcir la configuration de son serveur SSH ? first appeared on IT-Connect.

Informatique : c’est quoi une DMZ ?

7 décembre 2021 à 17:15

I. Présentation

Dans cet article, je vais aborder une notion fondamentale en sécurité informatique : la notion de DMZ, c'est-à-dire de zone démilitarisée.

Je vais vous expliquer à quoi ça sert, comment ça fonctionne et nous verrons des exemples à travers quelques schémas.

II. Qu'est-ce qu'une DMZ en informatique ?

Tout d'abord, il faut savoir que DMZ, ça signifie en anglais DeMilitarized Zone, et en français zone démilitarisée. Pour comprendre l'origine de ce terme, il faut s'intéresser à l'histoire, non pas à l'histoire de l'informatique, mais à l'histoire de la Corée et à la Guerre Froide. La zone démilitarisée Coréenne est une zone tampon (représentée par des terres inhabitées et où l'accès est très limité) qui sert de frontière entre la Corée du Nord et la Corée du Sud.

Sur l'image ci-dessous, on peut voir que la zone démilitarisée crée une véritable séparation entre la Corée du Nord et la Corée du Sud.

Source : lefigaro.fr

Quel est le rapport entre la DMZ entre les deux Corée et une DMZ en informatique ? Et bien, si l'on compare la situation des deux Corée avec un réseau informatique, on peut voir quelques similitudes et imaginer que :

  • La Corée du Nord, c'est le réseau Internet (ou le réseau local, comme vous voulez)
  • La Corée du Sud, c'est le réseau local (ou Internet)
  • La zone démilitarisée est une séparation entre les deux qui est là pour des raisons de sécurité

Effectivement, on peut considérer que le réseau local est une zone de confiance, tandis qu'Internet est une zone à risque. Grâce à la DMZ, on va chercher à protéger le réseau local d'Internet, tout en permettant la communication entre les deux zones, mais de façon contrôlée et filtrée.

En informatique, la DMZ est un sous-réseau isolé à la fois du réseau local et de l'internet, c'est en quelque sorte une zone tampon, entre un réseau sécurisé et un réseau non sécurisé. Bien sûr, le réseau non sécurisé c'est Internet, car on sait qu'Internet est dangereux.

Mais, alors, qu'est-ce que l'on en fait de cette DMZ ?

Dans la DMZ, on va venir connecter des serveurs avec des rôles spécifiques. Plus précisément, en DMZ on va connecter des serveurs qui ont besoin d'accéder à Internet et d'être joignables depuis Internet. Par exemple, un serveur Web si vous hébergez un site Internet, ou alors un serveur de messagerie pour l'envoi et la réception d'e-mails. On peut aussi positionner un serveur proxy qui sert de relais pour la navigation à Internet entre les postes de travail et Internet.

Depuis quelques années maintenant, il est très courant d'utiliser un reverse proxy plutôt que d'exposer directement les serveurs, que ce soit les serveurs Web ou les serveurs de messagerie. Ce serveur va gérer les connexions entrantes, en provenance d'Internet, pour les relayer vers le(s) bon(s) serveur(s).

L'objectif étant de ne jamais exposer directement sur Internet les serveurs et postes de travail connectés au réseau local de l'entreprise. Les flux de ces équipements doivent passer par la DMZ, et donc par la zone tampon, afin de contrôler, relayer et filtrer les échanges entre le réseau local et Internet.

L'intérêt de la DMZ, c'est de créer une zone étanche dans laquelle sera contenu un pirate informatique en cas de compromission d'un serveur. En théorie, car cela dépend aussi de la configuration en place et notamment du firewall (pare-feu) car c'est bien lui qui crée la séparation entre les différentes zones : le réseau local (LAN), Internet et la DMZ.

III. Architecture réseau d'une DMZ

Pour mettre en place une zone démilitarisée au sein d'une architecture réseau, vous avez besoin d'un firewall (c'est-à-dire un pare-feu). On peut créer une DMZ avec un seul firewall, mais dans certains cas il y a deux firewalls.

A. DMZ avec un seul pare-feu

Prenons l'exemple le plus courant : la création d'une DMZ avec un seul et unique firewall. Avec cette configuration, il faut imaginer un pare-feu avec trois zones déclarées où chaque zone dispose de sa propre adresse IP. Ainsi, une machine dans le réseau local passera par le pare-feu pour accéder à la DMZ (ou à Internet, selon la politique en place).

Sur le schéma ci-dessous, il est important de préciser que le réseau local et la DMZ ont un adresse IP qui s'appuie sur les classes d'adresses IP privées.

DMZ avec un seul pare-feu
DMZ avec un seul pare-feu

On peut imaginer que le serveur en DMZ soit le serveur de messagerie de l'entreprise. On le positionne en DMZ car il est exposé sur Internet : il doit accéder à Internet pour envoyer les e-mails, mais aussi être joignable depuis Internet pour recevoir les e-mails. De ce fait, il représente un risque en termes de sécurité.

Depuis le réseau, on autorise les machines à contacter le serveur de messagerie, en DMZ, via quelques protocoles et ports seulement : SMTP pour l'envoi des e-mails et IMAP pour la réception des e-mails.

Éventuellement, on peut ajouter le protocole HTTPS pour accéder au Webmail. Par contre, le serveur de messagerie n'est pas autorisé à réaliser un ping vers le réseau local, ni à établir une connexion Bureau à distance ou un transfert de fichiers vers une machine du réseau local, etc. Le pare-feu devra refuser les flux des autres protocoles (ICMP, SSH, RDP, etc.) pour des raisons de sécurité.

Le positionnement du serveur de messagerie permet de créer une politique de sécurité stricte et adaptée au sein du pare-feu.

B. DMZ avec deux pare-feu

Si vous avez un peu plus d'argent, vous pouvez mettre en œuvre une DMZ basée sur deux niveaux de pare-feu. De cette façon, la DMZ est créée grâce à la zone tampon située entre les deux pare-feu.

L'idéal c'est de mettre en place un serveur proxy en DMZ pour que la connexion Internet de tous les équipements du réseau local passe par ce serveur proxy situé en DMZ, ce dernier sera alors un relais. De cette façon, les machines du réseau local ne sont jamais en contact direct avec Internet. Attention, la mise en place d'un proxy est tout à fait possible lorsqu'il n'y a qu'un seul pare-feu.

DMZ avec deux pare-feu
DMZ avec deux pare-feu

Avec deux pare-feu, on peut appliquer la configuration suivante :

  • Le pare-feu n°1 autorise seulement les communications entre Internet et la DMZ
  • Le pare-feu n°2 autorise seulement les communications entre le réseau local et la DMZ

Dans les deux cas, avec des protocoles et des ports spécifiques. Si un attaquant parvient à passe-outre la politique de sécurité du pare-feu n°1 et prendre la main du serveur situé en DMZ, il devra passer une seconde barrière : le pare-feu n°2, afin d'accéder au réseau et aux serveurs connectés directement sur ce segment du réseau.

Dans cet exemple, je montre uniquement le flux lié à la messagerie, mais si vous souhaitez que vos utilisateurs accèdent à Internet en direct (sans passer par votre éventuel proxy), il faudra bien sûr autoriser les protocoles HTTP/HTTPS.

Que ce soit avec un ou deux pare-feu, gardez à l'esprit que l'objectif sera de protéger notre réseau de confiance, à savoir le réseau local, grâce à la zone démilitarisée.

The post Informatique : c’est quoi une DMZ ? first appeared on IT-Connect.

Politique de mot de passe : comment appliquer les bonnes pratiques de l’ANSSI ?

24 novembre 2021 à 10:00

I. Présentation

Dans cet article, je vais vous parler des bonnes pratiques de l'ANSSI en matière de politique de mot de passe, et nous verrons quelles sont les solutions techniques envisageables pour appliquer ces recommandations dans un environnement Active Directory.

Pour rédiger cet article, je me suis appuyé sur le guide publié par l'ANSSI le 08 octobre 2021 et qui s'appelle "Recommandations relatives à l'authentification multifacteur et aux mots de passe - v2.0".

II. Les bonnes pratiques de l'ANSSI sur les mots de passe

Avant de rentrer dans la technique, je souhaitais vous proposer une synthèse des bonnes pratiques de l'ANSSI au sujet des politiques de mot de passe. Ce guide aborde d'autres sujets, comme l'authentification multifacteurs, mais ici, on va se concentrer uniquement sur l'aspect "politique de mot de passe".

Tout d'abord, une politique de mot de passe définit les règles à respecter par un utilisateur lorsqu'il souhaite définir un nouveau mot de passe pour son compte. À cela s'ajoutent des règles de gestion des mots de passe, comme la limite du nombre d'essais avant verrouillage du compte, la gestion de l'historique des mots de passe, etc.

A. Longueur minimale du mot de passe, en nombre de caractères

Pour les mots de passe ne devant pas être mémorisés par l'utilisateur, l'ANSSI recommande une longueur minimale beaucoup plus importante : minimum 20 caractères. Le stockage de ce précieux sésame s'effectuera dans votre gestionnaire de mots de passe.

Pour les mots de passe devant être mémorisés par l'utilisateur, ce qui est le cas du mot de passe Active Directory puisqu'il permet à l'utilisateur d'accéder à sa session Windows, l'ANSSI met à disposition le tableau suivant à la page 28 de son guide :

Source : Guide de l'ANSSI

Le niveau a choisir dépend de la sensibilité du compte concerné. Pour un compte d'un utilisateur lambda, on se situera sur les deux premiers niveaux de sensibilité. Pour les utilisateurs qui ont accès à des ressources sensibles ou des données confidentielles, on définira à minima le niveau de sensibilité "Moyen à fort". Et enfin, pour les administrateurs, la sensibilité sera au maximum, et donc il est recommandé de mettre en place l'authentification multifacteurs en complément. Tout cela pour dire que la longueur minimale à imposer n'est pas une évidence et dépend du niveau de criticité du compte.

Il faut retenir aussi qu'il est bien souvent plus pertinent d'augmenter la longueur de son mot de passe plutôt que de chercher à conserver la longueur tout en le complexifiant. Cela va permettre d'avoir une meilleure entropie sur votre mot de passe, et donc, de le rendre plus robuste, plus fort (voir cet article).

B. Ne pas imposer de longueur maximale pour les mots de passe

Imposer une longueur minimale est une excellente idée, mais à l'inverse imposer une longueur maximale est une mauvaise idée, ou alors elle doit être très élevée (et là pour des questions de sécurité et contrainte vis-à-vis du logiciel en lui-même). Fixer une longueur maximale revient aussi à empêcher l'utilisation de passphrase, appelée aussi "phrase de passe".

C. La complexité des mots de passe

En imposant des contraintes sur les types de caractères qu'un utilisateur doit utiliser pour définir un mot de passe, on définit ce que l'on appelle la règle de complexité des mots de passe. Pour cela, on met à la disposition de l'utilisateur différents jeux de caractères : les chiffres, les lettres A à Z en minuscules, les lettres de A à Z en majuscules, les caractères spéciaux, etc. Plus il y a de jeux de caractères autorisés, plus il y a de combinaisons possibles.

Généralement, pour s'en sortir et respecter cette notion de complexité des mots de passe, les utilisateurs vont remplacer un "a" par un "@", un "o" par un "0", ou encore ajouter un "!" à la fin du mot de passe. C'est un grand classique. On le sait tous, et on a tous fait ça un jour pour inventer un mot de passe.

Dans le cas d'une tentative d'attaque en ligne, c'est-à-dire contre un système actif, cette méthode reste encore efficace à condition que le compte ciblé soit en mesure d'être verrouillé au bout de quelques tentatives en échec. Par contre, dans le cas d'une attaque hors ligne où il est possible d'effectuer du brute force sans limites, il y a de fortes chances pour que le mot de passe soit deviné. En effet, il existe des outils et des dictionnaires capables d'imaginer ces variantes, et donc, de trouver votre mot de passe.

D. Le délai d'expiration des mots de passe

Alors que pendant longtemps, on entendait qu'il était nécessaire d'imposer aux utilisateurs de changer leur mot de passe tous les 6 mois ou une fois par an, aujourd'hui ce n'est plus aussi évident. Quel est l'intérêt de modifier son mot de passe "Bonjour1" par "Bonjour2" ? Si le mot de passe précédent fuite, il y a des chances pour que le suivant soit deviné assez facilement.

L'ANSSI précise que pour les comptes non sensibles, c'est-à-dire les comptes des utilisateurs : "Si la politique de mots de passe exige des mots de passe robustes et que les systèmes permettent son implémentation, alors il est recommandé de ne pas imposer par défaut de délai d’expiration sur les mots de passe des comptes non sensibles comme les comptes utilisateur." [page 30 du guide].

Par contre, pour les comptes avec des privilèges, il est recommandé d'imposer un délai d'expiration compris entre 1 et 3 ans.

E. Contrôler la robustesse des mots de passe

Un mot de passe qui respecte la longueur minimale et les contraintes de complexité, est-il pour autant un mot de passe robuste ? En voilà une bonne question, et c'est un point très intéressant soulevé par l'ANSSI.

Ainsi, il est recommandé de :

  • Vérifier si votre mot de passe a déjà fait l'objet d'une fuite de données.

En fait, si vous définissez un mot de passe qui à première vue semble complexe, mais qu'il est présent dans un dictionnaire qui circule sur Internet ou qui est utilisé par certains outils, alors on peut douter de sa robustesse.

Dans le même esprit, lorsqu'il y a une fuite de données suite à un piratage, on se retrouve avec d'énormes bases de données de mots de passe constituées à partir ces fuites. Si le nouveau mot de passe que vous venez de choisir se situe dans une fuite de données, il vaut mieux le changer immédiatement, car la probabilité qu'il soit trouvé est plus élevée. Par exemple, le site Have I Been Pwned permet de rechercher un mot de passe dans une base regroupant les données d'un ensemble de fuites d'information.

  • Bloquer les suites de caractères ("12345", "azerty", "aaaa", "abcd", etc.)
  • Bloquer l'utilisation d'informations personnelles dans le mot de passe (nom, prénom, date de naissance)
  • Bloquer la réutilisation d'un mot de passe déjà utilisé lors des X derniers mots de passe (gestion de l'historique des mots de passe)

III. Quelles solutions techniques ?

En prenant connaissance des différentes recommandations de l'ANSSI en matière de politique de mot de passe, on se rend compte que d'un point de vue technique, cela ne va pas forcément être évident à mettre en œuvre. Enfin, c'est comme tout, il suffit d'avoir les bons outils alors cela tombe bien, car nous allons en parler de ces solutions potentielles.

Ici, j'évoque le cas des mots de passe stockés dans l'Active Directory et utilisé par les utilisateurs pour une connexion à Windows. En complément ce mot de passe peut être utilisé pour se connecter sur Microsoft 365, s'il y a un outil tel que Azure AD Connect en place au sein de votre infrastructure. Le stockage des mots de passe doit être effectué de façon sécurisée et il convient de ne pas activer le chiffrement réversible au niveau de votre Active Directory, même si c'est demandé par la solution logicielle que vous souhaitez utiliser.

A. Les politiques de mots de passe de l'Active Directory

La première solution qui nous vient à l'esprit, c'est la politique de mots de passe native à l'Active Directory. Il y a deux types de politiques de mots de passe : celle définie par GPO, et celle que l'on définira sous la forme d'objets appelée stratégie de mots de passe affinée.

Si l'on compare les recommandations de l'ANSSI avec les possibilités offertes nativement par l'Active Directory, on voit rapidement qu'on ne pourra pas appliquer toutes les recommandations.

Exemple d'une politique de mot de passe affinée
Exemple d'une politique de mot de passe affinée

Sur des choses basiques comme la longueur minimale ou l'âge maximal du mot de passe, ce sera gérable. Par contre, sur les recommandations plus spécifiques comme le blocage de certaines chaînes de caractères ou la vérification dans les fuites de données, ce ne sera pas possible avec la méthode native de l'Active Directory. Pour la complexité des mots de passe, il est bien possible d'imposer le fait que le mot de passe doive respecter une certaine complexité, mais cette complexité n'est pas ajustable. Dommage.

Voici un récapitulatif :

Même si cette méthode ne remplit pas toutes les cases vis-à-vis des recommandations de l'ANSSI, il vaut mieux mettre en place une stratégie de mot de passe affinée plutôt que de ne rien faire.

B. La solution Password protection for Windows Server Active Directory

Azure AD intègre une fonctionnalité baptisée "Password protection for Windows Server Active Directory". Cette fonctionnalité s'applique aux utilisateurs Cloud, mais aussi aux utilisateurs locaux de l'Active Directory lorsqu'il y a une synchronisation avec Azure AD Connect.

Avec Azure AD Password Protection, vous allez renforcer la sécurité de vos mots de passe locaux puisque vous allez pouvoir bloquer certains termes (et leurs variantes) à partir d'un dictionnaire personnalisé, limité à 1000 entrées. Par exemple, avec l'entrée "it-connect", les mots de passe suivants sont bloqués : "it-connect123", "it-c0nnect14!" ou encore "1t-c0nnect14!". Certaines substitutions ne sont pas prises en compte, car si l'on bloque "securite", on peut définir "S€curite14!" comme mot de passe.

En complément, Microsoft dispose de sa propre liste globale de mots de passe interdits (car trop faibles). J'ignore combien de mots de passe contient cette liste (ce n'est pas précisé) mais certains mots de passe présents dans des fuites de données semblent fonctionner. En tout cas, un mot de passe basique comme "Password123!" est bien bloqué alors qu'il pourrait matcher avec la politique de sécurité. Idem pour "Azerty123!" qui est bien bloqué, par contre "Motdepasse123!" et "123soleil" sont autorisés. J'ai tendance à penser que l'outil de Microsoft analyse surtout les mots anglais et qu'il ne doit pas forcément se référer à une liste externe comme I Have Been Pwned.

En cumulant une politique de mot de passe affinée et la protection Password Protection en complément, on obtient la synthèse suivante :

Cette fonctionnalité est incluse dans certaines licences et vous devez couvrir vos utilisateurs. L'installation est assez simple et s'appuie sur la mise en œuvre d'agents sur vos serveurs locaux. L'outil en tant que tel est peu configurable pour le moment, ce qui est dommage.

Si vous souhaitez en savoir plus sur Password Protection, je vous invite à lire ce tutoriel :

C. La solution Specops Password Policy

En termes de solution payante et proposée par un éditeur tiers, je souhaitais inclure Specops Password Policy (SPP) à cet article. Pourquoi ? Pour une raison simple : je connais ce logiciel et je sais qu'il répond à la majorité des recommandations de l'ANSSI, pour ne pas dire toutes.

Ce logiciel va beaucoup plus loin que la solution native intégrée à l'Active Directory, notamment pour gérer la complexité des mots de passe. En fait, vous pouvez créer des règles très précises pour imposer l'utilisation à minima de X majuscules, X minuscules, X chiffres, etc...

Concernant le blocage des suites de caractères, c'est géré par SPP, car il y a une option pour bloquer les caractères identiques consécutifs, et il est possible de créer des expressions régulières pour empêcher certains patterns.

Pour bloquer la présence des informations personnelles dans le mot de passe (nom, prénom, date de naissance), c'est un peu plus complexe. L'outil intègre une option pour empêcher l'utilisation de l'identifiant dans le mot de passe, ce qui dans de nombreux cas, devrait permettre de bloquer le nom et le prénom puisque c'est souvent utilisé pour construire le login Active Directory de l'utilisateur. Pour la date de naissance, cette option n'est pas prise en charge par l'outil proposé par Specops. Pour cela, il faudrait pouvoir se référer à un attribut de l'Active Directory, pour chaque utilisateur. Néanmoins, la solution SPP intègre la gestion de dictionnaires personnalisés, ce qui vous permet d'importer des dictionnaires existants, ou de créer votre propre dictionnaire : vous pouvez créer un dictionnaire avec toutes les dates de naissance de vos salariés (cela signifie aussi qu'un utilisateur X ne pourra pas utiliser dans son mot de passe la date de naissance d'un utilisateur Y, car le dictionnaire est commun à tous les utilisateurs ciblés par la politique).

Pour ma part, je vous recommande de créer un dictionnaire avec le nom de votre entreprise, car c'est souvent réutilisé dans les mots de passe. Enfin, à partir des mots du dictionnaire l'outil bloquera aussi les variantes (exemple : le mot "itconnect" implique que "itc0nnect" avec un zéro sera bloqué aussi), en prenant compte de nombreuses méthodes de substitution (plus que la solution Microsoft présentée ci-dessus).

Aperçu de Specops Password Policy
Aperçu de Specops Password Policy

La solution de l'éditeur Specops est capable de vérifier si votre mot de passe a été compromis (fuite de données, collecté via les honey pots SpecOps, etc.), en s'appuyant à la fois sur une base locale et sur une base en ligne au travers d'une API. Cette base en ligne est actualisée quotidiennement et elle contient 2,5 milliards de mots de passe. Si c'est le cas, l'utilisateur sera notifié par e-mail/SMS et invité à changer son mot de passe de nouveau. Sur ce point, on est vraiment conforme vis-à-vis des préconisations de l'ANSSI.

Voici un récapitulatif :

Pour découvrir plus en détail ce logiciel, je vous invite à lire mon tutoriel complet au sujet de Specops Password Policy, dans lequel vous pouvez retrouver également une vidéo de démonstration (réalisée par mes soins).

IV. Conclusion

Suite à la lecture de cet article, vous avez connaissance des recommandations de l'ANSSI en matière de politique de mot de passe, et en plus, vous avez quelques pistes à explorer afin de mettre en pratique ces recommandations sur un annuaire Active Directory. En complément de la mise en œuvre de cette politique de mot de passe, il ne faudra pas oublier de configurer le verrouillage des comptes afin de bloquer les attaques Brute Force.

Si vous connaissez d'autres solutions susceptibles de mettre en place une politique de mot de passe qui respecte les best practices de l'ANSSI, n'hésitez pas à poster un commentaire.

The post Politique de mot de passe : comment appliquer les bonnes pratiques de l’ANSSI ? first appeared on IT-Connect.
❌