#!/usr/bin/env bash # # degrade-security.sh # =================== # But pédagogique : dégrade VOLONTAIREMENT la configuration d'une VM # Debian 12 fraîchement installée afin de générer des alertes Lynis # claires, faciles à expliquer puis à corriger. # # /!\ A N'UTILISER QUE SUR UNE VM JETABLE / DE DEMO, ISOLEE DU RESEAU. # /!\ Certaines options ouvrent réellement la machine (root SSH, # mots de passe vides autorisés, etc.). # # Le script : # 1. sauvegarde chaque fichier modifié dans /root/lynis-demo-backups// # 2. journalise chaque action dans CHANGELOG.txt # 3. génère un restore.sh pour tout remettre en l'état # 4. écrit la liste des chemins touchés dans FICHIERS-MODIFIES.txt # set -euo pipefail # ---------------------------------------------------------------------- # Garde-fous # ---------------------------------------------------------------------- if [[ ${EUID} -ne 0 ]]; then echo "Ce script doit être lancé en root (sudo)." >&2 exit 1 fi TS="$(date +%Y%m%d-%H%M%S)" BACKUP_DIR="/root/lynis-demo-backups/${TS}" CHANGELOG="${BACKUP_DIR}/CHANGELOG.txt" RESTORE="${BACKUP_DIR}/restore.sh" MODIFIED="${BACKUP_DIR}/FICHIERS-MODIFIES.txt" mkdir -p "${BACKUP_DIR}" log() { echo "[$(date +%H:%M:%S)] $*" | tee -a "${CHANGELOG}"; } # Sauvegarde un fichier et inscrit sa commande de restauration. # - fichier existant -> restauré par copie (contenu + droits préservés) # - fichier absent -> supprimé à la restauration backup_file() { local f="$1" if [[ -e "${f}" ]]; then local dest="${BACKUP_DIR}/files${f}" mkdir -p "$(dirname "${dest}")" cp -a "${f}" "${dest}" echo "cp -a -- '${dest}' '${f}'" >> "${RESTORE}" log "Sauvegarde : ${f}" else echo "rm -f -- '${f}'" >> "${RESTORE}" log "Fichier neuf : ${f} (sera supprimé à la restauration)" fi echo "${f}" >> "${MODIFIED}" } init_restore() { cat > "${RESTORE}" <<'EOF' #!/usr/bin/env bash # Script de restauration généré automatiquement par degrade-security.sh set -euo pipefail [[ ${EUID} -ne 0 ]] && { echo "Lancez en root." >&2; exit 1; } echo "Restauration de la configuration d'origine..." EOF chmod +x "${RESTORE}" } init_restore : > "${MODIFIED}" log "=== Début de la dégradation - sauvegardes : ${BACKUP_DIR} ===" # ---------------------------------------------------------------------- # 1. SSH : ouverture large du démon (Lynis : SSH-7408) # ---------------------------------------------------------------------- SSHD_DROPIN="/etc/ssh/sshd_config.d/00-lynis-demo-insecure.conf" backup_file "${SSHD_DROPIN}" cat > "${SSHD_DROPIN}" <<'EOF' # DEMO Lynis - configuration SSH volontairement NON sécurisée PermitRootLogin yes PasswordAuthentication yes PermitEmptyPasswords yes X11Forwarding yes MaxAuthTries 10 LoginGraceTime 120 AllowTcpForwarding yes ClientAliveInterval 0 EOF log "SSH : drop-in non sécurisé créé" if sshd -t 2>/dev/null; then systemctl reload ssh 2>/dev/null || systemctl reload sshd 2>/dev/null || true echo "systemctl reload ssh 2>/dev/null || systemctl reload sshd 2>/dev/null || true" >> "${RESTORE}" log "SSH : service rechargé" else log "SSH : ATTENTION, test de config échoué -> non rechargé" fi # ---------------------------------------------------------------------- # 2. login.defs : umask trop permissif (Lynis : AUTH-9328) # ---------------------------------------------------------------------- LOGIN_DEFS="/etc/login.defs" backup_file "${LOGIN_DEFS}" sed -i -E 's/^(\s*UMASK\s+).*/\1000/' "${LOGIN_DEFS}" grep -qE '^\s*UMASK\s+' "${LOGIN_DEFS}" || echo "UMASK 000" >> "${LOGIN_DEFS}" log "login.defs : UMASK fixé à 000 (recommandé : 027)" # ---------------------------------------------------------------------- # 3. Paramètres noyau non durcis (Lynis : KRNL-6000) # ---------------------------------------------------------------------- SYSCTL_DROPIN="/etc/sysctl.d/99-lynis-demo-insecure.conf" backup_file "${SYSCTL_DROPIN}" cat > "${SYSCTL_DROPIN}" <<'EOF' # DEMO Lynis - paramètres noyau volontairement NON durcis net.ipv4.ip_forward = 1 net.ipv4.conf.all.accept_redirects = 1 net.ipv4.conf.all.send_redirects = 1 net.ipv4.conf.all.accept_source_route = 1 net.ipv4.conf.all.log_martians = 0 net.ipv4.conf.default.accept_redirects = 1 net.ipv6.conf.all.accept_redirects = 1 kernel.sysrq = 1 kernel.dmesg_restrict = 0 kernel.kptr_restrict = 0 fs.suid_dumpable = 2 EOF sysctl -p "${SYSCTL_DROPIN}" >/dev/null 2>&1 || true log "sysctl : drop-in non durci appliqué" # Restauration : on supprime le fichier (backup_file) ET on réapplique des valeurs saines cat >> "${RESTORE}" <<'EOF' for kv in \ "net.ipv4.ip_forward=0" \ "net.ipv4.conf.all.accept_redirects=0" \ "net.ipv4.conf.all.send_redirects=0" \ "net.ipv4.conf.all.accept_source_route=0" \ "net.ipv4.conf.all.log_martians=1" \ "net.ipv4.conf.default.accept_redirects=0" \ "net.ipv6.conf.all.accept_redirects=0" \ "kernel.sysrq=0" \ "kernel.dmesg_restrict=1" \ "kernel.kptr_restrict=2" \ "fs.suid_dumpable=0" ; do sysctl -w "$kv" >/dev/null 2>&1 || true done sysctl --system >/dev/null 2>&1 || true EOF # ---------------------------------------------------------------------- # 4. Bannières légales absentes (Lynis : BANN-7126 / BANN-7130) # ---------------------------------------------------------------------- backup_file /etc/issue backup_file /etc/issue.net : > /etc/issue : > /etc/issue.net log "Bannières : /etc/issue et /etc/issue.net vidées" # ---------------------------------------------------------------------- # 5. Permissions dangereuses (Lynis : section File Permissions) # ---------------------------------------------------------------------- # 5a. /etc/crontab en 0777 backup_file /etc/crontab chmod 0777 /etc/crontab log "Permissions : /etc/crontab en 0777 (attendu : 0644)" # 5b. fichier monde-inscriptible dans /etc WW_FILE="/etc/lynis-demo-world-writable.conf" backup_file "${WW_FILE}" echo "# fichier de demo" > "${WW_FILE}" chmod 0666 "${WW_FILE}" log "Permissions : ${WW_FILE} créé en 0666" # 5c. répertoire 0777 sans sticky bit WW_DIR="/opt/lynis-demo-shared" mkdir -p "${WW_DIR}" chmod 0777 "${WW_DIR}" echo "rm -rf -- '${WW_DIR}'" >> "${RESTORE}" echo "${WW_DIR}" >> "${MODIFIED}" log "Permissions : ${WW_DIR} créé en 0777 (sans sticky bit)" # ---------------------------------------------------------------------- # 6. (OPTIONNEL) Désactivation d'AppArmor (Lynis : MACF-6208) # Décommentez le bloc ci-dessous SI vous voulez aussi cet écart. # Effet pleinement visible APRÈS un redémarrage de la VM. # ---------------------------------------------------------------------- # if systemctl is-enabled apparmor >/dev/null 2>&1; then # systemctl disable --now apparmor >/dev/null 2>&1 || true # echo "systemctl enable --now apparmor >/dev/null 2>&1 || true" >> "${RESTORE}" # echo "service:apparmor" >> "${MODIFIED}" # log "AppArmor : désactivé (effet complet après reboot)" # fi # ---------------------------------------------------------------------- # Fin # ---------------------------------------------------------------------- echo 'echo "Restauration terminée. Un reboot est conseillé pour les paramètres noyau."' >> "${RESTORE}" log "=== Dégradation terminée ===" echo echo "------------------------------------------------------------------" echo " Fichiers / éléments modifiés :" sed 's/^/ - /' "${MODIFIED}" echo "------------------------------------------------------------------" echo " Journal complet : ${CHANGELOG}" echo " Pour analyser : sudo lynis audit system" echo " Pour tout annuler : sudo ${RESTORE}" echo "------------------------------------------------------------------"