Pulsa ESC para cerrar

Curso WordpressCurso Wordpress

Comprueba si un plugin instalado en WordPress fue modificado

Un plugin gratuito de wordpress.org se puede verificar archivo por archivo contra el original publicado por su autor: si alguien le inyectó código, la diferencia salta de inmediato. WP-CLI trae ese comando (wp plugin verify-checksums), pero leer su salida plugin por plugin y cuenta por cuenta es tedioso.

Estos dos scripts lo automatizan: revisar-plugin.sh revisa un plugin y revisar-todos-plugins.sh los revisa todos.

Antes de empezar

  • Necesitas un VPS o servidor dedicado con cPanel/WHM y acceso root (desde WHM → Terminal basta).
  • Los scripts se probaron en AlmaLinux 10 con cPanel 138, PHP 8.3 de EasyApache (/opt/cpanel/ea-php83) y WP-CLI instalado en /usr/local/bin/wp. Si tu servidor usa otra versión de PHP, cambia la ruta ea-php83 en el script.
  • Pruébalos primero en un horario tranquilo y lee lo que hace cada uno antes de ejecutarlo. Se comparten tal cual, sin garantía: adáptalos a tu servidor.

Qué revisa

  • Comparación con wordpress.org: si el plugin está publicado ahí, confirma que sea idéntico al original.
  • Si es premium (no está en wordpress.org), revisa su código: marcas de clubes que definas en MARCAS, código malicioso conocido, archivos raros y enlaces.
  • Funciones que crean usuarios o inician sesiones, y respaldos de archivos originales (señal de que alguien lo modificó).
  • En la cuenta: PHP escondido dentro de uploads, errores de PHP del día y si el sitio responde.

Instalación

Primero revisar-plugin.sh, porque el segundo script lo usa. Pega cada bloque en WHM → Terminal:

cat > /root/revisar-plugin.sh <<'EOF'
#!/bin/bash
# Revisa un plugin ya instalado. Uso: revisar-plugin.sh CUENTA PLUGIN
# Ejemplo: revisar-plugin.sh micuenta elementor-pro
# Sin PLUGIN, muestra la lista de plugins de la cuenta.
# Marcas de clubes GPL o sitios de plugins no oficiales que quieras detectar (separadas por |)
MARCAS="nombre-del-club|dominio-del-club\.com"
U="$1"; PL="$2"
WPATH="/home/$U/public_html"
[ -f "$WPATH/wp-config.php" ] || { echo "No hay WordPress en la cuenta '$U'"; ls /home | grep -v -E '^(virtfs|cPanelInstall)' ; exit 1; }
W=(sudo -u "$U" -- /opt/cpanel/ea-php83/root/usr/bin/php /usr/local/bin/wp --path="$WPATH" --skip-plugins --skip-themes)
if [ -z "$PL" ]; then echo "Plugins de $U:"; "${W[@]}" plugin list --fields=name,version,status 2>/dev/null; echo "Uso: $0 $U NOMBRE-DEL-PLUGIN"; exit 0; fi
D="$WPATH/wp-content/plugins/$PL"
[ -d "$D" ] || { echo "No existe el plugin '$PL' en $U. Plugins instalados:"; "${W[@]}" plugin list --field=name 2>/dev/null; exit 1; }
MAL=0

echo "===== $PL en $U"; "${W[@]}" plugin get "$PL" --fields=version,status 2>/dev/null | tail -n +2
echo "--- Comparacion con wordpress.org"
V=$("${W[@]}" plugin verify-checksums "$PL" 2>&1)
if echo "$V" | grep -qE "Verified [1-9][0-9]* of [1-9]"; then
  echo "OK: identico al original de wordpress.org"
elif echo "$V" | grep -qiE "could not retrieve|skipped|no se pudo"; then
  echo "No esta en wordpress.org (premium o del club): se revisa el codigo"
elif echo "$V" | grep -qiE "checksum|should not exist|was added|File "; then
  echo "ATENCION: archivos distintos al original:"; echo "$V" | grep -v "^Error: No plugins verified" | head -15; MAL=1
else
  echo "No se pudo comparar: $(echo "$V" | tail -1 | cut -c1-150)"
fi
echo "--- Marcas del club";         grep -rlE "$MARCAS" "$D" | sed "s|$D/||"
R=$(grep -rnoE ".{0,40}(eval\s*\(\s*(base64_decode|gzinflate|str_rot13|\\\$_(POST|GET|REQUEST|COOKIE))|(assert|system|passthru|shell_exec|exec|popen)\s*\(\s*\\\$_(POST|GET|REQUEST|COOKIE)|base64_decode\s*\(\s*\\\$_(POST|GET|REQUEST|COOKIE)|\\\\x65\\\\x76\\\\x61\\\\x6c).{0,40}" "$D" --include=*.php | grep -v json_decode | sed "s|$D/||" | head)
echo "--- Codigo malicioso conocido"; [ -n "$R" ] && { echo "$R"; MAL=1; }
echo "--- Crea usuarios o inicia sesiones (en plugins de tienda, foro o membresia puede ser normal)"; grep -rlE "wp_create_user|wp_insert_user|wp_set_auth_cookie" "$D" --include=*.php | sed "s|$D/||" | head
R=$(find "$D" \( -name "*.suspected" -o -name "*.phtml" -o -name "*.phar" -o -name "*.pht" -o -name ".*.php" \) -o -type l | sed "s|$D/||")
echo "--- Archivos raros o enlaces";  [ -n "$R" ] && { echo "$R"; MAL=1; }
echo "--- Respaldos de originales (senal de modificacion)"; find "$D" \( -name "*.bak" -o -name "*.backup" -o -name "*.orig" \) | sed "s|$D/||"
R=$(find "$WPATH/wp-content/uploads" -type f \( -iname "*.php*" -o -iname "*.phtml" \) -size +200c 2>/dev/null | sed "s|$WPATH/||")
echo "--- PHP dentro de uploads";     [ -n "$R" ] && { echo "$R"; MAL=1; }
echo "--- Errores de PHP de hoy";      grep "$(date +%d-%b-%Y)" "$WPATH/error_log" 2>/dev/null | tail -5 | cut -c1-200
DOM=$(grep -m1 '^DNS=' "/var/cpanel/users/$U" 2>/dev/null | cut -d= -f2)
[ -n "$DOM" ] && echo "--- Sitio responde: $(curl -s -o /dev/null -k --resolve $DOM:443:127.0.0.1 -w '%{http_code} %{time_total}s' https://$DOM/)"
echo; [ $MAL = 0 ] && echo "RESULTADO: sin hallazgos graves" || echo "RESULTADO: HAY HALLAZGOS, revisar antes de seguir usando el plugin"
EOF
chmod 700 /root/revisar-plugin.sh && bash -n /root/revisar-plugin.sh && echo SCRIPT_OK
cat > /root/revisar-todos-plugins.sh <<'EOF'
#!/bin/bash
# Revisa todos los plugins de todas las cuentas usando /root/revisar-plugin.sh
# Uso: /root/revisar-todos-plugins.sh            (todas las cuentas)
#      /root/revisar-todos-plugins.sh micuenta   (solo una cuenta)
[ -x /root/revisar-plugin.sh ] || { echo "Falta /root/revisar-plugin.sh"; exit 1; }
MALOS=""
for C in /home/${1:-*}/public_html/wp-config.php; do
  [ -f "$C" ] || continue
  U=$(stat -c %U "$(dirname "$C")")
  echo "======== $U"
  for D in /home/$U/public_html/wp-content/plugins/*/; do
    P=$(basename "$D")
    R=$(/root/revisar-plugin.sh "$U" "$P" 2>/dev/null)
    ORIGEN=$(echo "$R" | grep -A1 "Comparacion con wordpress.org" | tail -1 | sed 's/OK: identico al original de wordpress.org/wordpress.org OK/; s/No esta en wordpress.org.*/premium o del club/' | cut -c1-40)
    CLUB=$(echo "$R" | sed -n '/--- Marcas del club/,/--- Codigo/p' | grep -vc -- '---')
    VER=$(echo "$R" | awk '/^version/{print $2}')
    if echo "$R" | grep -q "HAY HALLAZGOS"; then EST="<<< HAY HALLAZGOS"; MALOS="$MALOS $U:$P"; else EST="ok"; fi
    printf "  %-38s %-10s %-22s %s%s\n" "$P" "$VER" "$ORIGEN" "$EST" "$( [ "$CLUB" -gt 0 ] && echo '  (del club)')"
  done
done
if [ -n "$MALOS" ]; then
  echo; echo "################ DETALLE DE LOS PLUGINS CON HALLAZGOS"
  for X in $MALOS; do /root/revisar-plugin.sh "${X%%:*}" "${X#*:}"; echo; done
else
  echo; echo "Ningun plugin con hallazgos."
fi
EOF
chmod 700 /root/revisar-todos-plugins.sh && bash -n /root/revisar-todos-plugins.sh && echo SCRIPT_OK

Cómo usarlos

/root/revisar-plugin.sh CUENTA PLUGIN          # un plugin de una cuenta
/root/revisar-plugin.sh micuenta elementor-pro  # ejemplo
/root/revisar-plugin.sh micuenta                # sin plugin: lista los plugins de la cuenta

/root/revisar-todos-plugins.sh                  # todos los plugins de todas las cuentas
/root/revisar-todos-plugins.sh micuenta         # solo una cuenta
/root/revisar-todos-plugins.sh > /root/plugins-$(date +%F).txt   # guardar el reporte

CUENTA es el usuario de cPanel y PLUGIN es el nombre de la carpeta del plugin. Si lo escribes mal, el script te muestra los nombres correctos.

Cómo leer el resultado

  • «OK: identico al original de wordpress.org»: verificación fuerte, nadie lo modificó.
  • «No esta en wordpress.org (premium o del club)»: no hay original con qué comparar, así que solo se revisó su código.
  • «ATENCION: archivos distintos al original»: un plugin gratuito fue modificado; revísalo de inmediato.
  • Algunos plugins generan archivos propios al guardar su configuración (por ejemplo, CSS personalizados). Si aparece «File was added» en un .css o .js con fecha del día en que guardaste ajustes, probablemente es eso; compáralo con el original para confirmarlo.
  • En el resumen de todos los plugins, cada línea muestra versión, origen y estado; al final aparece el detalle solo de los que tienen hallazgos.

Cuándo usarlos

  • revisar-plugin.sh: después de instalar o actualizar un plugin.
  • revisar-todos-plugins.sh: una vez al mes, o después de actualizar varios sitios.