TL;DR: está circulando una campaña (“ClickFix”) que muestra una pantalla falsa de Cloudflare pidiéndote presionar Windows + R y pegar un comando msiexec para instalar un programa “necesario”. Es un engaño. Cloudflare nunca te pedirá ejecutar comandos fuera del navegador.
Si tu WordPress redirige a dominios como defensecorex.com o llama a metricaltic.com, tu sitio probablemente tiene inyección de JavaScript (plugin/tema/snippet/archivo modificado). Abajo tienes un MU-plugin que bloquea las cargas maliciosas (sin romper Elementor/admin) y, después, una guía de limpieza completa.
Cómo funciona el engaño
Los atacantes comprometen sitios (a menudo WordPress) e insertan un “Cloudflare Check” falso. La página imita Turnstile/CAPTCHA y pide presionar Win+R para ejecutar un comando que descarga/instala un MSI malicioso. Es ingeniería social: el usuario se instala el malware. Esta táctica se conoce como ClickFix y se ha observado ampliamente contra webs y usuarios finales en 2024–2025. Cloudflare no solicita ejecutar comandos; cualquier “verificación” real ocurre dentro del navegador.
Por qué es peligroso (msiexec)
msiexec.exe es el instalador de Windows; los atacantes lo abusan para descargar e instalar paquetes en silencio (/qn, /passive). Eso permite desplegar stealers (e.g., Lumma, MetaStealer, LegionLoader) y tomar credenciales/sesiones.
Bloqueo inmediato: MU-plugin (solo front, no rompe Elementor)
Este MU-plugin impide que WordPress imprima/inyecte scripts remotos hacia los hosts maliciosos en el front (no corre en admin/editor). También bloquea inserciones dinámicas de <script> en tiempo de ejecución. Ajusta la lista si detectas más dominios.
Guarda como wp-content/mu-plugins/bm-block-bad-scripts.php:
<?php
/*
Plugin Name: BM Guard (Front + Elementor) [MU]
Plugin URI: https://devcristian.com
Description: Bloquea IOCs (defensecorex/metricaltic/daftarhargapipa) en frontend y en el editor de Elementor; corta HTTP saliente, limpia <script> maliciosos y loguea con stack en consola.
Version: 1.4.0
Author: devcristian
Author URI: https://devcristian.com
*/
if (!defined('ABSPATH')) exit;
/** ================== Config ================== */
function bm_iocs() {
return ['defensecorex.com','metricaltic.com','daftarhargapipa.com'];
}
function bm_site_host(){
static $h = null;
if ($h !== null) return $h;
$h = parse_url(home_url(), PHP_URL_HOST);
return $h ? strtolower($h) : '';
}
function bm_host_of($url){
$h = parse_url($url, PHP_URL_HOST);
return $h ? strtolower($h) : '';
}
/* Compat helpers (PHP < 8) */
function bm_starts_with($hay,$nee){ return $nee==='' || strncmp($hay,$nee,strlen($nee))===0; }
function bm_ends_with($hay,$nee){ if($nee==='') return true; $l=strlen($hay)-strlen($nee); return $l>=0 && strpos($hay,$nee,$l)!==false; }
function bm_is_same_or_sub($host,$root){ return $host===$root || ($root && bm_ends_with($host,'.'.$root)); }
function bm_in_iocs($host){
foreach (bm_iocs() as $d) { if ($host===$d || bm_ends_with($host,'.'.$d)) return true; }
return false;
}
/** ================== Contextos ================== */
/* Frontend normal */
function bm_is_front_ctx(){
if (defined('REST_REQUEST') && REST_REQUEST) return false;
if (wp_doing_ajax()) return false;
return !is_admin(); // front puro
}
/* Editor/preview de Elementor dentro del admin */
function bm_is_elementor_admin_ctx(){
if (!is_admin()) return false;
// Editor: post.php?post=ID&action=elementor
if (isset($_GET['action']) && $_GET['action'] === 'elementor') return true;
// Vista previa: elementor-preview
if (isset($_GET['elementor-preview'])) return true;
return false;
}
/** ================== 1) Bloqueo HTTP saliente (server-side) ==================
* Evita phone-home desde plugins/temas hacia IOCs (también en admin/elementor).
*/
add_filter('pre_http_request', function($pre, $args, $url){
$h = bm_host_of($url);
if ($h && bm_in_iocs($h)) {
return new WP_Error('bm_blocked', 'BM: blocked server-side -> '.$h);
}
return $pre;
}, 10, 3);
/** ================== 2) Limpiar HTML (quitar <script src> IOCs) ==================
* Se aplica en frontend y en páginas de visualización/preview (no afecta REST/AJAX).
*/
function bm_start_buffer_cleaner(){
if (bm_is_front_ctx() || bm_is_elementor_admin_ctx()) {
ob_start(function($html){
if (!$html) return $html;
// a) Eliminar <script src> que apunten a IOCs (por si se imprimieron fuera de las colas)
if (preg_match_all('#<script\b[^>]*\bsrc=["\']\s*(https?:)?//([^/"\']+)[^"\']*["\'][^>]*>\s*</script>#i', $html, $m, PREG_SET_ORDER)) {
foreach ($m as $mm) {
$full = $mm[0]; $host = strtolower($mm[2]);
if (bm_in_iocs($host)) {
$html = str_replace($full, "<!-- BM removed IOC script: //{$host}/... -->", $html);
}
}
}
// b) Neutraliza y LOGUEA (luego en JS) posibles URLs defensecorex ya impresas en HTML
// (no rompemos el HTML aquí, solo lo dejamos; el runtime las intercepta)
return $html;
});
}
}
add_action('template_redirect', 'bm_start_buffer_cleaner', 0);
add_action('admin_init', 'bm_start_buffer_cleaner', 0); // para editor Elementor en admin
/** ================== 3) Cortar scripts encolados a IOCs (WP_Scripts) ==================
* También en admin cuando estás en el editor de Elementor (no toca otros screens).
*/
function bm_dequeue_ioc_scripts(){
$apply = bm_is_front_ctx() || bm_is_elementor_admin_ctx();
if (!$apply) return;
global $wp_scripts; if (!$wp_scripts) return;
foreach ($wp_scripts->registered as $handle => $obj) {
$src = isset($obj->src) ? $obj->src : '';
if (!$src) continue;
$abs = (bm_starts_with($src,'http://') || bm_starts_with($src,'https://'))
? $src
: trailingslashit($wp_scripts->base_url).ltrim($src,'/');
$h = bm_host_of($abs);
if ($h && bm_in_iocs($h)) {
wp_dequeue_script($handle);
wp_deregister_script($handle);
// Sustituimos por un aviso en consola (para que el DOM no falle por dependencias)
add_action(bm_is_front_ctx() ? 'wp_footer' : 'admin_footer', function() use ($abs,$handle){
echo "<script>console.warn('[BM] BLOCKED enqueued script IOC:', ".wp_json_encode($abs).", 'handle:', ".wp_json_encode($handle).");</script>";
}, 9999);
}
}
}
add_action('wp_print_scripts', 'bm_dequeue_ioc_scripts', 999);
add_action('admin_print_scripts', 'bm_dequeue_ioc_scripts', 999);
/** ================== 4) Runtime (JS) con stack trace ==================
* Inyecta en <head> del front y del editor de Elementor:
* - bloquea fetch/XHR/WebSocket y redirecciones hacia IOCs
* - loguea <script> dinámicos a IOCs
* - decodifica defensecorex (domain/link base64) si aparece
* NOTA: si tu CSP bloquea inline scripts, cambia a una versión que encole un .js de este plugin.
*/
function bm_print_runtime_js(){
$apply = bm_is_front_ctx() || bm_is_elementor_admin_ctx();
if (!$apply) return;
$site = bm_site_host();
$iocs = wp_json_encode(bm_iocs());
?>
<script>
(function(){
try{
var SITE=<?php echo json_encode($site); ?>;
var IOCs=new Set(<?php echo $iocs; ?>);
function hostOf(u){ try{ return new URL(u, document.baseURI).hostname.toLowerCase(); }catch(e){ return ''; } }
function isIOC(h){ if(!h) return false; for (var b of IOCs){ if (h===b || h.endsWith('.'+b)) return true; } return false; }
function trace(kind, url){
try{ throw new Error('[BM] STACK '+kind+' -> '+url); }
catch(e){ console.warn('[BM] BLOCKED '+kind+' ->', url, '\n'+(e.stack||e)); }
}
// fetch
if (window.fetch){
var _f=window.fetch;
window.fetch=function(i,o){
var url=(typeof i==='string')? i : (i && i.url ? i.url : '');
var h=hostOf(url);
if (isIOC(h)){ trace('fetch', url); return Promise.reject(new Error('BM blocked '+url)); }
return _f.apply(this, arguments);
};
}
// XHR
if (window.XMLHttpRequest){
var _o=XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open=function(m,u){
var h=hostOf(u);
if (isIOC(h)){ trace('XHR', u); try{this.abort();}catch(e){} throw new Error('BM blocked '+u); }
return _o.apply(this, arguments);
};
}
// WebSocket
if (window.WebSocket){
var _WS=window.WebSocket;
window.WebSocket=function(u,p){
var h=hostOf(u.replace(/^ws(s)?:\/\//,'https://'));
if (isIOC(h)){ trace('WS', u); throw new Error('BM blocked '+u); }
return new _WS(u,p);
};
}
// <script> dinámicos
['appendChild','insertBefore'].forEach(function(fn){
var orig=Node.prototype[fn];
Node.prototype[fn]=function(el){
try{
if (el && el.tagName==='SCRIPT' && el.src){
var h=hostOf(el.src);
if (isIOC(h)){ trace('dynamic<script>', el.src); return el; }
}
}catch(e){}
return orig.apply(this, arguments);
};
});
// Redirecciones
var _open=window.open; window.open=function(u,n,s){ var h=hostOf(u); if (isIOC(h)){ trace('window.open', u); return null; } return _open.apply(this, arguments); };
try{
var L=Object.getPrototypeOf(window.location);
if(L && L.assign){ var _a=L.assign; L.assign=function(u){ var h=hostOf(u); if (isIOC(h)){ trace('location.assign', u); return; } return _a.call(this,u); }; }
if(L && L.replace){ var _r=L.replace; L.replace=function(u){ var h=hostOf(u); if (isIOC(h)){ trace('location.replace', u); return; } return _r.call(this,u); }; }
}catch(e){}
// defensecorex decoder (base64 query params)
function scanDefensecorex(s){
try{
var m=s && s.match && s.match(/https?:\/\/defensecorex\.com\/\?[^"'\s<>]+/i);
if(!m) return;
var u=new URL(m[0]);
var d=u.searchParams.get('domain'), l=u.searchParams.get('link');
var decD=d?atob(decodeURIComponent(d)):null;
var decL=l?atob(decodeURIComponent(l)):null;
console.warn('[BM] defensecorex detected -> raw:', u.href, 'domain_dec:', decD, 'link_dec:', decL);
}catch(e){}
}
scanDefensecorex(location.href);
try{
var mo=new MutationObserver(function(list){
list.forEach(function(r){
r.addedNodes && r.addedNodes.forEach(function(n){
try{
if(n.nodeType===1 && n.tagName==='SCRIPT' && !n.src && n.textContent){ scanDefensecorex(n.textContent); }
}catch(e){}
});
});
});
mo.observe(document.documentElement, {childList:true,subtree:true});
}catch(e){}
}catch(e){}
})();
</script>
<?php
}
add_action('wp_head', 'bm_print_runtime_js', 0); // Front muy temprano
add_action('admin_head', 'bm_print_runtime_js', 0); // Editor Elementor en admin
/** ================== 5) Reporte compacto al final (opcional) ==================
* Solo imprime si hubo algo bloqueado por server-side (pocas veces necesario, puedes comentar si no quieres nada)
*/
add_action('wp_footer', function(){
// intencionalmente vacío: los bloqueos se muestran en vivo con stack (fetch/xhr/ws/script/open/assign/replace)
}, 9999);
add_action('admin_footer', function(){
// idem para editor Elementor
}, 9999);
este bloqueo no sustituye la limpieza. Úsalo para cortar la redirección hoy mismo y ganar tiempo para el saneamiento completo (siguiente sección). Reportes recientes confirman que estas campañas cambian de dominio con frecuencia; revisa periódicamente tu consola de navegador y amplia la lista si aparece un host nuevo
Limpieza profunda de WordPress y BD (lo recomendado)
Aislar y actualizar
- Poner el sitio en mantenimiento.
- Reinstalar core de WordPress y actualizar todos los plugins/temas (elimina los que no uses).
Revisa tu computador (por si ejecutaste el comando)
- Microsoft Defender escaneo sin conexión y una segunda opinión (Malwarebytes, etc.).
- Comprueba tareas programadas, programas de inicio y conexiones salientes anómalas.
- Si viste un instalador “Cloudflare.msi/PDF”, trátalo como malicioso.
Preguntas frecuentes
¿Cloudflare puede pedirme Win+R o copiar un comando?
No. Cualquier verificación real se hace en el navegador (checkbox, desafío visual). Si te piden ejecutar comandos, es falso.
¿Por qué mi sitio redirige solo a algunos usuarios?
Porque muchas inyecciones son condicionales (solo para Chrome/ciertos países, 1 de cada N visitas). A veces no verás nada en curl pero sí en el navegador.
¿Basta con el MU-plugin?
Es una mitigación inmediata. La limpieza de archivos/BD y el hardening siguen siendo indispensables; estas campañas rotan dominios y técnicas.