monkey/chaos_monkey/config.py

275 lines
8.7 KiB
Python
Raw Normal View History

2015-08-30 15:27:35 +08:00
import os
import sys
2017-09-25 20:13:36 +08:00
import types
import uuid
from abc import ABCMeta
2017-08-21 00:32:18 +08:00
from itertools import product
2017-09-25 20:13:36 +08:00
from exploit import WmiExploiter, Ms08_067_Exploiter, SmbExploiter, RdpExploiter, SSHExploiter, ShellShockExploiter, \
2017-09-26 20:43:46 +08:00
SambaCryExploiter, ElasticGroovyExploiter
2017-09-25 23:23:31 +08:00
from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger, MySQLFinger, ElasticFinger
2017-09-25 20:13:36 +08:00
from network.range import FixedRange
2015-11-30 16:56:20 +08:00
2015-08-30 15:27:35 +08:00
__author__ = 'itamar'
GUID = str(uuid.getnode())
EXTERNAL_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), 'monkey.bin')
2017-09-25 20:13:36 +08:00
def _cast_by_example(value, example):
2016-01-14 17:58:15 +08:00
"""
a method that casts a value to the type of the parameter given as example
"""
example_type = type(example)
if example_type is str:
return str(os.path.expandvars(value))
elif example_type is tuple and len(example) != 0:
if value is None or value == tuple(None):
return tuple()
return tuple([_cast_by_example(x, example[0]) for x in value])
elif example_type is list and len(example) != 0:
if value is None or value == [None]:
return []
return [_cast_by_example(x, example[0]) for x in value]
elif example_type is type(value):
return value
elif example_type is bool:
return value.lower() == 'true'
elif example_type is int:
return int(value)
elif example_type is float:
return float(value)
elif example_type is types.ClassType or example_type is ABCMeta:
return globals()[value]
else:
return None
class Configuration(object):
def from_dict(self, data):
"""
Get a dict of config variables, set known variables as attributes on self.
Return dict of unknown variables encountered.
"""
unknown_variables = {}
for key, value in data.items():
if key.startswith('_'):
continue
if key in ["name", "id", "current_server"]:
2016-01-14 17:58:15 +08:00
continue
if self._depth_from_commandline and key == "depth":
continue
try:
default_value = getattr(Configuration, key)
except AttributeError:
unknown_variables[key] = value
continue
2016-01-14 17:58:15 +08:00
setattr(self, key, _cast_by_example(value, default_value))
return unknown_variables
def as_dict(self):
result = {}
for key in dir(Configuration):
if key.startswith('_'):
continue
try:
value = getattr(self, key)
except AttributeError:
continue
val_type = type(value)
if val_type is types.FunctionType or val_type is types.MethodType:
continue
if val_type is types.ClassType or val_type is ABCMeta:
value = value.__name__
elif val_type is tuple or val_type is list:
if len(value) != 0 and (type(value[0]) is types.ClassType or type(value[0]) is ABCMeta):
value = val_type([x.__name__ for x in value])
result[key] = value
return result
2016-08-20 22:56:23 +08:00
# Used to keep track of our depth if manually specified
_depth_from_commandline = False
2015-08-30 15:27:35 +08:00
###########################
# logging config
2015-11-30 16:56:20 +08:00
###########################
2015-08-30 15:27:35 +08:00
use_file_logging = True
2017-09-27 16:24:42 +08:00
dropper_log_path_windows = '%temp%\\~df1562.tmp'
dropper_log_path_linux = '/tmp/user-1562'
2017-09-27 16:24:42 +08:00
monkey_log_path_windows = '%temp%\\~df1563.tmp'
monkey_log_path_linux = '/tmp/user-1563'
2015-08-30 15:27:35 +08:00
###########################
# dropper config
2015-08-30 15:27:35 +08:00
###########################
dropper_try_move_first = True
2015-08-30 15:27:35 +08:00
dropper_set_date = True
2017-09-27 16:24:42 +08:00
dropper_date_reference_path_windows = r"%windir%\system32\kernel32.dll"
dropper_date_reference_path_linux = '/bin/sh'
dropper_target_path = r"C:\Windows\monkey.exe"
dropper_target_path_linux = '/tmp/monkey'
2015-08-30 15:27:35 +08:00
###########################
# Kill file
###########################
2017-09-27 16:24:42 +08:00
kill_file_path_windows = '%windir%\\monkey.not'
kill_file_path_linux = '/var/run/monkey.not'
2015-08-30 15:27:35 +08:00
###########################
# monkey config
2015-08-30 15:27:35 +08:00
###########################
2016-07-15 22:00:55 +08:00
# sets whether or not the monkey is alive. if false will stop scanning and exploiting
2015-09-30 20:05:30 +08:00
alive = True
2016-07-15 22:00:55 +08:00
# sets whether or not to self delete the monkey executable when stopped
self_delete_in_cleanup = False
2016-07-15 22:00:55 +08:00
# string of the mutex name for single instance
2015-08-30 15:27:35 +08:00
singleton_mutex_name = "{2384ec59-0df8-4ab9-918c-843740924a28}"
# how long to wait between scan iterations
2016-01-14 17:58:15 +08:00
timeout_between_iterations = 100
2015-08-30 15:27:35 +08:00
# how many scan iterations to perform on each run
2016-01-13 16:27:49 +08:00
max_iterations = 1
2015-08-30 15:27:35 +08:00
2016-01-14 17:58:15 +08:00
scanner_class = TcpScanner
2017-09-25 23:23:31 +08:00
finger_classes = [SMBFinger, SSHFinger, PingScanner, HTTPFinger, MySQLFinger, ElasticFinger]
exploiter_classes = [SmbExploiter, WmiExploiter, RdpExploiter, Ms08_067_Exploiter, # Windows exploits
2017-09-25 20:13:36 +08:00
SSHExploiter, ShellShockExploiter, SambaCryExploiter, # Linux
2017-09-26 20:43:46 +08:00
ElasticGroovyExploiter, # multi
]
2015-08-30 15:27:35 +08:00
# how many victims to look for in a single scan iteration
victims_max_find = 14
# how many victims to exploit before stopping
victims_max_exploit = 7
2015-12-08 01:08:15 +08:00
# depth of propagation
2016-01-14 17:58:15 +08:00
depth = 2
current_server = ""
# Configuration servers to try to connect to, in this order.
2015-12-02 17:18:27 +08:00
command_servers = [
"41.50.73.31:5000"
2015-12-02 17:18:27 +08:00
]
2016-07-23 13:59:26 +08:00
# sets whether or not to locally save the running configuration after finishing
serialize_config = False
2016-07-15 22:00:55 +08:00
# sets whether or not to retry failed hosts on next scan
retry_failed_explotation = True
2015-08-30 15:27:35 +08:00
# addresses of internet servers to ping and check if the monkey has internet acccess.
internet_services = ["monkey.guardicore.com", "www.google.com"]
2015-08-30 15:27:35 +08:00
###########################
# scanners config
2015-08-30 15:27:35 +08:00
###########################
# Auto detect and scan local subnets
local_network_scan = True
2016-01-14 17:58:15 +08:00
range_class = FixedRange
range_size = 1
2017-09-25 20:13:36 +08:00
range_fixed = ['', ]
2015-08-30 15:27:35 +08:00
blocked_ips = ['', ]
2015-08-30 15:27:35 +08:00
# TCP Scanner
HTTP_PORTS = [80, 8080, 443,
8008, # HTTP alternate
]
2017-09-25 20:13:36 +08:00
tcp_target_ports = [22,
2222,
2017-09-25 20:13:36 +08:00
445,
135,
3389,
80,
8080,
443,
8008,
2017-09-25 23:23:31 +08:00
3306,
2017-09-25 20:13:36 +08:00
9200]
tcp_target_ports.extend(HTTP_PORTS)
2015-12-02 17:18:27 +08:00
tcp_scan_timeout = 3000 # 3000 Milliseconds
2015-08-30 15:27:35 +08:00
tcp_scan_interval = 200
tcp_scan_get_banner = True
2015-08-30 15:27:35 +08:00
# Ping Scanner
ping_scan_timeout = 1000
###########################
# exploiters config
2015-08-30 15:27:35 +08:00
###########################
skip_exploit_if_file_exist = False
2015-08-30 15:27:35 +08:00
ms08_067_exploit_attempts = 5
ms08_067_remote_user_add = "Monkey_IUSER_SUPPORT"
2015-08-30 15:27:35 +08:00
ms08_067_remote_user_pass = "Password1!"
# rdp exploiter
2015-09-30 20:05:30 +08:00
rdp_use_vbs_download = True
# User and password dictionaries for exploits.
2017-08-21 00:32:18 +08:00
2017-08-21 16:51:47 +08:00
def get_exploit_user_password_pairs(self):
2017-09-25 20:13:36 +08:00
"""
Returns all combinations of the configurations users and passwords
:return:
"""
2017-08-21 00:32:18 +08:00
return product(self.exploit_user_list, self.exploit_password_list)
2017-09-26 23:11:13 +08:00
def get_exploit_user_password_or_hash_product(self):
"""
Returns all combinations of the configurations users and passwords or lm/ntlm hashes
:return:
"""
cred_list = []
for cred in product(self.exploit_user_list, self.exploit_password_list, [''], ['']):
cred_list.append(cred)
for cred in product(self.exploit_user_list, [''], [''], self.exploit_ntlm_hash_list):
cred_list.append(cred)
for cred in product(self.exploit_user_list, [''], self.exploit_lm_hash_list, ['']):
cred_list.append(cred)
return cred_list
2017-08-21 00:32:18 +08:00
exploit_user_list = ['Administrator', 'root', 'user']
exploit_password_list = ["Password1!", "1234", "password", "12345678"]
2017-09-26 23:11:13 +08:00
exploit_lm_hash_list = []
exploit_ntlm_hash_list = []
# smb/wmi exploiter
2017-09-25 20:13:36 +08:00
smb_download_timeout = 300 # timeout in seconds
smb_service_name = "InfectionMonkey"
# Timeout (in seconds) for sambacry's trigger to yield results.
sambacry_trigger_timeout = 5
# Folder paths to guess share lies inside.
2017-09-04 21:36:15 +08:00
sambacry_folder_paths_to_guess = ['/', '/mnt', '/tmp', '/storage', '/export', '/share', '/shares', '/home']
# Shares to not check if they're writable.
sambacry_shares_not_to_check = ["IPC$", "print$"]
# system info collection
collect_system_info = True
###########################
# systeminfo config
###########################
mimikatz_dll_name = "mk.dll"
2017-09-25 20:13:36 +08:00
WormConfiguration = Configuration()