Découvrez notre société Contactez-nous

e-Xpert Solutions Genève

109, chemin du Pont-Du-Centenaire
CH-1228 Plan-les-Ouates / Genève
SUISSE

Tel. : +41 22 727 05 55 Fax : +41 22 727 05 50

e-Xpert Solutions Lausanne

Avenue de Gratta-Paille 20
CH-1018 Lausanne
SUISSE

Tel. : +41 21 802 26 78 Fax : +41 22 727 05 50
Contactez notre support : +41 22 727 05 56
Envoyez votre message

Swiss Security Hackademy

Suivez notre blog bilingue en sécurité informatique !

Retour aux articles

Extraction des IP malicieuses depuis le fichier auth.log d’un serveur linux


Auteur : Gilliek

Date de publication : 6 novembre 2016 - Dernière mise à jour : 11 juillet 2018


Dans cette article, nous présentons une commande shell qui a pour but d’extraire les adresses IP et les noms d’utilisateurs liés à des tentatives manquées de se connecter à un serveur Linux. Dans notre exemple, les logs sont collectés sur une machine Linux tournant sous Ubuntu Server 16.04 LTS. La commande a été développée et testée sur ce même système et elle peut donc varier d’un système à l’autre.

Afin que le résultat de cette commande puisse être directement consommé par une API REST, nous allons la formater en JSON.

Nous allons récupérer ces informations depuis les logs d’authentification qui se trouvent généralement dans /var/log/auth.log. Les logs se trouvent dans /var/log/secure sur CentOS.

Dans notre cas, nous nous intéressons uniquement aux logs provenant du service sshd, vu qu’il s’agit d’un serveur publique accessible uniquement en SSH.

Sans plus attendre, voici ladite commande:

echo “[” > failed_auth.json && zcat -f –stdout auth.log* | grep “Invalid user” | awk ‘{print ” {\”user\”: \”” $8 “\”, \”ip\”: \”” $10 “\”\},”}’ | uniq | sed ‘$ s/,$//’ | tee -a failed_auth.json && echo “]” >> failed_auth.json

Décortiquons-la un peu! La commande commence et se termine par un simple « echo ». Rien de bien particulier ici, nous voulons une liste d’objets JSON en sortie, il nous faut donc mettre le résultat entre crochets carrés. Il nous reste les commandes suivantes: zcat, grep, awk, uniq, sed et tee. Regardons chacune d’entre elles séparément.

*zcat*

zcat(1) fonctionne comme cat(1) mais sur des fichiers compressés en gzip. Les logs auth.log subissent périodiquement des rotations suivies d’une compression en gzip. Afin d’analyser dans la même commande les logs archivés (rotation) ainsi que le log courant non-archivé, nous avons besoin de lui passer l’option « -f » (pour « force »). Faute de quoi, sans ce flag, la commande échouerait. Ce dernier permet en effet de traiter normalement les fichiers non compressés, c’est-à-dire comme le ferait cat(1). Mais pour que cela fonctionne nous devons également activer le flag « –stdout ».

*grep*

grep(1) permet de ne garder que les lignes qui contiennent « Invalid user »,
c’est-à-dire les lignes contenant les tentatives de connexions ratées.

*awk*

awk(1) est une commande très puissante qui permet de manipuler des chaines de caractères. Elle requiert qu’une expression AWK lui soit passée en argument. Nous n’utilisons ici qu’une expression très basique qui se contente d’afficher un objet JSON en passant les références $8 et $10 qui correspondent respectivement aux colonnes 8 et 10 de chaque ligne de log.

*uniq*

uniq(1) permet de filtrer les doublons.

*sed*

sed(1) est assez similaire à awk(1). Elle permet également la manipulation de chaines de caractères. La commande awk(1) que nous avons utilisé ajoute automatiquement une virgule à la fin de chaque ligne. Or la dernière ligne ne doit pas comporter de virgule, sinon notre JSON ne sera pas valide. Par conséquent, nous devons supprimer la toute dernière virgule! Pour ce faire, nous utilisons un ‘$’ au début de l’expression afin de se positionner à la dernière ligne. Puis, à l’aide d’une expression régulière, nous substituons la virgule à la fin de la ligne par rien, ce qui correspond à la supprimer.

*tee*

tee(1) est une commande très simple qui permet de rediriger le contenu lu depuis l’entrée standard (stdin) dans un fichier. L’option « -a » permet d’ajouter le contenu à la suite du fichier de destination plutôt que de remplacer le contenu déjà existant. Nous utilisons donc tee(1) pour envoyer les objets JSON dans notre fichier JSON final.

Voici un exemple de résultat que retourne l’exécution de la commande :

[{“user”: “root1”, “ip”: “197.242.156.22”},
{“user”: “root2”, “ip”: “197.242.156.22”},
{“user”: “root3”, “ip”: “197.242.156.22”},
{“user”: “root4”, “ip”: “197.242.156.22”},
{“user”: “pgsql”, “ip”: “197.242.156.22”},
{“user”: “oracle”, “ip”: “197.242.156.22”},
{“user”: “rootalias”, “ip”: “182.18.170.237”},
{“user”: “admin”, “ip”: “146.0.74.223”},
{“user”: “manager”, “ip”: “146.0.74.223”},
{“user”: “monitor”, “ip”: “146.0.74.223”},
{“user”: “uploader”, “ip”: “146.0.74.223”},
{“user”: “john”, “ip”: “146.0.74.223”},
{“user”: “adm”, “ip”: “146.0.74.223”},
{“user”: “sysadm”, “ip”: “190.151.238.207”}]

On peut ensuite aisément construire une liste noire d’adresses IP ou interroger une API externe pour valider la réputation des adresses. Cela permet également de générer des statistiques sur les noms d’utilisateurs les plus testés par les attaquants.