@@ -6,20 +6,14 @@ def __init__(self, connection, logger):
66 self .mssql_conn = connection
77 self .logger = logger
88
9+ # Store the original state of options that have to be enabled/disabled in order to restore them later
10+ self .backuped_options = {}
11+
912 def execute (self , command ):
1013 result = None
11- xp_cmdshell_was_enabled = False
1214
13- try :
14- xp_cmdshell_was_enabled = self .is_xp_cmdshell_enabled ()
15- if not xp_cmdshell_was_enabled :
16- self .logger .debug ("xp_cmdshell is disabled, attempting to enable it." )
17- self .enable_xp_cmdshell ()
18- else :
19- self .logger .debug ("xp_cmdshell is already enabled." )
20-
21- except Exception as e :
22- self .logger .error (f"Error when checking/enabling xp_cmdshell: { e } " )
15+ self .backup_and_enable ("advanced options" )
16+ self .backup_and_enable ("xp_cmdshell" )
2317
2418 try :
2519 cmd = f"exec master..xp_cmdshell '{ command } '"
@@ -35,56 +29,57 @@ def execute(self, command):
3529 except Exception as e :
3630 self .logger .error (f"Error when attempting to execute command via xp_cmdshell: { e } " )
3731
32+ self .restore ("xp_cmdshell" )
33+ self .restore ("advanced options" )
34+
35+ return result
36+
37+ def restore (self , option ):
3838 try :
39- if not xp_cmdshell_was_enabled :
40- self .logger .debug ("xp_cmdshell was not enabled originally, attempting to disable it." )
41- self .disable_xp_cmdshell ()
39+ if not self .backuped_options [option ]:
40+ self .logger .debug (f"Option '{ option } ' was not enabled originally, attempting to disable it." )
41+ query = f"EXEC master.dbo.sp_configure '{ option } ', 0;RECONFIGURE;"
42+ self .logger .debug (f"Executing query: { query } " )
43+ self .mssql_conn .sql_query (query )
4244 else :
43- self .logger .debug ("xp_cmdshell was originally enabled, leaving it enabled." )
45+ self .logger .debug (f"Option ' { option } ' was originally enabled, leaving it enabled." )
4446 except Exception as e :
45- self .logger .error (f"[OPSEC] Error when attempting to disable xp_cmdshell: { e } " )
46-
47- return result
47+ self .logger .error (f"[OPSEC] Error when attempting to restore option '{ option } ': { e } " )
4848
49- def is_xp_cmdshell_enabled (self ):
50- query = "EXEC sp_configure 'xp_cmdshell';"
51- self .logger .debug (f"Checking if xp_cmdshell is enabled: { query } " )
49+ def backup_and_enable (self , option ):
50+ try :
51+ self .backuped_options [option ] = self .is_option_enabled ("show advanced options" )
52+ if not self .backuped_options [option ]:
53+ self .logger .debug (f"Option '{ option } ' is disabled, attempting to enable it." )
54+ query = f"EXEC master.dbo.sp_configure '{ option } ', 1;RECONFIGURE;"
55+ self .logger .debug (f"Executing query: { query } " )
56+ self .mssql_conn .sql_query (query )
57+ else :
58+ self .logger .debug (f"Option '{ option } ' is already enabled." )
59+ except Exception as e :
60+ self .logger .error (f"Error when checking/enabling option '{ option } ': { e } " )
61+
62+ def is_option_enabled (self , option ):
63+ query = f"EXEC master.dbo.sp_configure '{ option } ';"
64+ self .logger .debug (f"Checking if { option } is enabled: { query } " )
5265 result = self .mssql_conn .sql_query (query )
5366 # Assuming the query returns a list of dictionaries with 'config_value' as the key
54- self .logger .debug (f"xp_cmdshell check result: { result } " )
67+ self .logger .debug (f"{ option } check result: { result } " )
5568 if result and result [0 ]["config_value" ] == 1 :
5669 return True
5770 return False
5871
59- def enable_xp_cmdshell (self ):
60- query = "exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'xp_cmdshell', 1;RECONFIGURE;"
61- self .logger .debug (f"Executing query: { query } " )
62- self .mssql_conn .sql_query (query )
63-
64- def disable_xp_cmdshell (self ):
65- query = "exec sp_configure 'xp_cmdshell', 0 ;RECONFIGURE;exec sp_configure 'show advanced options', 0 ;RECONFIGURE;"
66- self .logger .debug (f"Executing query: { query } " )
67- self .mssql_conn .sql_query (query )
68-
69- def enable_ole (self ):
70- query = "exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'Ole Automation Procedures', 1;RECONFIGURE;"
71- self .logger .debug (f"Executing query: { query } " )
72- self .mssql_conn .sql_query (query )
73-
74- def disable_ole (self ):
75- query = "exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'Ole Automation Procedures', 0;RECONFIGURE;"
76- self .logger .debug (f"Executing query: { query } " )
77- self .mssql_conn .sql_query (query )
78-
7972 def put_file (self , data , remote ):
8073 try :
81- self .enable_ole ()
74+ self .backup_and_enable ("advanced options" )
75+ self .backup_and_enable ("Ole Automation Procedures" )
8276 hexdata = data .hex ()
8377 self .logger .debug (f"Hex data to write to file: { hexdata } " )
8478 query = f"DECLARE @ob INT;EXEC sp_OACreate 'ADODB.Stream', @ob OUTPUT;EXEC sp_OASetProperty @ob, 'Type', 1;EXEC sp_OAMethod @ob, 'Open';EXEC sp_OAMethod @ob, 'Write', NULL, 0x{ hexdata } ;EXEC sp_OAMethod @ob, 'SaveToFile', NULL, '{ remote } ', 2;EXEC sp_OAMethod @ob, 'Close';EXEC sp_OADestroy @ob;"
8579 self .logger .debug (f"Executing query: { query } " )
8680 self .mssql_conn .sql_query (query )
87- self .disable_ole ()
81+ self .restore ("Ole Automation Procedures" )
82+ self .restore ("advanced options" )
8883 except Exception as e :
8984 self .logger .debug (f"Error uploading via mssqlexec: { e } " )
9085
0 commit comments