monkey/infection_monkey/system_info/windows_info_collector.py

141 lines
4.0 KiB
Python
Raw Normal View History

2018-02-27 00:26:43 +08:00
import os
import logging
2018-02-27 00:26:43 +08:00
import traceback
2018-02-27 22:43:40 +08:00
import sys
sys.coinit_flags = 0 # needed for proper destruction of the wmi python module
import wmi
2018-02-27 00:26:43 +08:00
import _winreg
2018-02-27 22:43:40 +08:00
from mimikatz_collector import MimikatzCollector
from . import InfoCollector
LOG = logging.getLogger(__name__)
__author__ = 'uri'
2018-02-27 00:26:43 +08:00
WMI_CLASSES = set(["Win32_OperatingSystem",
"Win32_ComputerSystem",
"Win32_LoggedOnUser",
2018-02-28 20:53:02 +08:00
"Win32_UserAccount",
2018-02-27 00:26:43 +08:00
"Win32_UserProfile",
2018-02-28 20:53:02 +08:00
"Win32_Group",
"Win32_GroupUser",
#"Win32_Product",
#"Win32_Process",
#"Win32_Service"
2018-02-27 22:43:40 +08:00
])
def fix_obj_for_mongo(o):
if type(o) == dict:
return dict([(k, fix_obj_for_mongo(v)) for k, v in o.iteritems()])
elif type(o) in (list, tuple):
return [fix_obj_for_mongo(i) for i in o]
elif type(o) in (int, float, bool):
return o
elif type(o) in (str, unicode):
# mongo dosn't like unprintable chars, so we use repr :/
return repr(o)
2018-02-27 23:38:54 +08:00
elif hasattr(o, "__class__") and o.__class__ == wmi._wmi_object:
return fix_wmi_obj_for_mongo(o)
2018-02-27 22:43:40 +08:00
else:
return repr(o)
def fix_wmi_obj_for_mongo(o):
2018-02-27 23:38:54 +08:00
row = {}
2018-02-27 22:43:40 +08:00
2018-02-27 23:38:54 +08:00
for prop in o.properties:
try:
value = getattr(o, prop)
except wmi.x_wmi:
continue
2018-02-27 22:43:40 +08:00
2018-02-27 23:38:54 +08:00
row[prop] = fix_obj_for_mongo(value)
2018-02-27 22:43:40 +08:00
2018-02-27 23:38:54 +08:00
for method_name in o.methods:
if not method_name.startswith("GetOwner"):
continue
2018-02-27 22:43:40 +08:00
2018-02-27 23:38:54 +08:00
method = getattr(o, method_name)
2018-02-27 00:26:43 +08:00
2018-02-27 23:38:54 +08:00
try:
value = method()
value = fix_obj_for_mongo(value)
row[method_name[3:]] = value
except wmi.x_wmi:
#LOG.error("Error running wmi method '%s'" % (method_name, ))
#LOG.error(traceback.format_exc())
continue
return row
2015-12-09 22:33:44 +08:00
class WindowsInfoCollector(InfoCollector):
"""
System information collecting module for Windows operating systems
"""
def __init__(self):
2015-12-09 22:33:44 +08:00
super(WindowsInfoCollector, self).__init__()
2018-02-27 00:26:43 +08:00
self.wmi = None
def get_info(self):
"""
Collect Windows system information
Hostname, process list and network subnets
Tries to read credential secrets using mimikatz
:return: Dict of system information
"""
LOG.debug("Running Windows collector")
2015-12-09 22:33:44 +08:00
self.get_hostname()
self.get_process_list()
2017-09-10 18:11:51 +08:00
self.get_network_info()
self.get_azure_info()
2018-02-27 00:26:43 +08:00
self.get_wmi_info()
self.get_reg_key(r"SYSTEM\CurrentControlSet\Control\Lsa")
self.get_installed_packages()
mimikatz_info = mimikatz_collector.get_logon_info()
self.info["credentials"].update(mimikatz_info)
2018-02-27 22:43:40 +08:00
self.info["mimikatz"] = mimikatz_collector.get_mimikatz_text()
2018-02-27 00:26:43 +08:00
return self.info
2018-02-27 00:26:43 +08:00
def get_installed_packages(self):
self.info["installed_packages"] = os.popen("dism /online /get-packages").read()
self.info["installed_features"] = os.popen("dism /online /get-features").read()
def get_wmi_info(self):
for wmi_class_name in WMI_CLASSES:
2018-02-27 23:38:54 +08:00
self.info[wmi_class_name] = self.get_wmi_class(wmi_class_name)
2018-02-27 00:26:43 +08:00
def get_wmi_class(self, class_name):
if not self.wmi:
2018-02-27 22:43:40 +08:00
self.wmi = wmi.WMI()
2018-02-27 00:26:43 +08:00
try:
wmi_class = getattr(self.wmi, class_name)()
2018-02-27 22:43:40 +08:00
except wmi.x_wmi:
#LOG.error("Error getting wmi class '%s'" % (class_name, ))
#LOG.error(traceback.format_exc())
2018-02-27 00:26:43 +08:00
return
2018-02-27 23:38:54 +08:00
return fix_obj_for_mongo(wmi_class)
2018-02-27 00:26:43 +08:00
def get_reg_key(self, subkey_path, store=_winreg.HKEY_LOCAL_MACHINE):
key = _winreg.ConnectRegistry(None, store)
subkey = _winreg.OpenKey(key, subkey_path)
2018-04-01 23:11:22 +08:00
d = dict([_winreg.EnumValue(subkey, i)[:2] for i in xrange(_winreg.QueryInfoKey(subkey)[1])])
2018-02-27 22:43:40 +08:00
d = fix_obj_for_mongo(d)
self.info[subkey_path] = d
2018-02-27 00:26:43 +08:00
subkey.Close()
key.Close()