from cc.services.pth_report_utils import PassTheHashReport, Machine
class PTHReportService(object):
def __init__(self):
pass
@staticmethod
def get_duplicated_password_nodes(pth):
usernames_lists = []
usernames_per_sid_list = []
dups = dict(map(lambda x: (x, len(pth.GetSidsBySecret(x))), pth.GetAllSecrets()))
for secret, count in sorted(dups.iteritems(), key=lambda (k, v): (v, k), reverse=True):
if count <= 1:
continue
for sid in pth.GetSidsBySecret(secret):
usernames_per_sid_list.append(pth.GetUsernameBySid(sid))
usernames_lists.append(usernames_per_sid_list)
return usernames_lists
@staticmethod
def get_shared_local_admins_nodes(pth):
dups = dict(map(lambda x: (x, len(pth.GetSharedAdmins(x))), pth.machines))
shared_admin_machines = []
for m, count in sorted(dups.iteritems(), key=lambda (k, v): (v, k), reverse=True):
if count <= 0:
continue
shared_admin_account_list = []
for sid in pth.GetSharedAdmins(m):
shared_admin_account_list.append(pth.GetUsernameBySid(sid))
machine = {
'ip': m.GetIp(),
'hostname': m.GetHostName(),
'domain': m.GetDomainName(),
'services_names': m.GetCriticalServicesInstalled(),
'user_count': count,
'admins_accounts': shared_admin_account_list
}
shared_admin_machines.append(machine)
return shared_admin_machines
@staticmethod
def get_strong_users_on_crit_services(pth):
threatening = dict(map(lambda x: (x, len(pth.GetThreateningUsersByVictim(x))), pth.GetCritialServers()))
strong_users_crit_list = []
for m, count in sorted(threatening.iteritems(), key=lambda (k, v): (v, k), reverse=True):
if count <= 0:
continue
threatening_users_attackers_dict = {}
for sid in pth.GetThreateningUsersByVictim(m):
username = pth.GetUsernameBySid(sid)
threatening_users_attackers_dict[username] = []
for mm in pth.GetAttackersBySid(sid):
if m == mm:
continue
threatening_users_attackers_dict[username] = mm.GetIp()
machine = {
'ip': m.GetIp(),
'hostname': m.GetHostName(),
'domain': m.GetDomainName(),
'services_names': m.GetCriticalServicesInstalled(),
'user_count': count,
'threatening_users': threatening_users_attackers_dict
}
strong_users_crit_list.append(machine)
return strong_users_crit_list
@staticmethod
def get_strong_users_on_non_crit_services(pth):
threatening = dict(map(lambda x: (x, len(pth.GetThreateningUsersByVictim(x))), pth.GetNonCritialServers()))
strong_users_non_crit_list = []
for m, count in sorted(threatening.iteritems(), key=lambda (k, v): (v, k), reverse=True):
if count <= 0:
continue
threatening_users_attackers_dict = {}
for sid in pth.GetThreateningUsersByVictim(m):
username = pth.GetUsernameBySid(sid)
threatening_users_attackers_dict[username] = []
for mm in pth.GetAttackersBySid(sid):
if m == mm:
continue
threatening_users_attackers_dict[username] = mm.GetIp()
machine = {
'ip': m.GetIp(),
'hostname': m.GetHostName(),
'domain': m.GetDomainName(),
'services_names': m.GetNonCritialServers(),
'user_count': count,
'threatening_users': threatening_users_attackers_dict
}
strong_users_non_crit_list.append(machine)
return strong_users_non_crit_list
@staticmethod
def generate_map_nodes(pth):
nodes_list = []
for node_id in pth.vertices:
machine = Machine(node_id)
node = {
"id": machine.get_monkey_id,
"label": '{0} : {1}'.format(machine.GetHostName(), machine.GetIp()),
'group': 'critical' if machine.IsCriticalServer() else 'normal',
'users': list(machine.GetCachedUsernames()),
'ips': machine.GetIp(),
'services': machine.GetCriticalServicesInstalled(),
'hostname': machine.GetHostName()
}
nodes_list.append(node)
return nodes_list
@staticmethod
def get_report():
pth = PassTheHashReport()
report = \
{
'report_info':
{
'same_password': PTHReportService.get_duplicated_password_nodes(pth),
'local_admin_shared': PTHReportService.get_shared_local_admins_nodes(pth),
'strong_users_on_crit_services': PTHReportService.get_strong_users_on_crit_services(pth),
'strong_users_on_non_crit_services': PTHReportService.get_strong_users_on_non_crit_services(pth)
},
'map':
{
'nodes': PTHReportService.generate_map_nodes(pth),
'edges': pth.edges
}
}
return report
# print """
"""
#
# print "
Cached Passwords
"
# print "
On how many machines each secret is cached (possible attacker count)?
"
# cache_counts = dict(map(lambda x: (x, pth.GetAttackCountBySecret(x)), pth.GetAllSecrets()))
#
# print """
"""
# print """Secret | Machine Count |
"""
# for secret, count in sorted(cache_counts.iteritems(), key=lambda (k,v): (v,k), reverse=True):
# if count <= 0:
# continue
# print """{secret} | {count} | """.format(secret=secret, count=count)
# print """
"""
#
# print "
User's Creds
"
# print "
To how many machines each user is able to connect with admin rights
"
# attackable_counts = dict(map(lambda x: (x, pth.GetVictimCountBySid(x)), pth.GetAllSids()))
#
# print """
"""
# print """SID | Username | Machine Count |
"""
# for sid, count in sorted(attackable_counts.iteritems(), key=lambda (k,v): (v,k), reverse=True):
# if count <= 1:
# continue
# print """{sid} | {username} | {count} | """.format(sid=sid, username=pth.GetUsernameBySid(sid), count=count)
# print """
"""
#
# print "
Actual Possible Attacks By SID
"
# print "
How many attacks possible using each SID (aka len(attacker->victim pairs))
"
# possible_attacks_by_sid = dict(map(lambda x: (x, pth.GetPossibleAttackCountBySid(x)), pth.GetAllSids()))
#
# print """
"""
# print """SID | Username | Machine Count |
"""
# for sid, count in sorted(possible_attacks_by_sid.iteritems(), key=lambda (k,v): (v,k), reverse=True):
# if count <= 1:
# continue
# print """{sid} | {username} | {count} | """.format(sid=sid, username=pth.GetUsernameBySid(sid), count=count)
# print """
"""
#
# print "
Machine's Creds
"
# print "
To how many machines each machine is able to directly connect with admin rights?
"
# attackable_counts = dict(map(lambda m: (m, pth.GetVictimCountByMachine(m)), pth.machines))
#
# print """
"""
# print """Attacker Ip | Attacker Hostname | Domain Name | Victim Machine Count |
"""
# for m, count in sorted(attackable_counts.iteritems(), key=lambda (k,v): (v,k), reverse=True):
# if count <= 1:
# continue
# print """{ip} | {hostname} | {domain} | {count} | """.format(ip=m.GetIp(), hostname=m.GetHostName(), domain=m.GetDomainName(), count=count)
# print """
"""
#
# print "
Domain Controllers
"
# print "
List of domain controllers (we count them as critical points, so they are listed here)
"
# DCs = dict(map(lambda m: (m, pth.GetInPathCountByVictim(m)), pth.GetAllDomainControllers()))
#
# print """
"""
# print """DC Ip | DC Hostname | Domain Name | In-Path Count |
"""
# for m, path_count in sorted(DCs.iteritems(), key=lambda (k,v): (v,k), reverse=True):
# print """{ip} | {hostname} | {domain} | {path_count} |
""".format(ip=m.GetIp(), hostname=m.GetHostName(), domain=m.GetDomainName(), path_count=path_count)
# print """
"""
#
# print "
Most Vulnerable Machines
"
# print "
List all machines in the network sorted by the potincial to attack them
"
# all_machines = dict(map(lambda m: (m, pth.GetInPathCountByVictim(m)), pth.machines))
#
# print """
"""
# print """Ip | Hostname | Domain Name | In-Path Count |
"""
# for m, path_count in sorted(all_machines.iteritems(), key=lambda (k,v): (v,k), reverse=True):
# if count <= 0:
# continue
# print """{ip} | {hostname} | {domain} | {path_count} |
""".format(ip=m.GetIp(), hostname=m.GetHostName(), domain=m.GetDomainName(), path_count=path_count)
# print """
"""
#
# print "
Critical Servers
"
# print "
List of all machines identified as critical servers
"
# critical_servers = pth.GetCritialServers()
#
# print """
"""
# print """Ip | Hostname | Domain Name |
"""
# for m in critical_servers:
# print """{ip} | {hostname} | {domain} |
""".format(ip=m.GetIp(), hostname=m.GetHostName(), domain=m.GetDomainName())
# print """
"""
#
# print "
"
#
# for m in pth.machines:
# print """
Machine '{ip}'
#
Hostname '{hostname}'
""".format(ip=m.GetIp(), hostname=m.GetHostName())
#
# print """
Cached SIDs
"""
# print """
SIDs cached on this machine
"""
# print """
"""
# for sid in pth.GetCachedSids(m):
# print """- {username} ({sid})
""".format(username=pth.GetUsernameBySid(sid), sid=sid)
# print """
"""
#
# print """
Possible Attackers
"""
# print """
Machines that can attack this machine
"""
# print """
"""
# for attacker in pth.GetAttackersByVictim(m):
# print """- {ip} ({hostname})
""".format(ip=attacker.GetIp(), hostname=attacker.GetHostName())
# print """
"""
#
#
# print """
Admins
"""
# print """
Users that have admin rights on this machine
"""
# print """
"""
# for sid in m.GetAdmins():
# print """- {username} ({sid})
""".format(username=m.GetUsernameBySid(sid), sid=sid)
# print """
"""
#
# print """
Installed Critical Services
"""
# print """
List of crtical services found installed on machine
"""
# print """
"""
# for service_name in m.GetCriticalServicesInstalled():
# print """- {service_name}
""".format(service_name=service_name)
# print """
"""
#
#
# print "
"
#
# for username in pth.GetAllUsernames():
# print """
User '{username}'
""".format(username=username)
#
# print """
Matching SIDs
"""
# print """
"""
# for sid in pth.GetSidsByUsername(username):
# print """- {username} ({sid})
""".format(username=pth.GetUsernameBySid(sid),
# sid=sid)
# print """
"""
#
# print "
"
#
# for sid in pth.GetAllSids():
# print """
SID '{sid}'
#
#
Domain: {domain}
#
# """.format(username=pth.GetUsernameBySid(sid), sid=sid, secret=pth.GetSecretBySid(sid),
# domain=pth.GetSidInfo(sid)["Domain"])
#
# print """
Machines the sid is local admin on
"""
# print """
"""
# for m in pth.GetVictimsBySid(sid):
# print """- {ip} ({hostname})
""".format(ip=m.GetIp(), hostname=m.GetHostName())
# print """
"""
#
# print """
Machines the sid is in thier cache
"""
# print """
"""
# for m in pth.GetAttackersBySid(sid):
# print """- {ip} ({hostname})
""".format(ip=m.GetIp(), hostname=m.GetHostName())
# print """
"""
#
# for secret in pth.GetAllSecrets():
# print """
Secret '{secret}'
""".format(secret=secret)
#
# print """
SIDs that use that secret
"""
# print """
"""
# for sid in pth.GetSidsBySecret(secret):
# print """- {username} ({sid})
""".format(username=pth.GetUsernameBySid(sid),
# sid=sid)
# print """
"""
#
# print """
Attackable Machines with that secret
"""
# print """
"""
# for m in pth.GetVictimsBySecret(secret):
# print """- {hostname}
""".format(ip=m.GetIp(), hostname=m.GetHostName())
# print """
"""
#
# print """
Machines that have this secret cached and can use it to attack other machines
"""
# print """
"""
# for m in pth.GetAttackersBySecret(secret):
# print """- {hostname}
""".format(ip=m.GetIp(), hostname=m.GetHostName())
# print """
"""