index.php beaucoup trop lourd : ce que cela révèle
Un `index.php` de cœur CMS pèse quelques kilo-octets. Un fichier de 80, 200, 400 Ko à la racine cache souvent du code encodé collé après le bootstrap. On pèse avant d'ouvrir, on compare au zip, on ne « reformate » pas le fichier à l'aveugle.
Un index de cœur CMS pèse quelques kilo-octets. Un fichier de 200 Ko à la racine cache souvent du code encodé. Pesez avant d'ouvrir.
Peser, c'est déjà diagnostiquer
Le gestionnaire de fichiers affiche la taille. Un `index.php` WordPress officiel de la branche 6.x tourne autour de 400 octets. Vous lisez 187 Ko : vous n'avez pas besoin d'un antivirus pour savoir qu'il y a un passager. La même logique pour Presta (`index.php` court) et pour beaucoup de fronts PHP.
Pesez aussi `wp-load.php`, `xmlrpc.php`, `wp-blog-header.php`. Un seul gros, les autres officiels : le gros est le payload. Tous gros : un pack a été uploadé par-dessus le cœur.
La date va avec le poids. Un fichier lourd daté d'aujourd'hui, cœur à jour d'il y a deux mois : heure d'entrée probable.
Tailles de référence (WP, Presta, Laravel)
WordPress : `index.php` minuscule, il charge `wp-blog-header.php`. PrestaShop 8 : `index.php` court qui bootstrap. Laravel / Symfony : `public/index.php` un peu plus long, mais de l'ordre de quelques Ko, pas d'un roman encodé.
Téléchargez le zip de votre version et pesez l'officiel. C'est plus fiable qu'un chiffre lu dans un article de 2019. Les versions bougent de quelques octets, pas de 200 Ko.
Un `index.html` de 300 Ko à la racine à côté d'un `index.php` : le serveur peut servir l'HTML en priorité. Regardez la config (`DirectoryIndex`). L'attaque peut être l'HTML (défacement) ou le PHP (shell). Les deux se pèsent.
- Peser `index.php` et les bootstrap voisins.
- Comparer au zip de la version installée.
- Vérifier `DirectoryIndex` si HTML et PHP coexistent.
Lire la fin du fichier, pas seulement le début
Le début est souvent le vrai bootstrap, pour passer un coup d'œil pressé. Le payload est collé à la fin, parfois après des milliers d'espaces, parfois dans un commentaire fermé trop tard. Ouvrez la fin. `eval`, `gzinflate`, `base64_decode` en chaîne : porte. Voir base64.
Certains kits mettent le payload au milieu, entre deux fonctions. Le diff contre le zip reste le juge de paix.
N'exécutez pas le fichier en CLI « pour voir ». Copiez, lisez comme texte. Un `php index.php` local lance le malware sur votre machine.
Index à la racine vs index des sous-dossiers
`uploads/2024/06/index.php`, `wp-content/index.php`, un dossier aléatoire : WordPress pose parfois des `index.php` silencieux (silence is golden) de quelques dizaines d'octets pour empêcher le listing. Un `index.php` de 90 Ko dans `uploads` n'est pas ça. C'est un shell ou un générateur.
Les dossiers de phishing apportent un `index.html` + un `index.php`. Pesez les deux. Voir dossier aléatoire.
Un `index.php` lourd dans `wp-admin` se fait passer pour un fichier cœur. Comparez au zip, toujours.
Un index lourd peut être un générateur
Au lieu d'un shell interactif, le fichier fabrique des pages selon l'URL. Vous pesez 250 Ko de if/else et de templates asiatiques. `site:` explose, l'index.php à la racine a remplacé le vrai front pour certains user-agents. Cloaking + générateur dans le même fichier.
Inspection d'URL : le HTML n'est plus WordPress. Le poids vous a mis sur la piste ; Search Console confirme. Voir cloaking.
Remplacer l'index sans couper le cron qui le réécrit : demain, 250 Ko à nouveau. Les cron dans la même passe.
Remplacer par l'officiel sans perdre la preuve
Copie hors serveur du lourd, puis overlay du fichier zip officiel. Pas « réinstaller WordPress » en un clic : trop large, trop d'oublis (mu-plugins). Fichier par fichier pour le cœur.
Vérifiez que le site bootstrap encore (home, wp-admin). Un mauvais copier-coller de `index.php` casse tout. Gardez le bak jusqu'au test.
Si le CMS n'est pas WordPress et que vous n'avez pas le zip, reconstituez un index minimal à partir de la doc de la version, ou déléguez. Un index « trouvé sur un forum » est un risque.
Quand le poids est légitime
Un front sur mesure (tout le routeur dans index.php) peut peser 30-80 Ko de code lisible, commenté, avec des classes nommées. Ce n'est pas `gzinflate`. Le critère est le contenu et le diff, pas la peur du Ko.
Un site « HTML exporté » avec un gros `index.html` : peser ne dit rien du pirate. Là, on cherche les scripts tiers et les iframes.
Les maps source, les bundles : ce ne sont pas des `index.php`. Ne mélangez pas un `app.js` de 400 Ko (normal) et un PHP de 400 Ko (anormal pour un bootstrap).
Après remplacement : réécriture
Pesez à J+1. Si le Ko est revenu, l'écrivain est vivant. Shell, cron, deploy. Panel changé dans la foulée du premier remplacement.
Les caches opcode (OPcache) peuvent servir l'ancien gros fichier quelques minutes. Reload PHP-FPM si vous en avez la main, ou attendez le TTL, ou un ticket hébergeur.
Un CDN a pu cacher le HTML généré, pas le PHP. Videz quand même : les visiteurs voyaient le spam, pas le poids.
Googlebot et l'index qui ment
Vous avez remplacé, vous voyez le vrai site, `site:` montre encore les titres japonais. Horloge d'index, pas échec du remplacement — si l'inspection live est propre. Réindexez les URL clés. Volume spam : 404 + préfixe. Voir titres japonais.
Si l'inspection live est encore sale, l'index.php n'était pas le seul serveur de HTML (mu-plugin, `.htaccess` prepend). Continuez.
Vous pouvez déclarer le site. Le couple taille + date de `index.php` est une des pièces les plus simples à transmettre.
- Poids vs zip officiel.
- Copie puis remplacement ciblé.
- Cron et prepend `.htaccess`.
- Pesée à J+1.