Make mimikatz inside zip and extract only if config says so

This commit is contained in:
Itay Mizeretz 2018-08-22 19:31:26 +03:00
parent 203943bf27
commit cdc576e77e
10 changed files with 119 additions and 55 deletions

View File

@ -273,13 +273,12 @@ class Configuration(object):
# system info collection # system info collection
collect_system_info = True collect_system_info = True
should_use_mimikatz = True
########################### ###########################
# systeminfo config # systeminfo config
########################### ###########################
mimikatz_dll_name = "mk.dll"
extract_azure_creds = True extract_azure_creds = True

View File

@ -19,7 +19,8 @@ import monkeyfs
from exploit import HostExploiter from exploit import HostExploiter
from model import DROPPER_ARG from model import DROPPER_ARG
from network.smbfinger import SMB_SERVICE from network.smbfinger import SMB_SERVICE
from tools import build_monkey_commandline, get_target_monkey_by_os, get_binaries_dir_path, get_monkey_depth from tools import build_monkey_commandline, get_target_monkey_by_os, get_monkey_depth
from pyinstaller_utils import get_binary_file_path
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'
@ -306,9 +307,9 @@ class SambaCryExploiter(HostExploiter):
def get_monkey_runner_bin_file(self, is_32bit): def get_monkey_runner_bin_file(self, is_32bit):
if is_32bit: if is_32bit:
return open(path.join(get_binaries_dir_path(), self.SAMBACRY_RUNNER_FILENAME_32), "rb") return open(get_binary_file_path(self.SAMBACRY_RUNNER_FILENAME_32), "rb")
else: else:
return open(path.join(get_binaries_dir_path(), self.SAMBACRY_RUNNER_FILENAME_64), "rb") return open(get_binary_file_path(self.SAMBACRY_RUNNER_FILENAME_64), "rb")
def get_monkey_commandline_file(self, location): def get_monkey_commandline_file(self, location):
return BytesIO(DROPPER_ARG + build_monkey_commandline(self.host, get_monkey_depth() - 1, location)) return BytesIO(DROPPER_ARG + build_monkey_commandline(self.host, get_monkey_depth() - 1, location))

View File

@ -471,13 +471,6 @@ def build_monkey_commandline(target_host, depth, location=None):
GUID, target_host.default_tunnel, target_host.default_server, depth, location) GUID, target_host.default_tunnel, target_host.default_server, depth, location)
def get_binaries_dir_path():
if getattr(sys, 'frozen', False):
return sys._MEIPASS
else:
return os.path.dirname(os.path.abspath(__file__))
def get_monkey_depth(): def get_monkey_depth():
from config import WormConfiguration from config import WormConfiguration
return WormConfiguration.depth return WormConfiguration.depth

View File

@ -1,22 +1,37 @@
# -*- mode: python -*- # -*- mode: python -*-
import os import os
import platform import platform
import zipfile
# Name of zip file that will be created
MIMIKATZ_ZIP_NAME = 'tmpzipfile123456.zip'
# Name of zip file in monkey. That's the name of the file in the _MEI folder
MIMIKATZ_ZIP_NAME_MONKEY = MIMIKATZ_ZIP_NAME
# Name of mimikatz dll in zip archive
MIMIKATZ_DLL_NAME_ZIP = 'tmpzipfile123456.dll'
# Password for mimikatz zip
MIMIKATZ_ZIP_PASSWORD = 'HEDFGFDSgfsdg4235342#@$^@#shd35'
def get_mimikatz_zip_path():
if platform.architecture()[0] == "32bit":
return '.\\bin\\mk32.zip'
else:
return '.\\bin\\mk64.zip'
a = Analysis(['main.py'], a = Analysis(['main.py'],
pathex=['.', '..'], pathex=['.', '..'],
hiddenimports=['_cffi_backend', 'queue'], hiddenimports=['_cffi_backend', 'queue'],
hookspath=None, hookspath=None,
runtime_hooks=None) runtime_hooks=None)
a.binaries += [('sc_monkey_runner32.so', '.\\bin\\sc_monkey_runner32.so', 'BINARY')]
a.binaries += [('sc_monkey_runner64.so', '.\\bin\\sc_monkey_runner64.so', 'BINARY')]
a.binaries += [('sc_monkey_runner32.so', '.\\bin\\sc_monkey_runner32.so', 'BINARY')] if platform.system().find("Windows") >= 0:
a.binaries += [('sc_monkey_runner64.so', '.\\bin\\sc_monkey_runner64.so', 'BINARY')]
if platform.system().find("Windows")>= 0:
a.datas = [i for i in a.datas if i[0].find('Include') < 0] a.datas = [i for i in a.datas if i[0].find('Include') < 0]
if platform.architecture()[0] == "32bit": a.binaries += [(MIMIKATZ_ZIP_NAME_MONKEY, get_mimikatz_zip_path(), 'BINARY')]
a.binaries += [('mk.dll', '.\\bin\\mk32.dll', 'BINARY')]
else:
a.binaries += [('mk.dll', '.\\bin\\mk64.dll', 'BINARY')]
pyz = PYZ(a.pure) pyz = PYZ(a.pure)
exe = EXE(pyz, exe = EXE(pyz,

View File

@ -0,0 +1,24 @@
import os
import sys
__author__ = 'itay.mizeretz'
def get_binaries_dir_path():
"""
Gets the path to the binaries dir (files packaged in pyinstaller if it was used, infection_monkey dir otherwise)
:return: Binaries dir path
"""
if getattr(sys, 'frozen', False):
return sys._MEIPASS
else:
return os.path.dirname(os.path.abspath(__file__))
def get_binary_file_path(filename):
"""
Gets the path to a binary file
:param filename: name of the file
:return: Path to file
"""
return os.path.join(get_binaries_dir_path(), filename)

View File

@ -70,4 +70,8 @@ Sambacry requires two standalone binaries to execute remotely.
Mimikatz is required for the Monkey to be able to steal credentials on Windows. It's possible to either compile from sources (requires Visual Studio 2013 and up) or download the binaries from Mimikatz is required for the Monkey to be able to steal credentials on Windows. It's possible to either compile from sources (requires Visual Studio 2013 and up) or download the binaries from
https://github.com/guardicore/mimikatz/releases/tag/1.0.0 https://github.com/guardicore/mimikatz/releases/tag/1.0.0
Download both 32 and 64 bit DLLs and place them under [code location]\infection_monkey\bin Download both 32 and 64 bit zipped DLLs and place them under [code location]\infection_monkey\bin
Alternatively, if you build Mimikatz, put each version in a zip file.
1. The zip should contain only the Mimikatz DLL named tmpzipfile123456.dll
2. It should be protected using the password 'VTQpsJPXgZuXhX6x3V84G'.
3. The zip file should be named mk32.zip/mk64.zip accordingly.

View File

@ -2,6 +2,9 @@ import binascii
import ctypes import ctypes
import logging import logging
import socket import socket
import zipfile
from pyinstaller_utils import get_binary_file_path, get_binaries_dir_path
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'
@ -13,12 +16,30 @@ class MimikatzCollector(object):
Password collection module for Windows using Mimikatz. Password collection module for Windows using Mimikatz.
""" """
def __init__(self): # Name of Mimikatz DLL. Must be name of file in Mimikatz zip.
try: MIMIKATZ_DLL_NAME = 'tmpzipfile123456.dll'
self._isInit = False # Name of ZIP containing Mimikatz. Must be identical to one on monkey.spec
self._config = __import__('config').WormConfiguration MIMIKATZ_ZIP_NAME = 'tmpzipfile123456.zip'
self._dll = ctypes.WinDLL(self._config.mimikatz_dll_name)
# Password to Mimikatz zip file
MIMIKATZ_ZIP_PASSWORD = r'VTQpsJPXgZuXhX6x3V84G'
def __init__(self):
self._config = __import__('config').WormConfiguration
self._isInit = False
self._dll = None
self._collect = None
self._get = None
self.init_mimikatz()
def init_mimikatz(self):
try:
with zipfile.ZipFile(get_binary_file_path(MimikatzCollector.MIMIKATZ_ZIP_NAME), 'r') as mimikatz_zip:
mimikatz_zip.extract(self.MIMIKATZ_DLL_NAME, path=get_binaries_dir_path(),
pwd=self.MIMIKATZ_ZIP_PASSWORD)
self._dll = ctypes.WinDLL(get_binary_file_path(self.MIMIKATZ_DLL_NAME))
collect_proto = ctypes.WINFUNCTYPE(ctypes.c_int) collect_proto = ctypes.WINFUNCTYPE(ctypes.c_int)
get_proto = ctypes.WINFUNCTYPE(MimikatzCollector.LogonData) get_proto = ctypes.WINFUNCTYPE(MimikatzCollector.LogonData)
self._collect = collect_proto(("collect", self._dll)) self._collect = collect_proto(("collect", self._dll))

View File

@ -15,6 +15,7 @@ class WindowsInfoCollector(InfoCollector):
def __init__(self): def __init__(self):
super(WindowsInfoCollector, self).__init__() super(WindowsInfoCollector, self).__init__()
self._config = __import__('config').WormConfiguration
def get_info(self): def get_info(self):
""" """
@ -28,7 +29,13 @@ class WindowsInfoCollector(InfoCollector):
self.get_process_list() self.get_process_list()
self.get_network_info() self.get_network_info()
self.get_azure_info() self.get_azure_info()
mimikatz_collector = MimikatzCollector() self._get_mimikatz_info()
mimikatz_info = mimikatz_collector.get_logon_info()
self.info["credentials"].update(mimikatz_info)
return self.info return self.info
def _get_mimikatz_info(self):
if self._config.should_use_mimikatz:
LOG.info("Using mimikatz")
self.info["credentials"].update(MimikatzCollector().get_logon_info())
else:
LOG.info("Not using mimikatz")

View File

@ -29,3 +29,4 @@ def is_64bit_python():
def is_windows_os(): def is_windows_os():
return sys.platform.startswith("win") return sys.platform.startswith("win")

View File

@ -279,6 +279,31 @@ SCHEMA = {
} }
} }
}, },
"system_info": {
"title": "System info",
"type": "object",
"properties": {
"extract_azure_creds": {
"title": "Harvest Azure Credentials",
"type": "boolean",
"default": True,
"description":
"Determine if the Monkey should try to harvest password credentials from Azure VMs"
},
"collect_system_info": {
"title": "Collect system info",
"type": "boolean",
"default": True,
"description": "Determines whether to collect system info"
},
"should_use_mimikatz": {
"title": "Should use Mimikatz",
"type": "boolean",
"default": True,
"description": "Determines whether to use Mimikatz"
},
}
},
"life_cycle": { "life_cycle": {
"title": "Life cycle", "title": "Life cycle",
"type": "object", "type": "object",
@ -339,12 +364,6 @@ SCHEMA = {
"description": "description":
"The name of the mutex used to determine whether the monkey is already running" "The name of the mutex used to determine whether the monkey is already running"
}, },
"collect_system_info": {
"title": "Collect system info",
"type": "boolean",
"default": True,
"description": "Determines whether to collect system info"
},
"keep_tunnel_open_time": { "keep_tunnel_open_time": {
"title": "Keep tunnel open time", "title": "Keep tunnel open time",
"type": "integer", "type": "integer",
@ -536,26 +555,6 @@ SCHEMA = {
"description": "List of SSH key pairs to use, when trying to ssh into servers" "description": "List of SSH key pairs to use, when trying to ssh into servers"
} }
} }
},
"systemInfo": {
"title": "System collection",
"type": "object",
"properties": {
"mimikatz_dll_name": {
"title": "Mimikatz DLL name",
"type": "string",
"default": "mk.dll",
"description":
"Name of Mimikatz DLL (should be the same as in the monkey's pyinstaller spec file)"
},
"extract_azure_creds": {
"title": "Harvest Azure Credentials",
"type": "boolean",
"default": True,
"description":
"Determine if the Monkey should try to harvest password credentials from Azure VMs"
}
}
} }
} }
}, },