De la cybersécurité (I’m back. Stronger.)

Enfin j’ai trouvé un peu de temps pour réparer tout mon bourbier.

En effet, depuis 2024, quand on accédait à mes sites wordpress, vous aviez ce message d’accueil fort charmant qui mentionnait un « incident technique ». J’avais dû fermer mes trois sites wordpress …

Pas des moindres. J’avais été piratée de partout ! Mon site d’urbex par exemple redirigeait vers une boutique en ligne. Et paf la cascade, mon site vitrine, mon blog et même un temps mon wiki sur mon jeu Minerland ! Un peu comme un jeu de dominos qu’on fait tomber petit à petit … de quoi être parano.

Il aura fallu attendre 2024 pour que ça se produise, en sachant que mes premiers sites perso remontent à 2000. Depuis, je me disais, tranquille, que je n’avais pas de raisons de me méfier ni de consolider mes iptables bien comme il le faut … voire faire l’impasse sur les mises à jour. L’erreur fatale. La cybersécurité est devenue lame de plus du développeur web qui doit apprendre de ses erreurs.

Intro sur la cybersécurité

En 2026, les petits sites web sont plus que jamais en première ligne.

Les attaques les plus courantes contre les petits sites sont silencieuses, opportunistes et automatisées. Elles défigurent un site, volent des données clients, ou utilisent le serveur pour héberger des contenus illicites, le tout à l’insu du propriétaire.

La grande nouveauté de 2026, c’est l’utilisation de l’IA par les attaquants. Les agents IA autonomes deviennent des outils courants de la cybercriminalité, capables de cartographier une attaque en quelques minutes et de générer des campagnes de phishing ciblées à grande échelle. Les campagnes de phishing générées par IA sont désormais quasiment indétectables — fini les fautes d’orthographe et les formulations bancales.

Plus de 90 % des piratages de sites WordPress exploitent des failles déjà corrigées dans une mise à jour que l’administrateur n’a pas appliquée. Le message est clair : mettre à jour, sécuriser ses accès, surveiller ses logs — ce n’est plus optionnel, même pour un petit blog perso.

Acte I — La découverte

Tout a commencé par un constat simple : mes sites WordPress ne répondaient plus correctement. En fouillant, j’ai découvert l’ampleur des dégâts. Les attaquants avaient réussi à s’introduire dans mes trois sites WordPress et ils s’étaient fait plaisir.

Leur spécialité : injecter du contenu. Des pages de spam, du phishing, et le pompon — un site de commerce en ligne complet, hébergé à mes frais sur mon propre serveur. Sympa.

En analysant les bases de données, j’ai retrouvé leurs traces partout. Dans la base d’amelieonline.net, un webshell — un script PHP qui permet de prendre le contrôle d’un serveur à distance — était planqué dans le fichier functions.php du thème. Du code obfusqué en base64 qui se connectait à des serveurs distants pour exécuter des commandes. Le plugin de sécurité All-In-One Security l’avait détecté et mis en quarantaine, mais le mal était fait.

Dans les fichiers du serveur, les bots avaient déposé des scripts PHP aux noms discrets : x.php, ha.php, gg.php… Des portes dérobées qui leur permettaient de revenir à volonté, même après un changement de mot de passe.

Acte II — Comment ils sont rentrés

La réponse est aussi simple que gênante : mon mot de passe wordpress était devenu trop faible. Ou alors ils se sont fait une joie de l’absence de certificat ssl …

Les bots qui parcourent internet 24h/24 testent des millions de combinaisons sur /wp-login.php et xmlrpc.php (une porte d’entrée WordPress souvent oubliée). Avec un mot de passe simple, il leur faut parfois quelques heures pour entrer.

Mais ce n’est pas tout. Mon serveur cumulait les facteurs aggravants. Ubuntu 18.04 en fin de vie depuis avril 2023, donc plus aucun correctif de sécurité. PHP 7.x, qui n’est plus maintenu depuis fin 2022. Pas de HTTPS — ce qui signifie que chaque fois que je me connectais à l’admin WordPress, mon identifiant et mon mot de passe transitaient en clair sur le réseau. Dans un café, à la gare, à l’hôtel, n’importe qui sur le même Wi-Fi pouvait les intercepter avec un simple outil comme Wireshark.

Et mon certificat SSL ? Expiré depuis des mois. J’avais payé cher pour un certificat classique, il avait expiré, et je n’avais jamais pris le temps de le renouveler. J’étais persuadée qu’il fallait racheter un certificat pour chaque nom de domaine. Trois domaines, trois certificats, une facture qui pique. En fait, non — mais j’y reviendrai.

Acte III — Le grand nettoyage

Le ménage a été méthodique. D’abord, les bases de données : analyser chaque dump SQL à la recherche de contenu injecté — du spam en chinois, en japonais, en cyrillique, des liens vers des boutiques frauduleuses, des webshells en quarantaine. Chaque site a été passé au peigne fin, table par table, grâce à l’aide de mon ami Claude, devenu mon nouveau formateur/secrétaire/IA couteau suisse.

Ensuite, les fichiers du serveur : traquer les scripts PHP malveillants dans les répertoires d’uploads (il ne devrait jamais y avoir de fichier PHP dans wp-content/uploads/), vérifier chaque thème, chaque plugin, identifier les fichiers modifiés récemment.

Et puis la grosse opération : migrer le serveur d’Ubuntu 18.04 vers une version maintenue. Trois sauts successifs — 18.04 vers 20.04, puis 22.04 — chacun avec son lot de surprises. PHP 7 vers PHP 8 a cassé plusieurs choses : des fonctions dépréciées, des syntaxes devenues invalides, des conflits de configuration entre l’ancien PHP-FPM et le nouveau module. À chaque étape, un site qui tombe, un diagnostic, une correction, on repart.

Acte IV — L’horreur des logs

C’est une fois le serveur remis d’aplomb que j’ai vraiment mesuré l’ampleur du problème. En regardant les logs d’authentification SSH :

Failed password for root from 179.111.150.107
Failed password for invalid user adurbex from 172.188.89.41
Failed password for invalid user amelayesbiophp from 59.51.98.254
Failed password for invalid user urbexmarseille from 187.191.48.4
Failed password for invalid user tonwebautableau from 121.78.158.30

Des dizaines de tentatives par heure. Et le plus flippant : les bots n’essayaient pas que des noms génériques comme « admin » ou « root ». Ils testaient adurbex, urbexmarseille, amelayesbiophp etc … — des identifiants dérivés de mes noms de domaines, de mon pseudo, de mes projets.

Quelqu’un — ou plutôt quelque chose — avait scanné mes sites, relevé tous les indices disponibles. Les noms d’auteur WordPress sont exposés par défaut via /?author=1 ou l’API REST (/wp-json/wp/v2/users). Les pages « à propos », les footers, les noms de domaine eux-mêmes : tout est découpé, recombiné, et testé automatiquement.

Les logs Apache racontaient la même histoire côté web : des scans massifs de wlwmanifest.xml (un fichier WordPress utilisé pour détecter les installations), des rafales de requêtes cherchant des webshells PHP à des noms comme x.php, ha.php, gg.php… Un bot a généré des dizaines de 404 en quelques millisecondes, balayant méthodiquement tous les noms de fichiers suspects.

En analysant les adresses IP, un inventaire géographique impressionnant : Brésil, Bulgarie, Chine, Corée du Sud, Russie, Vietnam, Pays-Bas, Ukraine, Singapour, Afrique du Sud… La plupart provenaient de datacenters ou de services cloud comme Microsoft Azure ou Alibaba Cloud. Et l’ironie : l’une des IP attaquantes appartenait à un serveur Kimsufi OVH — un serveur dédié comme le mien, probablement compromis et utilisé comme relais.

Ce ne sont pas de vrais humains derrière un écran. Ce sont des botnets — des réseaux de milliers de machines compromises qui scannent automatiquement toutes les IP du monde, 24 heures sur 24.

Acte V — Pourquoi mon petit serveur ?

C’est la question que je me suis posée. Mes sites ne contiennent rien de sensible. Mais ce n’est pas mes données qui intéressent les attaquants. C’est mon serveur lui-même : sa bande passante pour lancer des attaques vers d’autres cibles ou participer à des attaques DDoS, son processeur pour miner de la cryptomonnaie, son adresse IP pour héberger du phishing ou envoyer des millions de spams, et le fait qu’il tourne 24h/24 en faisant office d’outil gratuit.

Un serveur dédié compromis devient un soldat anonyme dans une armée de machines zombies. Et quand quelqu’un remonte la piste d’une attaque, c’est sur mon Kimsufi qu’il tombe — pas sur le vrai attaquant.

Acte VI — La fortification

La reconstruction s’est faite couche par couche.

Fail2ban, valeur sûre. J’avais fail2ban d’installé, mais sa configuration par défaut était une passoire : 10 minutes de bannissement après 5 échecs. Les bots attendaient tranquillement et revenaient. 4681 tentatives échouées au compteur, 491 IP bannies au total, mais zéro bannie à l’instant T. J’ai durci la config : 3 échecs en une heure, et c’est 24 heures de ban.

Mais le SSH n’était pas le seul front. J’ai ajouté des jails fail2ban pour chaque type d’attaque : les scans WordPress (wlwmanifest), les floods de 404 génériques, les tentatives de brute force sur DokuWiki, les scans de fichiers sensibles. Six jails au total, chacune avec ses propres seuils. Le port 22 quant à lui, exit !

Iptables pour les récidivistes. Pour les IP les plus agressives — celles avec 60, 80, 90 tentatives au compteur — j’ai écrit un script qui les bloque définitivement dans iptables. Ces adresses ne peuvent plus du tout communiquer avec mon serveur, sur aucun port, par aucun protocole.

CrowdSec, la défense collaborative. En plus de fail2ban, j’ai installé CrowdSec — un outil communautaire où les serveurs partagent les IP malveillantes. Quand une IP attaque un serveur du réseau, elle est signalée et bloquée sur tous les autres.

HTTPS avec Let’s Encrypt. Fini les certificats payants. Certbot et Let’s Encrypt m’ont permis de sécuriser mes trois domaines en une seule commande, gratuitement, avec renouvellement automatique tous les 90 jours. Plus jamais de certificat expiré oublié dans un coin. Un timer systemd vérifie deux fois par jour si un renouvellement est nécessaire.

Le blocage de xmlrpc.php. Ce fichier WordPress est un vecteur classique de brute force. Bloqué.

Les permissions qui vont bien. 644 pour les fichiers, 755 pour wp-content.

La mise à jour de tout. Ubuntu à jour, PHP à jour, WordPress core à jour, plugins à jour, thèmes à jour. Chaque composant obsolète est une porte ouverte.

Ce que j’ai appris

Cette aventure m’a enseigné des leçons que j’aurais aimé connaître plus tôt.

Un mot de passe faible est une porte ouverte. C’est banal à dire, mais c’est la cause numéro un des compromissions WordPress. Aujourd’hui, 20 caractères minimum, générés aléatoirement, et uniques pour chaque site.

Le HTTPS n’est pas optionnel. Même pour un blog perso, chaque page de connexion sans HTTPS est une invitation au vol d’identifiants. Et avec Let’s Encrypt, il n’y a plus aucune excuse financière.

La sécurité par défaut n’existe pas. Fail2ban installé avec sa config d’usine, c’est presque comme s’il n’était pas là. Il faut prendre le temps de configurer chaque outil correctement.

Tout serveur exposé sur internet est une cible. Ce n’est pas une question de « si », mais de « quand ». Les bots ne dorment jamais, et ils sont plus malins qu’on ne le croit — ils analysent vos sites pour en extraire des identifiants potentiels. Les premières tentatives de brute force arrivent dans les minutes qui suivent la mise en ligne d’un serveur.

Un système non maintenu est un système compromis. Ubuntu 18.04 en fin de vie + PHP 7 abandonné = zéro correctif de sécurité depuis des mois. Autant laisser la porte grande ouverte.

Vérifiez vos logs régulièrement. Sans cette habitude, je n’aurais jamais su que mon serveur subissait des milliers de tentatives d’intrusion quotidiennes.