diff --git a/monkey/monkey_island/cc/resources/telemetry.py b/monkey/monkey_island/cc/resources/telemetry.py
index 0c390a192..644fd6984 100644
--- a/monkey/monkey_island/cc/resources/telemetry.py
+++ b/monkey/monkey_island/cc/resources/telemetry.py
@@ -217,8 +217,6 @@ class Telemetry(flask_restful.Resource):
telemetry_json['data']['wmi']['Win32_Product'],
monkey_id)
-
-
@staticmethod
def update_critical_services(wmi_services, wmi_products, machine_id):
critical_names = ("W3svc", "MSExchangeServiceHost", "MSSQLServer", "dns", 'MSSQL$SQLEXPRESS', 'SQL')
diff --git a/monkey/monkey_island/cc/services/pth_report.py b/monkey/monkey_island/cc/services/pth_report.py
index 364c2c5aa..0bd9c332d 100644
--- a/monkey/monkey_island/cc/services/pth_report.py
+++ b/monkey/monkey_island/cc/services/pth_report.py
@@ -7,14 +7,6 @@ from bson import ObjectId
class PTHReportService(object):
- """
-
- """
-
- def __init__(self):
- pass
-
-
@staticmethod
def get_duplicated_passwords_nodes():
users_cred_groups = []
@@ -153,6 +145,34 @@ class PTHReportService(object):
return issues
+ @staticmethod
+ def get_strong_users_on_crit_details():
+ table_entries = []
+ user_details = {}
+ crit_machines = PTHReportService.get_strong_users_on_critical_machines_nodes()
+ for machine in crit_machines:
+ for user in crit_machines[machine]['threatening_users']:
+ username = user['name']
+ if username not in user_details:
+ user_details[username] = {}
+ user_details[username]['machines'] = []
+ user_details[username]['services'] = []
+ user_details[username]['machines'].append(machine)
+ user_details[username]['services'] += crit_machines[machine]['critical_services']
+
+ for user in user_details:
+ table_entries.append(
+ {
+ 'username': user,
+ 'machines': user_details[user]['machines'],
+ 'services_names': user_details[user]['services']
+ }
+ )
+
+ return table_entries
+
+
+
@staticmethod
def generate_map_nodes():
@@ -188,14 +208,13 @@ class PTHReportService(object):
for pair in pairs:
edges_list.append(
{
- 'from': pair[0],
- 'to': pair[1],
+ 'from': pair[1],
+ 'to': pair[0],
'id': str(uuid.uuid4())
}
)
return edges_list
-
@staticmethod
def generate_edges_tuples(*lists):
@@ -205,7 +224,6 @@ class PTHReportService(object):
if pair[0] != pair[1]:
yield pair
-
@staticmethod
def get_report():
@@ -216,8 +234,10 @@ class PTHReportService(object):
{
'report_info':
{
+ 'strong_users_table': PTHReportService.get_strong_users_on_crit_details(),
'pth_issues': issues
},
+
'pthmap':
{
'nodes': PTHReportService.generate_map_nodes(),
diff --git a/monkey/monkey_island/cc/services/report.py b/monkey/monkey_island/cc/services/report.py
index 552250b35..304867495 100644
--- a/monkey/monkey_island/cc/services/report.py
+++ b/monkey/monkey_island/cc/services/report.py
@@ -717,6 +717,7 @@ class ReportService:
},
'pth':
{
+ 'strong_users': pth_report['report_info']['strong_users_table'],
'map': pth_report.get('pthmap'),
}
}
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js
index f4982a9e8..260701c4d 100644
--- a/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -347,8 +347,7 @@ class ReportPageComponent extends AuthComponent {
{this.state.report.overview.issues[this.Issue.HADOOP] ?
Hadoop/Yarn servers are vulnerable to remote code execution. : null }
{this.state.report.overview.issues[this.Issue.PTH_CRIT_SERVICES_ACCESS] ?
- Credentials of strong users was found on machines and can give access to critical servers
- (DC, MSSQL, etc..): null }
+ Mimikatz found login credentials of a user who has admin access to a server defined as critical.: null }
:
@@ -375,11 +374,9 @@ class ReportPageComponent extends AuthComponent {
{this.state.report.overview.warnings[this.Warning.TUNNEL] ?
Weak segmentation - Machines were able to communicate over unused ports. : null}
{this.state.report.overview.warnings[this.Warning.SHARED_LOCAL_ADMIN] ?
- The monkey has found that some users have administrative rights on several machines. : null}
- {this.state.report.overview.warnings[this.Warning.SHARED_PASSWORDS_DOMAIN] ?
- The monkey has found that some users are sharing passwords on domain accounts. : null}
+ Shared local administrator account - Different machines have the same account as a local administrator. : null}
{this.state.report.overview.warnings[this.Warning.SHARED_PASSWORDS] ?
- The monkey has found that some users are sharing passwords. : null}
+ Multiple users have the same password : null}
:
@@ -471,10 +468,15 @@ class ReportPageComponent extends AuthComponent {
+
{this.generateReportPthMap()}
+
+
+
+
);
}
@@ -488,6 +490,10 @@ class ReportPageComponent extends AuthComponent {
This map visualizes possible attack paths through the network using credential compromise. Paths represent lateral movement opportunities by attackers.
+
+ Legend:
+ Access credentials |
+
@@ -779,7 +785,7 @@ class ReportPageComponent extends AuthComponent {
generateSharedLocalAdminsIssue(issue) {
return (
- Credentials for the user {issue.username} could be found and the user is an administrator account on more than one machines in the domain.
+ Make sure the right administrator accounts are managing the right machines, and that there isn’t an unintentional local admin sharing.
Here is a list of machines which has this account defined as an administrator:
{this.generateInfoBadges(issue.shared_machines)}
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/StrongUsers.js b/monkey/monkey_island/cc/ui/src/components/report-components/StrongUsers.js
index 36068f26e..a8f045479 100644
--- a/monkey/monkey_island/cc/ui/src/components/report-components/StrongUsers.js
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/StrongUsers.js
@@ -11,7 +11,6 @@ const columns = [
Header: 'Powerful Users',
columns: [
{ Header: 'Username', accessor: 'username'},
- { Header: 'Domain', accessor: 'domain'},
{ Header: 'Machines', id: 'machines', accessor: x => renderArray(x.machines)},
{ Header: 'Services', id: 'services', accessor: x => renderArray(x.services_names)}
]
diff --git a/monkey_island/cc/services/group_info.py b/monkey_island/cc/services/group_info.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/monkey_island/cc/services/pth_report.py b/monkey_island/cc/services/pth_report.py
deleted file mode 100644
index fe25fd494..000000000
--- a/monkey_island/cc/services/pth_report.py
+++ /dev/null
@@ -1,259 +0,0 @@
-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):
- if sid:
- usernames_per_sid_list.append(pth.GetUsernameBySid(sid))
-
- usernames_lists.append({'cred_group': 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_by_machine(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': m.GetCriticalServicesInstalled(),
- 'threatening_users': threatening_users_attackers_dict
- }
- strong_users_crit_list.append(machine)
- return strong_users_crit_list
-
- @staticmethod
- def get_strong_users_on_crit_services_by_user(pth):
- critical_servers = pth.GetCritialServers()
- strong_users_dict = {}
-
- for server in critical_servers:
- users = pth.GetThreateningUsersByVictim(server)
- for sid in users:
- username = pth.GetUsernameBySid(sid)
- if username not in strong_users_dict:
- strong_users_dict[username] = {
- 'services_names': [],
- 'machines': []
- }
- strong_users_dict[username]['username'] = username
- strong_users_dict[username]['domain'] = server.GetDomainName()
- strong_users_dict[username]['services_names'] += server.GetCriticalServicesInstalled()
- strong_users_dict[username]['machines'].append(server.GetHostName())
-
- return strong_users_dict.values()
-
- @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': [],
- 'user_count': count,
- 'threatening_users': threatening_users_attackers_dict
- }
- strong_users_non_crit_list.append(machine)
- return strong_users_non_crit_list
-
- @staticmethod
- def get_duplicated_passwords_issues(pth, password_groups):
- issues = []
- previeous_group = []
- for group in password_groups:
- username = group['cred_group'][0]
- if username in previeous_group:
- continue
- sid = list(pth.GetSidsByUsername(username.split('\\')[1]))
- machine_info = pth.GetSidInfo(sid[0])
- issues.append(
- {
- 'type': 'shared_passwords',
- 'machine': machine_info.get('hostname').split('.')[0],
- 'shared_with': group['cred_group']
- }
- )
- previeous_group += group['cred_group']
-
- return issues
-
- @staticmethod
- def get_shared_local_admins_issues(shared_admins_machines):
- issues = []
- for machine in shared_admins_machines:
- issues.append(
- {
- 'type': 'shared_admins',
- 'machine': machine.get('hostname'),
- 'shared_accounts': machine.get('admins_accounts'),
- 'ip': machine.get('ip'),
- }
- )
-
- return issues
-
- @staticmethod
- def strong_users_on_crit_issues(strong_users):
- issues = []
- for machine in strong_users:
- issues.append(
- {
- 'type': 'strong_users_on_crit',
- 'machine': machine.get('hostname'),
- 'services': machine.get('services'),
- 'ip': machine.get('ip'),
- 'threatening_users': machine.get('threatening_users').keys()
- }
- )
-
- return issues
-
- @staticmethod
- def get_machine_details(node_id):
- machine = Machine(node_id)
- node = {}
- if machine.latest_system_info:
- node = {
- "id": str(node_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()
- }
- return node
-
- @staticmethod
- def generate_map_nodes(pth):
- nodes_list = []
- for node_id in pth.vertices:
- node = PTHReportService.get_machine_details(node_id)
- nodes_list.append(node)
-
- return nodes_list
-
- @staticmethod
- def get_issues_list(issues):
- issues_dict = {}
-
- for issue in issues:
- machine = issue['machine']
- if machine not in issues_dict:
- issues_dict[machine] = []
- issues_dict[machine].append(issue)
-
- return issues_dict
-
- @staticmethod
- def get_report():
-
- issues = []
- pth = PassTheHashReport()
-
- 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_by_user(pth)
- strong_users_on_non_crit_services = PTHReportService.get_strong_users_on_non_crit_services(pth)
-
- issues += PTHReportService.get_duplicated_passwords_issues(pth, same_password)
- issues += PTHReportService.get_shared_local_admins_issues(local_admin_shared)
- issues += PTHReportService.strong_users_on_crit_issues(
- PTHReportService.get_strong_users_on_crit_services_by_machine(pth))
-
- report = \
- {
- 'report_info':
- {
- 'same_password': same_password,
- 'local_admin_shared': local_admin_shared,
- 'strong_users_on_crit_services': strong_users_on_crit_services,
- 'strong_users_on_non_crit_services': strong_users_on_non_crit_services,
- 'pth_issues': issues
- },
- 'pthmap':
- {
- 'nodes': PTHReportService.generate_map_nodes(pth),
- 'edges': pth.edges
- }
- }
- return report
\ No newline at end of file
diff --git a/monkey_island/cc/services/pth_report_utils.py b/monkey_island/cc/services/pth_report_utils.py
deleted file mode 100644
index 61fe78765..000000000
--- a/monkey_island/cc/services/pth_report_utils.py
+++ /dev/null
@@ -1,958 +0,0 @@
-import hashlib
-import binascii
-import copy
-import uuid
-
-from cc.database import mongo
-from cc.services.node import NodeService
-
-DsRole_RoleStandaloneWorkstation = 0
-DsRole_RoleMemberWorkstation = 1
-DsRole_RoleStandaloneServer = 2
-DsRole_RoleMemberServer = 3
-DsRole_RoleBackupDomainController = 4
-DsRole_RolePrimaryDomainController = 5
-
-SidTypeUser = 1
-SidTypeGroup = 2
-SidTypeDomain = 3
-SidTypeAlias = 4
-SidTypeWellKnownGroup = 5
-SidTypeDeletedAccount = 6
-SidTypeInvalid = 7
-SidTypeUnknown = 8
-SidTypeComputer = 9
-
-
-def is_group_sid_type(type):
- return type in (SidTypeGroup, SidTypeAlias, SidTypeWellKnownGroup)
-
-
-def myntlm(x):
- hash = hashlib.new('md4', x.encode('utf-16le')).digest()
- return str(binascii.hexlify(hash))
-
-
-def cache(foo):
- def hash(o):
- if type(o) in (int, float, str, unicode):
- return repr(o)
-
- elif type(o) in (type(None),):
- return "___None___"
-
- elif type(o) in (list, tuple, set):
- hashed = tuple([hash(x) for x in o])
-
- if "NotHashable" in hashed:
- return "NotHashable"
-
- return hashed
-
- elif type(o) == dict:
- hashed_keys = tuple([hash(k) for k, v in o.iteritems()])
- hashed_vals = tuple([hash(v) for k, v in o.iteritems()])
-
- if "NotHashable" in hashed_keys or "NotHashable" in hashed_vals:
- return "NotHashable"
-
- return tuple(zip(hashed_keys, hashed_vals))
-
- elif type(o) == Machine:
- return o.monkey_guid
-
- # elif type(o) == PthMap:
- # return "PthMapSingleton"
-
- elif type(o) == PassTheHashReport:
- return "PassTheHashReportSingleton"
-
- else:
- assert False, "%s of type %s is not hashable" % (repr(o), type(o))
- return "NotHashable"
-
- def wrapper(*args, **kwargs):
- hashed = (hash(args), hash(kwargs))
-
- if "NotHashable" in hashed:
- return foo(*args, **kwargs)
-
- if not hasattr(foo, "_mycache_"):
- foo._mycache_ = dict()
-
- if hashed not in foo._mycache_.keys():
- foo._mycache_[hashed] = foo(*args, **kwargs)
-
- return copy.deepcopy(foo._mycache_[hashed])
-
- return wrapper
-
-
-class Machine(object):
- def __init__(self, monkey_guid):
- self.monkey_guid = str(monkey_guid)
-
- self.latest_system_info = mongo.db.telemetry.find(
- {"telem_type": "system_info_collection", "monkey_guid": self.monkey_guid}).sort([("timestamp", -1)]).limit(
- 1)
-
- if self.latest_system_info.count() > 0:
- self.latest_system_info = self.latest_system_info[0]
- else:
- self.latest_system_info = None
-
- self.monkey_info = NodeService.get_monkey_by_guid(self.monkey_guid)
-
- def __eq__(self, other):
- if isinstance(other, self.__class__):
- return self.monkey_guid == other.monkey_guid
- else:
- return False
-
- @cache
- def GetMimikatzOutput(self):
- doc = self.latest_system_info
-
- if not doc:
- return None
-
- return doc.get("data").get("mimikatz")
-
- @cache
- def GetHostName(self):
- doc = self.latest_system_info
-
- for comp in doc.get("data").get("Win32_ComputerSystem", {}):
- return eval(comp.get("Name"))
-
- return None
-
- @cache
- def GetIp(self):
- doc = self.latest_system_info
-
- for addr in doc.get("data").get("network_info", {}).get("networks", {}):
- return str(addr["addr"])
-
- return None
-
- @cache
- def get_monkey_id(self):
- doc = self.monkey_info
-
- return str(doc.get('_id'))
-
- @cache
- def GetDomainName(self):
- doc = self.latest_system_info
-
- for comp in doc.get("data").get("Win32_ComputerSystem", {}):
- return eval(comp.get("Domain"))
-
- return None
-
- @cache
- def GetDomainRole(self):
- doc = self.latest_system_info
-
- for comp in doc.get("data").get("Win32_ComputerSystem", {}):
- return comp.get("DomainRole")
-
- return None
-
- @cache
- def IsDomainController(self):
- return self.GetDomainRole() in (DsRole_RolePrimaryDomainController, DsRole_RoleBackupDomainController)
-
- #@cache
- def GetSidByUsername(self, username, domain=None):
- doc = self.latest_system_info
-
- for user in doc.get("data").get("Win32_UserAccount", {}):
- if eval(user.get("Name")) != username:
- continue
-
- if user.get("SIDType") != SidTypeUser:
- continue
-
- if domain and user.get("Domain") != domain:
- continue
-
- return eval(user.get("SID"))
-
- if not self.IsDomainController():
- for dc in self.GetDomainControllers():
- sid = dc.GetSidByUsername(username)
-
- if sid != None:
- return sid
-
- return None
-
- @cache
- def GetUsernameBySid(self, sid):
- info = self.GetSidInfo(sid)
-
- if not info:
- return None
-
- return str(info.get("Domain")) + "\\" + str(info.get("Username"))
-
- @cache
- def GetSidInfo(self, sid):
- doc = self.latest_system_info
-
- for user in doc.get("data").get("Win32_UserAccount",{}):
- if eval(user.get("SID")) != sid:
- continue
-
- if user.get("SIDType") != SidTypeUser:
- continue
-
- return {"Domain": eval(user.get("Domain")),
- "Username": eval(user.get("Name")),
- "Disabled": user.get("Disabled") == "true",
- "PasswordRequired": user.get("PasswordRequired") == "true",
- "PasswordExpires": user.get("PasswordExpires") == "true",
- 'hostname': doc.get('data').get('hostname'), }
-
- if not self.IsDomainController():
- for dc in self.GetDomainControllers():
- domain = dc.GetSidInfo(sid)
-
- if domain != None:
- return domain
-
- return None
-
- @cache
- def GetCriticalServicesInstalled(self):
- def IsNameOfCriticalService(name):
- services = ("W3svc", "MSExchangeServiceHost", "MSSQLServer", "dns", 'MSSQL$SQLEXPRESS')
- services = map(str.lower, services)
-
- if not name:
- return False
-
- name = name.lower()
-
- return name in services
- # for ser in services:
- # if ser in name:
- # return True
-
- return False
-
- doc = self.latest_system_info
- found = []
-
- if self.IsDomainController():
- found.append("Domain Controller")
-
- for product in doc.get("data").get("Win32_Product", {}):
- service_name = eval(product.get("Name"))
-
- if not IsNameOfCriticalService(service_name):
- continue
-
- found.append(service_name)
-
- for service in doc.get("data").get("Win32_Service", {}):
- service_name = eval(service.get("Name"))
-
- if not IsNameOfCriticalService(service_name):
- continue
-
- if eval(service.get("State")) != "Running":
- continue
-
- found.append(service_name)
-
- return found
-
- @cache
- def IsCriticalServer(self):
- return len(self.GetCriticalServicesInstalled()) > 0
-
- @cache
- def GetUsernamesBySecret(self, secret):
- sam = self.GetLocalSecrets()
-
- names = set()
-
- for username, user_secret in sam.iteritems():
- if secret == user_secret:
- names.add(username)
-
- return names
-
- @cache
- def GetSidsBySecret(self, secret):
- usernames = self.GetUsernamesBySecret(secret)
- return set(map(self.GetSidByUsername, usernames))
-
- def GetGroupSidByGroupName(self, group_name):
- doc = self.latest_system_info
-
- for group in doc.get('data').get("Win32_Group", {}):
- if eval(group.get("Name")) != group_name:
- continue
-
- if not is_group_sid_type(group.get("SIDType")):
- continue
-
- return eval(group.get("SID"))
-
- return None
-
- def GetUsersByGroupSid(self, sid):
- doc = self.latest_system_info
-
- users = dict()
-
- for group_user in doc.get('data').get("Win32_GroupUser", {}):
- if eval(group_user.get("GroupComponent", {}).get("SID")) != sid:
- continue
-
- if not is_group_sid_type(group_user.get("GroupComponent", {}).get("SIDType")):
- continue
-
- if "PartComponent" not in group_user.keys():
- continue
-
- if type(group_user.get("PartComponent")) in (str, unicode):
- # PartComponent is an id to Win32_UserAccount table
-
- wmi_id = group_user.get("PartComponent")
-
- if "cimv2:Win32_UserAccount" not in wmi_id:
- continue
-
- username = wmi_id.split('cimv2:Win32_UserAccount.Domain="')[1].split('",Name="')[0]
- domain = wmi_id.split('cimv2:Win32_UserAccount.Domain="')[1].split('",Name="')[1][:-1]
-
- sid = self.GetSidByUsername(username, domain)
- users[sid] = username
-
- else:
- if group_user.get("PartComponent", {}).get("SIDType") != SidTypeUser:
- continue
-
- users[eval(group_user.get("PartComponent", {}).get("SID"))] = eval(group_user.get("PartComponent")
- .get("Name"))
-
- return users
-
- @cache
- def GetDomainControllersMonkeyGuidByDomainName(self, domain_name):
- cur = mongo.db.telemetry.find(
- {"telem_type": "system_info_collection", "data.Win32_ComputerSystem.Domain": "u'%s'" % (domain_name,)})
-
- GUIDs = set()
-
- for doc in cur:
- if not Machine(doc.get("monkey_guid")).IsDomainController():
- continue
-
- GUIDs.add(doc.get("monkey_guid"))
-
- return GUIDs
-
- def GetLocalAdmins(self):
- admins = self.GetUsersByGroupSid(self.GetGroupSidByGroupName("Administrators"))
-
- # debug = self.GetUsersByGroupSid(self.GetGroupSidByGroupName("Users"))
- # admins.update(debug)
-
- return admins
-
- def GetLocalAdminSids(self):
- return set(self.GetLocalAdmins().keys())
-
- @cache
- def GetLocalSids(self):
- doc = self.latest_system_info
-
- SIDs = set()
-
- for user in doc.get('data').get("Win32_UserAccount", {}):
- if user.get("SIDType") != SidTypeUser:
- continue
-
- SIDs.add(eval(user.get("SID")))
-
- return SIDs
-
- @cache
- def GetLocalAdminNames(self):
- return set(self.GetLocalAdmins().values())
-
- @cache
- def GetSam(self):
- if not self.GetMimikatzOutput():
- return {}
-
- mimikatz = self.GetMimikatzOutput()
-
- if mimikatz.count("\n42.") != 2:
- return {}
-
- try:
- sam_users = mimikatz.split("\n42.")[1].split("\nSAMKey :")[1].split("\n\n")[1:]
-
- sam = {}
-
- for sam_user_txt in sam_users:
- sam_user = dict([map(unicode.strip, line.split(":")) for line in
- filter(lambda l: l.count(":") == 1, sam_user_txt.splitlines())])
-
- ntlm = sam_user.get("NTLM")
- if "[hashed secret]" not in ntlm:
- continue
-
- sam[sam_user.get("User")] = ntlm.replace("[hashed secret]", "").strip()
-
- return sam
-
- except:
- return {}
-
- @cache
- def GetNtds(self):
- if not self.GetMimikatzOutput():
- return {}
-
- mimikatz = self.GetMimikatzOutput()
-
- if mimikatz.count("\n42.") != 2:
- return {}
-
- ntds_users = mimikatz.split("\n42.")[2].split("\nRID :")[1:]
- ntds = {}
-
- for ntds_user_txt in ntds_users:
- user = ntds_user_txt.split("User :")[1].splitlines()[0].replace("User :", "").strip()
- ntlm = ntds_user_txt.split("* Primary\n NTLM :")[1].splitlines()[0].replace("NTLM :", "").strip()
- ntlm = ntlm.replace("[hashed secret]", "").strip()
-
- if ntlm:
- ntds[user] = ntlm
-
- return ntds
-
- @cache
- def GetLocalSecrets(self):
- sam = self.GetSam()
- ntds = self.GetNtds()
-
- secrets = sam.copy()
- secrets.update(ntds)
-
- return secrets
-
- @cache
- def GetLocalAdminSecrets(self):
- return set(self.GetLocalAdminCreds().values())
-
- @cache
- def GetLocalAdminCreds(self):
- admin_names = self.GetLocalAdminNames()
- sam = self.GetLocalSecrets()
-
- admin_creds = dict()
-
- for username, secret in sam.iteritems():
- if username not in admin_names:
- continue
-
- admin_creds[username] = secret
-
- return admin_creds
-
- @cache
- def GetCachedSecrets(self):
- return set(self.GetCachedCreds().values())
-
- @cache
- def GetCachedCreds(self):
- doc = self.latest_system_info
-
- creds = dict()
-
- if not self.GetMimikatzOutput():
- return {}
-
- mimikatz = self.GetMimikatzOutput()
-
- for user in mimikatz.split("\n42.")[0].split("Authentication Id")[1:]:
- username = None
- secret = None
-
- for line in user.splitlines():
- if "User Name" in line:
- username = line.split(":")[1].strip()
-
- if ("NTLM" in line or "Password" in line) and "[hashed secret]" in line:
- secret = line.split(":")[1].replace("[hashed secret]", "").strip()
-
- if username and secret:
- creds[username] = secret
-
- return creds
-
- @cache
- def GetDomainControllers(self):
- domain_name = self.GetDomainName()
- DCs = self.GetDomainControllersMonkeyGuidByDomainName(domain_name)
- return map(Machine, DCs)
-
- def GetDomainAdminsOfMachine(self):
- DCs = self.GetDomainControllers()
-
- domain_admins = set()
-
- for dc in DCs:
- domain_admins |= set(dc.GetUsersByGroupSid(self.GetGroupSidByGroupName("Domain Admins")).keys())
-
- return domain_admins
-
- #@cache
- def GetAdmins(self):
- return self.GetLocalAdminSids() # | self.GetDomainAdminsOfMachine()
-
- @cache
- def GetAdminNames(self):
- return set(map(lambda x: self.GetUsernameBySid(x), self.GetAdmins()))
-
- #@cache
- def GetCachedSids(self):
- doc = self.latest_system_info
-
- SIDs = set()
-
- for username in doc.get('data').get("credentials", {}):
- sid = self.GetSidByUsername(username)
-
- if not sid:
- sid = "__USERNAME__" + username
-
- SIDs.add(sid)
-
- return SIDs
-
- @cache
- def GetCachedUsernames(self):
- doc = self.latest_system_info
-
- names = set()
-
- for username in doc.get('data').get("credentials", {}):
- names.add(username)
-
- return names
-
-
-class PassTheHashReport(object):
-
- def __init__(self):
- self.vertices = self.GetAllMachines()
-
- self.machines = map(Machine, self.vertices)
- self.edges = self.get_edges_by_sid() # Useful for non-cached domain users
- #self.edges |= self.GetEdgesBySamHash() # This will add edges based only on password hash without caring about username
-
-
- def GetAllMachines(self):
- cur = mongo.db.telemetry.find({"telem_type": "system_info_collection"})
-
- GUIDs = set()
-
- for doc in cur:
- GUIDs.add(doc.get("monkey_guid"))
-
- return GUIDs
-
- @cache
- def ReprSidList(self, sid_list, victim):
- users_list = []
-
- for sid in sid_list:
- username = Machine(victim).GetUsernameBySid(sid)
-
- if username:
- users_list.append(username)
-
- return users_list
-
- @cache
- def ReprSecretList(self, secret_list, victim):
- relevant_users_list = []
-
- for secret in secret_list:
- relevant_users_list.append(Machine(victim).GetUsernamesBySecret(secret))
-
- return relevant_users_list
-
- @staticmethod
- def __get_edge_label(attacker, victim):
- attacker_monkey = NodeService.get_monkey_by_guid(attacker)
- victim_monkey = NodeService.get_monkey_by_guid(victim)
-
- attacker_label = NodeService.get_monkey_label(attacker_monkey)
- victim_label = NodeService.get_monkey_label(victim_monkey)
-
- RIGHT_ARROW = u"\u2192"
- return "%s %s %s" % (attacker_label, RIGHT_ARROW, victim_label)
-
- def get_edges_by_sid(self):
- edges_list = []
-
- for attacker in self.vertices:
- cached = list(self.GetCachedSids(Machine(attacker)))
-
- for victim in self.vertices:
- if attacker == victim:
- continue
-
- admins = list(Machine(victim).GetAdmins())
-
- cached_admins = [i for i in cached if i in admins]
-
- if cached_admins:
- relevant_users_list = self.ReprSidList(cached_admins, victim)
- edges_list.append(
- {
- 'from': attacker,
- 'to': victim,
- 'users': relevant_users_list,
- '_label': PassTheHashReport.__get_edge_label(attacker, victim),
- 'id': str(uuid.uuid4())
- })
-
- return edges_list
-
- @cache
- def GetEdgesBySamHash(self):
- edges = set()
-
- for attacker in self.vertices:
- cached_creds = set(Machine(attacker).GetCachedCreds().items())
-
- for victim in self.vertices:
- if attacker == victim:
- continue
-
- admin_creds = set(Machine(victim).GetLocalAdminCreds().items())
-
- if len(cached_creds & admin_creds) > 0:
- label = self.ReprSecretList(set(dict(cached_creds & admin_creds).values()), victim)
- edges.add((attacker, victim, label))
-
- return edges
-
- @cache
- def GetEdgesByUsername(self):
- edges = set()
-
- for attacker in self.vertices:
- cached = Machine(attacker).GetCachedUsernames()
-
- for victim in self.vertices:
- if attacker == victim:
- continue
-
- admins = Machine(victim).GetAdminNames()
-
- if len(cached & admins) > 0:
- edges.add((attacker, victim))
-
- return edges
-
- @cache
- def GetPossibleAttackCountBySid(self, sid):
- return len(self.GetPossibleAttacksBySid(sid))
-
- @cache
- def GetPossibleAttacksByAttacker(self, attacker):
- attacks = set()
-
- cached_creds = set(Machine(attacker).GetCachedCreds().items())
-
- for victim in self.vertices:
- if attacker == victim:
- continue
-
- admin_creds = set(Machine(victim).GetLocalAdminCreds().items())
-
- if len(cached_creds & admin_creds) > 0:
- curr_attacks = dict(cached_creds & admin_creds)
- attacks.add((attacker, victim, curr_attacks))
-
- return attacks
-
- @cache
- def GetPossibleAttacksBySid(self, sid):
- attacks = set()
-
- for attacker in self.vertices:
- tmp = self.GetPossibleAttacksByAttacker(attacker)
-
- for _, victim, curr_attacks in tmp:
- for username, secret in curr_attacks.iteritems():
- if Machine(victim).GetSidByUsername(username) == sid:
- attacks.add((attacker, victim))
-
- return attacks
-
- @cache
- def GetSecretBySid(self, sid):
- for m in self.machines:
- for user, user_secret in m.GetLocalSecrets().iteritems():
- if m.GetSidByUsername(user) == sid:
- return user_secret
-
- return None
-
- @cache
- def GetVictimCountBySid(self, sid):
- return len(self.GetVictimsBySid(sid))
-
- @cache
- def GetVictimCountByMachine(self, attacker):
- return len(self.GetVictimsByAttacker(attacker))
-
- @cache
- def GetAttackCountBySecret(self, secret):
- return len(self.GetAttackersBySecret(secret))
-
- @cache
- def GetAllUsernames(self):
- names = set()
-
- for sid in self.GetAllSids():
- names.add(self.GetUsernameBySid(sid))
-
- return names
-
- @cache
- def GetAllSids(self):
- SIDs = set()
-
- for m in self.machines:
- SIDs |= m.GetLocalSids()
-
- return SIDs
-
- @cache
- def GetAllSecrets(self):
- secrets = set()
-
- for m in self.machines:
- for secret in m.GetLocalAdminSecrets():
- secrets.add(secret)
-
- return secrets
-
- @cache
- def GetUsernameBySid(self, sid):
- for m in self.machines:
- username = m.GetUsernameBySid(sid)
-
- if username:
- return username
-
- return None
-
- @cache
- def GetSidInfo(self, sid):
- for m in self.machines:
- info = m.GetSidInfo(sid)
-
- if info:
- return info
-
- return None
-
- @cache
- def GetSidsBySecret(self, secret):
- SIDs = set()
-
- for m in self.machines:
- SIDs |= m.GetSidsBySecret(secret)
-
- return SIDs
-
- @cache
- def GetAllDomainControllers(self):
- DCs = set()
-
- for m in self.machines:
- if m.IsDomainController():
- DCs.add(m)
-
- return DCs
-
- @cache
- def GetSidsByUsername(self, username):
- SIDs = set()
-
- for m in self.machines:
- sid = m.GetSidByUsername(username)
- if sid:
- SIDs.add(sid)
-
- return SIDs
-
- @cache
- def GetVictimsBySid(self, sid):
- machines = set()
-
- for m in self.machines:
- if sid in m.GetAdmins():
- machines.add(m)
-
- return machines
-
- @cache
- def GetVictimsBySecret(self, secret):
- machines = set()
-
- SIDs = self.GetSidsBySecret(secret)
-
- for m in self.machines:
- if len(SIDs & m.GetAdmins()) > 0:
- machines.add(m)
-
- return machines
-
- @cache
- def GetAttackersBySecret(self, secret):
- machines = set()
-
- for m in self.machines:
- if secret in m.GetCachedSecrets():
- machines.add(m)
-
- return machines
-
- @cache
- def GetAttackersByVictim(self, victim):
- if type(victim) != unicode:
- victim = victim.monkey_guid
-
- attackers = set()
-
- for edge in self.edges:
- if edge.get('to', None) == victim:
- attackers.add(edge.get('from', None))
-
- return set(map(Machine, attackers))
-
- @cache
- def GetAttackersBySid(self, sid):
- machines = set()
-
- for m in self.machines:
- if sid in self.GetCachedSids(m):
- machines.add(m)
-
- return machines
-
- @cache
- def GetVictimsByAttacker(self, attacker):
- if type(attacker) != unicode:
- attacker = attacker.monkey_guid
-
- victims = set()
-
- for atck, vic, _ in self.edges:
- if atck == attacker:
- victims.add(vic)
-
- return set(map(Machine, victims))
-
- @cache
- def GetInPathCountByVictim(self, victim, already_processed=None):
- if type(victim) != unicode:
- victim = victim.monkey_guid
-
- if not already_processed:
- already_processed = set([victim])
-
- count = 0
-
- for atck, vic, _ in self.edges:
- if atck == vic:
- continue
-
- if vic != victim:
- continue
-
- if atck in already_processed:
- continue
-
- count += 1
-
- already_processed.add(atck)
- count += self.GetInPathCountByVictim(atck, already_processed)
-
- return count
-
- @cache
- def GetCritialServers(self):
- machines = set()
-
- for m in self.machines:
- if m.IsCriticalServer():
- machines.add(m)
-
- return machines
-
- @cache
- def GetNonCritialServers(self):
- return set(self.machines) - self.GetCritialServers()
-
- #@cache
- def GetCachedSids(self, m):
- sids = set()
- tmp = m.GetCachedSids()
-
- for sid in tmp:
- if sid.startswith("__USERNAME__"):
-
- s = self.GetSidsByUsername(sid[len("__USERNAME__"):])
- if len(s) == 1:
- sids.add(s.pop())
- else:
- sids.add(sid)
-
- else:
- sids.add(sid)
-
- return sids
-
- @cache
- def GetThreateningUsersByVictim(self, victim):
- threatening_users = set()
-
- for attacker in self.GetAttackersByVictim(victim):
- # For each attacker, get the cached users and check which of them is an admin on the victim
- threatening_users |= (self.GetCachedSids(attacker) & victim.GetAdmins())
-
- return threatening_users
-
- def GetSharedAdmins(self, m):
- shared_admins = []
-
- for other in self.machines:
- if m == other:
- continue
- for sid in m.GetLocalAdminSids():
- if sid in other.GetLocalAdminSids():
- shared_admins.append(sid)
-
- #shared_admins |= (m.GetLocalAdminSids() & other.GetLocalAdminSids())
-
- shared_admins = [admin for admin in shared_admins if admin not in list(m.GetDomainAdminsOfMachine())]
-
- return shared_admins
diff --git a/monkey_island/cc/services/user_info.py b/monkey_island/cc/services/user_info.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/monkey_island/cc/ui/src/components/map/preview-pane/InfMapPreviewPane.js b/monkey_island/cc/ui/src/components/map/preview-pane/InfMapPreviewPane.js
deleted file mode 100644
index e06043c20..000000000
--- a/monkey_island/cc/ui/src/components/map/preview-pane/InfMapPreviewPane.js
+++ /dev/null
@@ -1,247 +0,0 @@
-import React from 'react';
-import {Icon} from 'react-fa';
-import Toggle from 'react-toggle';
-import {OverlayTrigger, Tooltip} from 'react-bootstrap';
-import download from 'downloadjs'
-import PreviewPaneComponent from 'components/map/preview-pane/PreviewPane';
-
-class InfMapPreviewPaneComponent extends PreviewPaneComponent {
-
- osRow(asset) {
- return (
-
- Operating System |
- {asset.os.charAt(0).toUpperCase() + asset.os.slice(1)} |
-
- );
- }
-
- ipsRow(asset) {
- return (
-
- IP Addresses |
- {asset.ip_addresses.map(val => {val} )} |
-
- );
- }
-
- servicesRow(asset) {
- return (
-
- Services |
- {asset.services.map(val => {val} )} |
-
- );
- }
-
- accessibleRow(asset) {
- return (
-
-
- Accessible From
- {this.generateToolTip('List of machine which can access this one using a network protocol')}
- |
- {asset.accessible_from_nodes.map(val => {val} )} |
-
- );
- }
-
- statusRow(asset) {
- return (
-
- Status |
- {(asset.dead) ? 'Dead' : 'Alive'} |
-
- );
- }
-
- forceKill(event, asset) {
- let newConfig = asset.config;
- newConfig['alive'] = !event.target.checked;
- this.authFetch('/api/monkey/' + asset.guid,
- {
- method: 'PATCH',
- headers: {'Content-Type': 'application/json'},
- body: JSON.stringify({config: newConfig})
- });
- }
-
- forceKillRow(asset) {
- return (
-
-
- Force Kill
- {this.generateToolTip('If this is on, monkey will die next time it communicates')}
- |
-
- this.forceKill(e, asset)}/>
-
- |
-
- );
- }
-
- unescapeLog(st) {
- return st.substr(1, st.length - 2) // remove quotation marks on beginning and end of string.
- .replace(/\\n/g, "\n")
- .replace(/\\r/g, "\r")
- .replace(/\\t/g, "\t")
- .replace(/\\b/g, "\b")
- .replace(/\\f/g, "\f")
- .replace(/\\"/g, '\"')
- .replace(/\\'/g, "\'")
- .replace(/\\&/g, "\&");
- }
-
- downloadLog(asset) {
- this.authFetch('/api/log?id=' + asset.id)
- .then(res => res.json())
- .then(res => {
- let timestamp = res['timestamp'];
- timestamp = timestamp.substr(0, timestamp.indexOf('.'));
- let filename = res['monkey_label'].split(':').join('-') + ' - ' + timestamp + '.log';
- let logContent = this.unescapeLog(res['log']);
- download(logContent, filename, 'text/plain');
- });
-
- }
-
- downloadLogRow(asset) {
- return (
-
-
- Download Log
- |
-
- this.downloadLog(asset)}>Download
- |
-
- );
- }
-
- exploitsTimeline(asset) {
- if (asset.exploits.length === 0) {
- return ();
- }
-
- return (
-
-
- Exploit Timeline
- {this.generateToolTip('Timeline of exploit attempts. Red is successful. Gray is unsuccessful')}
-
-
-
- )
- }
-
- assetInfo(asset) {
- return (
-
-
-
- {this.osRow(asset)}
- {this.ipsRow(asset)}
- {this.servicesRow(asset)}
- {this.accessibleRow(asset)}
-
-
- {this.exploitsTimeline(asset)}
-
- );
- }
-
- infectedAssetInfo(asset) {
- return (
-
-
-
- {this.osRow(asset)}
- {this.statusRow(asset)}
- {this.ipsRow(asset)}
- {this.servicesRow(asset)}
- {this.accessibleRow(asset)}
- {this.forceKillRow(asset)}
- {this.downloadLogRow(asset)}
-
-
- {this.exploitsTimeline(asset)}
-
- );
- }
-
- scanInfo(edge) {
- return (
-
-
-
-
- Operating System |
- {edge.os.type} |
-
-
- IP Address |
- {edge.ip_address} |
-
-
- Services |
- {edge.services.map(val => {val} )} |
-
-
-
- {
- (edge.exploits.length === 0) ?
- '' :
-
- }
-
- );
- }
-
- islandEdgeInfo() {
- return (
-
-
- );
- }
-
- getInfoByProps() {
- switch (this.props.type) {
- case 'edge':
- return this.scanInfo(this.props.item);
- case 'node':
- return this.props.item.group.includes('monkey', 'manual') ?
- this.infectedAssetInfo(this.props.item) : this.assetInfo(this.props.item);
- case 'island_edge':
- return this.islandEdgeInfo();
- }
-
- return null;
- }
-}
-
-export default InfMapPreviewPaneComponent;
diff --git a/monkey_island/cc/ui/src/components/map/preview-pane/PthPreviewPane.js b/monkey_island/cc/ui/src/components/map/preview-pane/PthPreviewPane.js
deleted file mode 100644
index f9a5ae1bb..000000000
--- a/monkey_island/cc/ui/src/components/map/preview-pane/PthPreviewPane.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import React from 'react';
-import {Icon} from 'react-fa';
-import Toggle from 'react-toggle';
-import {OverlayTrigger, Tooltip} from 'react-bootstrap';
-import download from 'downloadjs'
-import PreviewPaneComponent from 'components/map/preview-pane/PreviewPane';
-
-class PthPreviewPaneComponent extends PreviewPaneComponent {
- nodeInfo(asset) {
- return (
-
-
-
-
- Hostname |
- {asset.hostname} |
-
-
- IP Addresses |
- {asset.ips.map(val => {val} )} |
-
-
- Services |
- {asset.services.map(val => {val} )} |
-
-
- Compromised Users |
- {asset.users.map(val => {val} )} |
-
-
-
-
- );
- }
-
- edgeInfo(edge) {
- return (
-
-
-
-
- Compromised Users |
- {edge.users.map(val => {val} )} |
-
-
-
-
- );
- }
-
- getInfoByProps() {
- switch (this.props.type) {
- case 'edge':
- return this.edgeInfo(this.props.item);
- case 'node':
- return this.nodeInfo(this.props.item);
- }
-
- return null;
- }
-}
-
-export default PthPreviewPaneComponent;
diff --git a/monkey_island/cc/ui/src/components/pages/PassTheHashMapPage.js b/monkey_island/cc/ui/src/components/pages/PassTheHashMapPage.js
deleted file mode 100644
index 20faafca7..000000000
--- a/monkey_island/cc/ui/src/components/pages/PassTheHashMapPage.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import React from 'react';
-import {ReactiveGraph} from 'components/reactive-graph/ReactiveGraph';
-import AuthComponent from '../AuthComponent';
-import {optionsPth, edgeGroupToColorPth, options} from '../map/MapOptions';
-import PreviewPane from "../map/preview-pane/PreviewPane";
-import {Col} from "react-bootstrap";
-import {Link} from 'react-router-dom';
-import {Icon} from 'react-fa';
-import PthPreviewPaneComponent from "../map/preview-pane/PthPreviewPane";
-
-class PassTheHashMapPageComponent extends AuthComponent {
- constructor(props) {
- super(props);
- this.state = {
- graph: props.graph,
- selected: null,
- selectedType: null
- };
- }
-
- events = {
- select: event => this.selectionChanged(event)
- };
-
- selectionChanged(event) {
- if (event.nodes.length === 1) {
- let displayedNode = this.state.graph.nodes.find(
- function (node) {
- return node['id'] === event.nodes[0];
- });
- this.setState({selected: displayedNode, selectedType: 'node'})
- }
- else if (event.edges.length === 1) {
- let displayedEdge = this.state.graph.edges.find(
- function (edge) {
- return edge['id'] === event.edges[0];
- });
- this.setState({selected: displayedEdge, selectedType: 'edge'});
- }
- else {
- this.setState({selected: null, selectedType: null});
- }
- }
-
- render() {
- return (
-
- );
- }
-}
-
-export default PassTheHashMapPageComponent;
diff --git a/monkey_island/cc/ui/src/components/report-components/SharedAdmins.js b/monkey_island/cc/ui/src/components/report-components/SharedAdmins.js
deleted file mode 100644
index bf57065d5..000000000
--- a/monkey_island/cc/ui/src/components/report-components/SharedAdmins.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react';
-import ReactTable from 'react-table'
-
-let renderArray = function(val) {
- return ;
-};
-
-const columns = [
- {
- Header: 'Shared Admins Between Machines',
- columns: [
- { Header: 'Username', accessor: 'username'},
- { Header: 'Domain', accessor: 'domain'},
- { Header: 'Machines', id: 'machines', accessor: x => renderArray(x.machines)},
- ]
- }
-];
-
-const pageSize = 10;
-
-class SharedAdminsComponent extends React.Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- let defaultPageSize = this.props.data.length > pageSize ? pageSize : this.props.data.length;
- let showPagination = this.props.data.length > pageSize;
- return (
-
-
-
- );
- }
-}
-
-export default SharedAdminsComponent;
diff --git a/monkey_island/cc/ui/src/components/report-components/SharedCreds.js b/monkey_island/cc/ui/src/components/report-components/SharedCreds.js
deleted file mode 100644
index f42494167..000000000
--- a/monkey_island/cc/ui/src/components/report-components/SharedCreds.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import React from 'react';
-import ReactTable from 'react-table'
-
-let renderArray = function(val) {
- console.log(val);
- return ;
-};
-
-const columns = [
- {
- Header: 'Shared Credentials',
- columns: [
- {Header: 'Credential Group', id: 'cred_group', accessor: x => renderArray(x.cred_group) }
- ]
- }
-];
-
-const pageSize = 10;
-
-class SharedCredsComponent extends React.Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- let defaultPageSize = this.props.data.length > pageSize ? pageSize : this.props.data.length;
- let showPagination = this.props.data.length > pageSize;
- return (
-
-
-
- );
- }
-}
-
-export default SharedCredsComponent;
diff --git a/monkey_island/cc/ui/src/components/report-components/StrongUsers.js b/monkey_island/cc/ui/src/components/report-components/StrongUsers.js
deleted file mode 100644
index 36068f26e..000000000
--- a/monkey_island/cc/ui/src/components/report-components/StrongUsers.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import React from 'react';
-import ReactTable from 'react-table'
-
-let renderArray = function(val) {
- console.log(val);
- return ;
-};
-
-const columns = [
- {
- Header: 'Powerful Users',
- columns: [
- { Header: 'Username', accessor: 'username'},
- { Header: 'Domain', accessor: 'domain'},
- { Header: 'Machines', id: 'machines', accessor: x => renderArray(x.machines)},
- { Header: 'Services', id: 'services', accessor: x => renderArray(x.services_names)}
- ]
- }
-];
-
-const pageSize = 10;
-
-class StrongUsersComponent extends React.Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- let defaultPageSize = this.props.data.length > pageSize ? pageSize : this.props.data.length;
- let showPagination = this.props.data.length > pageSize;
- return (
-
-
-
- );
- }
-}
-
-export default StrongUsersComponent;
diff --git a/monkey_island/cc/ui/src/images/nodes/pth/critical.png b/monkey_island/cc/ui/src/images/nodes/pth/critical.png
deleted file mode 100644
index 0348a7f5d..000000000
Binary files a/monkey_island/cc/ui/src/images/nodes/pth/critical.png and /dev/null differ
diff --git a/monkey_island/cc/ui/src/images/nodes/pth/normal.png b/monkey_island/cc/ui/src/images/nodes/pth/normal.png
deleted file mode 100644
index 3b1e9b638..000000000
Binary files a/monkey_island/cc/ui/src/images/nodes/pth/normal.png and /dev/null differ