Interceptando contraseñas de SQL

Cuando se desarrolla una aplicación Windows que acceda a una base de datos en SQL se afronta el problema de la metodología de conexión al servidor de base de datos. Es decir, ¿qué es mejor utilizar Autentificación Windows o Mixta (SQL)?



Si miramos las recomendaciones de Microsoft, no hay lugar a dudas, la conexión debe ser realizada con autentificación Windows. Sin embargo, esta opción requiere trabajo adicional y también presenta sus desventajas. 



El trabajo adicional consiste en configurar la seguridad para que cada usuario (o un grupo de ellos) pueda acceder a los recursos sin experimentar problemas de acceso por falta de permisos. También es recomendable que no se confieran a dichos usuarios más permisos de los necesarios. Y ahí está el problema, porque un usuario podrá acceder a la base de datos utilizando la aplicación pero, por desgracia, también podrá acceder desde cualquier otra aplicación menos restrictiva como por ejemplo el analizador de consultas (Query Analyzer). Esto quiere decir que un usuario podría manipular los datos de la aplicación directamente disparando comandos a la base de datos.



Estos motivos hacen que, la mayoría de los programadores, opte por utilizar una autentificación mixta y pasar el nombre de usuario y contraseña en la string de conexión. Esta forma de trabajar garantiza que solo la aplicación puede acceder a la base de datos independientemente de los permisos del usuario que la utiliza. Pero, ¿qué tanto riesgo existe en colocar las credenciales en la aplicación?



Si se utiliza una autentificación SQL para conectarse a un servidor, será necesario guardar la contraseña en algún lugar para proporcionársela al servidor cuando la aplicación necesite conectarse. Las alternativas pueden ir de una solución muy simple y poco segura (tal como almacenarla en el mismo código) a más compleja como por ejemplo utilizar archivos de configuración y cifrar su contenido.



No obstante, sea cual sea la mecánica que se utilice para almacenarla, la aplicación enviará, tarde o temprano, (por la red) esta información al servidor en texto “casi” plano por lo que puede ser interceptada por un hacker.



La intención de este artículo es demostrar lo simple que resulta obtener las credenciales de usuario utilizadas en una string de conexión que se utiliza para extraer información de un servidor SQL.



Para ello, lo primero que hace falta es una aplicación que se conecte a SQL Server utilizando la autenticación básica y luego utilizar una herramienta para interceptar el tráfico de red entre el servidor y el cliente.



En mi caso, voy a utilizar Network Monitor de Windows para monitorizar el tráfico entre las partes.



 


Nota: Esta herramienta viene con el sistema operativo, pero no se instala por defecto. Para agregarla se debe utilizar el panel de control. Los pasos son:


·          Star -> Control Panel -> Add/Remove Programs


·          Add Remove Windows Components


·          Seleccionar Management a Monitoring Tools


·          Hacer click en el botón Details


·          Marcar Network Monitor Tools


·          Presionar OK


·          Presionar Next



El escenario que he utilizado para escribir este artículo es muy simple: consta de un pc cliente con la aplicación que accederá al servidor de base de datos que se encuentra en otra PC. De ahora en más los llamaré PC Cliente y Servidor, respectivamente.



En el PC Cliente he instalado Network Monitor aparte de la aplicación que voy a utilizar para disparar consultas a la base de datos.



Por cuestiones de sencillez he guardado la cadena de conexión en el mismo código. Aunque recomiendo no hacer esto. Es muy fácil ver el código fuente a partir de un ensamblado (Ver http://www.aisto.com/roeder/dotnet/). Incluso se puede pensar que basta con utilizar el ofuscador de código que viene con Visual Studio para esconder el contenido de la cadena de conexión, pero esto no es así. En la versión gratuita del ofuscador no se pueden cifrar strings. Por lo que el código si queda ofuscado, pero el contenido de la string de conexión sigue siendo visible.



Mi aplicación tiene el siguiente código (porción que interesa):




Entonces, antes de ejecutarla, debo iniciar el Network Monitor e indicarle que escuche la información transmitida entre la PC Cliente y la PC Servidor.


Para ello sigo los siguientes pasos:


·          Start -> Programs -> Administrative Tools -> Network Monitor


·          Ya dentro de Network Monitor, selecciono Capture -> Start


·          Ahora que está monitorizando el tráfico, ejecuto mi aplicación cliente para que se conecte al servidor de base de datos.


·          Una vez ha concluido la consulta, vuelvo al Network Monitor y selecciono la opción Capture -> Stop and View


·          Network Monitor me muestra todo el tráfico capturado.



Dentro de esta información recolectada es donde, en alguna parte, se encuentran las credenciales de usuario enviadas por la aplicación cliente.


Es importante saber que, prácticamente, todos los datos de la cadena de conexión viajan en texto plano, por lo que es muy sencillo encontrar la información mirando los paquetes SMB, tal como se muestra en la siguiente imagen:


 





La parte más interesante es que la contraseña viaja cifrada, aunque el mecanismo que se utiliza para esconder su contenido es bastante simple y por lo tanto muy poco seguro.


Veamos como cifra el cliente la password cuando contacta con el servidor:



 



Si miramos con atención hay un conjunto de siglas prácticamente ilegibles que siguen un patrón bastante simple. Se trata de la contraseña que el cliente ha cifrado. En la siguiente imagen se puede apreciar que por cada byte, a la derecha, aparece un byte repetido (A5).


Es factible buscar este byte seleccionando las opciones: Display -> Find Next Frame. En la pestaña Property, seleccionar SMB -> Data y, verificando que la opción Contains está seleccionada ingresar el valor A5. Al presionar OK se visualiza la trama correspondiente.



Hasta aquí hemos obtenido el nombre de usuario utilizado por la aplicación y un conjunto de Bytes que representar el password. Si bien la contraseña parece estar cifrada se trata de un mecanismo muy sencillo de ofuscación utilizando la operación XOR. Para descifrarlo lo único que hace falta es realizar los siguientes pasos:



a)      Invertir todos los bytes que contienen la contraseña:


      Original: A2 B3 92 92 D2 53 82 E3


      Convertido: 2A 3B 29 29 2D 35 28 3E


b)      Aplicarles un XOR con 5A (que es el valor invertido de A5)


      2A (XOR) 5A =  70


      3B (XOR) 5A = 61


            29 (XOR) 5A = 73


            29 (XOR) 5A = 73


            2D (XOR) 5A = 77


            35 (XOR) 5A = 6F


            28 (XOR) 5A = 72


            3E (XOR) 5A = 64


 c)       Convertir a decimal y ver su representación ASCII:


            112,  p


             97,   a


            115,  s


            115,  s


            119,  w


            111,  o


            114,  r


            100,  d


Conclusión:



Si utiliza autenticación mixta debería utilizar simultáneamente algún mecanismo que cifre el tráfico entre el cliente y el servidor. Algunas opciones posibles son IPSec o SSL.

Un comentario en “Interceptando contraseñas de SQL”

  1. Hola

    me parece muy interesante este tema de la intercepcion SQL, soy nuevo en estos trotes ¿sabes de algun programa que intercepte los querys a una base SQL? las consultas las hace un programa X.

    Saludos

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *