Fuente: Hispahack Autor: MiST
Acceso a webs ASP restringidas
Antes que nada me gustaría decir que este artículo ha sido inspirado en el escrito de rain.forest.puppy "NT Web Technology Vulnerabilities" publicado en la Phrack número 54.
Las Active Server Pages (ASP) son paginas creadas en lenguaje visual basic script, además de los usuales tags html, las cuales son ejecutadas en el servidor y sus respuestas son enviadas al browser cliente. Normalmente se utilizan para hacer consultas a un motor de base de datos con driver ODBC, de ese modo pueden crearse páginas dinámicas de una forma muy sencilla.
Cada vez son más las empresas que apuestan por esta tecnología aunque, como explicaré seguidamente, en algunos aspectos hay que programarlas concienzudamente para evitar posibles intrusiones en la parte restringida del web.
Vamos al grano: Imaginemos una web de acceso restringido cualquiera, digámosle login.asp, donde hay que rellenar dos campos de texto de un formulario uno con el login y otro con el password. En el action del formulario hay chek_passwd.asp. El código asp de la consulta y acceso a datos de esta página sería mas o menos el siguiente:
Vamos a comentarlo un poco. Las marcas indican principio y fin de código a interpretar por el server por lo tanto código que el cliente no verá.
ConsultaSQL="SELECT * FROM tabla_de_usuarios WHERE login='" & _ request.querystring("login") & "' AND password='" & _
request.querystring("password) & "'"
Se carga en la variable ConsultaSQL la consulta (SQL claro).
SELECT * 'Selecciona todos los campos
FROM tabla_de_usuarios 'de la tabla de usuarios
WHERE login= 'que el login sea igual a
' 'inicio de cadena a comparar
"& 'inicio de variable
1_ 'continua en la siguiente línea
request.querystring("login") 'variable login pasada desde el formulario de la página
&" 'fin de variable
' 'fin de cadena a comparar
AND 'y lo mismo con la variable password mandada desde el formulario.
La consulta hablada seria "Seleccionar todos los campos de la tabla de usuarios donde el login sea el nombre introducido en el formulario y el password sea el password introducido en el formulario".
Prosigamos:
Set Conn = Server.CreateObject("ADODB.Connection")
Crea un objeto de conexión a datos ADODB el nombre del cual es Conn.
Conn.Open "DSN=websql;UID=Uid_page;PWD=pwd_page;DATABASE=page"
Abre la conexión con todos los parámetros necesarios para ello, servicio de datos, uid, password y base de datos.
Set recst = Server.CreateObject("ADODB.RecordSet")
Crea un objeto recordset llamado recst.
recst.ActiveConnection=Conn
Indica la conexión por la que el recordset se instanciará.
recst.Open ConsultaSQL
Instancia el recordset con los resultados de la consulta SQL vista anteriormente. Este recordset se utilizará ahora para generar las páginas dinámicas de la cuenta del usuario dentro del web, o si el recordset no se instancia con nada (login y/o password incorrecto), saldrá una página de error.
Y dónde está el problema? Muy señores míos, el problema se encuentra en el carácter ' . Si, tan pequeñito como es el delimitador de cadena a comparar es muy peligroso si no se controla ya que imaginemos que en el textbox del formulario donde piden el login ponemos la cadena:
loquesea' x
y en el password ponemos cualquier cosa, la página si no está bien programada nos dará la siguiente respuesta:
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Line 1: Incorrect syntax near 'x'.
/chek_passwd.asp, line 18
Con un poco de intuición podemos suponer que esta línea 18 coincide con la línea:
request.querystring("login") & "' AND password='" & _
ya que al instanciarse las variables del formulario la consulta quedará:
"SELECT * FROM tabla_de_usuarios WHERE login='loquesea' x'
AND password='qualquiercosa'"
Como vemos el formato de la consulta queda erróneo debido a los caracteres x' . Nuestro objetivo será pues sustituir estos caracteres erróneos por otros que puedan ser interpretados correctamente como consulta SQL, y que, de paso, nos de de retorno en el recordset datos válidos de la base de datos para entrar en el web. En mi opinión, muy cuestionable por cierto, una buena cadena sería:
loquesea' or nombre_atributo_bd like '%letra o numero%' or nombre_atributo_bd='algo
Ejemplo:
loquesea' or login like '%a%' or login='algo
De ese modo la consulta nos quedará:
"SELECT * FROM tabla_de_usuarios WHERE login='loquesea'
OR login like '%letra o numero%' OR login='algo'
AND password='qualquiercosa'"
Tengo que remarcar que letra o numero es una letra o un numero cualquiera, por ejemplo a (de administrador ). Esta consulta junto con el resto de código que le sigue nos dará un recordset con todos los datos de un usuario que su login contenga una a (si ponemos a), y por lo tanto entraremos en su cuenta dentro del web. Como veis el error se da por un descuido de programación, que, acompañado con una mala administración del IIS donde se alberga la página y un diseño poco cuidado de la misma, entrar en una web restringida puede ser muy sencillo. Una pregunta que podríamos hacernos una vez leído esto es: ¿Y cómo sé el nombre del atributo de la base de datos que contiene el nombre de usuario? En el ejemplo he utilizado login, pero es verdad, no hay modo de saberlo de una forma segura, aunque normalmente los programadores de asp cometemos el error de bautizar los textbox de los formularios con el mismo nombre que el atributo equivalente en la bd y solo con un vistazo al código html visible se puede deducir. Si eso no funciona siempre queda probar con los nombres típicos login, user, usuario, idusuario, etc.
SOLUCIÓN:
Para solucionar esta vulnerabilidad sólo hay que poner una pequeña rutina en javascript o en vbscript que mire las cadenas contenidas en las variables del request.querystring controlando que no contengan ninguna comilla. No estaría de más, pero, delimitar los textbox del formulario con maxlength para que no puedan introducirse cadenas demasiado largas. Eso no és ninguna solución definitiva, el atacante siempre podrá llamar al asp vulnerable desde la barra del browser o desde una copia local del web modificado, pero la cuestión és intentar hacer el trabajo del atacante lo más molesto posible. Tampoco estaría de más configurar el IIS para que al producirse un error dé como respuesta una página estándar de fallo y no la típica página que te dice el número de error y te chiva una parte del código del fichero asp. De ese modo el atacante no podrá disponer de información, como partes de la consulta, motivos del fallo, etc, que podría utilizar en su beneficio.
MiST
http://hispahack.ccc.de/mi027.htm