2022-07-18 23:59:14 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2017-11-02 09:43:08 +00:00
|
|
|
from cme.helpers.misc import validate_ntlm
|
2023-03-06 23:41:33 +00:00
|
|
|
from cme.cmedb import DatabaseNavigator, print_table, print_help
|
2016-12-15 07:28:00 +00:00
|
|
|
|
|
|
|
|
2017-11-02 09:43:08 +00:00
|
|
|
class navigator(DatabaseNavigator):
|
2017-03-27 21:09:36 +00:00
|
|
|
def display_creds(self, creds):
|
2017-11-02 09:43:08 +00:00
|
|
|
data = [['CredID', 'Admin On', 'CredType', 'Domain', 'UserName', 'Password']]
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2017-03-27 21:09:36 +00:00
|
|
|
for cred in creds:
|
2023-03-05 00:10:18 +00:00
|
|
|
cred_id = cred[0]
|
2017-03-27 21:09:36 +00:00
|
|
|
domain = cred[1]
|
|
|
|
username = cred[2]
|
|
|
|
password = cred[3]
|
|
|
|
credtype = cred[4]
|
2017-11-02 09:43:08 +00:00
|
|
|
# pillaged_from = cred[5]
|
2017-03-27 21:09:36 +00:00
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
links = self.db.get_admin_relations(user_id=cred_id)
|
|
|
|
data.append([cred_id, str(len(links)) + ' Host(s)', credtype, domain, username, password])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Credentials')
|
2017-03-27 21:09:36 +00:00
|
|
|
|
|
|
|
def display_groups(self, groups):
|
2023-03-16 22:02:48 +00:00
|
|
|
data = [['GroupID', 'Domain', 'Name', 'RID', 'Enumerated Members', 'AD Members', 'Last Query Time']]
|
2017-03-27 21:09:36 +00:00
|
|
|
|
|
|
|
for group in groups:
|
2023-03-05 02:48:19 +00:00
|
|
|
group_id = group[0]
|
2017-03-27 21:09:36 +00:00
|
|
|
domain = group[1]
|
|
|
|
name = group[2]
|
2023-03-16 22:02:48 +00:00
|
|
|
rid = group[3]
|
2023-03-05 02:48:19 +00:00
|
|
|
members = len(self.db.get_group_relations(group_id=group_id))
|
2023-03-16 22:02:48 +00:00
|
|
|
ad_members = group[4]
|
|
|
|
last_query_time = group[5]
|
|
|
|
data.append([group_id, domain, name, rid, members, ad_members, last_query_time])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Groups')
|
2017-03-27 21:09:36 +00:00
|
|
|
|
2023-03-05 00:00:20 +00:00
|
|
|
# pull/545
|
2017-03-27 21:09:36 +00:00
|
|
|
def display_hosts(self, hosts):
|
2023-03-05 00:10:18 +00:00
|
|
|
data = [[
|
|
|
|
'HostID',
|
|
|
|
'Admins',
|
|
|
|
'IP',
|
|
|
|
'Hostname',
|
|
|
|
'Domain',
|
|
|
|
'OS',
|
|
|
|
'SMBv1',
|
|
|
|
'Signing',
|
|
|
|
'Spooler',
|
|
|
|
'Zerologon',
|
|
|
|
'PetitPotam'
|
|
|
|
]]
|
2022-06-18 21:43:09 +00:00
|
|
|
|
2017-03-27 21:09:36 +00:00
|
|
|
for host in hosts:
|
2023-03-05 00:10:18 +00:00
|
|
|
host_id = host[0]
|
2017-03-27 21:09:36 +00:00
|
|
|
ip = host[1]
|
|
|
|
hostname = host[2]
|
|
|
|
domain = host[3]
|
2023-03-03 14:50:28 +00:00
|
|
|
|
2021-01-21 10:08:06 +00:00
|
|
|
try:
|
|
|
|
os = host[4].decode()
|
|
|
|
except:
|
|
|
|
os = host[4]
|
2022-06-18 21:43:09 +00:00
|
|
|
try:
|
|
|
|
smbv1 = host[6]
|
|
|
|
signing = host[7]
|
2023-03-03 17:04:46 +00:00
|
|
|
except IndexError:
|
|
|
|
smbv1 = ''
|
|
|
|
signing = ''
|
|
|
|
try:
|
|
|
|
spooler = host[8]
|
|
|
|
zerologon = host[9]
|
|
|
|
petitpotam = host[10]
|
|
|
|
except IndexError:
|
|
|
|
spooler = ''
|
|
|
|
zerologon = ''
|
|
|
|
petitpotam = ''
|
2023-03-05 00:10:18 +00:00
|
|
|
|
|
|
|
links = self.db.get_admin_relations(host_id=host_id)
|
|
|
|
data.append([
|
|
|
|
host_id,
|
|
|
|
str(len(links)) + ' Cred(s)',
|
|
|
|
ip,
|
|
|
|
hostname,
|
|
|
|
domain,
|
|
|
|
os,
|
|
|
|
smbv1,
|
|
|
|
signing,
|
|
|
|
spooler,
|
|
|
|
zerologon,
|
|
|
|
petitpotam
|
|
|
|
])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Hosts')
|
2020-11-15 23:42:28 +00:00
|
|
|
|
|
|
|
def display_shares(self, shares):
|
2023-03-12 02:25:23 +00:00
|
|
|
data = [["ShareID", "host", "Name", "Remark", "Read Access", "Write Access"]]
|
2020-11-15 23:42:28 +00:00
|
|
|
|
|
|
|
for share in shares:
|
2023-03-05 00:10:18 +00:00
|
|
|
share_id = share[0]
|
2023-03-12 02:25:23 +00:00
|
|
|
host_id = share[1]
|
2020-11-15 23:42:28 +00:00
|
|
|
name = share[3]
|
|
|
|
remark = share[4]
|
|
|
|
|
|
|
|
users_r_access = self.db.get_users_with_share_access(
|
2023-03-12 02:25:23 +00:00
|
|
|
host_id=host_id,
|
2020-11-15 23:42:28 +00:00
|
|
|
share_name=name,
|
|
|
|
permissions='r'
|
|
|
|
)
|
|
|
|
users_w_access = self.db.get_users_with_share_access(
|
2023-03-12 02:25:23 +00:00
|
|
|
host_id=host_id,
|
2020-11-15 23:42:28 +00:00
|
|
|
share_name=name,
|
|
|
|
permissions='w'
|
|
|
|
)
|
2023-03-05 00:10:18 +00:00
|
|
|
data.append([
|
|
|
|
share_id,
|
2023-03-12 02:25:23 +00:00
|
|
|
host_id,
|
2023-03-05 00:10:18 +00:00
|
|
|
name,
|
|
|
|
remark,
|
|
|
|
f"{len(users_r_access)} User(s)",
|
|
|
|
f"{len(users_w_access)} Users"
|
|
|
|
])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data)
|
2020-11-15 23:42:28 +00:00
|
|
|
|
|
|
|
def do_shares(self, line):
|
2023-03-05 00:10:18 +00:00
|
|
|
filter_term = line.strip()
|
2020-11-15 23:42:28 +00:00
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
if filter_term == "":
|
2020-11-15 23:42:28 +00:00
|
|
|
shares = self.db.get_shares()
|
|
|
|
self.display_shares(shares)
|
2023-03-09 22:39:07 +00:00
|
|
|
elif filter_term in ["r", "w", "rw"]:
|
|
|
|
shares = self.db.get_shares_by_access(line)
|
|
|
|
self.display_shares(shares)
|
2020-11-15 23:42:28 +00:00
|
|
|
else:
|
2023-03-05 00:10:18 +00:00
|
|
|
shares = self.db.get_shares(filter_term=filter_term)
|
2020-11-15 23:42:28 +00:00
|
|
|
|
|
|
|
if len(shares) > 1:
|
|
|
|
self.display_shares(shares)
|
|
|
|
elif len(shares) == 1:
|
|
|
|
share = shares[0]
|
2023-03-05 00:10:18 +00:00
|
|
|
share_id = share[0]
|
2023-03-12 02:25:23 +00:00
|
|
|
host_id = share[1]
|
2020-11-15 23:42:28 +00:00
|
|
|
name = share[3]
|
|
|
|
remark = share[4]
|
|
|
|
|
|
|
|
users_r_access = self.db.get_users_with_share_access(
|
2023-03-12 02:25:23 +00:00
|
|
|
host_id=host_id,
|
2020-11-15 23:42:28 +00:00
|
|
|
share_name=name,
|
|
|
|
permissions='r'
|
|
|
|
)
|
|
|
|
users_w_access = self.db.get_users_with_share_access(
|
2023-03-12 02:25:23 +00:00
|
|
|
host_id=host_id,
|
2020-11-15 23:42:28 +00:00
|
|
|
share_name=name,
|
|
|
|
permissions='w'
|
|
|
|
)
|
|
|
|
|
2023-03-05 02:48:19 +00:00
|
|
|
data = [["ShareID", "Name", "Remark"], [share_id, name, remark]]
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Share')
|
2023-03-12 02:25:23 +00:00
|
|
|
host = self.db.get_hosts(filter_term=host_id)[0]
|
2020-11-15 23:42:28 +00:00
|
|
|
data = [['HostID', 'IP', 'Hostname', 'Domain', 'OS', 'DC']]
|
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
host_id = host[0]
|
2020-11-15 23:42:28 +00:00
|
|
|
ip = host[1]
|
|
|
|
hostname = host[2]
|
|
|
|
domain = host[3]
|
|
|
|
os = host[4]
|
|
|
|
dc = host[5]
|
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
data.append([host_id, ip, hostname, domain, os, dc])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Share Location')
|
2020-11-15 23:42:28 +00:00
|
|
|
|
|
|
|
if users_r_access:
|
|
|
|
data = [['CredID', 'CredType', 'Domain', 'UserName', 'Password']]
|
|
|
|
for user in users_r_access:
|
|
|
|
userid = user[0]
|
2023-03-04 01:38:31 +00:00
|
|
|
creds = self.db.get_credentials(filter_term=userid)
|
2020-11-15 23:42:28 +00:00
|
|
|
|
|
|
|
for cred in creds:
|
2023-03-05 00:10:18 +00:00
|
|
|
cred_id = cred[0]
|
2020-11-15 23:42:28 +00:00
|
|
|
domain = cred[1]
|
|
|
|
username = cred[2]
|
|
|
|
password = cred[3]
|
|
|
|
credtype = cred[4]
|
2023-03-05 00:10:18 +00:00
|
|
|
data.append([cred_id, credtype, domain, username, password])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Users(s) with Read Access')
|
2020-11-15 23:42:28 +00:00
|
|
|
|
|
|
|
if users_w_access:
|
|
|
|
data = [['CredID', 'CredType', 'Domain', 'UserName', 'Password']]
|
|
|
|
for user in users_w_access:
|
|
|
|
userid = user[0]
|
2023-03-04 01:38:31 +00:00
|
|
|
creds = self.db.get_credentials(filter_term=userid)
|
2020-11-15 23:42:28 +00:00
|
|
|
|
|
|
|
for cred in creds:
|
2023-03-05 00:10:18 +00:00
|
|
|
cred_id = cred[0]
|
2020-11-15 23:42:28 +00:00
|
|
|
domain = cred[1]
|
|
|
|
username = cred[2]
|
|
|
|
password = cred[3]
|
|
|
|
credtype = cred[4]
|
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
data.append([cred_id, credtype, domain, username, password])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Users(s) with Write Access')
|
2020-11-15 23:42:28 +00:00
|
|
|
|
2023-03-06 23:41:33 +00:00
|
|
|
def help_shares(self):
|
|
|
|
help_string = """
|
|
|
|
shares [filter_term]
|
|
|
|
By default prints all shares
|
|
|
|
Can use a filter term to filter shares
|
|
|
|
"""
|
|
|
|
print_help(help_string)
|
|
|
|
|
2016-12-15 07:28:00 +00:00
|
|
|
def do_groups(self, line):
|
2023-03-05 00:10:18 +00:00
|
|
|
filter_term = line.strip()
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
if filter_term == "":
|
2016-12-15 07:28:00 +00:00
|
|
|
groups = self.db.get_groups()
|
|
|
|
self.display_groups(groups)
|
|
|
|
else:
|
2023-03-05 00:10:18 +00:00
|
|
|
groups = self.db.get_groups(filter_term=filter_term)
|
2016-12-15 07:28:00 +00:00
|
|
|
|
|
|
|
if len(groups) > 1:
|
|
|
|
self.display_groups(groups)
|
|
|
|
elif len(groups) == 1:
|
2023-03-16 22:02:48 +00:00
|
|
|
data = [['GroupID', 'Domain', 'Name', 'RID', 'Enumerated Members', 'AD Members', 'Last Query Time']]
|
2016-12-15 07:28:00 +00:00
|
|
|
|
|
|
|
for group in groups:
|
2023-03-05 00:10:18 +00:00
|
|
|
group_id = group[0]
|
2017-03-27 21:09:36 +00:00
|
|
|
domain = group[1]
|
|
|
|
name = group[2]
|
2023-03-16 22:02:48 +00:00
|
|
|
rid = group[3]
|
|
|
|
members = len(self.db.get_group_relations(group_id=group_id))
|
|
|
|
ad_members = group[4]
|
|
|
|
last_query_time = group[5]
|
2017-03-27 21:09:36 +00:00
|
|
|
|
2023-03-16 22:02:48 +00:00
|
|
|
data.append([group_id, domain, name, rid, members, ad_members, last_query_time])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Group')
|
2017-11-02 09:43:08 +00:00
|
|
|
data = [['CredID', 'CredType', 'Pillaged From HostID', 'Domain', 'UserName', 'Password']]
|
2017-03-27 21:09:36 +00:00
|
|
|
|
|
|
|
for group in groups:
|
2023-03-04 00:37:02 +00:00
|
|
|
members = self.db.get_group_relations(group_id=group[0])
|
2017-11-02 09:43:08 +00:00
|
|
|
|
2017-03-27 21:09:36 +00:00
|
|
|
for member in members:
|
2023-03-05 00:10:18 +00:00
|
|
|
_, userid, _ = member
|
2023-03-04 01:38:31 +00:00
|
|
|
creds = self.db.get_credentials(filter_term=userid)
|
2017-03-27 21:09:36 +00:00
|
|
|
|
|
|
|
for cred in creds:
|
2023-03-05 00:10:18 +00:00
|
|
|
cred_id = cred[0]
|
2017-03-27 21:09:36 +00:00
|
|
|
domain = cred[1]
|
|
|
|
username = cred[2]
|
|
|
|
password = cred[3]
|
|
|
|
credtype = cred[4]
|
|
|
|
pillaged_from = cred[5]
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
data.append([cred_id, credtype, pillaged_from, domain, username, password])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Member(s)')
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2023-03-06 23:42:34 +00:00
|
|
|
def help_groups(self):
|
|
|
|
help_string = """
|
|
|
|
groups [filter_term]
|
|
|
|
By default prints all groups
|
|
|
|
Can use a filter term to filter groups
|
|
|
|
"""
|
|
|
|
print_help(help_string)
|
|
|
|
|
2016-12-15 07:28:00 +00:00
|
|
|
def do_hosts(self, line):
|
2023-03-05 00:10:18 +00:00
|
|
|
filter_term = line.strip()
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
if filter_term == "":
|
2023-03-12 02:25:23 +00:00
|
|
|
hosts = self.db.get_hosts()
|
2016-12-15 07:28:00 +00:00
|
|
|
self.display_hosts(hosts)
|
|
|
|
else:
|
2023-03-12 02:25:23 +00:00
|
|
|
hosts = self.db.get_hosts(filter_term=filter_term)
|
2016-12-15 07:28:00 +00:00
|
|
|
|
|
|
|
if len(hosts) > 1:
|
|
|
|
self.display_hosts(hosts)
|
|
|
|
elif len(hosts) == 1:
|
2023-03-09 23:28:35 +00:00
|
|
|
data = [[
|
|
|
|
'HostID',
|
|
|
|
'IP',
|
|
|
|
'Hostname',
|
|
|
|
'Domain',
|
|
|
|
'OS',
|
|
|
|
'DC',
|
|
|
|
'SMBv1',
|
|
|
|
'Signing',
|
|
|
|
'Spooler',
|
|
|
|
'Zerologon',
|
|
|
|
'PetitPotam'
|
|
|
|
]]
|
2023-03-05 00:10:18 +00:00
|
|
|
host_id_list = []
|
2016-12-15 07:28:00 +00:00
|
|
|
|
|
|
|
for host in hosts:
|
2023-03-05 00:10:18 +00:00
|
|
|
host_id = host[0]
|
|
|
|
host_id_list.append(host_id)
|
2016-12-15 07:28:00 +00:00
|
|
|
ip = host[1]
|
|
|
|
hostname = host[2]
|
|
|
|
domain = host[3]
|
|
|
|
|
2023-03-09 23:28:35 +00:00
|
|
|
try:
|
|
|
|
os = host[4].decode()
|
|
|
|
except:
|
|
|
|
os = host[4]
|
|
|
|
try:
|
|
|
|
dc = host[5]
|
|
|
|
except IndexError:
|
|
|
|
dc = ''
|
|
|
|
try:
|
|
|
|
smbv1 = host[6]
|
|
|
|
signing = host[7]
|
|
|
|
except IndexError:
|
|
|
|
smbv1 = ''
|
|
|
|
signing = ''
|
|
|
|
try:
|
|
|
|
spooler = host[8]
|
|
|
|
zerologon = host[9]
|
|
|
|
petitpotam = host[10]
|
|
|
|
except IndexError:
|
|
|
|
spooler = ''
|
|
|
|
zerologon = ''
|
|
|
|
petitpotam = ''
|
|
|
|
|
|
|
|
data.append([
|
|
|
|
host_id,
|
|
|
|
ip,
|
|
|
|
hostname,
|
|
|
|
domain,
|
|
|
|
os,
|
|
|
|
dc,
|
|
|
|
smbv1,
|
|
|
|
signing,
|
|
|
|
spooler,
|
|
|
|
zerologon,
|
|
|
|
petitpotam,
|
|
|
|
])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Host')
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2017-11-02 09:43:08 +00:00
|
|
|
data = [['CredID', 'CredType', 'Domain', 'UserName', 'Password']]
|
2023-03-05 00:10:18 +00:00
|
|
|
for host_id in host_id_list:
|
|
|
|
links = self.db.get_admin_relations(host_id=host_id)
|
2016-12-15 07:28:00 +00:00
|
|
|
|
|
|
|
for link in links:
|
2023-03-05 00:10:18 +00:00
|
|
|
link_id, cred_id, host_id = link
|
|
|
|
creds = self.db.get_credentials(filter_term=cred_id)
|
2016-12-15 07:28:00 +00:00
|
|
|
|
|
|
|
for cred in creds:
|
2023-03-05 00:10:18 +00:00
|
|
|
cred_id = cred[0]
|
2016-12-20 07:23:40 +00:00
|
|
|
domain = cred[1]
|
|
|
|
username = cred[2]
|
|
|
|
password = cred[3]
|
2017-03-27 21:09:36 +00:00
|
|
|
credtype = cred[4]
|
2017-11-02 09:43:08 +00:00
|
|
|
# pillaged_from = cred[5]
|
2023-03-05 00:10:18 +00:00
|
|
|
data.append([cred_id, credtype, domain, username, password])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Credential(s) with Admin Access')
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2023-03-06 23:45:44 +00:00
|
|
|
def help_hosts(self):
|
|
|
|
help_string = """
|
2023-03-10 04:36:31 +00:00
|
|
|
hosts [dc|spooler|zerologon|petitpotam|filter_term]
|
2023-03-06 23:45:44 +00:00
|
|
|
By default prints all hosts
|
2023-03-10 04:36:31 +00:00
|
|
|
Table format:
|
|
|
|
| 'HostID', 'IP', 'Hostname', 'Domain', 'OS', 'DC', 'SMBv1', 'Signing', 'Spooler', 'Zerologon', 'PetitPotam' |
|
|
|
|
Subcommands:
|
|
|
|
dc - list all domain controllers
|
|
|
|
spooler - list all hosts with Spooler service enabled
|
|
|
|
zerologon - list all hosts vulnerable to zerologon
|
|
|
|
petitpotam - list all hosts vulnerable to petitpotam
|
|
|
|
filter_term - filters hosts with filter_term
|
|
|
|
If a single host is returned (e.g. `hosts 15`, it prints the following tables:
|
|
|
|
Host | 'HostID', 'IP', 'Hostname', 'Domain', 'OS', 'DC', 'SMBv1', 'Signing', 'Spooler', 'Zerologon', 'PetitPotam' |
|
|
|
|
Credential(s) with Admin Access | 'CredID', 'CredType', 'Domain', 'UserName', 'Password' |
|
|
|
|
Otherwise, it prints the default host table from a `like` query on the `ip` and `hostname` columns
|
2023-03-06 23:45:44 +00:00
|
|
|
"""
|
|
|
|
print_help(help_string)
|
|
|
|
|
2023-02-22 12:58:53 +00:00
|
|
|
def do_dpapi(self, line):
|
2023-03-14 05:24:42 +00:00
|
|
|
filter_term = line.strip()
|
2023-02-22 12:58:53 +00:00
|
|
|
|
2023-03-14 05:24:42 +00:00
|
|
|
if filter_term == "":
|
2023-02-22 12:58:53 +00:00
|
|
|
secrets = self.db.get_dpapi_secrets()
|
2023-03-14 05:24:42 +00:00
|
|
|
secrets.insert(0, ["ID", "Host", "DPAPI Type", "Windows User", "Username", "Password", "URL"])
|
|
|
|
print_table(secrets, title='DPAPI Secrets')
|
|
|
|
elif filter_term.split()[0].lower() == "browser":
|
2023-02-22 12:58:53 +00:00
|
|
|
secrets = self.db.get_dpapi_secrets(dpapi_type="MSEDGE")
|
|
|
|
secrets += self.db.get_dpapi_secrets(dpapi_type="GOOGLE CHROME")
|
|
|
|
secrets += self.db.get_dpapi_secrets(dpapi_type="IEX")
|
|
|
|
secrets += self.db.get_dpapi_secrets(dpapi_type="FIREFOX")
|
|
|
|
if len(secrets) > 0:
|
2023-03-14 05:24:42 +00:00
|
|
|
secrets.insert(0, ["ID", "Host", "DPAPI Type", "Windows User", "Username", "Password", "URL"])
|
|
|
|
print_table(secrets, title='DPAPI Secrets')
|
|
|
|
elif filter_term.split()[0].lower() == "chrome":
|
2023-02-22 12:58:53 +00:00
|
|
|
secrets = self.db.get_dpapi_secrets(dpapi_type="GOOGLE CHROME")
|
|
|
|
if len(secrets) > 0:
|
2023-03-14 05:24:42 +00:00
|
|
|
secrets.insert(0, ["ID", "Host", "DPAPI Type", "Windows User", "Username", "Password", "URL"])
|
|
|
|
print_table(secrets, title='DPAPI Secrets')
|
|
|
|
elif filter_term.split()[0].lower() == "msedge":
|
2023-02-22 12:58:53 +00:00
|
|
|
secrets = self.db.get_dpapi_secrets(dpapi_type="MSEDGE")
|
|
|
|
if len(secrets) > 0:
|
2023-03-14 05:24:42 +00:00
|
|
|
secrets.insert(0, ["ID", "Host", "DPAPI Type", "Windows User", "Username", "Password", "URL"])
|
|
|
|
print_table(secrets, title='DPAPI Secrets')
|
|
|
|
elif filter_term.split()[0].lower() == "credentials":
|
2023-02-22 12:58:53 +00:00
|
|
|
secrets = self.db.get_dpapi_secrets(dpapi_type="CREDENTIAL")
|
|
|
|
if len(secrets) > 0:
|
2023-03-14 05:24:42 +00:00
|
|
|
secrets.insert(0, ["ID", "Host", "DPAPI Type", "Windows User", "Username", "Password", "URL"])
|
|
|
|
print_table(secrets, title='DPAPI Secrets')
|
|
|
|
elif filter_term.split()[0].lower() == "iex":
|
2023-02-22 12:58:53 +00:00
|
|
|
secrets = self.db.get_dpapi_secrets(dpapi_type="IEX")
|
|
|
|
if len(secrets) > 0:
|
2023-03-14 05:24:42 +00:00
|
|
|
secrets.insert(0, ["ID", "Host", "DPAPI Type", "Windows User", "Username", "Password", "URL"])
|
|
|
|
print_table(secrets, title='DPAPI Secrets')
|
|
|
|
elif filter_term.split()[0].lower() == "firefox":
|
2023-02-22 12:58:53 +00:00
|
|
|
secrets = self.db.get_dpapi_secrets(dpapi_type="FIREFOX")
|
|
|
|
if len(secrets) > 0:
|
2023-03-14 05:24:42 +00:00
|
|
|
secrets.insert(0, ["ID", "Host", "DPAPI Type", "Windows User", "Username", "Password", "URL"])
|
|
|
|
print_table(secrets, title='DPAPI Secrets')
|
2023-02-22 12:58:53 +00:00
|
|
|
else:
|
2023-03-14 05:24:42 +00:00
|
|
|
secrets = self.db.get_dpapi_secrets(filter_term=filter_term)
|
2023-02-22 12:58:53 +00:00
|
|
|
if len(secrets) > 0:
|
2023-03-14 05:24:42 +00:00
|
|
|
secrets.insert(0, ["ID", "Host", "DPAPI Type", "Windows User", "Username", "Password", "URL"])
|
|
|
|
print_table(secrets, title='DPAPI Secrets')
|
2023-02-22 12:58:53 +00:00
|
|
|
|
2023-03-21 09:41:10 +00:00
|
|
|
def help_dpapi(self):
|
|
|
|
help_string = """
|
|
|
|
dpapi [browser|chrome|msedge|credentials|iex|firefox|filter_term]
|
|
|
|
By default prints all dpapi dumped secrets
|
|
|
|
Table format:
|
|
|
|
| 'ID', 'Host', 'DPAPI Type', 'Windows User', 'Username', 'Password', 'URL' |
|
|
|
|
Subcommands:
|
|
|
|
browser - list all secrets dumped from browser
|
|
|
|
chrome - list all secrets dumped from chrome
|
|
|
|
msedge - list all secrets dumped from microsoft edge
|
|
|
|
credentials - list all secrets dumped from credential manager (user and system)
|
|
|
|
iex - list all secrets dumped from Internet Explorer
|
|
|
|
firefox - list all secrets dumped from Firefox
|
|
|
|
filter_term - filters dpapi secrets with filter_term
|
|
|
|
"""
|
|
|
|
print_help(help_string)
|
|
|
|
|
2016-12-15 07:28:00 +00:00
|
|
|
def do_creds(self, line):
|
2023-03-05 00:10:18 +00:00
|
|
|
filter_term = line.strip()
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
if filter_term == "":
|
2016-12-15 07:28:00 +00:00
|
|
|
creds = self.db.get_credentials()
|
|
|
|
self.display_creds(creds)
|
2023-03-05 00:10:18 +00:00
|
|
|
elif filter_term.split()[0].lower() == "add":
|
2016-12-15 07:28:00 +00:00
|
|
|
# add format: "domain username password <notes> <credType> <sid>
|
2023-03-05 00:10:18 +00:00
|
|
|
args = filter_term.split()[1:]
|
2016-12-15 07:28:00 +00:00
|
|
|
|
|
|
|
if len(args) == 3:
|
|
|
|
domain, username, password = args
|
|
|
|
if validate_ntlm(password):
|
|
|
|
self.db.add_credential("hash", domain, username, password)
|
|
|
|
else:
|
|
|
|
self.db.add_credential("plaintext", domain, username, password)
|
|
|
|
else:
|
2019-11-12 21:39:26 +00:00
|
|
|
print("[!] Format is 'add domain username password")
|
2016-12-15 07:28:00 +00:00
|
|
|
return
|
2023-03-05 00:10:18 +00:00
|
|
|
elif filter_term.split()[0].lower() == "remove":
|
|
|
|
args = filter_term.split()[1:]
|
2017-11-02 09:43:08 +00:00
|
|
|
if len(args) != 1:
|
2019-11-12 21:39:26 +00:00
|
|
|
print("[!] Format is 'remove <credID>'")
|
2016-12-15 07:28:00 +00:00
|
|
|
return
|
|
|
|
else:
|
|
|
|
self.db.remove_credentials(args)
|
2023-03-04 20:33:07 +00:00
|
|
|
self.db.remove_admin_relation(user_ids=args)
|
2023-03-05 00:10:18 +00:00
|
|
|
elif filter_term.split()[0].lower() == "plaintext":
|
2023-03-04 01:38:31 +00:00
|
|
|
creds = self.db.get_credentials(cred_type="plaintext")
|
2016-12-15 07:28:00 +00:00
|
|
|
self.display_creds(creds)
|
2023-03-05 00:10:18 +00:00
|
|
|
elif filter_term.split()[0].lower() == "hash":
|
2023-03-04 01:38:31 +00:00
|
|
|
creds = self.db.get_credentials(cred_type="hash")
|
2016-12-15 07:28:00 +00:00
|
|
|
self.display_creds(creds)
|
|
|
|
else:
|
2023-03-05 00:10:18 +00:00
|
|
|
creds = self.db.get_credentials(filter_term=filter_term)
|
2017-11-02 09:43:08 +00:00
|
|
|
if len(creds) != 1:
|
2017-04-07 04:34:30 +00:00
|
|
|
self.display_creds(creds)
|
|
|
|
elif len(creds) == 1:
|
2017-11-02 09:43:08 +00:00
|
|
|
data = [['CredID', 'CredType', 'Pillaged From HostID', 'Domain', 'UserName', 'Password']]
|
2023-03-05 00:10:18 +00:00
|
|
|
cred_id_list = []
|
2017-04-07 04:34:30 +00:00
|
|
|
|
|
|
|
for cred in creds:
|
2023-03-05 00:10:18 +00:00
|
|
|
cred_id = cred[0]
|
|
|
|
cred_id_list.append(cred_id)
|
2017-04-07 04:34:30 +00:00
|
|
|
domain = cred[1]
|
|
|
|
username = cred[2]
|
|
|
|
password = cred[3]
|
|
|
|
credtype = cred[4]
|
|
|
|
pillaged_from = cred[5]
|
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
data.append([cred_id, credtype, pillaged_from, domain, username, password])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Credential(s)')
|
2017-03-27 21:09:36 +00:00
|
|
|
|
2017-11-02 09:43:08 +00:00
|
|
|
data = [['GroupID', 'Domain', 'Name']]
|
2023-03-05 00:10:18 +00:00
|
|
|
for cred_id in cred_id_list:
|
2023-03-08 06:43:55 +00:00
|
|
|
links = self.db.get_group_relations(user_id=cred_id)
|
2017-03-27 21:09:36 +00:00
|
|
|
|
2017-04-07 04:34:30 +00:00
|
|
|
for link in links:
|
2023-03-05 00:10:18 +00:00
|
|
|
link_id, user_id, group_id = link
|
|
|
|
groups = self.db.get_groups(group_id)
|
2017-03-27 21:09:36 +00:00
|
|
|
|
2017-04-07 04:34:30 +00:00
|
|
|
for group in groups:
|
2023-03-05 00:10:18 +00:00
|
|
|
group_id = group[0]
|
2017-11-02 09:43:08 +00:00
|
|
|
domain = group[1]
|
|
|
|
name = group[2]
|
2023-03-05 00:10:18 +00:00
|
|
|
data.append([group_id, domain, name])
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Member of Group(s)')
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2017-11-02 09:43:08 +00:00
|
|
|
data = [['HostID', 'IP', 'Hostname', 'Domain', 'OS']]
|
2023-03-05 00:10:18 +00:00
|
|
|
for cred_id in cred_id_list:
|
|
|
|
links = self.db.get_admin_relations(user_id=cred_id)
|
2016-12-15 07:28:00 +00:00
|
|
|
|
2017-04-07 04:34:30 +00:00
|
|
|
for link in links:
|
2023-03-05 00:10:18 +00:00
|
|
|
link_id, cred_id, host_id = link
|
2023-03-12 02:25:23 +00:00
|
|
|
hosts = self.db.get_hosts(host_id)
|
2017-04-07 04:34:30 +00:00
|
|
|
|
|
|
|
for host in hosts:
|
2023-03-05 00:10:18 +00:00
|
|
|
host_id = host[0]
|
2017-04-07 04:34:30 +00:00
|
|
|
ip = host[1]
|
|
|
|
hostname = host[2]
|
|
|
|
domain = host[3]
|
|
|
|
os = host[4]
|
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
data.append([host_id, ip, hostname, domain, os])
|
2023-03-04 00:06:18 +00:00
|
|
|
print_table(data, title='Admin Access to Host(s)')
|
2017-03-27 21:09:36 +00:00
|
|
|
|
2023-03-08 06:43:55 +00:00
|
|
|
def help_creds(self):
|
|
|
|
help_string = """
|
|
|
|
creds [add|remove|plaintext|hash|filter_term]
|
|
|
|
By default prints all creds
|
|
|
|
Table format:
|
|
|
|
| 'CredID', 'Admin On', 'CredType', 'Domain', 'UserName', 'Password' |
|
|
|
|
Subcommands:
|
|
|
|
add - format: "add domain username password <notes> <credType> <sid>"
|
|
|
|
remove - format: "remove <credID>"
|
|
|
|
plaintext - prints plaintext creds
|
|
|
|
hash - prints hashed creds
|
|
|
|
filter_term - filters creds with filter_term
|
|
|
|
If a single credential is returned (e.g. `creds 15`, it prints the following tables:
|
|
|
|
Credential(s) | 'CredID', 'CredType', 'Pillaged From HostID', 'Domain', 'UserName', 'Password' |
|
|
|
|
Member of Group(s) | 'GroupID', 'Domain', 'Name' |
|
|
|
|
Admin Access to Host(s) | 'HostID', 'IP', 'Hostname', 'Domain', 'OS'
|
2023-03-10 04:36:31 +00:00
|
|
|
Otherwise, it prints the default credential table from a `like` query on the `username` column
|
2023-03-08 06:43:55 +00:00
|
|
|
"""
|
|
|
|
print_help(help_string)
|
|
|
|
|
2023-03-04 16:12:29 +00:00
|
|
|
def do_clear_database(self, line):
|
2023-03-10 00:25:18 +00:00
|
|
|
if input("This will destroy all data in the current database, are you SURE you want to run this? (y/n): ") == "y":
|
|
|
|
self.db.clear_database()
|
|
|
|
|
|
|
|
def help_clear_database(self):
|
|
|
|
help_string = """
|
|
|
|
clear_database
|
|
|
|
THIS COMPLETELY DESTROYS ALL DATA IN THE CURRENTLY CONNECTED DATABASE
|
|
|
|
YOU CANNOT UNDO THIS COMMAND
|
|
|
|
"""
|
|
|
|
print_help(help_string)
|
2023-03-04 16:12:29 +00:00
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
def complete_hosts(self, text, line):
|
|
|
|
"""
|
2023-03-06 23:29:08 +00:00
|
|
|
Tab-complete 'hosts' commands.
|
2023-03-05 00:10:18 +00:00
|
|
|
"""
|
2017-11-02 09:43:08 +00:00
|
|
|
commands = ["add", "remove", "dc"]
|
2017-03-27 21:09:36 +00:00
|
|
|
|
|
|
|
mline = line.partition(' ')[2]
|
|
|
|
offs = len(mline) - len(text)
|
|
|
|
return [s[offs:] for s in commands if s.startswith(mline)]
|
|
|
|
|
2023-03-05 00:10:18 +00:00
|
|
|
def complete_creds(self, text, line):
|
|
|
|
"""
|
|
|
|
Tab-complete 'creds' commands.
|
|
|
|
"""
|
2017-11-02 09:43:08 +00:00
|
|
|
commands = ["add", "remove", "hash", "plaintext"]
|
2017-05-08 03:16:18 +00:00
|
|
|
|
|
|
|
mline = line.partition(' ')[2]
|
|
|
|
offs = len(mline) - len(text)
|
|
|
|
return [s[offs:] for s in commands if s.startswith(mline)]
|