Un site WordPress infecté ne ressemble pas toujours à un désastre immédiat. Souvent, l’infection commence comme un détail technique, puis s’étend en coulisse: un utilisateur apparaît, un fichier “bizarre” se glisse dans un dossier inutilisé, un appel vers un script externe se met à revenir dans les logs. Le plus dur, quand on prend en charge un incident, n’est pas seulement de nettoyer, c’est de comprendre comment ça a commencé.
Identifier le point d’entrée initial, c’est ce qui évite la récidive. On peut désinfecter le thème ou supprimer un webshell, et pourtant l’attaque revient parce qu’on a raté la vraie porte d’entrée: un plugin compromis, un compte admin récupéré, une dépendance dont l’installation a été remplacée, un accès par FTP mal protégé, ou une faille d’interface qui n’a pas été patchée.
Je vais détailler une méthode pragmatique, orientée preuves, pour remonter du symptôme jusqu’à la première action malveillante. Sans promesses magiques, parce que WordPress est un écosystème vivant, et les traces se brouillent vite.
Commencer par regarder les symptômes, pas le code
Le “symptôme” est ce qui a déclenché la découverte. Qu’on soit alerté par un outil de sécurité, un client qui voit des redirections, ou un index SEO pollué, les détails comptent. Un site compromis peut injecter du contenu au niveau des pages, modifier des fichiers, publier du spam via WP-Cron, déclencher des requêtes sortantes, ou créer des backdoors pour revenir.
Avant même d’ouvrir le disque, j’aime répondre à trois questions simples, parce qu’elles orientent la suite:
- Est-ce que le site injecte du contenu dans le rendu (front) ou agit de façon “opaque” (requêtes, cron, administration)? Est-ce que le comportement est constant ou opportuniste (par exemple, seulement certains pays, seulement certains navigateurs, seulement quand un cookie est présent)? Est-ce que l’impact a commencé d’un coup (une date claire) ou s’étale (une dérive progressive)?
Une observation concrète change le plan d’attaque. Par exemple, si on voit des redirections systématiques, on suspecte souvent un changement de fichier dans le thème, dans wp-content ou des règles de serveur. Si on observe plutôt des pages qui renvoient vers des pages spam, il peut y avoir une injection dans un fichier d’en-tête, ou un script qui s’exécute au chargement. Si ce sont des tâches planifiées qui publient ou contactent l’extérieur, on pense aux cron jobs, aux comptes utilisateurs, ou à une persistance via base de données.
Triage: contenir pour éviter d’empirer les preuves
Quand on approche un site infecté, il y a un piège courant: “On nettoie vite”. Mais si on modifie trop tôt, on efface les repères. Dans la pratique, je fais une photo de https://gardewp.fr/nettoyage-malware-wordpress/ la situation avant toute suppression.

La priorité est double: couper la capacité d’exécution et préserver les traces.
Mettre le site en pause ou le mettre derrière une page statique de maintenance (pour réduire le trafic sur le vecteur). Récupérer des copies horodatées des fichiers sensibles (au minimum wp-config.php, dossiers wp-content et fichiers racine liés à l’exécution). Extraire une copie de la base de données (ou au moins les tables “cibles”: utilisateurs, options, posts, postmeta, cron). Exporter des logs web et applicatifs disponibles (Nginx/Apache, PHP error logs, accès, et si possible logs WP plugin ou audit). Isoler les comptes d’administration et changer les identifiants depuis un environnement sûr.C’est parfois intrusif, mais ça limite la casse et ça rend le diagnostic plus fiable.
Où chercher le point d’entrée: la persistance et l’exécution
Le point d’entrée initial n’est pas forcément le dernier endroit où on voit du code malveillant. Il y a deux couches à distinguer:
- La persistance, c’est ce qui permet de revenir. L’exécution, c’est ce qui déclenche le comportement observable (injection, redirection, exfiltration, publication automatique).
Le piège est de confondre les deux. Exemple fréquent: on trouve un fichier “webshell” dans wp-content/uploads/ ou wp-content/plugins/. On le supprime, mais l’attaquant a peut-être laissé une autre porte. En identifiant le point d’entrée initial, on cherche à remonter vers la première modification non légitime, celle qui a permis ensuite de déposer d’autres composants.
Dans WordPress, les emplacements où la persistance apparaît souvent comprennent le noyau de WordPress via modifications de fichiers, les thèmes et plugins, le système de médias (uploads), les hooks enregistrés dans la base de données, et les tâches planifiées.
Construire une chronologie à partir des horodatages
La chronologie est votre boussole. Et elle n’est pas parfaite, parce que les horloges serveur peuvent dériver, et parce que certains hébergeurs copient des fichiers avec un timestamp “générique”. Pourtant, elle donne souvent un ordre de grandeur.
Voici ce que je fais concrètement, sans tomber dans des scripts magiques:
- Je regarde la date de modification des fichiers suspects (y compris ceux qui “sentent” l’injection: fichiers PHP inattendus dans uploads, ajouts récents dans des dossiers de plugins ou de thèmes, ou modifications dans le dossier racine). Je compare ces dates avec la fenêtre de début d’incident (par exemple, à partir du moment où la redirection a été observée). Je fais correspondre avec les logs web: une activité de connexion anormale, une tentative de téléchargement de fichier, ou des appels à des endpoints inhabituels.
Si vous n’avez pas de logs, ou si l’hébergement ne fournit pas les détails, la chronologie devient plus difficile. Mais même dans ce cas, les timestamps et les timestamps internes de WordPress (par exemple dates d’inscription des utilisateurs) aident.
Attention aux faux “premiers” coups
J’ai vu des cas où la date de modification d’un fichier “bizarre” correspondait au dernier moment où quelqu’un a nettoyé ou déployé. Par exemple, un passage en mise à jour automatique ou une restauration partielle peut rafraîchir certains fichiers. Dans ce scénario, le fichier “suspect” n’est pas le point d’entrée, il est peut-être la conséquence.
La règle pratique: le point d’entrée initial est celui qui peut expliquer comment l’attaquant a obtenu exécution, et pas seulement la trace la plus récente.
Exploiter les logs: les accès avant la modification
Les logs d’accès et d’erreur sont souvent la meilleure voie pour retrouver le moment initial. On cherche des schémas qui ne correspondent pas à du trafic normal.
Selon votre configuration, vous pouvez voir:
- des tentatives répétées de connexion vers /wp-login.php, parfois avec un agent utilisateur atypique des requêtes vers des chemins inexistants, ou des uploads directs vers des répertoires sensibles des réponses HTTP suspectes, comme des téléchargements “ombreux” suivis rapidement de changements de fichiers
Si vous observez une séquence cohérente, elle devient très précieuse. Par exemple: d’abord des requêtes vers un endpoint d’administration, puis la création d’un utilisateur, puis un changement dans un plugin, puis une injection visible sur le front.
Même sans contexte utilisateur, les modèles temporels comptent.
Edge case: l’attaque “sans logs”
Certains hébergeurs masquent ou conservent peu les logs, ou les rotations sont trop agressives. Si vous ne disposez pas des logs applicatifs ou serveur, vous pouvez quand même reconstruire une partie de l’histoire via:
- le journal des modifications d’utilisateurs WordPress (dates d’inscription) la base de données (changements d’options, enregistrements de cron) la présence de fichiers récemment modifiés dans des dossiers moins manipulés par les équipes internes
C’est moins précis, mais ça limite les erreurs grossières.
Les indicateurs forts dans WordPress: utilisateurs, options, cron, et fichiers
Pour remonter au point d’entrée, on se concentre sur les “preuves” de contrôle.
Comptes admin et utilisateurs “trop récents”
Un classique: un nouvel utilisateur admin apparaît. Parfois, il a un pseudo banal, parfois il ressemble à un compte créé lors d’une migration. La différence se fait via la date d’inscription, la première connexion, et les rôles.
WordPress stocke beaucoup d’éléments dans la base, et les tables utilisateurs aident à cerner le début. Si vous trouvez un admin créé juste avant l’apparition du symptôme, c’est un candidat sérieux pour le point d’entrée ou un élément très proche.
Options et hooks: quand WordPress “se souvient” de l’intrusion
Les options et certains paramètres enregistrent souvent des éléments qui subsistent même après suppression de fichiers. Par exemple, des options peuvent référencer un comportement d’injection, ou un script chargé à chaque requête.
Quand je cherche un point d’entrée initial, je regarde aussi les éléments qui auraient été “écrits” par l’exécution initiale. Si un plugin compromis a injecté des hooks, vous pouvez retrouver des traces dans la base via des options nouvellement créées ou des valeurs modifiées.
WP-Cron: la persistance sous forme de tâches
WP-Cron est une zone où les attaques se cachent sans bruit. Une tâche planifiée peut publier, modifier, contacter un endpoint externe, ou effectuer un nettoyage de trace selon une logique malveillante.
Si le comportement malveillant dépend d’une exécution périodique, le cron est souvent impliqué, parfois sans aucune modification visible côté front. C’est un bon indice pour identifier le “moment initial” comme l’instant où une tâche a été ajoutée pour la première fois.
Fichiers “inattendus”: le signal le plus facile, mais pas toujours le point d’entrée
Quand on voit un fichier PHP dans wp-content/uploads/, ou une modification soudaine dans un plugin ou thème, on a un signal fort. Mais comme je l’ai déjà mentionné, ce signal peut être une conséquence.
Ce que je fais, c’est d’évaluer si ce fichier peut expliquer l’accès initial. Par exemple, un webshell installé via une autre porte, c’est une étape de persistance. Le point d’entrée réel peut être plus ancien et ailleurs.
Déterminer le vecteur d’accès: exploitation, vol de session, ou compromission de plugin
Il existe trois familles fréquentes de vecteurs, et elles se distinguent par les traces.
Exploitation d’une faille non patchée
Si un plugin ou un thème exploite une faille connue, vous pouvez retrouver des séquences de requêtes répétées, parfois avec des paramètres “bizarres”, suivies d’une modification de fichiers ou d’une création d’utilisateur.
Le diagnostic ici demande une lecture attentive des versions installées. Si votre site utilisait une version vulnérable, le vecteur devient plausible. Le point d’entrée initial correspond alors souvent au moment où l’exploit a abouti à une exécution de code.
Vol de session ou brute force sur l’authentification
Quand l’attaquant obtient un accès via connexion, vous verrez souvent:
- des tentatives de login anormales puis une action “légitime” côté WordPress, comme l’installation d’un plugin, une édition de thème, ou la modification d’un fichier
Le point d’entrée initial, dans ce cas, est l’instant où l’attaquant a réussi à s’authentifier, puis a utilisé son accès pour déposer du code.
Un détail qui aide: si le site a été compromis après qu’un employé a réutilisé un mot de passe, ou après une fuite de credentials, l’enchaînement suit souvent une logique “compromission rapide”.
Compromission supply chain (plugin, thème, librairie)
Parfois, ce n’est pas une attaque “au moment T”, c’est un composant déjà compromis. Un plugin peut être “installé” ou mis à jour avec un contenu malveillant, sans exploitation externe visible.
Dans ce cas, la trace “initiale” peut être moins évidente dans les logs web. Vous détectez surtout une incohérence entre la version attendue et ce qui est réellement présent, ou une date de modification qui ne correspond pas à votre calendrier de déploiement.
C’est là que les horodatages et le changelog interne sont précieux: si vous savez qu’il n’y a eu aucune mise à jour à telle date, et qu’un plugin change juste à ce moment, l’hypothèse se renforce.
Méthode de remontée: du fichier suspect au premier événement
On peut formaliser la remontée en pratique, sans faire une “procédure militaire” qui ignore la réalité.
1) Repérer ce qui s’exécute et ce qui persiste
Vous identifiez d’abord ce qui injecte ou exécute. Sur un WordPress infecté, c’est souvent:
- un fichier PHP modifié chargé par le thème un plugin modifié un script exécuté depuis un hook, une redirection, ou un filtre parfois une modification au niveau serveur (rewrite, configuration)
Ensuite, vous repérez ce qui sert de persistance: création de compte, cron, fichiers de retour, options.
2) Relier chaque élément à une date
Vous assignez une date d’apparition à chaque composant. C’est là que le point d’entrée initial devient le plus probable: c’est l’élément le plus ancien parmi ceux qui expliquent le reste.
Si vous trouvez un fichier webshell récent, mais que l’utilisateur admin a été créé plus tôt, la logique la plus probable est: accès initial via compte volé ou brute force, puis déploiement du webshell pour revenir.
3) Vérifier la cohérence avec le comportement observé
Si le comportement observable est du spam ou des redirections, le code d’injection devrait correspondre au moment où il a été déployé. Un décalage important entre la date d’installation du composant et l’apparition du symptôme peut indiquer une seconde étape, ou un nettoyage partiel qui a masqué l’origine.
C’est un point où le jugement compte. Un antivirus web peut signaler une présence, mais la “vraie” exécution peut dépendre de conditions.
Deux checklists qui sauvent du temps
Quand je fais ce travail pour de vrai, je reviens toujours à deux mini checklists. Elles évitent les oublis, et elles réduisent le risque de détruire des preuves.
Checklist d’éléments à collecter avant toute suppression
Copie des fichiers modifiés, avec horodatages Export de la base (au minimum utilisateurs, options, cron) Captures ou relevés des pages incriminées (avant nettoyage) Logs web et logs PHP sur la fenêtre suspecte Liste des plugins et thèmes installés, avec leurs versionsChecklist de cohérence pour remonter au point d’entrée initial
Quelle date est la plus ancienne parmi les traces de contrôle (user, option, cron, fichier)? Est-ce que cette trace explique la capacité d’exécution des autres? Les logs montrent-ils un événement d’accès au même moment? Les plugins ou thèmes modifiés correspondent-ils à un déploiement interne? Le comportement observé dépend-il d’une exécution périodique ou d’un rendu immédiat?Je sais que ces listes sont courtes, mais elles forcent la discipline. Sans elles, on finit trop souvent à supprimer “le dernier truc trouvé”, au lieu de remonter l’attaque.
Cas fréquents, et comment ils influencent l’identification
“Un admin a été ajouté, puis tout le reste”
C’est souvent le scénario le plus lisible. Le point d’entrée initial peut être:
- brute force sur /wp-login.php puis création d’un compte via interface vol d’identifiants via email ou réutilisation compromission session si un cookie admin a été récupéré
Les logs donnent souvent l’heure de la première connexion. Ensuite, la date d’inscription et les actions dans WordPress suivent.
“Le webshell est là, mais pas de nouvel utilisateur”
Dans ce cas, l’entrée initiale n’est pas forcément une prise de contrôle via compte. L’attaquant peut avoir exécuté du code via une faille, puis avoir déposé une porte de retour sans modifier l’interface d’administration.
Ce scénario arrive aussi quand l’attaquant supprime ensuite les traces d’accès à l’interface, ou quand l’administrateur n’a pas été surveillé au moment où la faille a été exploitée.
“Aucun fichier modifié évident, seulement du comportement intermittent”
Là, le suspect numéro un est le cron, des injections conditionnelles, ou des options modifiées en base. Les fichiers peuvent sembler propres, mais la base contiendra des valeurs qui déclenchent une action.
Dans ce cas, le point d’entrée initial est très souvent une commande d’écriture dans la base, donc une attaque qui a eu un accès applicatif, même si elle n’a pas laissé de fichiers “spectaculaires”.
Les erreurs qui rendent le diagnostic faux
Il y a quelques habitudes qui piègent, même chez des équipes compétentes.
- Se contenter d’un scan antivirus ou d’un outil “malware signature”. Ils trouvent parfois ce qui est évident, pas ce qui a déclenché l’ensemble. Nettoyer sans cartographier. Sans inventaire, on ne peut pas comparer les dates. Refaire les mises à jour en aveugle. Ça peut masquer l’origine, surtout si la mise à jour remplace des fichiers proches de la trace initiale. Supprimer les logs ou écraser le serveur. Si les logs ne sont pas exportés, on perd la fenêtre critique.
Le “bon sens” technique consiste à préserver, puis à comparer.
Après identification: neutraliser le vecteur, pas seulement le contenu
Une fois le point d’entrée initial identifié, l’action doit couvrir la racine du problème. Sinon, on a une désinfection fragile.
Si le point d’entrée est un compte compromis, la réponse inclut changement de mots de passe, rotation des sessions, vérification de l’authentification à deux facteurs quand c’est possible, et audit des comptes.
Si le point d’entrée est un plugin ou thème compromis, la réponse inclut suppression complète, vérification des sources d’installation, et contrôle de la chaîne de déploiement. Une simple réinstallation “depuis le même endroit” peut répéter l’infection.
Si le point d’entrée est une faille non patchée, la réponse inclut mise à jour et vérification des composants autour de la faille, car parfois des plugins “adjacents” partagent une même lib.
Et si le point d’entrée correspond à une modification serveur ou à une configuration de routage, alors il faut traiter aussi la couche hébergement, pas seulement WordPress.
Ce que j’attends d’une identification réussie
Quand je parle d’identifier le point d’entrée initial, je ne cherche pas juste “un fichier suspect”. Je cherche une histoire cohérente, qui relie au moins trois éléments:
- un premier événement daté (accès, création d’utilisateur, modification d’option, apparition d’un fichier) une capacité à exécuter ou persister (webshell, cron, hook, rôle) une correspondance temporelle avec l’apparition du symptôme
Si vous avez ça, vous pouvez nettoyer sans angoisse. Et vous pouvez aussi communiquer en interne ou auprès du client avec des faits: ce qui s’est passé, quand ça a commencé, et pourquoi le nettoyage actuel suffit ou ne suffit pas.
Un site WordPress infecté ne “tombe” pas toujours pour des raisons mystérieuses. Les attaques laissent des routes, même minces. Le travail consiste à retrouver la première route praticable, celle qui a rendu les suivantes possibles.