NetExec/cme/protocols/mssql/mssqlexec.py

84 lines
3.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
2022-06-29 11:44:41 +00:00
import binascii
from cme.logger import cme_logger
2016-05-16 23:48:31 +00:00
class MSSQLEXEC:
2016-05-16 23:48:31 +00:00
def __init__(self, connection):
self.mssql_conn = connection
self.outputBuffer = ""
2016-05-16 23:48:31 +00:00
def execute(self, command, output=False):
command_output = []
2016-05-16 23:48:31 +00:00
try:
self.enable_xp_cmdshell()
except Exception as e:
cme_logger.error(f"Error when attempting to enable x_cmdshell: {e}")
try:
result = self.mssql_conn.sql_query(f"exec master..xp_cmdshell '{command}'")
cme_logger.debug(f"SQL Query Result: {result}")
for row in result:
if row["output"] == "NULL":
continue
command_output.append(row["output"])
except Exception as e:
2023-05-08 18:39:36 +00:00
cme_logger.error(f"Error when attempting to execute command via xp_cmdshell: {e}")
if output:
cme_logger.debug(f"Output is enabled")
for row in command_output:
2023-06-30 13:29:59 +00:00
cme_logger.debug(row)
# self.mssql_conn.printReplies()
# self.mssql_conn.colMeta[0]["TypeData"] = 80 * 2
# self.mssql_conn.printRows()
# self.outputBuffer = self.mssql_conn._MSSQL__rowsPrinter.getMessage()
# if len(self.outputBuffer):
# self.outputBuffer = self.outputBuffer.split('\n', 2)[2]
try:
2016-05-16 23:48:31 +00:00
self.disable_xp_cmdshell()
2017-10-25 06:45:58 +00:00
except Exception as e:
2023-05-08 18:39:36 +00:00
cme_logger.error(f"[OPSEC] Error when attempting to disable xp_cmdshell: {e}")
return command_output
# return self.outputBuffer
2016-05-16 23:48:31 +00:00
def enable_xp_cmdshell(self):
2023-05-08 18:39:36 +00:00
self.mssql_conn.sql_query("exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'xp_cmdshell', 1;RECONFIGURE;")
2016-05-16 23:48:31 +00:00
def disable_xp_cmdshell(self):
2023-05-08 18:39:36 +00:00
self.mssql_conn.sql_query("exec sp_configure 'xp_cmdshell', 0 ;RECONFIGURE;exec sp_configure 'show advanced options', 0 ;RECONFIGURE;")
2022-06-29 11:44:41 +00:00
def enable_ole(self):
2023-05-08 18:39:36 +00:00
self.mssql_conn.sql_query("exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'Ole Automation Procedures', 1;RECONFIGURE;")
2022-06-29 11:44:41 +00:00
def disable_ole(self):
2023-05-08 18:39:36 +00:00
self.mssql_conn.sql_query("exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'Ole Automation Procedures', 0;RECONFIGURE;")
2022-06-29 11:44:41 +00:00
def put_file(self, data, remote):
try:
self.enable_ole()
hexdata = data.hex()
2023-05-08 18:39:36 +00:00
self.mssql_conn.sql_query("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{};" "EXEC sp_OAMethod @ob, 'SaveToFile', NULL, '{}', 2;" "EXEC sp_OAMethod @ob, 'Close';" "EXEC sp_OADestroy @ob;".format(hexdata, remote))
2022-06-29 11:44:41 +00:00
self.disable_ole()
except Exception as e:
cme_logger.debug(f"Error uploading via mssqlexec: {e}")
2022-06-29 11:44:41 +00:00
def file_exists(self, remote):
try:
2023-05-08 18:39:36 +00:00
res = self.mssql_conn.batch(f"DECLARE @r INT; EXEC master.dbo.xp_fileexist '{remote}', @r OUTPUT; SELECT @r as n")[0]["n"]
2022-06-29 11:44:41 +00:00
return res == 1
except:
return False
def get_file(self, remote, local):
try:
2023-05-08 18:39:36 +00:00
self.mssql_conn.sql_query(f"SELECT * FROM OPENROWSET(BULK N'{remote}', SINGLE_BLOB) rs")
data = self.mssql_conn.rows[0]["BulkColumn"]
2022-06-29 11:44:41 +00:00
with open(local, "wb+") as f:
2022-06-29 11:44:41 +00:00
f.write(binascii.unhexlify(data))
except Exception as e:
2023-05-02 15:17:59 +00:00
cme_logger.debug(f"Error downloading via mssqlexec: {e}")