Hackeando un SQL Server

24/01/2005

pdf

¿Considera que el servidor de Microsoft SQL es un ambiente popular y robusto para muchos usos que utilicen bases de datos? En efecto, éste ofrece excelentes capacidades multi-access, cobertura comprensiva de la seguridad y puede ser transportado fácilmente a otras plataformas de la base de datos. Este artículo apunta a identificar ciertos tipos de riesgos que pudieron resultar de la gerencia inadecuada del servidor de Microsoft SQL.

Microsoft SQL Server es un medio popular y robusto para muchas aplicaciones que utilizan bases de datos, ofrece excelentes capacidades multi-acceso, cubre aspectos de seguridad y puede utilizarse fácilmente con otras plataformas de base de datos. Desafortunadamente, no se podrá observar tal potencial, a pesar del uso del MSDE (motor de la base de datos de Microsoft, optimizado para soluciones individuales o pequeñas de un grupo de trabajo) si no se proporciona un mínimo de protección adecuada a la seguridad de las bases de datos. ¿Por qué es necesaria esta tecnología? Porque las altas capacidades del SQL Server se combinan con alta flexibilidad, y demasiada flexibilidad puede ser perjudicial si es utilizada de forma incorrecta.

Si se configuran correctamente, cada SQL Server permite que todos los usuarios tengan acceso a la base de datos principal, que a su vez contenga la configuración del SQL Server y toda la información que el SQL Server utiliza para abrir las bases de datos. También incluye todas las identificaciones SQL, datos de los servidores conectados etc. Por supuesto no se permite a los usuarios "normales" tener acceso a todos los recursos de la información.

La figura 1 ilustra cómo se comporta el servidor con un intento de acceso a la lista de cuentas, como puede verse, el servidor evita la lectura de contraseñas a los usuarios. Sin embargo, los nombres de cuenta y las bases de datos (incluyendo la información almacenada en ellas) se pueden alcanzar por usuarios no privilegiados. Un ejemplo que muestra una parte de información adquirida por un usuario, se ilustra abajo, en el cuadro 2.

CUADRO 1: Un intento fallido de acceso a la lista de usuarios.

CUADRO 2: Cuando un usuario normal manipula el acceso a la lista usuarios.

Desplazándonos al final de la pantalla en la figura anterior, obtenemos las líneas finales de la solicitud a la base de datos, mostradas a continuación:

  1> select name, dbid from sysdatabases
  2> go
  namedbid
 -----------------
  master1
  tempdb2
  model3
  msdb4
  pubs5
  Northwind6
  Pages7
  (7 rows affected)
  

Puede apreciarse lo difícil que es mantener los datos a salvo de usuarios curiosos.

Por supuesto, el lector podría inquirir "pero, después de todo, mis usuarios no tienen permitido realizar peticiones en el SQL Server", no obstante, si se examina minuciosamente lo anterior es una afirmación bastante dudosa, ¡porque la posibilidad o imposibilidad de poner peticiones deliberadamente creadas en una aplicación del SQL Server no implica necesariamente que la misma regla es válida para el propio servidor!

Aunque una aplicación específica es segura aparentemente contra tal situación, sugiere reconsiderar la idea de "que todos los scripts están protegidos contra ataques de SQL Injection"[[1][2] ¿Qué si el usuario, al definir las condiciones de una petición, puede unir una tabla a los resultados? ¿Y cuál es el esquema de autenticación definido en el servidor que se aplicará a usuarios potenciales? Incluso si la aplicación presumiblemente está bien protegida contra el acceso no autorizado, acaso el propio usuario no puede ejecutar las herramientas de comunicación estándar en su computadora para conectar el SQL Server sql.exe, VBScript que utiliza ADO, o cualquier otro programa que funcione como ODBC (u OLEDB), directamente con el servidor de la base de datos.

Conocer la contraseña del SQL Server es el único prerrequisito. Todavía, en muchas situaciones la posibilidad de autenticación de los usuarios locales de la red en los servicios de directorio es suficiente. Sin embargo no deje que la paranoia lo domine, simplemente debemos aceptar que la posibilidad de autenticación del usuario en el SQL Server está asociada a sus permisos de realizar peticiones probadas, o aún las indiscretas.

¿Cuáles son las conclusiones?

En el ejemplo anterior se entregan los nombres de usuarios, algunos están definidos en el SQL Server y son reconocibles por el valor 0 en la columna "isntname". Si está c se configura para realizar la autenticación en modo de autenticación mixto, el SQL Server aceptará intentos de conexión con estas cuentas, mientras no se deshabilite la cuenta por intentos repetidos. Éste es el inconveniente del mecanismo de autenticar conexiones en modo mixto del SQL Server. Afortunadamente, su uso es opcional y aún cuando está presente, no se recomienda, porque crea las oportunidades para un ataque de fuerza bruta en el cual se pruebe cada llave o contraseña posible hasta que se encuentra la correcta.

Un atacante puede hacer esto si usa un programa adecuado para automatizar tal trabajo. La más "apreciada" es una cuenta "sa" (administrador de sistema), que tiene acceso a todo lo creado específicamente por el SQL Server (es similar a root en Linux o LocalSystem en Windows NT) al contar con privilegios para manejar cualquier base de datos (incluyendo la base de datos "master"), acceso completo para realizar cualquier función en el SQL Server e incluso ejecutar los procesos que son heredados por el servidor, a saber el proceso SQLSERVR.EXE.

Por otra parte, en muchas instalaciones, el SQL Server funciona en el contexto que tiene el administrador de la seguridad - de tal modo el usuario "sa" puede manejar una computadora con el servicio de MS SQL Server instalado además de todas las bases de datos. Al trabajar con MSDE, la situación empeora, pues el servicio está instalado debajo de LocalSystem, con una cuenta por default "sa" con una contraseña ¡EN BLANCO! El cuadro 3 ilustra dos intentos consecutivos de obtener la cuenta "sa", uno erróneo y otro acertado.

CUADRO 3: ¿Dos ataques contra una cuenta "sa", con una contraseña en blanco? El segundo intento es exitoso.

Usando la cuenta del administrador del sistema

Primero que nada, el usuario "sa" tiene control sobre todos los datos, esquema y disposición del SQL Server. No es necesario entrar en detalles porque la lista de privilegios del administrador de sistema puede contener casi cualquier cosa. Mejor centrémonos en ciertos tipos de ataques maliciosos. El más simple consiste en crear una cuenta nueva con los mismos privilegios que el usuario "sa" tiene. A continuación se muestra un ejemplo:

  1> sp_addlogin 'hacked','h4xor'
  2> go
  New login created.
  1> sp_addsrvrolemember 'hacked','sysadmin'
  2> go
  'hacked' added to role 'sysadmin'.
  1> quit
  C:\>osql -U hacked -P h4xor -Q "SELECT DB_NAME(),USER_NAME()"
 -----------
  master   dbo
  (1 row affected)
  C:\>
  

En lugar del procedimiento "sp_addlogin" uno puede utilizar, por ejemplo, el "sp_grantlogin" éste crea una cuenta que es autenticada por el sistema operativo en el que se encuentre el SQL Server. Se debe hacer notar, que es muy fácil ganar privilegios "sa" apenas asignando el rol de sysadmin a la cuenta seleccionada del usuario (o un grupo de usuarios definidos en la fase de inicialización del SQL Server).

Aparte de este rol, el servicio del SQL Server permite explotar otra característica que, sin embargo, no se puede utilizar para manejar completamente el servidor. (Consultar [3]). Por supuesto, no se puede excluir que el administrador detectará tal cuenta (incluso si su nombre no parece inusual). Si es así un atacante no tiene otra opción más que utilizar la cuenta existente la manera más simple sería modificar la contraseña empleando el procedimiento "sp_password".-

Si un intruso desea cubrir su rastro, puede intentar descifrar las contraseñas, que utilizan los usuarios para acceder al servidor. Debemos recordar en este punto el modo mixto de autenticación, el SQL Server puede utilizar su propio mecanismo de autenticación almacenando no sólo la información de los identificadores de los usuarios (similar a la autenticación realizada por el sistema operativo), también contraseñas. Esto se hace en la columna de "passwd" de la tabla de syslogins la cual contiene un hash de la contraseña del usuario producida por la función pwdencrypt().

Este es un hecho bastante conocido, descrito brillantemente por David Litchfield en su artículo "Crackeando contraseñas en SQL" [4] indica las herramientas que se pueden utilizar para realizar ataques de fuerza bruta [5]. Si su SQL Server no se configura para utilizar SQL Server Authentication, no tiene que preocuparse de ser atacado de dicha manera. Un intruso más malévolo puede procurar instalar una puerta trasera. Dos posibilidades se presentan a continuación.

Procedimientos Almacenados Extendidos

El SQL Server ofrece la posibilidad de ejecutar procedimientos escritos por el usuario. Estos procedimientos pueden ser escritos en el lenguaje de SQL y almacenados en cualquier base de datos, o ser bibliotecas de ligado dinámico (DLLs) que el SQL Server pueda cargar y ejecutar dinámicamente si lo requiere. Este último tipo se conoce como "procedimientos almacenados extendidos" y tienen características interesantes: se agregan directamente al SQL Server y comparten la seguridad ejecutada por el SQL Server. En la práctica, éstos se hacen para funcionar con privilegios de "sa" en la base de datos. Pueden ser definidos solamente en la base de datos "master" y pueden ser agregados a la base de datos exclusivamente por el administrador (el usuario "sa").

La configuración del SQL Server por default contiene virtualmente un número enorme de estos procedimientos, sin embargo la mayoría de ellos no están documentados. Los procedimientos almacenados extendidos ejecutan bajo diversos esquemas de autenticación, ciertos procedimientos son accesibles para todos los usuarios incluso de forma predeterminada o porque la funcionalidad del servidor los requiere. Solamente el administrador de sistema puede ejecutar otros procedimientos almacenados extendidos.

Esto crea varias dificultades operacionales para el administrador especialmente en la detección de procedimientos "especiales" que un intruso colocó probablemente en el servidor. Es suficiente cargar un archivo DLL previamente preparado (usando el API de Open Data Services, que se instala opcionalmente con el SQL Server), llama después al procedimiento "sp_addextendedproc" con sus respectivos argumentos, se conceden derechos de ejecución de dicho procedimiento para todos los usuarios (por ejemplo, al grupo de usuarios "public"). El resultado, un atacante podrá utilizar tal procedimiento podrá ser utilizado por un atacante, para ejecutar operaciones con privilegios de "sa" desde cualquier cuenta de usuario sin importar su nivel.

¿Por qué no revocar la autorización?

Chris Anley en su documento titulado "Violating Database - Enforced Security Mechanisms" [6], describe un enfoque para mejorar la seguridad, que incluye una modificación del funcionamiento de SQL Server para que se ignoren las peticiones de "cualquiera" excepto de los usuarios "sa". Su invención se basa en el manejo de excepciones de autorización por el código SQL.

"En vez de intentar un análisis estático de todo el código de la base de datos, con un pequeño depurador nos llevaría en la dirección correcta". Por supuesto, dichos cambios son factibles bajo ciertas condiciones, algunas manipulando el archivo ejecutable que contiene el código de la base de datos o haciendo operaciones en la imagen en memoria. En ambos casos el administrador del SQL Server es la única persona autorizada para hacerlo. Sin embargo, esta es una situación simplificada y la realidad es más triste. Antes de entrar en mayor detalle, recordemos que es importante el observar los boletines de seguridad, pues de otra forma el buffer podría desbordarse.

¿Por qué el problema de buffer overrun es de preocuparse?

SQL Server procedimientos predeterminados, por ejemplo funciones DLL que vienen con el SQL Server. Dichas rutinas están escritas en lenguajes de alto nivel (por ejemplo C) y son compiladas como DLL. Cuando comienza la ejecución, leen los parámetros que introduce el usuario a un buffer de memoria. Sin embargo podría suceder, por alguna razón, que el programador olvide codificar una verificación de datos antes de meter la información en las variables del programa, y si un atacante envía demasiada información es posible que dichos datos se "desborden" del tamaño predeterminado y sobrescriban datos en las áreas adyacentes del buffer.

Este desbordamiento del buffer puede permitir a usuarios maliciosos ejecutar comandos de cualquier tipo en el sistema remoto. (Ver, por ejemplo, "Análisis de Ataques de Buffer Overflow" por Piotr Frej y Maciej Ogórkiewicz).

El problema es que SQL Server de Microsoft contiene procedimientos que son vulnerables a este tipo de ataques. Estos procedimientos y funciones implementadas en el lenguaje Transact-SQL (un ejemplo puede ser la función antes mencionada "pwdencrypt"). Esto puede suceder también con las bibliotecas OLEDB, que son objetos COM cargados en el proceso del cliente.

Recuerde que en el contexto COM, todo programa basado en componentes se convierte en cliente. Siempre que el comando OPENROWSET es activado, el SQL Server se convierte en cliente del proveedor de datos, que lo hace automáticamente vulnerable a errores en el código de alguna función de OLEDB. Aquellos interesados pueden leer varios boletines de seguridad [7] para mayores detalles de los problemas y de las soluciones propuestas. Si lo hacen tengan en cuenta que un ataque de buffer overflow exitoso significa que el usuario puede ejecutar cualquier código en el SQL Server en el contexto de la cuenta de administración local. Estos privilegios de ("sa") permiten la manipulación arbitraria del servicio de SQL, sin embargo seguimos con el mismo problema ¿qué tan poderosos son los privilegios "sa" en el contexto del sistema?

Son igualmente poderosos que el servicio SQL y razonablemente estrictos en términos de seguridad, dichos privilegios corresponden a los del proceso SQLSERVR.EXE. De forma predeterminada el servidor SQL incluye varios procedimientos eficaces para comunicarse con el sistema operativo. Por sólo mencionar algunos de ellos: "xp_cmdshell", "sp_OACreate","xp_regwrite","xp_instance_rewrite", "xp_adsirequest". Aunque algunos de ellos están documentados (los dos primeros), aún no estamos seguros de los efectos de los otros.

Con estos procedimientos los administradores del servidor SQL pueden interactuar con el sistema operativo y con la limitación del nivel de privilegios configurada en el servicio de MSSQLSERVER. Si fuera el caso de que este servicio se ejecute bajo la cuenta de LocalSystem, el "sa" podría acceder a los mayores privilegios para ingresar al escritorio, pero no a los servicios de red. El atacante puede usar los privilegios como se ilustra en la figura 4.

FIGURA 4: Usando la cuenta "sa" para cargar un programa desde Internet al servidor.

Si en vez de esto, se ejecuta el servicio con una cuenta de dominio, que tenga acceso a la red, entonces el "sa" puede acceder a toda ella. Los privilegios del "sa" dependen de cómo se configuró MSSQLSERVER. En la documentación de SQL Server, se especifica claramente que la cuenta de MSSQLSERVER es una cuenta de usuario y no de sistema. Incluso aunque leímos en los boletines de seguridad de Microsoft del SQL: "SQL Server 2000 puede ejecutarse con una cuenta no-administrativa, requiere de un completo acceso a la llave de registro:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MSSQLServer"

Teniendo este nivel de acceso, el SQL Server, puede modificar un valor de "ObjectName" en el registry. Éste contiene el nombre de la cuenta que se requiere para ejecutar el servicio. Y es suficiente para reconfigurar el servicio, ejecutando como LocalSystem. Por lo tanto, un atacante que pueda aplicar código sobre la cuenta de SQL Server es capaz de reconfigurar el servicio para que se implemente con los mayores privilegios del sistema, aunque el SQL Server lo haga como usuario normal. Este problema fue tratado en la tercera sección del boletín MS02-034 [8]. Para leer acerca de los permisos que requiere SQL Server, ver el documento SQL Server 2000 Security[9]

¿LocalSystem predeterminado?

El Servidor MS SQL 2000 Desktop Edition (MSDE 2000), en la última versión se instala con cuenta de LocalSystem de forma predeterminada. Por supuesto, esto genera el potencial de vulnerabilidades antes mencionadas. Naturalmente el parche para SQL Server, Service Pack 3, mejora la seguridad sólo en el servicio SQL, no así en el equipo en que se ejecuta.

Al tener Service Pack 3, se pueden experimentar problemas si el servidor se está ejecutando fuera de la localhost. Esto es consecuencia de los permisos que se colocan en las llaves del registry y en el sistema de archivos donde se instala el Service Pack 3. Por supuesto, minimiza privilegios no deseados, que es algo positivo, pero fuera de este enfoque, la documentación insuficiente es una mala práctica. Más adelante se incluye información básica para ayudarle a documentar correctamente.

Para reducir los privilegios asociados a MSDE en el sistema operativo:

  • Sustituya las cuentas de MSSQLSERVER y SQLSERVERAGENT (de LocalSystem) a alguna otra.

  • Dé a la nueva cuenta permiso de leer en el directorio C:\Program Files\Microsoft SQL Server\MSSQL, recordando seleccionar la opción "Reset permisions on all child objects".

  • Aplique todos los privilegios en los subdirectorios DATA y LOG.

  • Ejecute regedt32.exe (registry editor) (de tal manera que permita editar permisos, usar regedit.exe en windows xp) y conceda todos los permisos para la cuenta en la llave de registro HKLM\SOFTWARE\Microsoft\MSSQLServer. Re-ejecute "Reset permisions on all child objects..."

  • Permita a la cuenta acceso de *sólo lectura, en la llave de registro HKLM\SYSTEM\CurrentControlSet\Services\MSSQLSERVER

  • Ejecute el servicio MSSQLSERVER

  • Agregue la cuenta del servicio al rol de sysadmin (para soporte del servicio de SQLServerAgent), usando los siguientes comandos:

  •     1> sp_grantlogin 'COMPUTER\account_sql'
        2> go
        Granted login access to 'COMPUTER\account_sql'.
        1> sp_addsrvrolemember 'COMPUTER\account_sql','sysadmin'
        2> go
        'COMPUTER\account_sql' added to role 'sysadmin'.
        
    
  • Ejecute el servicio SQLServerAgent

Los comandos SQL deben ser ejecutados con el programa osql.exe, bajo la cuenta de administrador de sistema especificando el parámetro E. Obviamente, deberá especificar el nombre real de la cuenta de SQL Service, precedido por el nombre del equipo. Si no desea permitir acceso al Servidor MSDE desde la red, deshabilite la siguiente llave de registro:

HKLM\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\SuperSocketNetLib

Por razones obvias, es buena práctica exportar dicha llave de registro en un archivo .reg antes de hacer cambios. Si hay problemas al iniciar el servicio MSDE, use FileMon y RegMon disponibles en www.sysinternals.com, las cuales son - Son herramientas muy útiles cuando se analizan y remedian dificultades, resultado de reglas sobre-protectoras en el registro o sistemas de archivos. Vale la pena consultar la documentación de SQL Server 2000 [3][9].

Referencias

[1]
http://www.spidynamics.com/papers/SQLInjectionWhitePaper.pdf
[2]
http://www.it-faq.pl/itfaqarticle.asp?id=136
[3]
http://msdn.microsoft.com/library/en-us/startsql/portal_7ap1.asp
[4]
http://www.nextgenss.com/papers/cracking-sql-passwords.pdf
[5]
http://www.cqure.net/tools10.html
[6]
http://www.nextgenss.com/papers/violating_database_security.pdf
[7]
http ://www.microsoft.com/technet/security/current.asp?productid=30
[8]
http://www.microsoft.com/technet/security/bulletin/MS02-034.asp
[9]
http://www.microsoft.com/technet/prodtechnol/sql/maintain/security/sql2ksec.asp

Liberación original: Lunes, 24 Enero 2005
Última revisión: Jueves, 16 Junio 2011

La Coordinación de Seguridad de la Información/UNAM-CERT agradece el apoyo en la elaboración y revisión de este documento a:

Rosendo Méndez López

Para mayor información acerca de este documento contactar a:

UNAM-CERT: Equipo de Respuesta a Incidentes UNAM 
Coordinación de Seguridad de la Información 
Dirección General de Cómputo y Tecnologías de Información y Comunicación 
Universidad Nacional Autónoma de México 
E-Mail: incidentes@cert.unam.mx 
http://www.cert.org.mx
http://www.seguridad.unam.mx
ftp://ftp.seguridad.unam.mx
Tel: 56 22 81 69