#!/bin/bash """ CVE-2026-1281/1340 Detection Script for Ivanti EPMM Author: Mehdi - Red Team Consultant Purpose: Rechercher des IOCs de compromission sur les systèmes EPMM """ # Couleurs pour output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Variables LOG_DIR="/var/log/httpd" EPMM_DIR="/mi" TOMCAT_DIR="/mi/tomcat" OUTPUT_FILE="epmm_ioc_scan_$(date +%Y%m%d_%H%M%S).txt" echo "╔═══════════════════════════════════════════════════════════════╗" echo "║ CVE-2026-1281/1340 IOC Detection Script ║" echo "║ Ivanti EPMM Compromise Analysis ║" echo "╚═══════════════════════════════════════════════════════════════╝" echo "" # Fonction de logging log_finding() { local severity=$1 local message=$2 case $severity in "CRITICAL") echo -e "${RED}[!] CRITICAL: ${message}${NC}" | tee -a "$OUTPUT_FILE" ;; "WARNING") echo -e "${YELLOW}[*] WARNING: ${message}${NC}" | tee -a "$OUTPUT_FILE" ;; "INFO") echo -e "${GREEN}[+] INFO: ${message}${NC}" | tee -a "$OUTPUT_FILE" ;; esac } # Vérifier les privilèges root if [ "$EUID" -ne 0 ]; then log_finding "CRITICAL" "Ce script doit être exécuté en tant que root" exit 1 fi log_finding "INFO" "Début de l'analyse - $(date)" # ===================================== # 1. ANALYSE DES LOGS APACHE # ===================================== echo "" echo "=== Analyse des logs Apache HTTPd ===" if [ -f "$LOG_DIR/https-access_log" ]; then log_finding "INFO" "Analyse de $LOG_DIR/https-access_log" # Rechercher les tentatives d'exploitation echo "" | tee -a "$OUTPUT_FILE" echo "--- Requêtes suspectes vers endpoints vulnérables ---" | tee -a "$OUTPUT_FILE" EXPLOIT_ATTEMPTS=$(grep -E '/mifs/c/(aft|app)store/fob/' "$LOG_DIR/https-access_log" | grep " 404 ") if [ ! -z "$EXPLOIT_ATTEMPTS" ]; then log_finding "CRITICAL" "Tentatives d'exploitation détectées dans les logs Apache!" echo "$EXPLOIT_ATTEMPTS" | tee -a "$OUTPUT_FILE" # Compter les tentatives COUNT=$(echo "$EXPLOIT_ATTEMPTS" | wc -l) log_finding "CRITICAL" "Nombre de requêtes suspectes: $COUNT" # Extraire les IPs sources echo "" | tee -a "$OUTPUT_FILE" echo "--- IPs sources des attaquants ---" | tee -a "$OUTPUT_FILE" echo "$EXPLOIT_ATTEMPTS" | awk '{print $1}' | sort -u | tee -a "$OUTPUT_FILE" else log_finding "INFO" "Aucune tentative d'exploitation évidente détectée" fi # Rechercher des commandes bash dans les logs echo "" | tee -a "$OUTPUT_FILE" echo "--- Requêtes contenant des commandes bash ---" | tee -a "$OUTPUT_FILE" BASH_COMMANDS=$(grep -E '/mifs/c/(aft|app)store/fob/' "$LOG_DIR/https-access_log" | grep -E '(\`|sleep|wget|curl|bash|sh|nc|ncat|id|whoami|uname)') if [ ! -z "$BASH_COMMANDS" ]; then log_finding "CRITICAL" "Commandes bash détectées dans les requêtes HTTP!" echo "$BASH_COMMANDS" | tee -a "$OUTPUT_FILE" fi # Rechercher gPath et theValue (marqueurs d'exploitation) ARITHMETIC_EXPANSION=$(grep -E "gPath\[|theValue" "$LOG_DIR/https-access_log") if [ ! -z "$ARITHMETIC_EXPANSION" ]; then log_finding "CRITICAL" "Marqueurs d'exploitation par arithmetic expansion détectés!" echo "$ARITHMETIC_EXPANSION" | tee -a "$OUTPUT_FILE" fi else log_finding "WARNING" "Fichier de log Apache introuvable: $LOG_DIR/https-access_log" fi # ===================================== # 2. RECHERCHE DE WEBSHELLS # ===================================== echo "" echo "=== Recherche de webshells ===" # Pages d'erreur JSP modifiées ERROR_PAGES=("401.jsp" "404.jsp" "500.jsp" "403.jsp") for page in "${ERROR_PAGES[@]}"; do FOUND=$(find "$TOMCAT_DIR" -name "$page" -type f) if [ ! -z "$FOUND" ]; then while IFS= read -r file; do # Vérifier la date de modification récente (30 derniers jours) if [ $(find "$file" -mtime -30 2>/dev/null | wc -l) -gt 0 ]; then log_finding "CRITICAL" "Page d'erreur modifiée récemment: $file" # Rechercher des patterns de webshell if grep -q -E "(Runtime\.getRuntime\(\)\.exec|ProcessBuilder|cmd|request\.getParameter)" "$file" 2>/dev/null; then log_finding "CRITICAL" "Webshell détecté dans: $file" echo "Contenu suspect:" | tee -a "$OUTPUT_FILE" grep -n -E "(Runtime\.getRuntime\(\)\.exec|ProcessBuilder|cmd|request\.getParameter)" "$file" | tee -a "$OUTPUT_FILE" fi fi done <<< "$FOUND" fi done # Rechercher tous les JSP récents echo "" | tee -a "$OUTPUT_FILE" echo "--- Fichiers JSP créés dans les 30 derniers jours ---" | tee -a "$OUTPUT_FILE" RECENT_JSP=$(find "$EPMM_DIR" -name "*.jsp" -type f -mtime -30 2>/dev/null) if [ ! -z "$RECENT_JSP" ]; then log_finding "WARNING" "Fichiers JSP récents trouvés:" echo "$RECENT_JSP" | tee -a "$OUTPUT_FILE" fi # Rechercher fichiers WAR/JAR suspects echo "" | tee -a "$OUTPUT_FILE" echo "--- Fichiers WAR/JAR créés dans les 30 derniers jours ---" | tee -a "$OUTPUT_FILE" RECENT_WAR_JAR=$(find "$TOMCAT_DIR/webapps" -type f \( -name "*.war" -o -name "*.jar" \) -mtime -30 2>/dev/null) if [ ! -z "$RECENT_WAR_JAR" ]; then log_finding "WARNING" "Fichiers WAR/JAR récents trouvés:" echo "$RECENT_WAR_JAR" | tee -a "$OUTPUT_FILE" fi # ===================================== # 3. RECHERCHE DE BACKDOORS ET PERSISTENCE # ===================================== echo "" echo "=== Recherche de backdoors et persistence ===" # Scripts shell suspects echo "" | tee -a "$OUTPUT_FILE" echo "--- Scripts shell récents dans /tmp et /var/tmp ---" | tee -a "$OUTPUT_FILE" SUSPICIOUS_SCRIPTS=$(find /tmp /var/tmp -type f \( -name "*.sh" -o -name "*.bash" \) -mtime -30 2>/dev/null) if [ ! -z "$SUSPICIOUS_SCRIPTS" ]; then log_finding "WARNING" "Scripts shell suspects trouvés:" echo "$SUSPICIOUS_SCRIPTS" | tee -a "$OUTPUT_FILE" fi # Cron jobs modifiés echo "" | tee -a "$OUTPUT_FILE" echo "--- Cron jobs modifiés récemment ---" | tee -a "$OUTPUT_FILE" RECENT_CRON=$(find /etc/cron* /var/spool/cron -type f -mtime -30 2>/dev/null) if [ ! -z "$RECENT_CRON" ]; then log_finding "WARNING" "Cron jobs modifiés:" echo "$RECENT_CRON" | tee -a "$OUTPUT_FILE" fi # Comptes utilisateurs créés récemment echo "" | tee -a "$OUTPUT_FILE" echo "--- Comptes utilisateurs créés dans les 30 derniers jours ---" | tee -a "$OUTPUT_FILE" # Date il y a 30 jours THIRTY_DAYS_AGO=$(date -d "30 days ago" +%Y-%m-%d 2>/dev/null || date -v-30d +%Y-%m-%d) awk -F: -v date="$THIRTY_DAYS_AGO" '$3 >= 1000 {print $1}' /etc/passwd | while read user; do # Vérifier la date de création via chage (si disponible) if command -v chage &> /dev/null; then CREATED=$(chage -l "$user" 2>/dev/null | grep "Last password change" | cut -d: -f2) if [ ! -z "$CREATED" ]; then log_finding "WARNING" "Utilisateur récent détecté: $user (créé: $CREATED)" fi fi done | tee -a "$OUTPUT_FILE" # Clés SSH ajoutées echo "" | tee -a "$OUTPUT_FILE" echo "--- Clés SSH modifiées récemment ---" | tee -a "$OUTPUT_FILE" RECENT_SSH_KEYS=$(find /root/.ssh /home/*/.ssh -name "authorized_keys" -mtime -30 2>/dev/null) if [ ! -z "$RECENT_SSH_KEYS" ]; then log_finding "WARNING" "Fichiers authorized_keys modifiés:" echo "$RECENT_SSH_KEYS" | tee -a "$OUTPUT_FILE" fi # ===================================== # 4. ANALYSE DES CONNEXIONS RÉSEAU # ===================================== echo "" echo "=== Analyse des connexions réseau ===" # Connexions établies suspectes echo "" | tee -a "$OUTPUT_FILE" echo "--- Connexions réseau sortantes actives ---" | tee -a "$OUTPUT_FILE" ESTABLISHED_CONNECTIONS=$(netstat -antp 2>/dev/null | grep ESTABLISHED | grep -v "127.0.0.1" | grep -v "::1") if [ ! -z "$ESTABLISHED_CONNECTIONS" ]; then log_finding "INFO" "Connexions établies:" echo "$ESTABLISHED_CONNECTIONS" | tee -a "$OUTPUT_FILE" fi # Processus suspects avec connexions réseau echo "" | tee -a "$OUTPUT_FILE" echo "--- Processus bash avec connexions réseau ---" | tee -a "$OUTPUT_FILE" BASH_NETWORK=$(lsof -i -n | grep bash) if [ ! -z "$BASH_NETWORK" ]; then log_finding "CRITICAL" "Processus bash avec connexions réseau détectés (possible reverse shell)!" echo "$BASH_NETWORK" | tee -a "$OUTPUT_FILE" fi # ===================================== # 5. ANALYSE DES PROCESSUS # ===================================== echo "" echo "=== Analyse des processus suspects ===" # Processus avec commandes bash suspectes SUSPICIOUS_PROCS=$(ps aux | grep -E "(nc|ncat|bash -i|/dev/tcp|bash -c)" | grep -v grep) if [ ! -z "$SUSPICIOUS_PROCS" ]; then log_finding "CRITICAL" "Processus suspects détectés:" echo "$SUSPICIOUS_PROCS" | tee -a "$OUTPUT_FILE" fi # ===================================== # 6. VÉRIFICATION DES CORRECTIFS # ===================================== echo "" echo "=== Vérification des correctifs appliqués ===" # Vérifier si les RPM de sécurité sont installés RPM_PATCH=$(rpm -qa | grep "ivanti-security-update-1761642") if [ ! -z "$RPM_PATCH" ]; then log_finding "INFO" "Correctif de sécurité détecté: $RPM_PATCH" else log_finding "CRITICAL" "Aucun correctif de sécurité détecté! Système potentiellement vulnérable!" fi # Vérifier les classes Java patchées if [ -f "/mi/bin/AppStoreUrlMapper.class" ] && [ -f "/mi/bin/AFTUrlMapper.class" ]; then log_finding "INFO" "Classes Java patchées présentes" else log_finding "WARNING" "Classes Java patchées absentes" fi # ===================================== # 7. RÉSUMÉ # ===================================== echo "" echo "╔═══════════════════════════════════════════════════════════════╗" echo "║ RÉSUMÉ DE L'ANALYSE ║" echo "╚═══════════════════════════════════════════════════════════════╝" echo "" log_finding "INFO" "Analyse terminée - $(date)" log_finding "INFO" "Rapport complet enregistré dans: $OUTPUT_FILE" echo "" echo "Actions recommandées si compromission détectée:" echo "1. Isoler immédiatement le système EPMM du réseau" echo "2. Créer un snapshot/backup du disque pour analyse forensique" echo "3. Contacter votre CSIRT/SOC" echo "4. Consulter: https://www.cert.ssi.gouv.fr/alerte/CERTFR-2026-ALE-001/" echo "" # Créer un tarball avec les preuves EVIDENCE_DIR="epmm_evidence_$(date +%Y%m%d_%H%M%S)" mkdir -p "$EVIDENCE_DIR" # Copier les logs pertinents if [ -f "$LOG_DIR/https-access_log" ]; then cp "$LOG_DIR/https-access_log" "$EVIDENCE_DIR/" 2>/dev/null fi # Copier la liste des fichiers récents find "$EPMM_DIR" -mtime -30 -ls > "$EVIDENCE_DIR/recent_files.txt" 2>/dev/null # Créer l'archive tar -czf "${EVIDENCE_DIR}.tar.gz" "$EVIDENCE_DIR" "$OUTPUT_FILE" 2>/dev/null rm -rf "$EVIDENCE_DIR" log_finding "INFO" "Archive de preuves créée: ${EVIDENCE_DIR}.tar.gz" echo "" echo "Analyse terminée."