Aller au contenu

ExécutionJournauxActivité utilisateur

Journaux sudo : traces d'usage de privilèges Linux

Comment sudo enregistre qui a exécuté quoi en root sous Linux : lignes syslog et journal, fichier de log optionnel, sessions enregistrées et règles sudoers.

Emplacement
/var/log/auth.log, /var/log/secure
Prouve
Quel compte a exécuté quelle commande sous quel utilisateur cible, depuis quel terminal et quel répertoire, ainsi que les tentatives échouées
Horodatages
Heure syslog/journal de l'hôte (voir les formats syslog) ; les journaux I/O conservent une chronologie relative par session
Accès
root (ou groupe adm pour auth.log sous Debian/Ubuntu)
Rétention
Suit la rotation d'auth.log/secure et les limites du journal ; journaux I/O jusqu'à suppression
Collecte
UAC, Velociraptor, cp -a, journalctl

Ce que c'est

Le plugin de politique sudoers de sudo journalise chaque requête acceptée ou refusée. Par défaut, il envoie une ligne par événement à syslog, via la facility authpriv lorsqu'elle existe (priorité notice pour les autorisations, alert pour les refus). Ces lignes arrivent dans le journal texte d'authentification et dans le journal. Des réglages optionnels ajoutent un fichier de log dédié, une sortie JSON, le code de sortie, la journalisation des sous-commandes, et l'enregistrement complet des frappes et de l'écran des sessions.

La politique elle-même (/etc/sudoers et ses répertoires d'inclusion) constitue aussi une preuve : un attaquant qui ajoute une règle NOPASSWD a créé une persistance et supprimé la demande de mot de passe qui apparaîtrait sinon comme un événement d'authentification.

Où il se trouve

ÉlémentDebian / UbuntuRHEL / FedoraRemarques
Lignes syslog/var/log/auth.log/var/log/securePlus le journal (SYSLOG_IDENTIFIER=sudo)
Politique/etc/sudoers, /etc/sudoers.d/*identique@includedir/#includedir ; les fichiers contenant . ou se terminant par ~ sont ignorés
Fichier de log optionnelDefaults logfile=... (désactivé par défaut)identiqueN'importe quel chemin, par exemple /var/log/sudo.log
Journaux de session I/O/var/log/sudo-io/identiqueUniquement avec log_input/log_output
Cache d'identifiants/run/sudo/ts/<user>/run/sudo/ts/ ou /var/run/sudo/ts/Vidé au démarrage
État du sermon/var/lib/sudo/lectured/<user>/var/db/sudo/lectured/ ou /var/lib/sudo/lectured/Fichier vide par utilisateur, dépend de la compilation
Enregistrements d'auditUSER_CMD dans audit.logidentiqueQuand sudo est compilé avec le support de l'audit Linux et qu'auditd tourne
Marqueur de première utilisation~/.sudo_as_admin_successful (Ubuntu)aucunCréé au premier sudo réussi

Ce qu'il prouve

  • Le compte appelant, l'utilisateur cible (USER=), le terminal, le répertoire de travail et la ligne de commande complète de chaque commande autorisée.
  • Les refus : user NOT in sudoers, user NOT authorized on host, command not allowed, N incorrect password attempts, a password is required.
  • Le contexte PAM associé : pam_unix(sudo:session): session opened for user root(uid=0) by deploy(uid=1001) et pam_unix(sudo:auth): authentication failure.
  • Avec la journalisation I/O : exactement ce qui a été saisi et affiché, rejouable.
  • Il ne montre pas ce qui s'est passé dans sudo -i, sudo -s ou sudo bash : le journal n'enregistre que le shell. Utilisez pour cela auditd (auid), l'historique du shell, log_subcmds ou les journaux I/O.
  • Un utilisateur root peut modifier ces journaux, et n'importe qui peut injecter des lignes ressemblantes avec logger.

Champs clés

Commande acceptée, format de log sudo :

Sep 20 03:15:30 web-prod-03 sudo:   deploy : TTY=pts/0 ; PWD=/home/deploy ; USER=root ; COMMAND=/usr/bin/bash
Sep 20 03:16:02 web-prod-03 sudo:   deploy : TTY=pts/0 ; PWD=/tmp ; USER=root ; TSID=000001 ; COMMAND=/usr/bin/tar -xf /tmp/x.tar
Sep 20 03:17:44 web-prod-03 sudo:   intern : user NOT in sudoers ; TTY=pts/1 ; PWD=/home/intern ; USER=root ; COMMAND=/usr/bin/id
ChampSignification
utilisateur avant :Nom de connexion de l'utilisateur ayant lancé sudo
motif de refusPrésent uniquement pour les requêtes refusées
TTY=Terminal, ou unknown sans tty (scripts, certaines commandes distantes)
PWD=Répertoire de travail au lancement de sudo
USER= / GROUP=Utilisateur cible et groupe optionnel
CHROOT=Répertoire racine si un chroot a été demandé
TSID=Identifiant du journal I/O, présent uniquement si la journalisation I/O est active
ENV=Variables d'environnement définies sur la ligne de commande
COMMAND=Chemin résolu de la commande et arguments

Les caractères de contrôle sont journalisés en octal précédés d'un # (#011 pour une tabulation), et les espaces dans le chemin de la commande apparaissent sous la forme #040. Avec log_format=json, le fichier de log contient des objets JSON avec le détail complet de l'utilisateur et l'environnement.

Enregistrement d'audit pour la même action (famille RHEL) :

type=USER_CMD msg=audit(1789874130.201:8830): pid=4302 uid=1001 auid=1001 ses=12 msg='cwd="/home/deploy" cmd="/usr/bin/bash" terminal=pts/0 res=success'

cmd et cwd sont encodés en hexadécimal lorsqu'ils contiennent des espaces ; ausearch -i les décode.

Horodatages

Les lignes syslog héritent du format du démon syslog : heure locale traditionnelle sans année avec la configuration par défaut de RHEL, RFC 3339 avec décalage sous Debian 12+ et Ubuntu 24.04 (voir auth.log). La copie du journal porte un horodatage UTC à la microseconde et constitue le point d'ancrage le plus simple. Le fichier de log propre à sudo utilise une date de style Mmm dd HH:MM:SS et n'ajoute l'année qu'avec log_year. Les journaux I/O enregistrent le début de session dans le fichier log/log.json et les délais relatifs dans timing.

Rétention

La copie syslog vit aussi longtemps qu'auth.log/secure (environ quatre générations hebdomadaires par défaut) et la copie du journal aussi longtemps que le permettent ses limites de taille. Les journaux I/O ne sont jamais soumis à rotation par sudo ; l'identifiant de session en base 36 sur six caractères (00/00/01) reboucle à maxseq, après quoi les anciennes sessions sont écrasées. Les fichiers de sermon et ~/.sudo_as_admin_successful persistent jusqu'à leur suppression.

Collecte

E=/mnt/evidence
tar -C "$E" -cpf /cases/2026-017/sudo.tar \
  etc/sudoers etc/sudoers.d var/log/sudo-io var/lib/sudo var/db/sudo 2>/dev/null
journalctl -D "$E/var/log/journal" SYSLOG_IDENTIFIER=sudo -o json --utc > sudo-journal.json
zgrep -h 'sudo:' "$E"/var/log/auth.log* "$E"/var/log/secure* 2>/dev/null > sudo-lines.txt

UAC collecte /var/log, /etc et les horodatages de sermon sudo (artefact sudo_lectured). Sur un système live, sudo -l -U <user> affiche les droits effectifs d'un compte sans rien modifier.

Analyse

# Allowed commands per invoking user
zgrep -h 'COMMAND=' auth.log* | sed -E 's/.*sudo: +([^ ]+) : .*USER=([^ ]+) ; .*COMMAND=(.*)/\1 -> \2 : \3/' | sort | uniq -c
# Failures
zgrep -hE 'sudo:.*(NOT in sudoers|not allowed|incorrect password)' auth.log*
# Replay a recorded session (read-only)
sudoreplay -d /cases/2026-017/var/log/sudo-io -l
sudoreplay -d /cases/2026-017/var/log/sudo-io 000001
# Audit copy
ausearch -if audit.log -m USER_CMD -i

Chaque répertoire de session I/O contient log, log.json, timing, ttyin, ttyout, stdin, stdout et stderr. Plaso récupère les lignes sudo via ses parsers syslog. Linux Log Parser lit dans le navigateur auth.log / secure, syslog, les fichiers du journal, audit.log et wtmp / btmp / lastlog, et les fusionne en une seule chronologie avec les sessions de connexion reconstituées ; rien n'est envoyé.

Conseils d'investigation

  • Examinez chaque fichier de /etc/sudoers.d/ ainsi que son mtime/ctime. De nouvelles entrées NOPASSWD: ALL, ou Defaults !syslog, !log_allowed ou syslog_goodpri=none qui réduisent la journalisation au silence, sont des indicateurs forts.
  • COMMAND=/usr/bin/bash, /bin/su, des éditeurs, find, less, vi ou des interpréteurs signifient que l'activité réelle s'est déroulée dans un processus enfant ; suivez l'auid dans audit.log et l'historique du shell du compte.
  • Un sudo réussi sans demande pam_unix(sudo:auth) préalable est normal dans le délai timestamp_timeout (5 minutes par défaut) ou avec NOPASSWD ; les fichiers de /run/sudo/ts/ n'existent que sur un système live.
  • Le fichier de sermon est créé la première fois que sudo affiche son avertissement avec une demande de mot de passe (par défaut lecture=once). Ses horodatages et le ~/.sudo_as_admin_successful d'Ubuntu donnent une date de première utilisation de sudo par compte, utile pour les comptes récemment créés par un attaquant (voir comptes).
  • Les lignes avec TTY=unknown proviennent de scripts, de cron ou de SSH non interactif ; corrélez avec cron et les lignes sshd.
  • Comparez les copies du journal texte, du journal systemd et de l'audit : un événement sudo présent dans le journal mais absent d'auth.log indique une modification du fichier texte.

Voir aussi