← Retour aux tutoriels

Drupal — détection d'exploitation dans les logs (SQLi, XSS, webshell)

Motifs de détection d'exploitation Drupal dans les logs serveur et applicatifs : signatures SQLi/XSS, fichiers PHP suspects dans files/, et surveillance d'intégrité du code.

Méthodes de détection d’exploitation d’une instance Drupal à partir des logs serveur, des journaux applicatifs et de la surveillance d’intégrité.

Menace

Une exploitation réussie de Drupal (SQLi via SA-CORE-2026-004, XSS via SA-CORE-2026-001, ou exécution de code par chaîne de désérialisation SA-CORE-2026-002) se traduit généralement par le dépôt d’un webshell dans sites/*/files/, la création de comptes administrateurs, ou l’altération de fichiers de code. La détection repose sur la corrélation de signatures de requêtes et de surveillance d’intégrité.

Détection

Signatures d’injection SQL dans les logs d’accès (motifs encodés et bruts) :

grep -aiE "union[[:space:]%+]+select|information_schema|pg_sleep|sleep\(|extractvalue|updatexml|0x[0-9a-f]{6,}" /var/log/nginx/access.log
grep -aiE "(%27|')[[:space:]%+]*(or|and)[[:space:]%+]*(%27|')?[0-9=]" /var/log/nginx/access.log

Signatures XSS et tentatives d’injection de balises :

grep -aiE "%3Cscript|<script|javascript:|onerror%3D|onload%3D|%3Cimg" /var/log/nginx/access.log

Recherche de fichiers PHP déposés dans le répertoire files, qui ne doit jamais contenir de code exécutable :

find /var/www/drupal.exemple.fr/web/sites/*/files -type f -name '*.php' -o -name '*.phtml' -o -name '*.php5' 2>/dev/null
grep -rlE "eval\(|base64_decode\(|gzinflate\(|assert\(|system\(|passthru\(|\\\$_(POST|GET|REQUEST)\[" /var/www/drupal.exemple.fr/web/sites/*/files 2>/dev/null

Détection de comptes administrateurs récents et de modifications de permissions de rôles :

drush sql:query "SELECT u.uid, u.name, FROM_UNIXTIME(u.created) FROM users_field_data u JOIN user__roles r ON u.uid=r.entity_id WHERE r.roles_target_id='administrator' ORDER BY u.created DESC LIMIT 10;"

Requêtes lentes ou erreurs PDO indiquant une injection en cours :

grep -aiE "PDOException|SQLSTATE\[42|DatabaseExceptionWrapper" /var/log/php/drupal-error.log | tail -50

Mitigation

Surveillance d’intégrité du code par empreinte de référence, comparée à chaque exécution :

find /var/www/drupal.exemple.fr/web -type f \( -name '*.php' -o -name '*.module' -o -name '*.inc' \) \
  -not -path '*/sites/*/files/*' -exec sha256sum {} + | sort -k2 > /var/lib/drupal-integrity/baseline.sha256
sha256sum -c /var/lib/drupal-integrity/baseline.sha256 2>&1 | grep -v ': OK$'

Comparaison directe avec la distribution Composer officielle, plus fiable qu’une baseline locale potentiellement déjà compromise :

cd /var/www/drupal.exemple.fr
git status --porcelain web/core web/modules/contrib | grep -vE '^\?\? (web/sites/default/files|web/sites/.*/files)'
composer install --dry-run 2>&1 | grep -i 'modif'

Blocage immédiat de l’exécution PHP dans files/ au niveau serveur (défense préventive) :

location ~ ^/sites/[^/]+/files/.*\.(php|phtml|php5|pl|py)$ {
    deny all;
    return 403;
}

Vérification

Après nettoyage, confirmation de l’absence de fichier PHP dans files/ et d’intégrité du code :

find /var/www/drupal.exemple.fr/web/sites/*/files -name '*.php' | wc -l
git -C /var/www/drupal.exemple.fr status --porcelain web/core | wc -l

Le résultat attendu est 0 dans les deux cas. La revue des comptes administrateurs doit confirmer l’absence de compte non légitime, et drush pm:security ne doit signaler aucune vulnérabilité résiduelle.

Vous avez un projet sur ces sujets ?

Nous contacter →