* fixed a lot of safe dict access

* some small fixed and typos
This commit is contained in:
maor.rayzin 2018-07-24 19:09:19 +03:00
parent f97df84da9
commit 48e1d85eb0
4 changed files with 76 additions and 75 deletions

View File

@ -12,6 +12,7 @@ from mimikatz_collector import MimikatzCollector
from . import InfoCollector
LOG = logging.getLogger(__name__)
LOG.info('started windows info collector')
__author__ = 'uri'
@ -138,16 +139,17 @@ class WindowsInfoCollector(InfoCollector):
self.get_hostname()
self.get_process_list()
self.get_network_info()
self.get_azure_info()
#self.get_azure_info()
self.get_wmi_info()
self.get_reg_key(r"SYSTEM\CurrentControlSet\Control\Lsa")
#self.get_wmi_info()
#self.get_reg_key(r"SYSTEM\CurrentControlSet\Control\Lsa")
self.get_installed_packages()
mimikatz_collector = MimikatzCollector()
mimikatz_info = mimikatz_collector.get_logon_info()
self.info["credentials"].update(mimikatz_info)
self.info["mimikatz"] = mimikatz_collector.get_mimikatz_text()
if mimikatz_info:
self.info["credentials"].update(mimikatz_info)
self.info["mimikatz"] = mimikatz_collector.get_mimikatz_text()
return self.info

View File

@ -112,7 +112,7 @@ class PTHReportService(object):
for node_id in pth.vertices:
machine = Machine(node_id)
node = {
"id": machine.get_monkey_id,
"id": str(machine.get_monkey_id()),
"label": '{0} : {1}'.format(machine.GetHostName(), machine.GetIp()),
'group': 'critical' if machine.IsCriticalServer() else 'normal',
'users': list(machine.GetCachedUsernames()),

View File

@ -115,14 +115,14 @@ class Machine(object):
if not doc:
return None
return doc["data"]["mimikatz"]
return doc.get("data").get("mimikatz")
@cache
def GetHostName(self):
doc = self.latest_system_info
for comp in doc["data"]["Win32_ComputerSystem"]:
return eval(comp["Name"])
for comp in doc.get("data").get("Win32_ComputerSystem", {}):
return eval(comp.get("Name"))
return None
@ -130,7 +130,7 @@ class Machine(object):
def GetIp(self):
doc = self.latest_system_info
for addr in doc["data"]["network_info"]["networks"]:
for addr in doc.get("data").get("network_info", {}).get("networks", {}):
return str(addr["addr"])
return None
@ -139,14 +139,14 @@ class Machine(object):
def get_monkey_id(self):
doc = self.monkey_info
return str(doc['_id'])
return str(doc.get('_id'))
@cache
def GetDomainName(self):
doc = self.latest_system_info
for comp in doc["data"]["Win32_ComputerSystem"]:
return eval(comp["Domain"])
for comp in doc.get("data").get("Win32_ComputerSystem", {}):
return eval(comp.get("Domain"))
return None
@ -154,8 +154,8 @@ class Machine(object):
def GetDomainRole(self):
doc = self.latest_system_info
for comp in doc["data"]["Win32_ComputerSystem"]:
return comp["DomainRole"]
for comp in doc.get("data").get("Win32_ComputerSystem", {}):
return comp.get("DomainRole")
return None
@ -167,17 +167,17 @@ class Machine(object):
def GetSidByUsername(self, username, domain=None):
doc = self.latest_system_info
for user in doc["data"]["Win32_UserAccount"]:
if eval(user["Name"]) != username:
for user in doc.get("data").get("Win32_UserAccount", {}):
if eval(user.get("Name")) != username:
continue
if user["SIDType"] != SidTypeUser:
if user.get("SIDType") != SidTypeUser:
continue
if domain and user["Domain"] != domain:
if domain and user.get("Domain") != domain:
continue
return eval(user["SID"])
return eval(user.get("SID"))
if not self.IsDomainController():
for dc in self.GetDomainControllers():
@ -195,24 +195,24 @@ class Machine(object):
if not info:
return None
return info["Domain"] + "\\" + info["Username"]
return str(info.get("Domain")) + "\\" + str(info.get("Username"))
@cache
def GetSidInfo(self, sid):
doc = self.latest_system_info
for user in doc["data"]["Win32_UserAccount"]:
if eval(user["SID"]) != sid:
for user in doc.get("data").get("Win32_UserAccount",{}):
if eval(user.get("SID")) != sid:
continue
if user["SIDType"] != SidTypeUser:
if user.get("SIDType") != SidTypeUser:
continue
return {"Domain": eval(user["Domain"]),
"Username": eval(user["Name"]),
"Disabled": user["Disabled"] == "true",
"PasswordRequired": user["PasswordRequired"] == "true",
"PasswordExpires": user["PasswordExpires"] == "true", }
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", }
if not self.IsDomainController():
for dc in self.GetDomainControllers():
@ -247,21 +247,21 @@ class Machine(object):
if self.IsDomainController():
found.append("Domain Controller")
for product in doc["data"]["Win32_Product"]:
service_name = eval(product["Name"])
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["data"]["Win32_Service"]:
service_name = eval(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["State"]) != "Running":
if eval(service.get("State")) != "Running":
continue
found.append(service_name)
@ -293,14 +293,14 @@ class Machine(object):
def GetGroupSidByGroupName(self, group_name):
doc = self.latest_system_info
for group in doc["data"]["Win32_Group"]:
if eval(group["Name"]) != group_name:
for group in doc.get('data').get("Win32_Group", {}):
if eval(group.get("Name")) != group_name:
continue
if not is_group_sid_type(group["SIDType"]):
if not is_group_sid_type(group.get("SIDType")):
continue
return eval(group["SID"])
return eval(group.get("SID"))
return None
@ -310,20 +310,20 @@ class Machine(object):
users = dict()
for group_user in doc["data"]["Win32_GroupUser"]:
if eval(group_user["GroupComponent"]["SID"]) != sid:
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["GroupComponent"]["SIDType"]):
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["PartComponent"]) in (str, unicode):
if type(group_user.get("PartComponent")) in (str, unicode):
# PartComponent is an id to Win32_UserAccount table
wmi_id = group_user["PartComponent"]
wmi_id = group_user.get("PartComponent")
if "cimv2:Win32_UserAccount" not in wmi_id:
continue
@ -336,10 +336,11 @@ class Machine(object):
users[sid] = username
else:
if group_user["PartComponent"]["SIDType"] != SidTypeUser:
if group_user.get("PartComponent", {}).get("SIDType") != SidTypeUser:
continue
users[eval(group_user["PartComponent"]["SID"])] = eval(group_user["PartComponent"]["Name"])
users[eval(group_user.get("PartComponent", {}).get("SID"))] = eval(group_user.get("PartComponent")
.get("Name"))
return users
@ -351,10 +352,10 @@ class Machine(object):
GUIDs = set()
for doc in cur:
if not Machine(doc["monkey_guid"]).IsDomainController():
if not Machine(doc.get("monkey_guid")).IsDomainController():
continue
GUIDs.add(doc["monkey_guid"])
GUIDs.add(doc.get("monkey_guid"))
return GUIDs
@ -377,11 +378,11 @@ class Machine(object):
SIDs = set()
for user in doc["data"]["Win32_UserAccount"]:
if user["SIDType"] != SidTypeUser:
for user in doc.get('data').get("Win32_UserAccount", {}):
if user.get("SIDType") != SidTypeUser:
continue
SIDs.add(eval(user["SID"]))
SIDs.add(eval(user.get("SID")))
return SIDs
@ -408,11 +409,11 @@ class Machine(object):
sam_user = dict([map(unicode.strip, line.split(":")) for line in
filter(lambda l: l.count(":") == 1, sam_user_txt.splitlines())])
ntlm = sam_user["NTLM"]
ntlm = sam_user.get("NTLM")
if "[hashed secret]" not in ntlm:
continue
sam[sam_user["User"]] = ntlm.replace("[hashed secret]", "").strip()
sam[sam_user.get("User")] = ntlm.replace("[hashed secret]", "").strip()
return sam
@ -533,7 +534,7 @@ class Machine(object):
SIDs = set()
for username in doc["data"]["credentials"]:
for username in doc.get('data').get("credentials", {}):
sid = self.GetSidByUsername(username)
if not sid:
@ -549,7 +550,7 @@ class Machine(object):
names = set()
for username in doc["data"]["credentials"]:
for username in doc.get('data').get("credentials", {}):
names.add(username)
return names
@ -576,7 +577,7 @@ class PassTheHashReport(object):
GUIDs = set()
for doc in cur:
GUIDs.add(doc["monkey_guid"])
GUIDs.add(doc.get("monkey_guid"))
return GUIDs

View File

@ -41,6 +41,8 @@ class ReportPageComponent extends AuthComponent {
super(props);
this.state = {
report: {},
pthreport: {},
pthmap: {},
graph: {nodes: [], edges: []},
allMonkeysAreDead: false,
runStarted: true
@ -49,6 +51,7 @@ class ReportPageComponent extends AuthComponent {
componentDidMount() {
this.updateMonkeysRunning().then(res => this.getReportFromServer(res));
this.getPTHReportFromServer();
this.updateMapFromServer();
this.interval = setInterval(this.updateMapFromServer, 1000);
}
@ -108,6 +111,17 @@ class ReportPageComponent extends AuthComponent {
});
};
getPTHReportFromServer(res) {
this.authFetch('/api/pthreport')
.then(res => res.json())
.then(res => {
this.setState({
pthreport: res.report_info,
pthmap: res.map
});
});
}
getReportFromServer(res) {
if (res['completed_steps']['run_monkey']) {
this.authFetch('/api/report')
@ -432,29 +446,13 @@ class ReportPageComponent extends AuthComponent {
<StolenPasswords data={this.state.report.glance.stolen_creds}/>
</div>
<div style={{marginBottom: '20px'}}>
{ /* TODO: use dynamic data */}
<SharedCreds data = {[{cred_group: ['MyDomain\\user1', 'user2', 'user3']}, {cred_group: ['user2', 'user4']}]} />
<SharedCreds data = {this.state.pthreport.same_password} />
</div>
<div style={{marginBottom: '20px'}}>
{ /* TODO: use dynamic data */}
<SharedAdmins data = {[
{
username: 'SharedLocalAdmin',
domain: 'MyDomain',
machines: ['hello : 1.2.3.4']
}
]} />
<SharedAdmins data = {this.state.pthreport.local_admin_shared} />
</div>
<div>
{ /* TODO: use dynamic data */}
<StrongUsers data = {[
{
username: 'SharedLocalAdmin',
domain: 'MyDomain',
machines: ['hello : 1.2.3.4'],
services: ['DC', 'DNS']
}
]} />
<StrongUsers data = {this.state.pthreport.strong_users_on_crit_services} />
</div>
</div>
);
@ -488,7 +486,7 @@ class ReportPageComponent extends AuthComponent {
Credential Map
</h3>
<div style={{position: 'relative', height: '100vh'}}>
<PassTheHashMapPageComponent graph={my_map} />
<PassTheHashMapPageComponent graph={this.state.pthmap} />
</div>
<br />
</div>