forked from p15670423/monkey
RE-CR: changed names, added doc, created consts.
This commit is contained in:
parent
3a2d9a9cc2
commit
707c88434c
|
@ -9,12 +9,12 @@ from flask import request
|
|||
|
||||
from cc.auth import jwt_required
|
||||
from cc.database import mongo
|
||||
from cc.services import user_info
|
||||
from cc.services import mimikatz_utils
|
||||
from cc.services.config import ConfigService
|
||||
from cc.services.edge import EdgeService
|
||||
from cc.services.node import NodeService
|
||||
from cc.encryptor import encryptor
|
||||
from cc.services.wmi_info_handler import WMIHandler
|
||||
from cc.services.wmi_handler import WMIHandler
|
||||
|
||||
__author__ = 'Barak'
|
||||
|
||||
|
@ -186,7 +186,7 @@ class Telemetry(flask_restful.Resource):
|
|||
Telemetry.add_system_info_creds_to_config(creds)
|
||||
Telemetry.replace_user_dot_with_comma(creds)
|
||||
if 'mimikatz' in telemetry_json['data']:
|
||||
users_secrets = user_info.MimikatzSecrets.\
|
||||
users_secrets = mimikatz_utils.MimikatzSecrets.\
|
||||
extract_secrets_from_mimikatz(telemetry_json['data'].get('mimikatz', ''))
|
||||
if 'wmi' in telemetry_json['data']:
|
||||
wmi_handler = WMIHandler(monkey_id, telemetry_json['data']['wmi'], users_secrets)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
"""This file will include consts values regarding the groupsandusers collection"""
|
||||
|
||||
USERTYPE = 1
|
||||
|
||||
GROUPTYPE = 2
|
|
@ -3,6 +3,7 @@ from itertools import product
|
|||
from cc.database import mongo
|
||||
from bson import ObjectId
|
||||
|
||||
from cc.services.groups_and_users_consts import USERTYPE
|
||||
from cc.services.node import NodeService
|
||||
|
||||
__author__ = 'maor.rayzin'
|
||||
|
@ -11,6 +12,19 @@ class PTHReportService(object):
|
|||
|
||||
@staticmethod
|
||||
def __dup_passwords_mongoquery():
|
||||
"""
|
||||
This function build and query the mongoDB for users found that are using the same passwords, this is done
|
||||
by comparing the NTLM hash found for each user by mimikatz.
|
||||
:return:
|
||||
A list of mongo documents (dicts in python) that look like this:
|
||||
{
|
||||
'_id': The NTLM hash,
|
||||
'count': How many users share it.
|
||||
'Docs': the name, domain name, _Id, and machine_id of the users
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
pipeline = [
|
||||
{"$match": {
|
||||
'NTLM_secret': {
|
||||
|
@ -30,18 +44,31 @@ class PTHReportService(object):
|
|||
|
||||
@staticmethod
|
||||
def __get_admin_on_machines_format(admin_on_machines, domain_name):
|
||||
|
||||
"""
|
||||
This function finds for each admin user, what machines its admin of and compile them to a list.
|
||||
:param admin_on_machines: A list of "monkey" documents "_id"s
|
||||
:param domain_name: The admin's domain name
|
||||
:return:
|
||||
A list of formatted machines names *domain*\*hostname*, to use in shared admins issues.
|
||||
"""
|
||||
machines = mongo.db.monkey.find({'_id': {'$in': admin_on_machines}}, {'hostname': 1})
|
||||
return [domain_name + '\\' + i['hostname'] for i in list(machines)]
|
||||
|
||||
@staticmethod
|
||||
def __strong_users_on_crit_query():
|
||||
"""
|
||||
This function build and query the mongoDB for users that mimikatz was able to find cached NTLM hash and
|
||||
are administrators on machines with services predefined as important services thus making these machines
|
||||
critical.
|
||||
:return:
|
||||
A list of said users
|
||||
"""
|
||||
pipeline = [
|
||||
{
|
||||
'$unwind': '$admin_on_machines'
|
||||
},
|
||||
{
|
||||
'$match': {'type': 1, 'domain_name': {'$ne': None}}
|
||||
'$match': {'type': USERTYPE, 'domain_name': {'$ne': None}}
|
||||
},
|
||||
{
|
||||
'$lookup':
|
||||
|
@ -100,7 +127,7 @@ class PTHReportService(object):
|
|||
# object has at least two objects in it, by making sure any value exists in the array index 1.
|
||||
# Excluding the name Administrator - its spamming the lists and not a surprise the domain Administrator account
|
||||
# is shared.
|
||||
admins = mongo.db.groupsandusers.find({'type': 1, 'name': {'$ne': 'Administrator'},
|
||||
admins = mongo.db.groupsandusers.find({'type': USERTYPE, 'name': {'$ne': 'Administrator'},
|
||||
'admin_on_machines.1': {'$exists': True}},
|
||||
{'admin_on_machines': 1, 'name': 1, 'domain_name': 1})
|
||||
return [
|
||||
|
@ -200,7 +227,7 @@ class PTHReportService(object):
|
|||
{
|
||||
'admin_on_machines': {'$ne': []},
|
||||
'secret_location': {'$ne': []},
|
||||
'type': 1
|
||||
'type': USERTYPE
|
||||
},
|
||||
{
|
||||
'admin_on_machines': 1, 'secret_location': 1
|
||||
|
|
|
@ -561,7 +561,7 @@ class ReportService:
|
|||
issues_dict = {}
|
||||
for issue in issues:
|
||||
if issue.get('is_local', True):
|
||||
machine = issue.get('machine', '').upper()
|
||||
machine = issue.get('machine').upper()
|
||||
if machine not in issues_dict:
|
||||
issues_dict[machine] = []
|
||||
issues_dict[machine].append(issue)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from cc.database import mongo
|
||||
from cc.services.groups_and_users_consts import USERTYPE
|
||||
|
||||
__author__ = 'maor.rayzin'
|
||||
|
||||
|
@ -15,8 +16,8 @@ class WMIHandler(object):
|
|||
self.users_info = wmi_info['Win32_UserAccount']
|
||||
self.groups_info = wmi_info['Win32_Group']
|
||||
self.groups_and_users = wmi_info['Win32_GroupUser']
|
||||
self.products = wmi_info['Win32_Service']
|
||||
self.services = wmi_info['Win32_Product']
|
||||
self.services = wmi_info['Win32_Service']
|
||||
self.products = wmi_info['Win32_Product']
|
||||
|
||||
def process_and_handle_wmi_info(self):
|
||||
|
||||
|
@ -128,7 +129,7 @@ class WMIHandler(object):
|
|||
# if entity is domain entity, add the monkey id of current machine to secrets_location.
|
||||
# (found on this machine)
|
||||
if entity.get('NTLM_secret'):
|
||||
mongo.db.groupsandusers.update_one({'SID': entity['SID'], 'type': 1},
|
||||
mongo.db.groupsandusers.update_one({'SID': entity['SID'], 'type': USERTYPE},
|
||||
{'$addToSet': {'secret_location': self.monkey_id}})
|
||||
|
||||
def update_admins_retrospective(self):
|
||||
|
@ -148,7 +149,7 @@ class WMIHandler(object):
|
|||
mongo.db.groupsandusers.update_one({'SID': sid},
|
||||
{'$addToSet': {'admin_on_machines': machine_id}})
|
||||
entity_details = mongo.db.groupsandusers.find_one({'SID': sid},
|
||||
{'type': 1, 'entities_list': 1})
|
||||
{'type': USERTYPE, 'entities_list': 1})
|
||||
if entity_details.get('type') == 2:
|
||||
self.add_admin(entity_details, machine_id)
|
||||
|
Loading…
Reference in New Issue