Je livre ce retour d’expérience qui pourrait être utile à ceux qui ont développé un site sous WordPress notamment.
1. Alerte, mon site est HS ! Suppression des scripts malicieux
L’autre jour, je dispensais un cours auprès d’officiers de la sécurité des systèmes d’information. A la pause, je voulais accéder à mon site www.davidfayon.fr réalisé avec WordPress. Or en me connectant, quelle ne fut pas ma surprise en voyant une page blanche apparaître !
Face à cette étrangeté, je contacte le soir par chat mon hébergeur qui m’indique de positionner dans les paramètres du compte PHP Error message à Ok. Après l’avoir fait, lors de la saisie de l’URL du site dans le navigateur, un message d’erreur apparaît :
« Parse error: syntax error, unexpected T_VARIABLE in /customers/d/f/1/davidfayon.fr/httpd.www/wp-includes/functions.php on line 192 »
Puis on m’indique de remplacer le fichier function.php ou de le regénérer. Je pense alors que mon site a été victime d’une infection. Là, on me communique après scan une liste de 50 fichiers .php infectés. Et que le script infectieux commence par « eval(gzinflate(base64_decode(‘tVh7c9pIEv/ ».
Avant de me connecter à mon espace Web, je change les mots de passe. Ils étaient alphanumériques et avec des caractères plus atypiques. Même si l’infection n’est pas liée à un crac de mot de passe, autant minimiser les risques ! J’utilise alors l’outil FTP pour accéder aux fichiers. Je constate que le script infectieux se présente dans les 15 premières lignes de chaque fichier contaminé. J’enregistre chacun des fichiers corrigés à la fois en nom.php et en nom1.php pour avoir une copie de sauvegarde et vérifier les tailles des fichiers pour toute recontamination éventuelle. Je procède pour l’ensemble des 50 fichiers.
Mais je constate que le problème subsiste. En effet, en me reconnectant à l’interface, les fichiers php qui étaient infectés le sont à nouveau (taille augmentée de 2 Ko environ du fait de l’insertion du code malicieux) mais pas les 1.php copiés en sécurité ! Le malware s’insérerait dans certains noms de fichiers (footer, header, function, etc.).
Face à cette nouvelle infection, je décide de vérifier mon disque dur via Mc Afee scan. Tout est ok. Puis un outil antimalware m’indique que 3 malwares sont présents dans les couches basses (au niveau des registres). Je les efface via cet outil. Je demande à Denis Brun, qui avait participé à la migration du contenu de mon précédent site entièrement réalisé sous Dreamweaver et à la création du site sous WordPress, de prendre le relais en nocturne via son PC et un disque dur externe pour effectuer les suppressions des fichiers infectés via le FTP et de les renommer en 1.php. Las, il m’envoie un mél au petit matin me disant qu’il a effectué toutes les suppressions mais qu’il existe peut-être des fichiers oubliés dans l’arborescence et que le problème persiste.
Pour autant, en me reconnectant, je constate que les modifications de Denis ont marché et que la présence du script malveillant a régressé, il est absent de tous les fichiers qu’il a corrigés. En regardant fichier par fichier, je constate néanmoins qu’il demeure 7 fichiers avec le script malveillant. Je procède aux corrections. J’efface par ailleurs 2 fichiers qui avaient un nom bizarre avec la souche du script ou un dérivé dans wp-content/themes/skeptical/cache.
Tout semble ok. L’hébergeur me confirme que le site n’est plus infecté. Seulement l’erreur à la ligne 192 dans functions.php subsiste.
2. Poursuite des corrections pour rétablir le fonctionnement
Après ces premières mesures, j’imagine alors trois solutions :
1. Continuer à chercher. On a peut-être d’autres hypothèses tout en regardant ce qui est dit sur les forums, Twitter, etc. à propos de WP et de ce malware ;
2. Acheter un antimalware et l’utiliser. Mais en cas de modification de code (functions.php), est-ce que l’outil va pouvoir réparer le fichier endommagé ?
3. Regénérer le site avec les fichiers images dans wp-content/uploads et le fichier .xml que je génère de temps à autre. Denis me dit qu’il est prêt à faire cela : méthode radicale de confinement et décontamination : réinstaller la dernière version de WP, remplacer le thème, tous les plug-ins, etc. ce qui est un sacré travail.
J’opte dans l’immédiat pour la solution 1.
Je regarde avec l’outil de vérification d’infection éventuelle de site Sucuri.net. Le diagnostic est que le site est contaminé. Mais je décide de rafraîchir le diagnostic, celui dans le cache pouvant remonter à 48 h. Il est alors indiqué que voici quelques minutes, le site n’était plus infecté. La purge des codes malicieux serait donc achevée… L’autre site de vérification Unmaskparasites me confirme qu’à sa connaissance le site est propre.
Je regarde alors sur les différents forums qui évoquent ce problème. Et je trouve ce commentaire relatif à une discussion démarrée voici 3 semaines :
I have compared new functions.php to broken functions.php files and here is the difference.
New function.php file does not have this on line 1 (or anywhere)
Also line 192-208 has been deleted and should have this:_if ( doubleval($bytes) >= $mag )_return number_format_i18n( $bytes / $mag, $decimals ) . ‘ ‘ . $unit;
return false;_}
/**_* Get the week start and end from the datetime or date string from mysql._*_* @since 0.71_*_* @param string $mysqlstring Date or datetime field type from mysql._* @param int $start_of_week Optional. Start of the week as an integer._* @return array Keys are ‘start’ and ‘end’._*/_function get_weekstartend( $mysqlstring, $start_of_week = » ) {_$my = substr( $mysqlstring, 0, 4 ); // Mysql string Year
J’effectue les modifications en rajoutant le code indiqué à partir de la ligne 192. Ensuite, j’observe que l’erreur affichée lors de la connexion à mon site depuis un navigateur est à présent repoussée en ligne 210. La piste est bonne…
Je cherche tous azimuts des fichiers functions.php sains pour faire la substitution de la partie modifiée. Car outre le rajout de ces scripts malveillants dans certains fichiers php, le code de functions.php a été indûment modifié en supprimant et modifiant des lignes de code.
Je finis par trouver cette page où figure une function size_format plus simple. J’effectue un copier-coller.
function size_format( $bytes, $decimals = 0 ) {
$quant = array(
// ========================= Origin ====
‘TB’ => 1099511627776, // pow( 1024, 4)
‘GB’ => 1073741824, // pow( 1024, 3)
‘MB’ => 1048576, // pow( 1024, 2)
‘kB’ => 1024, // pow( 1024, 1)
‘B ‘ => 1, // pow( 1024, 0)
);
foreach ( $quant as $unit => $mag )
if ( doubleval($bytes) >= $mag )
return number_format_i18n( $bytes / $mag, $decimals ) . ‘ ‘ . $unit;
return false;
}
Puis j’enregistre le nouveau fichier functions.php, en conserve une copie de l’ancienne version. Je quitte l’interface, saisis l’adresse de mon site dans le navigateur. Et ô miracle, le site est à nouveau en ligne. Le mal a été vaincu.
3. D’autres considérations pour prévenir les risques
J’ai également vu d’autres sources intéressantes comme celle-ci. Et découvert des informations à propos du code malveillant sur ce site avec des aides pour la suppression des malwares avec WordPress.
Enfin, je conseille un article qui donne des conseils en matière de sécurité pour ses sites « se protéger des pirates et des hackers ».
Le fait de se mettre le nez dans le cambouis tel un geek plongé dans ses lignes de code m’a fait revenir 20 ans en arrière rappelant les compilations en langage C et fut instructif. Le passage de sites en HTML en sites dynamiques en PHP est un vecteur de risque supplémentaire. Pourtant tel est le sens de l’histoire pour avoir un site digne de ce nom. Se pose la question de mise à jour des thèmes utilisés sous WordPress, de la tentation de maîtriser le code et la complexité sachant que les risques d’infiltration sont supérieurs. Pas facile sachant que la sécurité est souvent sous-estimée.
6 Commentaires
Passer au formulaire de commentaire
Vive wordpress.com 🙂
@Dominique,
Il ne s’agit pas d’erreurs mais de codages effectués automatiquement en PHP via les plug-in utilisés (themes, fonctionnalités complémentaires pour l’ergonomie du site). Les versions de WP, etc. sont indiqués automatiquement. Et du reste des outils comme securi.net permettent de collecter ce type d’information.
J’avais sauvegardé les articles via l’export XML généré automatiquement ainsi que les images, etc. mais pas les fichiers PHP. Désormais, c’est chose faite. Néanmoins, le plus gros du travail aura été de supprimer les scripts infectueux et non le travail de développeur.
Avec ton blog hébergé sur lemonde.fr en marque ombrelle, les soucis sont différents (avec le quotidien qui a X. Niel et P.Bergé comme actionnaires, des attaques sont néanmoins possibles et ciblées…). Mais quid de l’export du contenu vers une autre plate-forme de blogs dans l’hypothèse d’une migration future ?
@Michel,
La phase 2 de correction du fichier function.php aura pris 2 heures (recherche de sources, parcours des forums et des blogs idoines, compréhension du fonctionnement des lignes de code, remplacement des lignes modifiées). Le plus difficile est de pouvoir trouver le temps pour effectuer ces modifications.
Dans l’histoire, on ne sort pas indemne. Après l’indisponibilité, le PageRank de la page d’accueil a pour l’heure diminué de 1.
Je sais bien que les fichiers php sont fournis. Mais cela n’interdit pas de les modifier. Pour des raisons de sécurité, il est conseillé de modifier certains comportements fournis par défaut.
Cela n’a pas beaucoup de sens de comparer ton blog avec le blog invité que je gère sur le site du Monde.fr, où je ne gère pas le développement et où je trouve quelques avantages. On parle ici de développement avec WordPress, pas de questions éditoriales ni de politique. Évitons de tout mélanger.
En revanche, je gère des blogs indépendants sous WordPress depuis bientôt 10 ans. J’en ai une vingtaine en ce moment.
Il est inutile de sauvegarder les fichiers php, sauf si on les modifie. Il vaut mieux les réinstaller, en cas de problème, à partir du site de WP. Il vaut mieux, donc, éviter de les modifier, sauf via des outils ad hoc.
C’est précisément l’expérience en matière de gestion des briques (code de base, thèmes et extensions, base SQL) qui fait le niveau d’expertise du développeur, la bonne gestion du temps passé et la sécurité du site.
Les personnalisations de comportements peuvent toutes se faire soit par un thème enfant, soit par une extension. Les API sont là pour ça.
Tu gagnerais beaucoup de temps à lire, au moins une fois, le codex de WordPress, d’autant plus qu’il existe maintenant en français :
http://codex.wordpress.org/fr:Accueil
Je n’ai plus la patience de perdre mon temps avec ces virus / bêtises. Je suis sur le serveur wordpress.com avec Ubuntu 12.04 LTS sur mon PC sans aucun antivirus.
La paix vaut bien quelques sacrifices.
1. Dès la 40e ligne de ton code, tu indiques déjà aux agresseurs la version de WordPress que tu utilises.
Une dizaine d’erreurs de ce genre sont visibles sur ton site.
2. La prochaine fois, réinstalle de suite. Ça te prendra une heure et pas deux jours.
Cela suppose de disposer de sauvegardes fraîches et de bonnes méthodes d’écarts par rapport au code standard.
Bon courage pour la suite de ton apprentissage…
@+, cordialement, Dom
Ce compte rendu est très intéressant !
On imagine le désespoir de ceux qui rencontrent le même problème, mais ne savent pas comment s’y prendre pour le résoudre.
Combien de temps cela vous a-t-il pris ?
Amitiés,
MV