#!/bin/bash
# ============================================================
# monitor_sites.sh — Monitoring sécurité WordPress / Citronze
# Cron : toutes les 30 min via panel OVH
# Alerte email si fichiers suspects détectés
# ============================================================

# --- CONFIG ---
HOSTING_ROOT="/homez.432/citronze/www/hosting"
REPORT_DIR="/homez.432/citronze/scan_reports"
ALERT_TO="miran@citronzebre.fr"
ALERT_FROM="nepasrepondre@citronzebre.fr"
SMTP_HOST="ssl0.ovh.net"
SMTP_PORT=465
SMTP_PASS="HtdW8Lb94Ucy8R7g5Xd2w"
HOURS_LOOKBACK=1          # Fichiers modifiés dans la dernière heure
MAX_REPORT_AGE_DAYS=30    # Purge des vieux rapports

# Patterns suspects dans le contenu PHP
SUSPICIOUS_PATTERNS=(
    'eval\s*('
    'base64_decode\s*('
    'str_rot13\s*('
    'gzinflate\s*('
    'preg_replace.*\/e'
    '\$_POST\[.*\]\s*\('
    '\$_GET\[.*\]\s*\('
    '\$_REQUEST\[.*\]\s*\('
    'system\s*(\$'
    'exec\s*(\$'
    'passthru\s*(\$'
    'shell_exec\s*(\$'
    'assert\s*(\$'
    'FilesMan'
    'r57shell'
    'c99shell'
    'WSO\s'
)

# Dossiers à surveiller dans chaque site
WATCH_DIRS=(
    "wp-content/mu-plugins"
    "wp-content"
    "wp-includes"
    "."
)

# Extensions surveillées
WATCH_EXT="-name '*.php' -o -name '*.phtml' -o -name '*.php5' -o -name '*.php7'"

# Sites non WP à ignorer
IGNORE_SITES="audreymaurel|AVEVE|imprimerieblachon|OSTEOBBOUDIN|ssl"

# --- INIT ---
mkdir -p "$REPORT_DIR"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DATE_HUMAN=$(date '+%d/%m/%Y %H:%M')
REPORT_FILE="$REPORT_DIR/monitor_${TIMESTAMP}.txt"
ALERT_NEEDED=false
TOTAL_SUSPECTS=0

# Purge vieux rapports
find "$REPORT_DIR" -name "monitor_*.txt" -mtime +$MAX_REPORT_AGE_DAYS -delete 2>/dev/null

echo "========================================" >> "$REPORT_FILE"
echo " MONITORING SÉCURITÉ — $DATE_HUMAN" >> "$REPORT_FILE"
echo " Lookback : ${HOURS_LOOKBACK}h" >> "$REPORT_FILE"
echo "========================================" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"

# --- SCAN PAR SITE ---
for SITE_PATH in "$HOSTING_ROOT"/*/; do
    SITE=$(basename "$SITE_PATH")

    # Ignorer sites non WP
    if echo "$SITE" | grep -qE "^($IGNORE_SITES)$"; then
        continue
    fi

    SITE_SUSPECTS=0
    SITE_REPORT=""

    for WATCH_DIR in "${WATCH_DIRS[@]}"; do
        TARGET="$SITE_PATH$WATCH_DIR"
        [ -d "$TARGET" ] || continue

        # Profondeur : racine wp-content = 1, mu-plugins = récursif
        if [ "$WATCH_DIR" = "." ] || [ "$WATCH_DIR" = "wp-includes" ]; then
            DEPTH="-maxdepth 1"
        elif [ "$WATCH_DIR" = "wp-content" ]; then
            DEPTH="-maxdepth 1"
        else
            DEPTH=""
        fi

        # Trouver fichiers PHP modifiés récemment
        while IFS= read -r -d '' FILE; do
            # Vérifier contenu suspect
            for PATTERN in "${SUSPICIOUS_PATTERNS[@]}"; do
                if grep -qP "$PATTERN" "$FILE" 2>/dev/null; then
                    SITE_SUSPECTS=$((SITE_SUSPECTS + 1))
                    TOTAL_SUSPECTS=$((TOTAL_SUSPECTS + 1))
                    ALERT_NEEDED=true
                    MOD_TIME=$(stat -c '%y' "$FILE" 2>/dev/null | cut -d'.' -f1)
                    FILE_SIZE=$(stat -c '%s' "$FILE" 2>/dev/null)
                    SITE_REPORT+="  ⚠ ${FILE#$HOSTING_ROOT/}\n"
                    SITE_REPORT+="    Pattern : $PATTERN\n"
                    SITE_REPORT+="    Modifié : $MOD_TIME | Taille : ${FILE_SIZE}o\n"
                    # Extraire ligne suspecte (max 200 chars)
                    SUSPECT_LINE=$(grep -oP ".{0,20}${PATTERN}.{0,50}" "$FILE" 2>/dev/null | head -1 | cut -c1-200)
                    [ -n "$SUSPECT_LINE" ] && SITE_REPORT+="    Extrait : $SUSPECT_LINE\n"
                    break  # Un pattern suffit par fichier
                fi
            done
        done < <(find "$TARGET" $DEPTH -mmin -$((HOURS_LOOKBACK * 60)) \( -name "*.php" -o -name "*.phtml" -o -name "*.php5" \) -type f -print0 2>/dev/null)
    done

    # Vérifier aussi mu-plugins (toujours, pas juste récents — zone critique)
    MU_DIR="$SITE_PATH/wp-content/mu-plugins"
    if [ -d "$MU_DIR" ]; then
        MU_COUNT=$(find "$MU_DIR" -name "*.php" -type f 2>/dev/null | wc -l)
        if [ "$MU_COUNT" -gt 2 ]; then
            ALERT_NEEDED=true
            SITE_REPORT+="  🔴 mu-plugins anormal : $MU_COUNT fichiers PHP\n"
            find "$MU_DIR" -name "*.php" -type f 2>/dev/null | while read f; do
                SITE_REPORT+="     - ${f#$HOSTING_ROOT/}\n"
            done
        fi
    fi

    # Vérifier checksums core WP (fichiers ajoutés/modifiés dans wp-admin et wp-includes)
    WP_CLI="/homez.432/citronze/bin/wp"
    CHECKSUM_OUT=$("$WP_CLI" --path="$SITE_PATH" --allow-root core verify-checksums 2>&1 \
        | grep "should not exist" \
        | grep -v "\.png\|\.DS_Store")
    if [ -n "$CHECKSUM_OUT" ]; then
        ALERT_NEEDED=true
        SITE_REPORT+="  🔴 Fichiers core suspects (verify-checksums) :\n"
        while IFS= read -r line; do
            SITE_REPORT+="     $line\n"
        done <<< "$CHECKSUM_OUT"
    fi

    # Détecter nouveaux admins (comparaison avec référence)
    REFERENCE="$REPORT_DIR/admins_reference.txt"
    if [ -f "$REFERENCE" ]; then
        CURRENT_ADMINS=$("$WP_CLI" --path="$SITE_PATH" --allow-root user list --role=administrator --fields=user_login,user_email --format=csv 2>/dev/null | tail -n +2)
        # Extraire les logins de référence pour ce site (format CSV)
        REF_LOGINS=$(awk "/^=== ${SITE} ===$/{found=1; next} found && /^===/{ exit } found{ print }" "$REFERENCE" | cut -d',' -f1 | tr -d '"')
        while IFS=',' read -r login email; do
            [ -z "$login" ] && continue
            login=$(echo "$login" | tr -d '"')
            if ! echo "$REF_LOGINS" | grep -qx "$login"; then
                ALERT_NEEDED=true
                SITE_REPORT+="  🔴 NOUVEL ADMIN DÉTECTÉ : $login ($email)\n"
            fi
        done <<< "$CURRENT_ADMINS"
    fi

    # Écrire dans rapport si suspects
    if [ -n "$SITE_REPORT" ]; then
        echo "--- $SITE ($SITE_SUSPECTS suspect(s)) ---" >> "$REPORT_FILE"
        echo -e "$SITE_REPORT" >> "$REPORT_FILE"
    fi
done

# --- FOOTER RAPPORT ---
echo "" >> "$REPORT_FILE"
echo "========================================" >> "$REPORT_FILE"
echo " TOTAL SUSPECTS : $TOTAL_SUSPECTS" >> "$REPORT_FILE"
echo " Rapport : $REPORT_FILE" >> "$REPORT_FILE"
echo "========================================" >> "$REPORT_FILE"

# --- SORTIE STDOUT (OVH envoie par mail si non vide) ---
if [ "$ALERT_NEEDED" = true ]; then
    echo "🚨 ALERTE SÉCURITÉ CITRONZE — $DATE_HUMAN"
    echo "Suspects détectés : $TOTAL_SUSPECTS"
    echo ""
    cat "$REPORT_FILE"
    echo "[$(date '+%d/%m/%Y %H:%M')] ALERTE — $TOTAL_SUSPECTS suspects" >> "$REPORT_DIR/monitor.log"
else
    echo "[$(date '+%d/%m/%Y %H:%M')] OK — aucun suspect" >> "$REPORT_DIR/monitor.log"
fi

exit 0
