👾Ataques a Bases de Datos
MySQL y Microsoft SQL Server ( MSSQL
) son sistemas de administración de bases de datos relacionales que almacenan datos en tablas, columnas y filas. Muchos sistemas de bases de datos relacionales como MSSQL y MySQL utilizan el Structured Query Language ( SQL
) para consultar y mantener la base de datos.
Los hosts de bases de datos se consideran objetivos importantes, ya que son responsables de almacenar todo tipo de datos confidenciales, incluidos, entre otros, credenciales de usuario, Personal Identifiable Information (PII)
datos relacionados con el negocio e información de pago. Además, esos servicios suelen estar configurados con usuarios muy privilegiados. Si obtenemos acceso a una base de datos, es posible que podamos aprovechar esos privilegios para realizar más acciones, incluido el movimiento lateral y la escalada de privilegios.
Enumeración
De forma predeterminada, MSSQL usa puertos TCP/1433
y UDP/1434
y MySQL usa TCP/3306
. Sin embargo, cuando MSSQL opera en modo "oculto", utiliza el puerto TCP/2433
. Podemos usar la opción -sC
de scripts predeterminados de Nmap
de para enumerar los servicios de bases de datos en un sistema de destino:
Banner Grabbing
El escaneo de Nmap revela información esencial sobre el objetivo, como la versión y el nombre de host, que podemos usar para identificar configuraciones erróneas comunes, ataques específicos o vulnerabilidades conocidas. Exploremos algunas configuraciones erróneas comunes y ataques específicos de protocolo.
Mecanismos de autenticación
MSSQL
admite dos modos de autenticación , lo que significa que los usuarios se pueden crear en Windows o SQL Server:
MySQL
también admite diferentes métodos de autenticación , como nombre de usuario y contraseña, así como autenticación de Windows (se requiere un complemento). Además, los administradores pueden elegir un modo de autenticación por muchos motivos, incluida la compatibilidad, la seguridad, la usabilidad y más. Sin embargo, dependiendo del método que se implemente, pueden ocurrir errores de configuración.
En el pasado, había una vulnerabilidad CVE-2012-2122 en los servidores MySQL 5.6.x
, entre otras, que nos permitía omitir la autenticación usando repetidamente la misma contraseña incorrecta para la cuenta dada porque la vulnerabilidad timing attack
existía en la forma en que MySQL manejaba los intentos de autenticación.
En este ataque de sincronización, MySQL intenta repetidamente autenticarse en un servidor y mide el tiempo que tarda el servidor en responder a cada intento. Al medir el tiempo que tarda el servidor en responder, podemos determinar cuándo se ha encontrado la contraseña correcta, incluso si el servidor no indica éxito o fracaso.
En el caso de MySQL 5.6.x
, el servidor tarda más en responder a una contraseña incorrecta que a una correcta. Así, si intentamos autenticarnos repetidamente con la misma contraseña incorrecta, eventualmente recibiremos una respuesta indicando que se encontró la contraseña correcta, aunque no sea así.
Configuraciones erróneas
La autenticación mal configurada en SQL Server puede permitirnos acceder al servicio sin credenciales si se habilita el acceso anónimo, se configura un usuario sin contraseña o cualquier usuario, grupo o máquina tiene permiso para acceder a SQL Server.
Privilegios
Dependiendo de los privilegios del usuario podremos realizar diferentes acciones dentro de un SQL Server, como por ejemplo:
Leer o cambiar el contenido de una base de datos.
Leer o cambiar la configuración del servidor.
Ejecutar comandos
Leer archivos locales
Comunicarse con otras bases de datos.
Capturar el hash del sistema local
Suplantar a usuarios existentes
Obtener acceso a otras redes
En esta sección, exploraremos algunos de estos ataques.
Ataques específicos de protocolo
Es fundamental comprender cómo funciona la sintaxis SQL. Podemos utilizar el módulo gratuito Fundamentos de inyección SQL para presentarnos la sintaxis SQL. Aunque este módulo cubre MySQL, la sintaxis de MSSQL y MySQL es bastante similar.
Leer/cambiar la base de datos
Imaginemos que obtuvimos acceso a una base de datos SQL. Primero, necesitamos identificar las bases de datos existentes en el servidor, qué tablas contiene la base de datos y, finalmente, el contenido de cada tabla. Hay que tener en cuenta que podemos encontrarnos con bases de datos con cientos de tablas. Si nuestro objetivo no es sólo obtener acceso a los datos, necesitaremos elegir qué tablas pueden contener información interesante para continuar con nuestros ataques, como nombres de usuario y contraseñas, tokens, configuraciones y más. Veamos cómo podemos hacer esto:
MySQL: conexión al servidor SQL
Sqlcmd: conexión al servidor SQL
Desde Windows:
Nota: Cuando nos autenticamos en MSSQL usando sqlcmd
podemos usar los parámetros -y
(SQLCMDMAXVARTYPEWIDTH) y -Y
(SQLCMDMAXFIXEDTYPEWIDTH) para obtener un resultado más atractivo. Tenga en cuenta que puede afectar el rendimiento.
Conexión desde Linux
Si apuntamos a MSSQL
desde Linux, podemos usar sqsh
como alternativa a sqlcmd
:
Alternativamente, podemos utilizar la herramienta de Impacket con el nombre mssqlclient.py
.
Nota: Cuando nos autenticamos en MSSQL usando sqsh
podemos usar el parámetro-h
para deshabilitar encabezados y pies de página para una apariencia más limpia.
Cuando utilizamos la autenticación de Windows, debemos especificar el nombre de dominio o el nombre de host de la máquina de destino. Si no especificamos un dominio o nombre de host, asumirá la autenticación SQL y se autenticará con los usuarios creados en SQL Server. En cambio, si definimos el dominio o nombre de host, utilizará la Autenticación de Windows. Si nos dirigimos a una cuenta local, podemos usar SERVERNAME\\accountname
o .\\accountname
. El comando completo se vería así:
Bases de datos SQL predeterminadas
Antes de explorar el uso de la sintaxis SQL, es esencial conocer las bases de datos predeterminadas para MySQL
y MSSQL
. Esas bases de datos contienen información sobre la base de datos en sí y nos ayudan a enumerar nombres de bases de datos, tablas, columnas, etc. Con acceso a esas bases de datos, podemos usar algunos procedimientos almacenados del sistema, pero generalmente no contienen datos de la empresa.
Nota: Recibiremos un error si intentamos enumerar o conectarnos a una base de datos para la que no tenemos permisos.
Schemas/databases predeterminadas en MySQL
:
MySQL
:mysql
- es la base de datos del sistema que contiene tablas que almacenan la información requerida por el servidor MySQLinformation_schema
- proporciona acceso a los metadatos de la base de datosperformance_schema
- es una característica para monitorear la ejecución del servidor MySQL en un nivel bajosys
- un conjunto de objetos que ayuda a los administradores de bases de datos y a los desarrolladores a interpretar los datos recopilados por el esquema de rendimiento
Schemas/databases predeterminadas en MSSQL
:
MSSQL
:master
- mantiene la información de una instancia de SQL Server.msdb
- utilizado por el Agente SQL Server.model
- una base de datos modelo copiada para cada nueva base de datos.resource
- una base de datos de solo lectura que mantiene los objetos del sistema visibles en cada base de datos del servidor en el esquema del sistema.tempdb
- mantiene objetos temporales para consultas SQL.
Sintaxis SQL
Mostrar bases de datos
Si usamos sqlcmd
, necesitaremos usar GO
después de nuestra consulta para ejecutar la sintaxis SQL.
Seleccionar una base de datos
Mostrar tablas
Seleccionar una tabla
Seleccionar todos los datos de la tabla "usuarios"
Ejecutar comandos
Command execution
Es una de las capacidades más deseadas a la hora de atacar servicios comunes porque nos permite controlar el sistema operativo. Si tenemos los privilegios adecuados, podemos utilizar la base de datos SQL para ejecutar comandos del sistema o crear los elementos necesarios para hacerlo.
MSSQL
tiene un procedimiento almacenado extendido llamado xp_cmdshell que nos permite ejecutar comandos del sistema usando SQL. Tenga en cuenta lo siguiente sobre xp_cmdshell
:
xp_cmdshell
es una característica poderosa y está deshabilitada de forma predeterminada.xp_cmdshell
se puede habilitar y deshabilitar mediante la administración basada en políticas o ejecutando sp_configureEl proceso de Windows generado
xp_cmdshell
tiene los mismos derechos de seguridad que la cuenta de servicio de SQL Server.xp_cmdshell
opera sincrónicamente. El control no se devuelve a la persona que llama hasta que se completa el comando del shell de comandos
Para ejecutar comandos usando la sintaxis SQL en MSSQL, use:
XP_CMDSHELL
Si xp_cmdshell
no está habilitado, podemos habilitarlo, si tenemos los privilegios adecuados, usando el siguiente comando:
Existen otros métodos para obtener la ejecución de comandos, como agregar procedimientos almacenados extendidos , ensamblados CLR , trabajos del Agente SQL Server y scripts externos . Sin embargo, además de esos métodos, también existen funcionalidades adicionales que se pueden utilizar, como el xp_regwrite
comando que se utiliza para elevar privilegios mediante la creación de nuevas entradas en el registro de Windows. Sin embargo, esos métodos están fuera del alcance de este módulo.
MySQL
admite funciones definidas por el usuario que nos permiten ejecutar código C/C++ como una función dentro de SQL; hay una función definida por el usuario para la ejecución de comandos en este repositorio de GitHub . No es común encontrar una función definida por el usuario como esta en un entorno de producción, pero debemos tener en cuenta que es posible que podamos utilizarla.
Escribir archivos locales
MySQL
no tiene un procedimiento almacenado como xp_cmdshell
, pero podemos lograr la ejecución de comandos si escribimos en una ubicación en el sistema de archivos que pueda ejecutar nuestros comandos. Por ejemplo, supongamos que MySQL
opera en un servidor web basado en PHP u otros lenguajes de programación como ASP.NET. Si tenemos los privilegios adecuados, podemos intentar escribir un archivo usando SELECT INTO OUTFILE en el directorio del servidor web. Luego podemos buscar la ubicación donde está el archivo y ejecutar nuestros comandos.
MySQL - Escribir archivo local
En MySQL
, una variable global del sistema Secure_file_priv limita el efecto de las operaciones de importación y exportación de datos, como las realizadas por las declaraciones LOAD DATA
y la función LOAD_FILE() . Estas operaciones sólo están permitidas a los usuarios que tienen el privilegio ARCHIVO .SELECT … INTO OUTFILE
secure_file_priv
se puede establecer de la siguiente manera:
Si está vacía, la variable no tiene ningún efecto, lo que no es una configuración segura.
Si se configura con el nombre de un directorio, el servidor limita las operaciones de importación y exportación para que funcionen solo con archivos en ese directorio. El directorio debe existir; el servidor no lo crea.
Si se establece en NULL, el servidor deshabilita las operaciones de importación y exportación.
En el siguiente ejemplo, podemos ver que la variable secure_file_priv
está vacía, lo que significa que podemos leer y escribir datos usando MySQL
:
MySQL: privilegios de archivos seguros
Para escribir archivos usando MSSQL
, necesitamos habilitar Ole Automation Procedimientos , que requiere privilegios de administrador, y luego ejecutar algunos procedimientos almacenados para crear el archivo:
MSSQL: habilitar procedimientos de automatización Ole
MSSQL: crear un archivo
Leer archivos locales
De forma predeterminada, MSSQL
permite la lectura de archivos en cualquier archivo del sistema operativo al que la cuenta tenga acceso de lectura. Podemos utilizar la siguiente consulta SQL:
Leer archivos locales en MSSQL
Como mencionamos anteriormente, de forma predeterminada una instalación de MySQL
no permite la lectura de archivos arbitrarios, pero si contamos con la configuración correcta y los privilegios adecuados, podemos leer archivos usando los siguientes métodos:
MySQL - Leer archivos locales en MySQL
Capturar hash del servicio MSSQL
En la sección Ataques a SMB
, discutimos que podríamos crear un servidor SMB falso para robar un hash y abusar de alguna implementación predeterminada dentro de un sistema operativo Windows. También podemos robar el hash de la cuenta de servicio MSSQL utilizando procedimientos almacenados xp_subdirs
o xp_dirtree
no documentados, que utilizan el protocolo SMB para recuperar una lista de directorios secundarios en un directorio principal específico del sistema de archivos. Cuando utilizamos uno de estos procedimientos almacenados y lo apuntamos a nuestro servidor SMB, la funcionalidad de escucha del directorio obligará al servidor a autenticarse y enviar el hash NTLMv2 de la cuenta de servicio que ejecuta SQL Server.
Para que esto funcione, primero debemos iniciar Responder o impacket-smbserver y ejecutar una de las siguientes consultas SQL:
XP_DIRTREE Robo de hash
XP_SUBDIRS Robo de hash
Si la cuenta del servicio tiene acceso a nuestro servidor, obtendremos su hash. Luego podemos intentar descifrar el hash o transmitirlo a otro host.
XP_SUBDIRS Robo de hash con Responder
XP_SUBDIRS Robo de hash con Impacket
Suplantar a usuarios existentes con MSSQL
SQL Server tiene un permiso especial, llamado IMPERSONATE
, que permite al usuario ejecutor asumir los permisos de otro usuario o iniciar sesión hasta que se restablezca el contexto o finalice la sesión. Exploremos cómo el privilegio IMPERSONATE
puede conducir a una escalada de privilegios en SQL Server.
Primero, necesitamos identificar a los usuarios a los que podemos suplantar. Los administradores de sistemas pueden hacerse pasar por cualquier persona de forma predeterminada, pero para los usuarios que no son administradores, los privilegios deben asignarse explícitamente. Podemos utilizar la siguiente consulta para identificar a los usuarios que podemos suplantar:
Identificar usuarios que podemos suplantar
Para tener una idea de las posibilidades de escalada de privilegios, verifiquemos si nuestro usuario actual tiene el rol de administrador de sistemas:
Verificar nuestro usuario y rol actual
Como indica el valor devuelto 0
, no tenemos el rol de administrador de sistemas, pero podemos suplantar al sa
usuario. Nos haremos pasar por el usuario y ejecutaremos los mismos comandos. Para suplantar a un usuario, podemos usar la instrucción Transact-SQL EXECUTE AS LOGIN
y configurarla para el usuario que queremos suplantar.
Hacerse pasar por el usuario SA (sysadmin)
Nota: Se recomienda ejecutar EXECUTE AS LOGIN
dentro de la base de datos maestra, porque todos los usuarios, de forma predeterminada, tienen acceso a esa base de datos. Si un usuario al que intenta suplantar no tiene acceso a la base de datos a la que se está conectando, presentará un error. Intente pasar a la base de datos maestra usando USE master
.
Ahora podemos ejecutar cualquier comando como administrador de sistemas como indica el valor devuelto 1
. Para revertir la operación y volver a nuestro usuario anterior, podemos usar la declaración Transact-SQL REVERT
.
Nota: Si encontramos un usuario que no es administrador de sistemas, aún podemos verificar si el usuario tiene acceso a otras bases de datos o servidores vinculados.
Comunicarse con otras bases de datos con MSSQL
MSSQL
tiene una opción de configuración llamada servidores vinculados . Los servidores vinculados generalmente se configuran para permitir que el motor de base de datos ejecute una declaración Transact-SQL que incluya tablas en otra instancia de SQL Server u otro producto de base de datos como Oracle.
Si logramos acceder a un SQL Server con un servidor vinculado configurado, es posible que podamos movernos lateralmente a ese servidor de base de datos. Los administradores pueden configurar un servidor vinculado utilizando credenciales del servidor remoto. Si esas credenciales tienen privilegios de administrador de sistemas, es posible que podamos ejecutar comandos en la instancia remota de SQL. Veamos cómo podemos identificar y ejecutar consultas en servidores vinculados.
Identificar servidores vinculados en MSSQL
Como podemos ver en el resultado de la consulta, tenemos el nombre del servidor y la columna isremote
, donde 1
significa es un servidor remoto y 0
es un servidor vinculado. Podemos ver sysservers Transact-SQL para más información.
A continuación, podemos intentar identificar el usuario utilizado para la conexión y sus privilegios. La instrucción EXECUTE se puede utilizar para enviar comandos de transferencia a servidores vinculados. Agregamos nuestro comando entre paréntesis y especificamos el servidor vinculado entre corchetes ( [ ]
).
Nota: Si necesitamos usar comillas en nuestra consulta al servidor vinculado, debemos usar comillas dobles simples para escapar de la comilla simple. Para ejecutar varios comandos a la vez podemos dividirlos con un punto y coma (;
).
Como hemos visto, ahora podemos ejecutar consultas con privilegios de administrador de sistemas en el servidor vinculado. Como sysadmin
, controlamos la instancia de SQL Server. Podemos leer datos de cualquier base de datos o ejecutar comandos del sistema con xp_cmdshell
. Esta sección cubrió algunas de las formas más comunes de atacar bases de datos SQL Server y MySQL durante las pruebas de penetración. Existen otros métodos para atacar estos tipos de bases de datos, así como otros, como PostGreSQL , SQLite, Oracle, Firebase y MongoDB , que se tratarán en otros módulos. Vale la pena tomarse un tiempo para leer sobre estas tecnologías de bases de datos y también sobre algunas de las formas comunes de atacarlas.
Cheatsheet
Caso práctico
Autentíquese en 10.129.108.37 con el usuario " htbdbuser " y la contraseña " MSSQLAccess01! "
Pregunta 1
¿Cuál es la contraseña del usuario "mssqlsvc
"?
Vamos a conectarnos a la base de datos con el módulo mssqlclient de Impacket:
Las flag objetivo está en flagDB
pero no tenemos permisos para acceder, por lo que vamos a extraer el hash.
Iniciamos Responder en nuestra máquina de atacante
Ejecutamos
xp_dirtree
en SQL:
Obtenemos el hash del usuario mssqlsvc, pero necesitamos crackearlo. Vamos a guardar el hash completo en un archivo hash.txt
, y vamos a usar john para crackearlo:
Obtenemos la contraseña en plano: princess1
🏆
Pregunta 2
Enumera la base de datos "flagDB" y envia la flag como respuesta.
Vamos a loguearnos con las credenciales que hemos descubierto:
No nos deja acceder porque tenemos que especificar la opción -windows-auth
, ya que se autentica por Windows:
Accedemos correctamente y enumeramos las tablas para acceder a la flag 🏆
Última actualización