From 72d3d1513b99b15f7873c6574687b0d5ecd5428b Mon Sep 17 00:00:00 2001 From: gabrielg5 Date: Fri, 15 Sep 2023 13:42:19 -0300 Subject: [PATCH] * Created handle_lastError decorator applied to every command to show errors in the corresponding SQLShell --- impacket/examples/mssqlshell.py | 23 +++++++++++++++++++ .../ntlmrelayx/attacks/mssqlattack.py | 10 +++++--- impacket/tds.py | 1 - 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/impacket/examples/mssqlshell.py b/impacket/examples/mssqlshell.py index 5758519934..58dfcde89e 100644 --- a/impacket/examples/mssqlshell.py +++ b/impacket/examples/mssqlshell.py @@ -21,6 +21,14 @@ import cmd import sys +def handle_lastError(f): + def wrapper(*args): + try: + f(*args) + finally: + if(args[0].sql.lastError): + print(args[0].sql.lastError) + return wrapper class SQLSHELL(cmd.Cmd): def __init__(self, SQL, show_queries=False, tcpShell=None): @@ -97,14 +105,17 @@ def execute_as(self, exec_as): self.sql_query(exec_as) self.sql.printReplies() + @handle_lastError def do_exec_as_login(self, s): exec_as = "execute as login='%s';" % s self.execute_as(exec_as) + @handle_lastError def do_exec_as_user(self, s): exec_as = "execute as user='%s';" % s self.execute_as(exec_as) + @handle_lastError def do_use_link(self, s): if s == 'localhost': self.at = [] @@ -128,6 +139,7 @@ def sql_query(self, query, show=True): def do_shell(self, s): os.system(s) + @handle_lastError def do_xp_dirtree(self, s): try: self.sql_query("exec master.sys.xp_dirtree '%s',1,1" % s) @@ -136,6 +148,7 @@ def do_xp_dirtree(self, s): except: pass + @handle_lastError def do_xp_cmdshell(self, s): try: self.sql_query("exec master..xp_cmdshell '%s'" % s) @@ -145,6 +158,7 @@ def do_xp_cmdshell(self, s): except: pass + @handle_lastError def do_sp_start_job(self, s): try: self.sql_query("DECLARE @job NVARCHAR(100);" @@ -166,6 +180,7 @@ def do_lcd(self, s): else: os.chdir(s) + @handle_lastError def do_enable_xp_cmdshell(self, line): try: self.sql_query("exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;" @@ -175,6 +190,7 @@ def do_enable_xp_cmdshell(self, line): except: pass + @handle_lastError def do_disable_xp_cmdshell(self, line): try: self.sql_query("exec sp_configure 'xp_cmdshell', 0 ;RECONFIGURE;exec sp_configure " @@ -184,6 +200,7 @@ def do_disable_xp_cmdshell(self, line): except: pass + @handle_lastError def do_enum_links(self, line): self.sql_query("EXEC sp_linkedservers") self.sql.printReplies() @@ -192,11 +209,13 @@ def do_enum_links(self, line): self.sql.printReplies() self.sql.printRows() + @handle_lastError def do_enum_users(self, line): self.sql_query("EXEC sp_helpuser") self.sql.printReplies() self.sql.printRows() + @handle_lastError def do_enum_db(self, line): try: self.sql_query("select name, is_trustworthy_on from sys.databases") @@ -205,6 +224,7 @@ def do_enum_db(self, line): except: pass + @handle_lastError def do_enum_owner(self, line): try: self.sql_query("SELECT name [Database], suser_sname(owner_sid) [Owner] FROM sys.databases") @@ -213,6 +233,7 @@ def do_enum_owner(self, line): except: pass + @handle_lastError def do_enum_impersonate(self, line): old_db = self.sql.currentDB try: @@ -247,6 +268,7 @@ def do_enum_impersonate(self, line): finally: self.sql_query("use " + old_db) + @handle_lastError def do_enum_logins(self, line): try: self.sql_query("select r.name,r.type_desc,r.is_disabled, sl.sysadmin, sl.securityadmin, " @@ -258,6 +280,7 @@ def do_enum_logins(self, line): except: pass + @handle_lastError def default(self, line): try: self.sql_query(line) diff --git a/impacket/examples/ntlmrelayx/attacks/mssqlattack.py b/impacket/examples/ntlmrelayx/attacks/mssqlattack.py index 3a7b6d07a0..1e7855a751 100644 --- a/impacket/examples/ntlmrelayx/attacks/mssqlattack.py +++ b/impacket/examples/ntlmrelayx/attacks/mssqlattack.py @@ -43,9 +43,13 @@ def run(self): if self.config.queries is not None: for query in self.config.queries: LOG.info('Executing SQL: %s' % query) - self.client.sql_query(query) - self.client.printReplies() - self.client.printRows() + try: + self.client.sql_query(query) + self.client.printReplies() + self.client.printRows() + finally: + if(self.client.lastError): + print(self.client.lastError) else: LOG.error('No SQL queries specified for MSSQL relay!') diff --git a/impacket/tds.py b/impacket/tds.py index 46b86f5124..c0447d3350 100644 --- a/impacket/tds.py +++ b/impacket/tds.py @@ -1022,7 +1022,6 @@ def printReplies(self): if key['TokenType'] == TDS_ERROR_TOKEN: error = "ERROR(%s): Line %d: %s" % (key['ServerName'].decode('utf-16le'), key['LineNumber'], key['MsgText'].decode('utf-16le')) self.lastError = SQLErrorException("ERROR: Line %d: %s" % (key['LineNumber'], key['MsgText'].decode('utf-16le'))) - LOG.error(error) elif key['TokenType'] == TDS_INFO_TOKEN: LOG.info("INFO(%s): Line %d: %s" % (key['ServerName'].decode('utf-16le'), key['LineNumber'], key['MsgText'].decode('utf-16le')))