WordPress piraté que faire : la méthode d'un expert, trois cas réels décortiqués

WordPress piraté que faire : la méthode d'un expert, trois cas réels décortiqués

Un site WordPress qui ralentit, des connexions étranges dans les logs, un client qui panique au téléphone. « WordPress piraté que faire ? » est la question qu’on me pose en urgence, et c’est presque toujours la mauvaise première question. La bonne, c’est : est-ce vraiment un piratage, et si oui, lequel ? Un site lent n’est pas forcément compromis. Un site compromis ne ralentit pas forcément. Et deux attaques différentes ne se traitent pas de la même façon.

Cet article n’est pas une checklist de plus. C’est la méthode que j’applique réellement, illustrée par trois interventions que j’ai menées — anonymisées, mais avec leurs vraies données : des dizaines de milliers de lignes de logs, des injections de code retrouvées dans les fichiers du thème, des fichiers .htaccess de blocage. Les trois cas montrent trois visages du problème : une attaque frontale d’un concurrent, une compromission furtive dont le client ne se doutait pas, et — le plus instructif — un site qu’on croyait piraté et qui ne l’était pas.

Avant de crier au piratage : le réflexe de diagnostic

La première erreur, celle que je vois systématiquement, c’est de sauter au diagnostic sans localiser le problème. On désactive des plugins au hasard, on restaure une sauvegarde, on change des mots de passe — et parfois on « répare » un site qui n’avait rien, en masquant le vrai souci pour quelques jours.

Ma règle est simple : localiser la couche avant de chercher le coupable dans la couche. Un site qui répond mal peut souffrir de son navigateur, de son réseau, de son PHP, de son application WordPress, de sa concurrence d’accès, ou de son hébergement. Tant qu’on ne sait pas ça coince, tout le reste est de la superstition.

Les trois questions qui orientent tout

Face à un site suspect, je me pose trois questions dans l’ordre, et chacune ferme des pistes :

Les symptômes sont-ils de la lenteur, ou du contenu anormal ? Une lenteur pure oriente d’abord vers la performance et l’hébergement. Du contenu anormal — pages inconnues, redirections, liens sortants bizarres — oriente vers une compromission réelle. Ce ne sont pas les mêmes chantiers.

Que disent les logs, précisément ? Pas « il y a des erreurs », mais : quelle méthode HTTP, quelle URL, quelle taille de réponse, quel referer, quel user-agent. La signature d’une requête raconte son intention. Une même page d’erreur peut signifier « PHP a planté » ou « le serveur a tué le processus avant même de commencer » — et ça change tout le diagnostic.

Les fichiers statiques sont-ils lents eux aussi ? Si une simple image ou un fichier CSS met des secondes à se charger, le problème est sous l’application. Aucun nettoyage de WordPress ne le résoudra. C’est le signal qui fait gagner des heures.

Ce cadre — mesurer avant d’affirmer, distinguer ce qui est prouvé de ce qui est supposé — est ce qui sépare une intervention propre d’un bricolage coûteux. Les trois cas qui suivent en sont l’illustration.

Cas 1 — L’attaque frontale : quand un concurrent veut faire tomber votre site

Secteur : fabricant de véhicules électriques légers (voiturettes). Type : attaque volumétrique, probablement concurrentielle.

Les symptômes

Le site tombait par intermittence. Pas de défaçage, pas de contenu modifié : il devenait simplement inaccessible, puis revenait, sans logique apparente. Le prestataire informatique en place, généraliste, ne savait pas qualifier le problème — ce qui est fréquent : ce type d’incident sort du périmètre habituel d’une maintenance de site.

Ce que les logs ont révélé

En consultant les journaux d’erreurs du serveur sur plusieurs jours consécutifs, le motif a sauté aux yeux. Sur une seule journée, plus de 1 600 requêtes malveillantes enregistrées, provenant de près de 600 adresses IP distinctes. Et une cible ultra-dominante : le fichier xmlrpc.php.

Sur les quatre jours analysés, la même signature revenait, massive :

  • 25 février : 669 entrées, dont 527 sur xmlrpc.php
  • 26 février : 686 entrées, dont 621 sur xmlrpc.php
  • 27 février : plus de 1 400 entrées, dont 728 sur xmlrpc.php, avec l’apparition de tentatives d’injection de commandes Unix
  • 1er mars : plus de 1 600 entrées, 591 IP différentes

xmlrpc.php est une porte historique de WordPress, conçue pour les pings et les clients distants, mais devenue un vecteur d’attaque classique : amplification par la méthode system.multicall, force brute sur les identifiants, et surcharge pure. Le pare-feu applicatif (ModSecurity) détectait bien les tentatives XSS et les scores d’anomalie, mais était configuré en mode « détection seule » — il constatait sans bloquer.

Le diagnostic était clair et prouvé par les données : il ne s’agissait pas d’un bug ni d’une lenteur naturelle, mais d’une campagne distribuée, orchestrée, visant à saturer le site. L’origine — un concurrent — reste une hypothèse plausible au vu du ciblage, mais ce qui compte pour l’intervention, ce sont les faits : volume, distribution géographique des IP, cible unique.

La résolution, en deux temps

Le blocage immédiat, côté serveur. La priorité absolue : arrêter l’hémorragie sans attendre. Le levier le plus direct est le fichier .htaccess, qui agit avant même que WordPress ne démarre — donc sans coût pour l’application. En croisant les IP attaquantes avec leur géolocalisation, il devient possible de bloquer par plages géographiques entières les zones d’où provenait l’essentiel du trafic hostile, tout en préservant l’accès légitime. Un service comme countryipblocks.net fournit des listes de plages d’adresses prêtes à intégrer. Résultat : un .htaccess volumineux (plusieurs centaines de milliers de lignes de règles de blocage), mais efficace immédiatement.

Le vrai problème de fond : un serveur inadapté. L’attaque a surtout révélé une fragilité structurelle. Le site tournait sur un serveur cloud (type Web Cloud) mal maintenu, dont l’entretien demandait plus de temps qu’il n’en valait la peine. Un serveur mal tenu est un serveur vulnérable — et coûteux en énergie. La décision, prise avec le client et documentée, a été de changer d’architecture : abandonner le serveur cloud sur-complexe au profit d’un hébergement mutualisé Pro, plus simple à administrer et évolutif en performance si besoin.

La migration a suivi une séquence maîtrisée : bascule d’abord sur un serveur de développement pour valider les tests de rapidité, puis migration vers le mutualisé, tests, validation, et enfin transfert du domaine principal. Une dizaine de noms de domaine associés à l’activité ont été rattachés, le certificat SSL régénéré, et une demande de réindexation soumise dans la Search Console — l’occasion aussi de prendre connaissance des problèmes d’accessibilité que Google avait relevés pendant les épisodes d’indisponibilité.

La leçon du cas 1

Une attaque frontale se combat sur deux fronts qu’il ne faut jamais confondre : l’urgence (bloquer, tout de suite, au niveau le plus bas possible) et la cause (une infrastructure qui n’aurait pas dû plier). Bloquer sans corriger l’hébergement, c’est retarder le prochain incident. Le diagnostic par les logs n’est pas un luxe : c’est ce qui transforme « le site déconne » en « voici 600 IP qui martèlent xmlrpc.php, voici comment on les arrête, et voici pourquoi il faut changer de serveur ».

Secteur : fabrication de produits de soin (dispositifs médicaux). Type : compromission non destructrice, injection de SEO parasite.

Le piratage qu’on ne voit pas

C’est le cas le plus vicieux, parce qu’il ne casse rien. Le site fonctionne parfaitement, le client ne remarque rien, et pendant ce temps l’attaquant l’utilise comme relais. Ici, l’objectif n’était ni de détruire ni de rançonner, mais de greffer des backlinks vers des sites de casinos et de paris en ligne — une pratique de SEO parasite qui exploite l’autorité du domaine compromis pour doper le référencement de sites tiers.

Comment on le repère quand rien ne « plante » ? Par des signaux faibles : des administrateurs inconnus apparus dans la liste des utilisateurs, un article publié qu’on n’a jamais écrit, un pic anormal de spam dans les formulaires. En remontant le fil des logs d’accès, la chronologie de l’intrusion se reconstitue précisément.

La reconstitution de l’intrusion

Les journaux ont permis de retracer les gestes de l’attaquant, horodatés à la seconde, tous depuis une même adresse IP géolocalisée à l’étranger :

  1. Connexion à l’administration avec un compte frauduleux
  2. Injection d’un article contenant des liens cachés (l’URL de l’article trahissait la thématique casino/paris)
  3. Tentative de commentaire, interceptée et mise en corbeille par le filtre anti-spam
  4. Modification du fichier footer.php du thème via l’éditeur de fichiers intégré de WordPress

Ce dernier point est le cœur de l’attaque. Le pied de page du thème avait été édité pour y insérer un bloc de liens rendus invisibles pour le visiteur mais parfaitement lisibles par les moteurs de recherche — la technique classique du positionnement hors écran : un conteneur repoussé très loin à gauche de la fenêtre, contenant une série de liens en nofollow vers des sites de bonus de paris. Invisible à l’œil, présent dans le code source servi à Google sur toutes les pages du site.

Le nettoyage et la vérification

Un scan de sécurité complet a été lancé sur l’ensemble de l’installation. Le résultat mérite qu’on s’y arrête, car il illustre un piège du métier : le scan a passé au crible plus de 32 000 fichiers et 6 700 dossiers, et n’a signalé aucune injection en base de données, aucune menace .htaccess, aucune modification de fichier cœur. Autrement dit, l’infection ne se cachait pas là où un scan automatique la cherche. Elle vivait dans un fichier légitime du thème et dans le contenu éditorial — deux endroits qu’un outil de scan considère comme « normaux ».

C’est pourquoi la vérification humaine reste irremplaçable : ce sont les yeux sur le footer.php, sur la liste des utilisateurs, sur les articles récents qui ont trouvé ce que la machine avait laissé passer. Le nettoyage a consisté à supprimer le code injecté du pied de page, révoquer les comptes administrateurs frauduleux, purger l’article parasite, et confirmer le retour à un état sain (les rapports de santé du site le validaient après coup).

La sécurisation : verrouiller la porte d’entrée réelle

Nettoyer ne suffit pas — il faut fermer la faille exploitée. Ici, l’attaquant avait pu créer des comptes administrateurs. Deux mesures ont été mises en place :

Un verrou sur la création de comptes administrateurs. Un extrait de code ajoute un champ « mot de passe de création admin » sur le formulaire de nouvel utilisateur : impossible désormais de créer un compte administrateur sans connaître ce second secret, même en ayant accès à l’admin. Une barrière simple contre l’escalade de privilèges.

Un CAPTCHA v3 sur les formulaires, activé de façon ciblée pour ne pas alourdir les pages qui n’en ont pas besoin — la sécurité ne doit pas se payer en performance.

À cela s’ajoute le durcissement classique : blocage des IP identifiées, surveillance renforcée via un pare-feu applicatif (Wordfence dans ce cas), et scan malware régulier.

La leçon du cas 2

Le piratage le plus dangereux est celui qui ne se voit pas. Un site qui « marche bien » peut être en train d’empoisonner sa propre réputation aux yeux de Google, en hébergeant à son insu des liens vers des contenus douteux — avec, à la clé, un risque de pénalité de référencement bien réel. Deux enseignements : un scan automatique qui ne trouve rien ne prouve rien (il faut inspecter à la main les fichiers de thème et le contenu), et nettoyer sans sécuriser, c’est laisser la porte ouverte pour la prochaine visite.

Cas 3 — Le faux piratage : quand le vrai coupable est l’hébergement

Contexte : deux sites vitrines sur hébergement mutualisé. Type : aucune attaque, aucune infection — un dimensionnement d’offre insuffisant.

Les symptômes trompeurs

Voici le cas que je trouve le plus formateur, parce qu’il n’y a ni pirate ni malware — et pourtant tous les signaux extérieurs y ressemblent. Deux sites présentaient des lenteurs bloquantes et, par intermittence, des erreurs serveur (des HTTP 500) qui apparaissaient et disparaissaient sans motif visible. Le genre de comportement erratique qui fait immédiatement penser : « on nous attaque » ou « quelque chose est infecté ».

Sauf que non. Après avoir assaini les défauts applicatifs évidents (images non optimisées, configuration PHP), les lenteurs et les 500 persistaient. Il fallait donc trancher méthodiquement entre les trois grandes hypothèses : une boucle dans un script PHP, une mémoire serveur insuffisante, ou une attaque. Le diagnostic a fait la différence.

La méthode qui tranche : le test de charge contrôlé

Plutôt que d’empiler les captures et les suppositions, j’ai posé un protocole à variable unique. Deux petits scripts déposés temporairement à la racine de chaque site :

  • l’un mesure la capacité brute du serveur (un simple délai, sans WordPress) ;
  • l’autre mesure le coût d’un démarrage complet de WordPress avec ses extensions.

Puis j’ai généré une charge croissante — 5, 10, 20 puis 30 requêtes strictement simultanées — en observant les temps de réponse et les erreurs à chaque palier. Point crucial : poser la grille de lecture avant de mesurer. Si les erreurs arrivent par vagues régulières, c’est une file d’attente de traitement saturée. Si tout ralentit uniformément dès les premières requêtes, c’est une contention de puissance de calcul. Deux pathologies, deux diagnostics.

Ce que les mesures ont prouvé

Les chiffres ont parlé sans ambiguïté :

  • à 5 requêtes simultanées, chaque démarrage de WordPress coûtait environ 1 seconde — sain ;
  • à 20 simultanées, les temps de réponse grimpaient à 6-9 secondes — dégradation d’un facteur 6 ;
  • à 30 simultanées, les premières erreurs 500 apparaissaient.

Et la signature de ces erreurs 500 était décisive. Le corps de la réponse était une page d’erreur générique du serveur web, d’environ 550 octets — la trace caractéristique d’un processus tué avant même d’avoir émis le moindre en-tête HTTP. Corrélé aux journaux de l’hébergeur en direct, on y lisait des interruptions de processus (« FastCGI: incomplete headers », « End of script output before headers »). Aucune trace correspondante dans les logs applicatifs de WordPress : l’interruption était donc antérieure à toute exécution PHP. Ce n’était pas WordPress qui plantait. C’était l’hébergeur qui coupait les processus quand ils étaient trop nombreux en même temps.

Le test a été répété à plusieurs passages et reproduit sur un second site témoin hébergé sur un nœud différent : même mécanisme de rupture, au même ordre de charge. Ce qui a transformé un « incident local » en « caractéristique de l’offre » : le mutualisé mettait les traitements en file au-delà d’une douzaine d’exécutions concurrentes, et commençait à les interrompre autour de 30. Or l’éditeur de pages du site émet couramment 15 à 30 requêtes PHP en parallèle au chargement — précisément la plage où l’offre saturait.

La résolution : un constat, pas un nettoyage

Ici, pas de code à supprimer, pas de compte à révoquer. Le livrable était un dossier de preuves horodaté : résultats bruts des tests, corps d’erreur type, extraits de logs de l’hébergeur, et un ticket au support posant des questions fermées et vérifiables (un seuil de ressources a-t-il été franchi aux horaires des tests ? Le comportement correspond-il à l’offre ?). La recommandation, chiffrée et transférée au client, était une montée en gamme d’hébergement vers une offre à ressources garanties — pas une optimisation cosmétique, mais un prérequis de bon fonctionnement.

La leçon du cas 3

C’est peut-être la plus importante de l’article : tout ce qui ressemble à un piratage n’en est pas un. Un site lent avec des erreurs 500 intermittentes évoque spontanément l’attaque ou l’infection. La discipline consiste à ne jamais l’affirmer sans preuve — et le test de charge contrôlé, reproductible et chiffré, est ce qui permet de dire au client la vérité : « votre site n’est ni piraté ni cassé, votre hébergement est simplement sous-dimensionné pour votre usage ». Savoir dire « ce n’est pas un hack » inspire, au fond, plus de confiance que de voir des attaques partout.

La méthode, condensée : votre plan d’action

Si votre WordPress montre des signes suspects, voici l’ordre dans lequel procéder — le même que celui qui structure les trois cas ci-dessus.

1. Ne touchez à rien, observez d’abord. Ne restaurez pas de sauvegarde, ne désactivez pas de plugins au hasard. Vous risquez d’effacer les preuves ou de masquer le vrai problème. La première action est un diagnostic, pas une réparation.

2. Distinguez lenteur et compromission. Un site lent oriente vers la performance et l’hébergement. Du contenu anormal (pages, redirections, comptes ou liens inconnus) oriente vers une vraie intrusion. Ce ne sont pas les mêmes traitements.

3. Lisez les logs comme des indices. Méthode HTTP, URL ciblée, taille de réponse, referer, user-agent, adresses IP. C’est là que se lit l’intention. Un pic sur xmlrpc.php signe une attaque volumétrique ; un footer.php récemment modifié signe une injection.

4. En cas d’attaque volumétrique : bloquez au plus bas. Le .htaccess agit avant WordPress. Blocage par IP ou par plages géographiques pour arrêter l’hémorragie immédiatement.

5. En cas de compromission : inspectez à la main, ne faites pas confiance qu’au scan. Fichiers de thème (surtout footer.php et header.php), liste des utilisateurs, articles récents, tâches planifiées. Un scan qui ne trouve rien ne veut pas dire que le site est sain.

6. Nettoyez ET sécurisez. Supprimer le code injecté ne suffit pas. Fermez la faille : verrou sur la création de comptes admin, CAPTCHA sur les formulaires, mots de passe renouvelés, pare-feu applicatif.

7. Envisagez le fond, pas seulement l’urgence. Un serveur mal maintenu, une offre sous-dimensionnée, un WordPress jamais mis à jour : l’incident est souvent le symptôme d’un problème structurel. Le régler, c’est éviter le prochain.

Une précaution générale qui vaut pour tous les cas : un site statique (comme un site reconstruit sur une architecture moderne sans base de données) supprime purement et simplement une grande partie de la surface d’attaque de WordPress. Quand un site vitrine n’a pas besoin de la complexité d’un CMS, le migrer est parfois la meilleure sécurisation possible.

Ce qu’il faut retenir

« WordPress piraté que faire » n’a pas de réponse unique, parce qu’il n’y a pas un piratage mais des situations très différentes — dont certaines ne sont pas des piratages du tout. Les trois cas de cet article dessinent la même discipline appliquée à des réalités opposées : mesurer avant d’affirmer, prouver avant d’agir, et distinguer toujours l’urgence de la cause.

L’attaque frontale se bloque au niveau serveur puis se règle en corrigeant l’infrastructure. L’injection furtive se traque à l’œil, là où les scans échouent, puis se verrouille à la porte d’entrée. Et le faux piratage se démasque par un test de charge honnête, qui rend au client une vérité plus utile qu’une fausse alerte.

Si vous êtes face à un site que vous soupçonnez compromis et que vous voulez un diagnostic clair, prouvé et sans panique — c’est exactement ce type d’intervention que je mène : voir SOS site piraté. Le premier pas est toujours le même : regarder les données avant de toucher à quoi que ce soit.