diff --git a/.flake8 b/.flake8
index 4bf127114..1f81c9edc 100644
--- a/.flake8
+++ b/.flake8
@@ -1,7 +1,7 @@
[flake8]
## Warn about linter issues.
-exclude = ../monkey/monkey_island/cc/ui
+exclude = monkey/monkey_island/cc/ui
show-source = True
max-complexity = 10
max-line-length = 100
diff --git a/.travis.yml b/.travis.yml
index 98b2d999e..d57069c05 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -55,7 +55,7 @@ install:
script:
# Check Python code
## Check syntax errors and fail the build if any are found.
-- flake8 ./monkey
+- flake8 .
## Check import order
- python -m isort ./monkey --check-only
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3bca2515f..d675e0461 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,4 +17,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Monkey agents are stored in the configurable data_dir when monkey is "run
from the island". #997
- Reformated all code using black. #1070
-- Sort all imports usind isort. #1081
+- Sorted all imports usind isort. #1081
+- Addressed all flake8 issues. #1071
diff --git a/envs/monkey_zoo/blackbox/analyzers/performance_analyzer.py b/envs/monkey_zoo/blackbox/analyzers/performance_analyzer.py
index 18390e67e..30e635652 100644
--- a/envs/monkey_zoo/blackbox/analyzers/performance_analyzer.py
+++ b/envs/monkey_zoo/blackbox/analyzers/performance_analyzer.py
@@ -33,7 +33,8 @@ class PerformanceAnalyzer(Analyzer):
if self.performance_test_config.break_on_timeout and not performance_is_good_enough:
LOGGER.warning(
- "Calling breakpoint - pausing to enable investigation of island. Type 'c' to continue once you're done "
+ "Calling breakpoint - pausing to enable investigation of island. "
+ "Type 'c' to continue once you're done "
"investigating. Type 'p timings' and 'p total_time' to see performance information."
)
breakpoint()
diff --git a/envs/monkey_zoo/blackbox/analyzers/zerologon_analyzer.py b/envs/monkey_zoo/blackbox/analyzers/zerologon_analyzer.py
index 5c256beaf..5762a0315 100644
--- a/envs/monkey_zoo/blackbox/analyzers/zerologon_analyzer.py
+++ b/envs/monkey_zoo/blackbox/analyzers/zerologon_analyzer.py
@@ -3,12 +3,7 @@ from typing import List
import dpath.util
-from common.config_value_paths import (
- LM_HASH_LIST_PATH,
- NTLM_HASH_LIST_PATH,
- PASSWORD_LIST_PATH,
- USER_LIST_PATH,
-)
+from common.config_value_paths import LM_HASH_LIST_PATH, NTLM_HASH_LIST_PATH, USER_LIST_PATH
from envs.monkey_zoo.blackbox.analyzers.analyzer import Analyzer
from envs.monkey_zoo.blackbox.analyzers.analyzer_log import AnalyzerLog
from envs.monkey_zoo.blackbox.island_client.monkey_island_client import MonkeyIslandClient
diff --git a/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/fake_monkey.py b/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/fake_monkey.py
index 2a39e6353..37245cefc 100644
--- a/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/fake_monkey.py
+++ b/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/fake_monkey.py
@@ -1,6 +1,6 @@
import random
-from envs.monkey_zoo.blackbox.tests.performance.telem_sample_parsing.sample_multiplier.fake_ip_generator import (
+from envs.monkey_zoo.blackbox.tests.performance.telem_sample_parsing.sample_multiplier.fake_ip_generator import ( # noqa: E501
FakeIpGenerator,
)
diff --git a/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/sample_multiplier.py b/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/sample_multiplier.py
index 7a1fb4032..221c3a87a 100644
--- a/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/sample_multiplier.py
+++ b/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/sample_multiplier.py
@@ -9,10 +9,10 @@ from tqdm import tqdm
from envs.monkey_zoo.blackbox.tests.performance.telem_sample_parsing.sample_file_parser import (
SampleFileParser,
)
-from envs.monkey_zoo.blackbox.tests.performance.telem_sample_parsing.sample_multiplier.fake_ip_generator import (
+from envs.monkey_zoo.blackbox.tests.performance.telem_sample_parsing.sample_multiplier.fake_ip_generator import ( # noqa: E501
FakeIpGenerator,
)
-from envs.monkey_zoo.blackbox.tests.performance.telem_sample_parsing.sample_multiplier.fake_monkey import (
+from envs.monkey_zoo.blackbox.tests.performance.telem_sample_parsing.sample_multiplier.fake_monkey import ( # noqa: E501
FakeMonkey,
)
diff --git a/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/test_fake_ip_generator.py b/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/test_fake_ip_generator.py
index 7a4f30cff..55662b307 100644
--- a/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/test_fake_ip_generator.py
+++ b/envs/monkey_zoo/blackbox/tests/performance/telem_sample_parsing/sample_multiplier/test_fake_ip_generator.py
@@ -1,6 +1,6 @@
from unittest import TestCase
-from envs.monkey_zoo.blackbox.tests.performance.telem_sample_parsing.sample_multiplier.fake_ip_generator import (
+from envs.monkey_zoo.blackbox.tests.performance.telem_sample_parsing.sample_multiplier.fake_ip_generator import ( # noqa: E501
FakeIpGenerator,
)
diff --git a/monkey/common/cloud/aws/aws_instance.py b/monkey/common/cloud/aws/aws_instance.py
index 236cde5e1..d34c6c77a 100644
--- a/monkey/common/cloud/aws/aws_instance.py
+++ b/monkey/common/cloud/aws/aws_instance.py
@@ -9,7 +9,6 @@ from common.cloud.instance import CloudInstance
__author__ = "itay.mizeretz"
-
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)
ACCOUNT_ID_KEY = "accountId"
@@ -60,7 +59,8 @@ class AwsInstance(CloudInstance):
@staticmethod
def _parse_region(region_url_response):
# For a list of regions, see:
- # https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html
+ # https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts
+ # .RegionsAndAvailabilityZones.html
# This regex will find any AWS region format string in the response.
re_phrase = r"((?:us|eu|ap|ca|cn|sa)-[a-z]*-[0-9])"
finding = re.findall(re_phrase, region_url_response, re.IGNORECASE)
@@ -79,9 +79,11 @@ class AwsInstance(CloudInstance):
def _extract_account_id(instance_identity_document_response):
"""
Extracts the account id from the dynamic/instance-identity/document metadata path.
- Based on https://forums.aws.amazon.com/message.jspa?messageID=409028 which has a few more solutions,
+ Based on https://forums.aws.amazon.com/message.jspa?messageID=409028 which has a few more
+ solutions,
in case Amazon break this mechanism.
- :param instance_identity_document_response: json returned via the web page ../dynamic/instance-identity/document
+ :param instance_identity_document_response: json returned via the web page
+ ../dynamic/instance-identity/document
:return: The account id
"""
return json.loads(instance_identity_document_response)[ACCOUNT_ID_KEY]
diff --git a/monkey/common/cloud/aws/aws_service.py b/monkey/common/cloud/aws/aws_service.py
index 0825811a9..dd4b1cb24 100644
--- a/monkey/common/cloud/aws/aws_service.py
+++ b/monkey/common/cloud/aws/aws_service.py
@@ -31,12 +31,14 @@ def filter_instance_data_from_aws_response(response):
class AwsService(object):
"""
- A wrapper class around the boto3 client and session modules, which supplies various AWS services.
+ A wrapper class around the boto3 client and session modules, which supplies various AWS
+ services.
This class will assume:
1. That it's running on an EC2 instance
2. That the instance is associated with the correct IAM role. See
- https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#iam-role for details.
+ https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#iam-role
+ for details.
"""
region = None
@@ -73,7 +75,8 @@ class AwsService(object):
Get the information for all instances with the relevant roles.
This function will assume that it's running on an EC2 instance with the correct IAM role.
- See https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#iam-role for details.
+ See https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#iam
+ -role for details.
:raises: botocore.exceptions.ClientError if can't describe local instance information.
:return: All visible instances from this instance
diff --git a/monkey/common/cloud/aws/test_aws_instance.py b/monkey/common/cloud/aws/test_aws_instance.py
index d3c89f067..74ef5dd15 100644
--- a/monkey/common/cloud/aws/test_aws_instance.py
+++ b/monkey/common/cloud/aws/test_aws_instance.py
@@ -30,7 +30,6 @@ INSTANCE_IDENTITY_DOCUMENT_RESPONSE = """
}
"""
-
EXPECTED_INSTANCE_ID = "i-1234567890abcdef0"
EXPECTED_REGION = "us-west-2"
diff --git a/monkey/common/cloud/azure/azure_instance.py b/monkey/common/cloud/azure/azure_instance.py
index 186ce3c9d..859ab279f 100644
--- a/monkey/common/cloud/azure/azure_instance.py
+++ b/monkey/common/cloud/azure/azure_instance.py
@@ -18,7 +18,8 @@ logger = logging.getLogger(__name__)
class AzureInstance(CloudInstance):
"""
Access to useful information about the current machine if it's an Azure VM.
- Based on Azure metadata service: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service
+ Based on Azure metadata service:
+ https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service
"""
def is_instance(self):
@@ -44,7 +45,8 @@ class AzureInstance(CloudInstance):
)
# If not on cloud, the metadata URL is non-routable and the connection will fail.
- # If on AWS, should get 404 since the metadata service URL is different, so bool(response) will be false.
+ # If on AWS, should get 404 since the metadata service URL is different,
+ # so bool(response) will be false.
if response:
logger.debug("Trying to parse Azure metadata.")
self.try_parse_response(response)
@@ -52,7 +54,8 @@ class AzureInstance(CloudInstance):
logger.warning(f"Metadata response not ok: {response.status_code}")
except requests.RequestException:
logger.debug(
- "Failed to get response from Azure metadata service: This instance is not on Azure."
+ "Failed to get response from Azure metadata service: This instance is not on "
+ "Azure."
)
def try_parse_response(self, response):
diff --git a/monkey/common/cloud/azure/test_azure_instance.py b/monkey/common/cloud/azure/test_azure_instance.py
index fb1e01abb..a7bed81dd 100644
--- a/monkey/common/cloud/azure/test_azure_instance.py
+++ b/monkey/common/cloud/azure/test_azure_instance.py
@@ -30,7 +30,8 @@ GOOD_DATA = {
],
"publisher": "RDFE-Test-Microsoft-Windows-Server-Group",
"resourceGroupName": "macikgo-test-may-23",
- "resourceId": "/subscriptions/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/macikgo-test-may-23/"
+ "resourceId": "/subscriptions/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/macikgo-test"
+ "-may-23/"
"providers/Microsoft.Compute/virtualMachines/examplevmname",
"securityProfile": {"secureBootEnabled": "true", "virtualTpmEnabled": "false"},
"sku": "Windows-Server-2012-R2-Datacenter",
@@ -101,12 +102,16 @@ GOOD_DATA = {
},
}
-
-BAD_DATA_NOT_JSON = '\n\n
\n\n\nWaiting...\n\n\n \n\n'
-
+BAD_DATA_NOT_JSON = (
+ '\n\n\n\n\nWaiting...\n\n\n "
+ "\n\n"
+)
BAD_DATA_JSON = {"": ""}
diff --git a/monkey/common/cloud/gcp/gcp_instance.py b/monkey/common/cloud/gcp/gcp_instance.py
index 14e4e554a..1fc208165 100644
--- a/monkey/common/cloud/gcp/gcp_instance.py
+++ b/monkey/common/cloud/gcp/gcp_instance.py
@@ -8,13 +8,13 @@ from common.common_consts.timeouts import SHORT_REQUEST_TIMEOUT
logger = logging.getLogger(__name__)
-
GCP_METADATA_SERVICE_URL = "http://metadata.google.internal/"
class GcpInstance(CloudInstance):
"""
- Used to determine if on GCP. See https://cloud.google.com/compute/docs/storing-retrieving-metadata#runninggce
+ Used to determine if on GCP. See https://cloud.google.com/compute/docs/storing-retrieving
+ -metadata#runninggce
"""
def is_instance(self):
diff --git a/monkey/common/cmd/aws/aws_cmd_result.py b/monkey/common/cmd/aws/aws_cmd_result.py
index 1e89115ef..e68f5bf6d 100644
--- a/monkey/common/cmd/aws/aws_cmd_result.py
+++ b/monkey/common/cmd/aws/aws_cmd_result.py
@@ -20,7 +20,8 @@ class AwsCmdResult(CmdResult):
@staticmethod
def is_successful(command_info, is_timeout=False):
"""
- Determines whether the command was successful. If it timed out and was still in progress, we assume it worked.
+ Determines whether the command was successful. If it timed out and was still in progress,
+ we assume it worked.
:param command_info: Command info struct (returned by ssm.get_command_invocation)
:param is_timeout: Whether the given command timed out
:return: True if successful, False otherwise.
diff --git a/monkey/common/cmd/cmd_runner.py b/monkey/common/cmd/cmd_runner.py
index 57966d0b5..efd9d7bf0 100644
--- a/monkey/common/cmd/cmd_runner.py
+++ b/monkey/common/cmd/cmd_runner.py
@@ -21,8 +21,10 @@ class CmdRunner(object):
* command id - any unique identifier of a command which was already run
* command result - represents the result of running a command. Always of type CmdResult
* command status - represents the current status of a command. Always of type CmdStatus
- * command info - Any consistent structure representing additional information of a command which was already run
- * instance - a machine that commands will be run on. Can be any dictionary with 'instance_id' as a field
+ * command info - Any consistent structure representing additional information of a command
+ which was already run
+ * instance - a machine that commands will be run on. Can be any dictionary with 'instance_id'
+ as a field
* instance_id - any unique identifier of an instance (machine). Can be of any format
"""
@@ -49,7 +51,8 @@ class CmdRunner(object):
"""
Run multiple commands on various instances
:param instances: List of instances.
- :param inst_to_cmd: Function which receives an instance, runs a command asynchronously and returns Cmd
+ :param inst_to_cmd: Function which receives an instance, runs a command asynchronously
+ and returns Cmd
:param inst_n_cmd_res_to_res: Function which receives an instance and CmdResult
and returns a parsed result (of any format)
:return: Dictionary with 'instance_id' as key and parsed result as value
diff --git a/monkey/common/common_consts/zero_trust_consts.py b/monkey/common/common_consts/zero_trust_consts.py
index 539bb7265..6ff2ab20f 100644
--- a/monkey/common/common_consts/zero_trust_consts.py
+++ b/monkey/common/common_consts/zero_trust_consts.py
@@ -1,8 +1,10 @@
"""
-This file contains all the static data relating to Zero Trust. It is mostly used in the zero trust report generation and
+This file contains all the static data relating to Zero Trust. It is mostly used in the zero
+trust report generation and
in creating findings.
-This file contains static mappings between zero trust components such as: pillars, principles, tests, statuses.
+This file contains static mappings between zero trust components such as: pillars, principles,
+tests, statuses.
Some of the mappings are computed when this module is loaded.
"""
@@ -82,12 +84,16 @@ PRINCIPLES = {
PRINCIPLE_SEGMENTATION: "Apply segmentation and micro-segmentation inside your network.",
PRINCIPLE_ANALYZE_NETWORK_TRAFFIC: "Analyze network traffic for malicious activity.",
PRINCIPLE_USER_BEHAVIOUR: "Adopt security user behavior analytics.",
- PRINCIPLE_ENDPOINT_SECURITY: "Use anti-virus and other traditional endpoint security solutions.",
+ PRINCIPLE_ENDPOINT_SECURITY: "Use anti-virus and other traditional endpoint "
+ "security solutions.",
PRINCIPLE_DATA_CONFIDENTIALITY: "Ensure data's confidentiality by encrypting it.",
- 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 (Mandatory "
+ 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 (Mandatory "
"Access Control) only.",
- PRINCIPLE_DISASTER_RECOVERY: "Ensure data and infrastructure backups for disaster recovery scenarios.",
+ PRINCIPLE_DISASTER_RECOVERY: "Ensure data and infrastructure backups for disaster "
+ "recovery scenarios.",
PRINCIPLE_SECURE_AUTHENTICATION: "Ensure secure authentication process's.",
PRINCIPLE_MONITORING_AND_LOGGING: "Ensure monitoring and logging in network resources.",
}
@@ -99,32 +105,40 @@ FINDING_EXPLANATION_BY_STATUS_KEY = "finding_explanation"
TEST_EXPLANATION_KEY = "explanation"
TESTS_MAP = {
TEST_SEGMENTATION: {
- TEST_EXPLANATION_KEY: "The Monkey tried to scan and find machines that it can communicate with from the machine it's "
+ 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: {
- 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_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.",
},
PRINCIPLE_KEY: PRINCIPLE_SEGMENTATION,
PILLARS_KEY: [NETWORKS],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_PASSED, STATUS_FAILED],
},
TEST_MALICIOUS_ACTIVITY_TIMELINE: {
- TEST_EXPLANATION_KEY: "The Monkeys in the network performed malicious-looking actions, like scanning and attempting "
+ TEST_EXPLANATION_KEY: "The Monkeys in the network performed malicious-looking "
+ "actions, like scanning and attempting "
"exploitation.",
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."
},
PRINCIPLE_KEY: PRINCIPLE_ANALYZE_NETWORK_TRAFFIC,
PILLARS_KEY: [NETWORKS, VISIBILITY_ANALYTICS],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_VERIFY],
},
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: {
- STATUS_FAILED: "Monkey didn't find ANY active endpoint security processes. Install and activate anti-virus "
+ STATUS_FAILED: "Monkey didn't find ANY active endpoint security processes. Install and "
+ "activate anti-virus "
"software on endpoints.",
- STATUS_PASSED: "Monkey found active endpoint security processes. Check their logs to see if Monkey was a "
+ STATUS_PASSED: "Monkey found active endpoint security processes. Check their logs to "
+ "see if Monkey was a "
"security concern. ",
},
PRINCIPLE_KEY: PRINCIPLE_ENDPOINT_SECURITY,
@@ -132,9 +146,11 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
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: {
- STATUS_FAILED: "Monkey successfully exploited endpoints. Check IDS/IPS logs to see activity recognized and see "
+ 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.",
},
@@ -145,7 +161,8 @@ TESTS_MAP = {
TEST_SCHEDULED_EXECUTION: {
TEST_EXPLANATION_KEY: "The Monkey was executed in a scheduled manner.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
- STATUS_VERIFY: "Monkey was executed in a scheduled manner. Locate this activity in User-Behavior security "
+ 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.",
},
@@ -154,10 +171,13 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_VERIFY],
},
TEST_DATA_ENDPOINT_ELASTIC: {
- 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: {
- 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 "
+ 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. ",
},
PRINCIPLE_KEY: PRINCIPLE_DATA_CONFIDENTIALITY,
@@ -165,10 +185,12 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_DATA_ENDPOINT_HTTP: {
- 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: {
- 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 "
+ 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. ",
},
PRINCIPLE_KEY: PRINCIPLE_DATA_CONFIDENTIALITY,
@@ -176,10 +198,12 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_DATA_ENDPOINT_POSTGRESQL: {
- TEST_EXPLANATION_KEY: "The Monkey scanned for unencrypted access to PostgreSQL servers.",
+ TEST_EXPLANATION_KEY: "The Monkey scanned for unencrypted access to " "PostgreSQL servers.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
- STATUS_FAILED: "Monkey accessed PostgreSQL servers. Limit access to data by encrypting it in in-transit.",
- STATUS_PASSED: "Monkey didn't find open PostgreSQL servers. If you have such servers, look for alerts that "
+ STATUS_FAILED: "Monkey accessed PostgreSQL servers. Limit access to data by encrypting"
+ " it in in-transit.",
+ STATUS_PASSED: "Monkey didn't find open PostgreSQL servers. If you have such servers, "
+ "look for alerts that "
"indicate attempts to access them. ",
},
PRINCIPLE_KEY: PRINCIPLE_DATA_CONFIDENTIALITY,
@@ -189,7 +213,8 @@ TESTS_MAP = {
TEST_TUNNELING: {
TEST_EXPLANATION_KEY: "The Monkey tried to tunnel traffic using other monkeys.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
- STATUS_FAILED: "Monkey tunneled its traffic using other monkeys. Your network policies are too permissive - "
+ STATUS_FAILED: "Monkey tunneled its traffic using other monkeys. Your network policies "
+ "are too permissive - "
"restrict them. "
},
PRINCIPLE_KEY: PRINCIPLE_RESTRICTIVE_NETWORK_POLICIES,
@@ -197,9 +222,11 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED],
},
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: {
- STATUS_FAILED: "Monkey caused a new user to access the network. Your network policies are too permissive - "
+ 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.",
},
@@ -218,7 +245,7 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_SCOUTSUITE_UNENCRYPTED_DATA: {
- TEST_EXPLANATION_KEY: "ScoutSuite searched for resources containing unencrypted data.",
+ TEST_EXPLANATION_KEY: "ScoutSuite searched for resources containing " "unencrypted data.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found resources with unencrypted data.",
STATUS_PASSED: "ScoutSuite found no resources with unencrypted data.",
@@ -228,7 +255,8 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_SCOUTSUITE_DATA_LOSS_PREVENTION: {
- TEST_EXPLANATION_KEY: "ScoutSuite searched for resources which are not protected against data loss.",
+ TEST_EXPLANATION_KEY: "ScoutSuite searched for resources which are not "
+ "protected against data loss.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found resources not protected against data loss.",
STATUS_PASSED: "ScoutSuite found that all resources are secured against data loss.",
@@ -238,7 +266,7 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_SCOUTSUITE_SECURE_AUTHENTICATION: {
- TEST_EXPLANATION_KEY: "ScoutSuite searched for issues related to users' authentication.",
+ TEST_EXPLANATION_KEY: "ScoutSuite searched for issues related to users' " "authentication.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found issues related to users' authentication.",
STATUS_PASSED: "ScoutSuite found no issues related to users' authentication.",
@@ -248,7 +276,7 @@ TESTS_MAP = {
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
},
TEST_SCOUTSUITE_RESTRICTIVE_POLICIES: {
- TEST_EXPLANATION_KEY: "ScoutSuite searched for permissive user access policies.",
+ TEST_EXPLANATION_KEY: "ScoutSuite searched for permissive user access " "policies.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_FAILED: "ScoutSuite found permissive user access policies.",
STATUS_PASSED: "ScoutSuite found no issues related to user access policies.",
diff --git a/monkey/common/network/network_range.py b/monkey/common/network/network_range.py
index 581c4bf77..a9e05caa6 100644
--- a/monkey/common/network/network_range.py
+++ b/monkey/common/network/network_range.py
@@ -159,7 +159,8 @@ class SingleIpRange(NetworkRange):
@staticmethod
def string_to_host(string_):
"""
- Converts the string that user entered in "Scan IP/subnet list" to a tuple of domain name and ip
+ Converts the string that user entered in "Scan IP/subnet list" to a tuple of domain name
+ and ip
:param string_: String that was entered in "Scan IP/subnet list"
:return: A tuple in format (IP, domain_name). Eg. (192.168.55.1, www.google.com)
"""
diff --git a/monkey/common/network/network_utils.py b/monkey/common/network/network_utils.py
index 6aa5076ae..2b01d1974 100644
--- a/monkey/common/network/network_utils.py
+++ b/monkey/common/network/network_utils.py
@@ -4,8 +4,10 @@ from urllib.parse import urlparse
def get_host_from_network_location(network_location: str) -> str:
"""
- URL structure is ":///;?#" (https://tools.ietf.org/html/rfc1808.html)
- And the net_loc is ":@:" (https://tools.ietf.org/html/rfc1738#section-3.1)
+ URL structure is ":///;?#" (
+ https://tools.ietf.org/html/rfc1808.html)
+ And the net_loc is ":@:" (
+ https://tools.ietf.org/html/rfc1738#section-3.1)
:param network_location: server network location
:return: host part of the network location
"""
diff --git a/monkey/common/network/segmentation_utils.py b/monkey/common/network/segmentation_utils.py
index 9bbaabf1d..d48c005cb 100644
--- a/monkey/common/network/segmentation_utils.py
+++ b/monkey/common/network/segmentation_utils.py
@@ -14,8 +14,10 @@ def get_ip_in_src_and_not_in_dst(ip_addresses, source_subnet, target_subnet):
def get_ip_if_in_subnet(ip_addresses, subnet):
"""
:param ip_addresses: IP address list.
- :param subnet: Subnet to check if one of ip_addresses is in there. This is common.network.network_range.NetworkRange
- :return: The first IP in ip_addresses which is in the subnet if there is one, otherwise returns None.
+ :param subnet: Subnet to check if one of ip_addresses is in there. This is
+ common.network.network_range.NetworkRange
+ :return: The first IP in ip_addresses which is in the subnet if there is one, otherwise
+ returns None.
"""
for ip_address in ip_addresses:
if subnet.is_in_range(ip_address):
diff --git a/monkey/common/utils/attack_utils.py b/monkey/common/utils/attack_utils.py
index c911ed780..98b6361c4 100644
--- a/monkey/common/utils/attack_utils.py
+++ b/monkey/common/utils/attack_utils.py
@@ -15,7 +15,8 @@ class ScanStatus(Enum):
class UsageEnum(Enum):
SMB = {
ScanStatus.USED.value: "SMB exploiter ran the monkey by creating a service via MS-SCMR.",
- ScanStatus.SCANNED.value: "SMB exploiter failed to run the monkey by creating a service via MS-SCMR.",
+ ScanStatus.SCANNED.value: "SMB exploiter failed to run the monkey by creating a service "
+ "via MS-SCMR.",
}
MIMIKATZ = {
ScanStatus.USED.value: "Windows module loader was used to load Mimikatz DLL.",
@@ -29,7 +30,8 @@ class UsageEnum(Enum):
ScanStatus.USED.value: "WinAPI was used to mark monkey files for deletion on next boot."
}
SINGLETON_WINAPI = {
- ScanStatus.USED.value: "WinAPI was called to acquire system singleton for monkey's process.",
+ ScanStatus.USED.value: "WinAPI was called to acquire system singleton for monkey's "
+ "process.",
ScanStatus.SCANNED.value: "WinAPI call to acquire system singleton"
" for monkey process wasn't successful.",
}
diff --git a/monkey/common/version.py b/monkey/common/version.py
index 4070fc2f6..3eb35274e 100644
--- a/monkey/common/version.py
+++ b/monkey/common/version.py
@@ -1,4 +1,5 @@
-# To get the version from shell, run `python ./version.py` (see `python ./version.py -h` for details).
+# To get the version from shell, run `python ./version.py` (see `python ./version.py -h` for
+# details).
import argparse
from pathlib import Path
diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py
index 7aeaccee2..ffdea551e 100644
--- a/monkey/infection_monkey/config.py
+++ b/monkey/infection_monkey/config.py
@@ -227,7 +227,8 @@ class Configuration(object):
@staticmethod
def hash_sensitive_data(sensitive_data):
"""
- Hash sensitive data (e.g. passwords). Used so the log won't contain sensitive data plain-text, as the log is
+ Hash sensitive data (e.g. passwords). Used so the log won't contain sensitive data
+ plain-text, as the log is
saved on client machines plain-text.
:param sensitive_data: the data to hash.
diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py
index 4ccd2bec4..0df989d99 100644
--- a/monkey/infection_monkey/control.py
+++ b/monkey/infection_monkey/control.py
@@ -23,7 +23,6 @@ from infection_monkey.utils.exceptions.planned_shutdown_exception import Planned
__author__ = "hoffer"
-
requests.packages.urllib3.disable_warnings()
LOG = logging.getLogger(__name__)
@@ -32,7 +31,8 @@ DOWNLOAD_CHUNK = 1024
PBA_FILE_DOWNLOAD = "https://%s/api/pba/download/%s"
# random number greater than 5,
-# to prevent the monkey from just waiting forever to try and connect to an island before going elsewhere.
+# to prevent the monkey from just waiting forever to try and connect to an island before going
+# elsewhere.
TIMEOUT_IN_SECONDS = 15
@@ -412,7 +412,10 @@ class ControlClient(object):
@staticmethod
def can_island_see_port(port):
try:
- url = f"https://{WormConfiguration.current_server}/api/monkey_control/check_remote_port/{port}"
+ url = (
+ f"https://{WormConfiguration.current_server}/api/monkey_control"
+ f"/check_remote_port/{port}"
+ )
response = requests.get(url, verify=False, timeout=SHORT_REQUEST_TIMEOUT)
response = json.loads(response.content.decode())
return response["status"] == "port_visible"
diff --git a/monkey/infection_monkey/dropper.py b/monkey/infection_monkey/dropper.py
index 74c20321b..3d34688ef 100644
--- a/monkey/infection_monkey/dropper.py
+++ b/monkey/infection_monkey/dropper.py
@@ -152,7 +152,8 @@ class MonkeyDrops(object):
)
else:
dest_path = self._config["destination_path"]
- # In linux we have a more complex commandline. There's a general outer one, and the inner one which actually
+ # In linux we have a more complex commandline. There's a general outer one,
+ # and the inner one which actually
# runs the monkey
inner_monkey_cmdline = (
MONKEY_CMDLINE_LINUX % {"monkey_filename": dest_path.split("/")[-1]}
@@ -207,7 +208,8 @@ class MonkeyDrops(object):
dropper_source_path_ctypes, None, MOVEFILE_DELAY_UNTIL_REBOOT
):
LOG.debug(
- "Error marking source file '%s' for deletion on next boot (error %d)",
+ "Error marking source file '%s' for deletion on next boot (error "
+ "%d)",
self._config["source_path"],
ctypes.windll.kernel32.GetLastError(),
)
diff --git a/monkey/infection_monkey/exploit/HostExploiter.py b/monkey/infection_monkey/exploit/HostExploiter.py
index e5bdf6dfe..95de0ec07 100644
--- a/monkey/infection_monkey/exploit/HostExploiter.py
+++ b/monkey/infection_monkey/exploit/HostExploiter.py
@@ -10,7 +10,6 @@ from infection_monkey.utils.plugins.plugin import Plugin
__author__ = "itamar"
-
logger = logging.getLogger(__name__)
@@ -37,7 +36,8 @@ class HostExploiter(Plugin):
EXPLOIT_TYPE = ExploitType.VULNERABILITY
# Determines if successful exploitation should stop further exploit attempts on that machine.
- # Generally, should be True for RCE type exploiters and False if we don't expect the exploiter to run the monkey agent.
+ # Generally, should be True for RCE type exploiters and False if we don't expect the
+ # exploiter to run the monkey agent.
# Example: Zerologon steals credentials
RUNS_AGENT_ON_SUCCESS = True
diff --git a/monkey/infection_monkey/exploit/drupal.py b/monkey/infection_monkey/exploit/drupal.py
index efbbc2f56..50594e656 100644
--- a/monkey/infection_monkey/exploit/drupal.py
+++ b/monkey/infection_monkey/exploit/drupal.py
@@ -1,7 +1,8 @@
"""
Remote Code Execution on Drupal server - CVE-2019-6340
Implementation is based on:
- https://gist.github.com/leonjza/d0ab053be9b06fa020b66f00358e3d88/f9f6a5bb6605745e292bee3a4079f261d891738a.
+ https://gist.github.com/leonjza/d0ab053be9b06fa020b66f00358e3d88
+ /f9f6a5bb6605745e292bee3a4079f261d891738a.
"""
import logging
@@ -28,7 +29,8 @@ class DrupalExploiter(WebRCE):
def get_exploit_config(self):
"""
- We override this function because the exploits requires a special extension in the URL, "node",
+ We override this function because the exploits requires a special extension in the URL,
+ "node",
e.g. an exploited URL would be http://172.1.2.3:/node/3.
:return: the Drupal exploit config
"""
@@ -42,7 +44,8 @@ class DrupalExploiter(WebRCE):
def add_vulnerable_urls(self, potential_urls, stop_checking=False):
"""
- We need a specific implementation of this function in order to add the URLs *with the node IDs*.
+ We need a specific implementation of this function in order to add the URLs *with the
+ node IDs*.
We therefore check, for every potential URL, all possible node IDs.
:param potential_urls: Potentially-vulnerable URLs
:param stop_checking: Stop if one vulnerable URL is found
@@ -71,7 +74,8 @@ class DrupalExploiter(WebRCE):
def check_if_exploitable(self, url):
"""
Check if a certain URL is exploitable.
- We use this specific implementation (and not simply run self.exploit) because this function does not "waste"
+ We use this specific implementation (and not simply run self.exploit) because this
+ function does not "waste"
a vulnerable URL. Namely, we're not actually exploiting, merely checking using a heuristic.
:param url: Drupal's URL and port
:return: Vulnerable URL if exploitable, otherwise False
@@ -117,7 +121,8 @@ class DrupalExploiter(WebRCE):
def get_target_url(self):
"""
- We're overriding this method such that every time self.exploit is invoked, we use a fresh vulnerable URL.
+ We're overriding this method such that every time self.exploit is invoked, we use a fresh
+ vulnerable URL.
Reusing the same URL eliminates its exploitability because of caching reasons :)
:return: vulnerable URL to exploit
"""
@@ -128,13 +133,15 @@ class DrupalExploiter(WebRCE):
For the Drupal exploit, 5 distinct URLs are needed to perform the full attack.
:return: Whether the list of vulnerable URLs has at least 5 elements.
"""
- # We need 5 URLs for a "full-chain": check remote files, check architecture, drop monkey, chmod it and run it.
+ # We need 5 URLs for a "full-chain": check remote files, check architecture, drop monkey,
+ # chmod it and run it.
num_urls_needed_for_full_exploit = 5
num_available_urls = len(self.vulnerable_urls)
result = num_available_urls >= num_urls_needed_for_full_exploit
if not result:
LOG.info(
- f"{num_urls_needed_for_full_exploit} URLs are needed to fully exploit a Drupal server "
+ f"{num_urls_needed_for_full_exploit} URLs are needed to fully exploit a "
+ f"Drupal server "
f"but only {num_available_urls} found"
)
return result
diff --git a/monkey/infection_monkey/exploit/elasticgroovy.py b/monkey/infection_monkey/exploit/elasticgroovy.py
index ca1c0408b..734e7e5ef 100644
--- a/monkey/infection_monkey/exploit/elasticgroovy.py
+++ b/monkey/infection_monkey/exploit/elasticgroovy.py
@@ -1,6 +1,7 @@
"""
Implementation is based on elastic search groovy exploit by metasploit
- https://github.com/rapid7/metasploit-framework/blob/12198a088132f047e0a86724bc5ebba92a73ac66/modules/exploits/multi/elasticsearch/search_groovy_script.rb
+ https://github.com/rapid7/metasploit-framework/blob/12198a088132f047e0a86724bc5ebba92a73ac66
+ /modules/exploits/multi/elasticsearch/search_groovy_script.rb
Max vulnerable elasticsearch version is "1.4.2"
"""
@@ -35,9 +36,9 @@ class ElasticGroovyExploiter(WebRCE):
GENERIC_QUERY = (
"""{"size":1, "script_fields":{"%s": {"script": "%%s"}}}""" % MONKEY_RESULT_FIELD
)
- JAVA_CMD = (
- GENERIC_QUERY
- % """java.lang.Math.class.forName(\\"java.lang.Runtime\\").getRuntime().exec(\\"%s\\").getText()"""
+ JAVA_CMD = GENERIC_QUERY % (
+ """java.lang.Math.class.forName(\\"java.lang.Runtime\\").getRuntime().exec("""
+ """\\"%s\\").getText()"""
)
_TARGET_OS_TYPE = ["linux", "windows"]
@@ -57,7 +58,8 @@ class ElasticGroovyExploiter(WebRCE):
return exploit_config
def get_open_service_ports(self, port_list, names):
- # We must append elastic port we get from elastic fingerprint module because It's not marked as 'http' service
+ # We must append elastic port we get from elastic fingerprint module because It's not
+ # marked as 'http' service
valid_ports = super(ElasticGroovyExploiter, self).get_open_service_ports(port_list, names)
if ES_SERVICE in self.host.services:
valid_ports.append([ES_PORT, False])
@@ -70,7 +72,8 @@ class ElasticGroovyExploiter(WebRCE):
response = requests.get(url, data=payload, timeout=DOWNLOAD_TIMEOUT)
except requests.ReadTimeout:
LOG.error(
- "Elastic couldn't upload monkey, because server didn't respond to upload request."
+ "Elastic couldn't upload monkey, because server didn't respond to upload "
+ "request."
)
return False
result = self.get_results(response)
diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py
index d92c39f6c..a30112cce 100644
--- a/monkey/infection_monkey/exploit/hadoop.py
+++ b/monkey/infection_monkey/exploit/hadoop.py
@@ -1,6 +1,7 @@
"""
Remote code execution on HADOOP server with YARN and default settings
- Implementation is based on code from https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn
+ Implementation is based on code from
+ https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn
"""
import json
diff --git a/monkey/infection_monkey/exploit/mssqlexec.py b/monkey/infection_monkey/exploit/mssqlexec.py
index 893ee8ca1..24b46d278 100644
--- a/monkey/infection_monkey/exploit/mssqlexec.py
+++ b/monkey/infection_monkey/exploit/mssqlexec.py
@@ -56,7 +56,8 @@ class MSSQLExploiter(HostExploiter):
def _exploit_host(self):
"""
First this method brute forces to get the mssql connection (cursor).
- Also, don't forget to start_monkey_server() before self.upload_monkey() and self.stop_monkey_server() after
+ Also, don't forget to start_monkey_server() before self.upload_monkey() and
+ self.stop_monkey_server() after
"""
# Brute force to get connection
username_passwords_pairs_list = self._config.get_exploit_user_password_pairs()
@@ -181,10 +182,12 @@ class MSSQLExploiter(HostExploiter):
Args:
host (str): Host ip address
port (str): Tcp port that the host listens to
- users_passwords_pairs_list (list): a list of users and passwords pairs to bruteforce with
+ users_passwords_pairs_list (list): a list of users and passwords pairs to bruteforce
+ with
Return:
- True or False depends if the whole bruteforce and attack process was completed successfully or not
+ True or False depends if the whole bruteforce and attack process was completed
+ successfully or not
"""
# Main loop
# Iterates on users list
@@ -196,9 +199,8 @@ class MSSQLExploiter(HostExploiter):
host, user, password, port=port, login_timeout=self.LOGIN_TIMEOUT
)
LOG.info(
- "Successfully connected to host: {0}, using user: {1}, password (SHA-512): {2}".format(
- host, user, self._config.hash_sensitive_data(password)
- )
+ "Successfully connected to host: {0}, using user: {1}, password ("
+ "SHA-512): {2}".format(host, user, self._config.hash_sensitive_data(password))
)
self.add_vuln_port(MSSQLExploiter.SQL_DEFAULT_TCP_PORT)
self.report_login_attempt(True, user, password)
diff --git a/monkey/infection_monkey/exploit/sambacry.py b/monkey/infection_monkey/exploit/sambacry.py
index b0387105e..72d36e234 100644
--- a/monkey/infection_monkey/exploit/sambacry.py
+++ b/monkey/infection_monkey/exploit/sambacry.py
@@ -54,7 +54,8 @@ LOG = logging.getLogger(__name__)
class SambaCryExploiter(HostExploiter):
"""
- SambaCry exploit module, partially based on the following implementation by CORE Security Technologies' impacket:
+ SambaCry exploit module, partially based on the following implementation by CORE Security
+ Technologies' impacket:
https://github.com/CoreSecurity/impacket/blob/master/examples/sambaPipe.py
"""
@@ -372,7 +373,8 @@ class SambaCryExploiter(HostExploiter):
# the extra / on the beginning is required for the vulnerability
self.open_pipe(smb_client, "/" + module_path)
except Exception as e:
- # This is the expected result. We can't tell whether we succeeded or not just by this error code.
+ # This is the expected result. We can't tell whether we succeeded or not just by this
+ # error code.
if str(e).find("STATUS_OBJECT_NAME_NOT_FOUND") >= 0:
return True
else:
@@ -450,7 +452,8 @@ class SambaCryExploiter(HostExploiter):
)
return smb_client
- # Following are slightly modified SMB functions from impacket to fit our needs of the vulnerability #
+ # Following are slightly modified SMB functions from impacket to fit our needs of the
+ # vulnerability #
@staticmethod
def create_smb(
smb_client,
@@ -513,7 +516,8 @@ class SambaCryExploiter(HostExploiter):
@staticmethod
def open_pipe(smb_client, pathName):
- # We need to overwrite Impacket's openFile functions since they automatically convert paths to NT style
+ # We need to overwrite Impacket's openFile functions since they automatically convert
+ # paths to NT style
# to make things easier for the caller. Not this time ;)
treeId = smb_client.connectTree("IPC$")
LOG.debug("Triggering path: %s" % pathName)
diff --git a/monkey/infection_monkey/exploit/shellshock.py b/monkey/infection_monkey/exploit/shellshock.py
index 11932c3f5..7854483a0 100644
--- a/monkey/infection_monkey/exploit/shellshock.py
+++ b/monkey/infection_monkey/exploit/shellshock.py
@@ -1,4 +1,5 @@
-# Implementation is based on shellshock script provided https://github.com/nccgroup/shocker/blob/master/shocker.py
+# Implementation is based on shellshock script provided
+# https://github.com/nccgroup/shocker/blob/master/shocker.py
import logging
import string
@@ -113,7 +114,8 @@ class ShellShockExploiter(HostExploiter):
self.check_remote_file_exists(url, header, exploit, dropper_target_path_linux)
):
LOG.info(
- "Host %s was already infected under the current configuration, done" % self.host
+ "Host %s was already infected under the current configuration, "
+ "done" % self.host
)
return True # return already infected
@@ -270,7 +272,8 @@ class ShellShockExploiter(HostExploiter):
break
if timeout:
LOG.debug(
- "Some connections timed out while sending request to potentially vulnerable urls."
+ "Some connections timed out while sending request to potentially vulnerable "
+ "urls."
)
valid_resps = [req for req in reqs if req and req.status_code == requests.codes.ok]
urls = [resp.url for resp in valid_resps]
diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py
index 4b5e941f8..81fc2848c 100644
--- a/monkey/infection_monkey/exploit/smbexec.py
+++ b/monkey/infection_monkey/exploit/smbexec.py
@@ -75,7 +75,8 @@ class SmbExploiter(HostExploiter):
if remote_full_path is not None:
LOG.debug(
- "Successfully logged in %r using SMB (%s : (SHA-512) %s : (SHA-512) %s : (SHA-512) %s)",
+ "Successfully logged in %r using SMB (%s : (SHA-512) %s : (SHA-512) "
+ "%s : (SHA-512) %s)",
self.host,
user,
self._config.hash_sensitive_data(password),
@@ -99,7 +100,8 @@ class SmbExploiter(HostExploiter):
except Exception as exc:
LOG.debug(
"Exception when trying to copy file using SMB to %r with user:"
- " %s, password (SHA-512): '%s', LM hash (SHA-512): %s, NTLM hash (SHA-512): %s: (%s)",
+ " %s, password (SHA-512): '%s', LM hash (SHA-512): %s, NTLM hash ("
+ "SHA-512): %s: (%s)",
self.host,
user,
self._config.hash_sensitive_data(password),
diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py
index 0f5af3258..3dedae114 100644
--- a/monkey/infection_monkey/exploit/sshexec.py
+++ b/monkey/infection_monkey/exploit/sshexec.py
@@ -157,7 +157,8 @@ class SSHExploiter(HostExploiter):
if stdout_res:
# file exists
LOG.info(
- "Host %s was already infected under the current configuration, done" % self.host
+ "Host %s was already infected under the current configuration, "
+ "done" % self.host
)
return True # return already infected
diff --git a/monkey/infection_monkey/exploit/struts2.py b/monkey/infection_monkey/exploit/struts2.py
index c08c174fb..ff5b9887b 100644
--- a/monkey/infection_monkey/exploit/struts2.py
+++ b/monkey/infection_monkey/exploit/struts2.py
@@ -35,7 +35,8 @@ class Struts2Exploiter(WebRCE):
def build_potential_urls(self, ports, extensions=None):
"""
We need to override this method to get redirected url's
- :param ports: Array of ports. One port is described as size 2 array: [port.no(int), isHTTPS?(bool)]
+ :param ports: Array of ports. One port is described as size 2 array: [port.no(int),
+ isHTTPS?(bool)]
Eg. ports: [[80, False], [443, True]]
:param extensions: What subdirectories to scan. www.domain.com[/extension]
:return: Array of url's to try and attack
diff --git a/monkey/infection_monkey/exploit/tools/helpers.py b/monkey/infection_monkey/exploit/tools/helpers.py
index cf94f6edc..a863f9499 100644
--- a/monkey/infection_monkey/exploit/tools/helpers.py
+++ b/monkey/infection_monkey/exploit/tools/helpers.py
@@ -29,7 +29,8 @@ def get_target_monkey(host):
if not monkey_path:
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 host.os.get(
"machine", ""
).lower() == platform.machine().lower():
diff --git a/monkey/infection_monkey/exploit/tools/payload_parsing.py b/monkey/infection_monkey/exploit/tools/payload_parsing.py
index 052ab18e5..2d38b593c 100644
--- a/monkey/infection_monkey/exploit/tools/payload_parsing.py
+++ b/monkey/infection_monkey/exploit/tools/payload_parsing.py
@@ -17,7 +17,8 @@ class Payload(object):
def get_payload(self, command=""):
"""
Returns prefixed and suffixed command (payload)
- :param command: Command to suffix/prefix. If no command is passed than objects' property is used
+ :param command: Command to suffix/prefix. If no command is passed than objects' property
+ is used
:return: prefixed and suffixed command (full payload)
"""
if not command:
@@ -46,7 +47,8 @@ class LimitedSizePayload(Payload):
def split_into_array_of_smaller_payloads(self):
if self.is_suffix_and_prefix_too_long():
raise Exception(
- "Can't split command into smaller sub-commands because commands' prefix and suffix already "
+ "Can't split command into smaller sub-commands because commands' prefix and "
+ "suffix already "
"exceeds required length of command."
)
diff --git a/monkey/infection_monkey/exploit/tools/smb_tools.py b/monkey/infection_monkey/exploit/tools/smb_tools.py
index 9943b4135..5fc2b4a44 100644
--- a/monkey/infection_monkey/exploit/tools/smb_tools.py
+++ b/monkey/infection_monkey/exploit/tools/smb_tools.py
@@ -36,7 +36,8 @@ class SmbTools(object):
# skip guest users
if smb.isGuestSession() > 0:
LOG.debug(
- "Connection to %r granted guest privileges with user: %s, password (SHA-512): '%s',"
+ "Connection to %r granted guest privileges with user: %s, password (SHA-512): "
+ "'%s',"
" LM hash (SHA-512): %s, NTLM hash (SHA-512): %s",
host,
username,
@@ -151,7 +152,7 @@ class SmbTools(object):
return remote_full_path
LOG.debug(
- "Remote monkey file is found but different, moving along with attack"
+ "Remote monkey file is found but different, moving along with " "attack"
)
except Exception:
pass # file isn't found on remote victim, moving on
@@ -197,7 +198,8 @@ class SmbTools(object):
if not file_uploaded:
LOG.debug(
"Couldn't find a writable share for exploiting victim %r with "
- "username: %s, password (SHA-512): '%s', LM hash (SHA-512): %s, NTLM hash (SHA-512): %s",
+ "username: %s, password (SHA-512): '%s', LM hash (SHA-512): %s, NTLM hash ("
+ "SHA-512): %s",
host,
username,
Configuration.hash_sensitive_data(password),
diff --git a/monkey/infection_monkey/exploit/vsftpd.py b/monkey/infection_monkey/exploit/vsftpd.py
index d8e88b44c..8af8e24d9 100644
--- a/monkey/infection_monkey/exploit/vsftpd.py
+++ b/monkey/infection_monkey/exploit/vsftpd.py
@@ -1,6 +1,7 @@
"""
Implementation is based on VSFTPD v2.3.4 Backdoor Command Execution exploit by metasploit
- https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/ftp/vsftpd_234_backdoor.rb
+ https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/ftp
+ /vsftpd_234_backdoor.rb
only vulnerable version is "2.3.4"
"""
@@ -151,7 +152,8 @@ class VSFTPDExploiter(HostExploiter):
}
# Set unlimited to memory
- # we don't have to revert the ulimit because it just applies to the shell obtained by our exploit
+ # we don't have to revert the ulimit because it just applies to the shell obtained by our
+ # exploit
run_monkey = ULIMIT_V + UNLIMITED + run_monkey
run_monkey = str.encode(str(run_monkey) + "\n")
time.sleep(FTP_TIME_BUFFER)
diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py
index f51fe1539..dafa6164a 100644
--- a/monkey/infection_monkey/exploit/web_rce.py
+++ b/monkey/infection_monkey/exploit/web_rce.py
@@ -69,21 +69,27 @@ class WebRCE(HostExploiter):
"""
exploit_config = {}
- # dropper: If true monkey will use dropper parameter that will detach monkey's process and try to copy
+ # dropper: If true monkey will use dropper parameter that will detach monkey's process
+ # and try to copy
# it's file to the default destination path.
exploit_config["dropper"] = False
- # upload_commands: Unformatted dict with one or two commands {'linux': WGET_HTTP_UPLOAD,'windows': WIN_CMD}
- # Command must have "monkey_path" and "http_path" format parameters. If None defaults will be used.
+ # upload_commands: Unformatted dict with one or two commands {'linux': WGET_HTTP_UPLOAD,
+ # 'windows': WIN_CMD}
+ # Command must have "monkey_path" and "http_path" format parameters. If None defaults
+ # will be used.
exploit_config["upload_commands"] = None
- # url_extensions: What subdirectories to scan (www.domain.com[/extension]). Eg. ["home", "index.php"]
+ # url_extensions: What subdirectories to scan (www.domain.com[/extension]). Eg. ["home",
+ # "index.php"]
exploit_config["url_extensions"] = []
- # stop_checking_urls: If true it will stop checking vulnerable urls once one was found vulnerable.
+ # stop_checking_urls: If true it will stop checking vulnerable urls once one was found
+ # vulnerable.
exploit_config["stop_checking_urls"] = False
- # blind_exploit: If true we won't check if file exist and won't try to get the architecture of target.
+ # blind_exploit: If true we won't check if file exist and won't try to get the
+ # architecture of target.
exploit_config["blind_exploit"] = False
return exploit_config
@@ -200,7 +206,8 @@ class WebRCE(HostExploiter):
except KeyError:
LOG.error(
"Provided command is missing/bad for this type of host! "
- "Check upload_monkey function docs before using custom monkey's upload commands."
+ "Check upload_monkey function docs before using custom monkey's upload "
+ "commands."
)
return False
return command
@@ -225,8 +232,10 @@ class WebRCE(HostExploiter):
def build_potential_urls(self, ports, extensions=None):
"""
- Build all possibly-vulnerable URLs on a specific host, based on the relevant ports and extensions.
- :param ports: Array of ports. One port is described as size 2 array: [port.no(int), isHTTPS?(bool)]
+ Build all possibly-vulnerable URLs on a specific host, based on the relevant ports and
+ extensions.
+ :param ports: Array of ports. One port is described as size 2 array: [port.no(int),
+ isHTTPS?(bool)]
Eg. ports: [[80, False], [443, True]]
:param extensions: What subdirectories to scan. www.domain.com[/extension]
:return: Array of url's to try and attack
@@ -253,7 +262,8 @@ class WebRCE(HostExploiter):
"""
Gets vulnerable url(s) from url list
:param urls: Potentially vulnerable urls
- :param stop_checking: If we want to continue checking for vulnerable url even though one is found (bool)
+ :param stop_checking: If we want to continue checking for vulnerable url even though one
+ is found (bool)
:return: None (we append to class variable vulnerable_urls)
"""
for url in urls:
@@ -330,7 +340,8 @@ class WebRCE(HostExploiter):
Get ports wrapped with log
:param ports: Potential ports to exploit. For example WormConfiguration.HTTP_PORTS
:param names: [] of service names. Example: ["http"]
- :return: Array of ports: [[80, False], [443, True]] or False. Port always consists of [ port.nr, IsHTTPS?]
+ :return: Array of ports: [[80, False], [443, True]] or False. Port always consists of [
+ port.nr, IsHTTPS?]
"""
ports = self.get_open_service_ports(ports, names)
if not ports:
@@ -350,7 +361,8 @@ class WebRCE(HostExploiter):
def run_backup_commands(self, resp, url, dest_path, http_path):
"""
- If you need multiple commands for the same os you can override this method to add backup commands
+ If you need multiple commands for the same os you can override this method to add backup
+ commands
:param resp: Response from base command
:param url: Vulnerable url
:param dest_path: Where to upload monkey
@@ -370,7 +382,8 @@ class WebRCE(HostExploiter):
def upload_monkey(self, url, commands=None):
"""
:param url: Where exploiter should send it's request
- :param commands: Unformatted dict with one or two commands {'linux': LIN_CMD, 'windows': WIN_CMD}
+ :param commands: Unformatted dict with one or two commands {'linux': LIN_CMD, 'windows':
+ WIN_CMD}
Command must have "monkey_path" and "http_path" format parameters.
:return: {'response': response/False, 'path': monkeys_path_in_host}
"""
@@ -435,7 +448,7 @@ class WebRCE(HostExploiter):
return False
elif "No such file or directory" in resp:
LOG.error(
- "Could not change permission because monkey was not found. Check path parameter."
+ "Could not change permission because monkey was not found. Check path " "parameter."
)
return False
LOG.info("Permission change finished")
@@ -499,7 +512,8 @@ class WebRCE(HostExploiter):
def get_monkey_upload_path(self, url_to_monkey):
"""
Gets destination path from one of WEB_RCE predetermined paths(self.monkey_target_paths).
- :param url_to_monkey: Hosted monkey's url. egz : http://localserver:9999/monkey/windows-32.exe
+ :param url_to_monkey: Hosted monkey's url. egz :
+ http://localserver:9999/monkey/windows-32.exe
:return: Corresponding monkey path from self.monkey_target_paths
"""
if not url_to_monkey or ("linux" not in url_to_monkey and "windows" not in url_to_monkey):
@@ -522,7 +536,8 @@ class WebRCE(HostExploiter):
return False
except KeyError:
LOG.error(
- 'Unknown key was found. Please use "linux", "win32" and "win64" keys to initialize '
+ 'Unknown key was found. Please use "linux", "win32" and "win64" keys to '
+ "initialize "
"custom dict of monkey's destination paths"
)
return False
@@ -577,8 +592,10 @@ class WebRCE(HostExploiter):
def are_vulnerable_urls_sufficient(self):
"""
- Determine whether the number of vulnerable URLs is sufficient in order to perform the full attack.
- Often, a single URL will suffice. However, in some cases (e.g. the Drupal exploit) a vulnerable URL is for
+ Determine whether the number of vulnerable URLs is sufficient in order to perform the
+ full attack.
+ Often, a single URL will suffice. However, in some cases (e.g. the Drupal exploit) a
+ vulnerable URL is for
single use, thus we need a couple of them.
:return: Whether or not a full attack can be performed using the available vulnerable URLs.
"""
diff --git a/monkey/infection_monkey/exploit/weblogic.py b/monkey/infection_monkey/exploit/weblogic.py
index 2d1a40c0a..017050346 100644
--- a/monkey/infection_monkey/exploit/weblogic.py
+++ b/monkey/infection_monkey/exploit/weblogic.py
@@ -160,7 +160,8 @@ class WebLogic201710271(WebRCE):
:param command: command itself
:return: Formatted payload
"""
- empty_payload = """
+ empty_payload = """
@@ -195,7 +196,8 @@ class WebLogic201710271(WebRCE):
:param port: Server's port
:return: Formatted payload
"""
- generic_check_payload = """
+ generic_check_payload = """
@@ -272,7 +274,8 @@ class WebLogic20192725(WebRCE):
return exploit_config
def execute_remote_monkey(self, url, path, dropper=False):
- # Without delay exploiter tries to launch monkey file that is still finishing up after downloading.
+ # Without delay exploiter tries to launch monkey file that is still finishing up after
+ # downloading.
time.sleep(WebLogic20192725.DELAY_BEFORE_EXPLOITING_SECONDS)
super(WebLogic20192725, self).execute_remote_monkey(url, path, dropper)
@@ -307,7 +310,8 @@ class WebLogic20192725(WebRCE):
"""
empty_payload = """
+ xmlns:wsa=\"http://www.w3.org/2005/08/addressing\"
+ xmlns:asy=\"http://www.bea.com/async/AsyncResponseService\">
xx
xx
diff --git a/monkey/infection_monkey/exploit/wmiexec.py b/monkey/infection_monkey/exploit/wmiexec.py
index 7120f5720..cad313f8c 100644
--- a/monkey/infection_monkey/exploit/wmiexec.py
+++ b/monkey/infection_monkey/exploit/wmiexec.py
@@ -142,7 +142,8 @@ class WmiExploiter(HostExploiter):
success = True
else:
LOG.debug(
- "Error executing dropper '%s' on remote victim %r (pid=%d, exit_code=%d, cmdline=%r)",
+ "Error executing dropper '%s' on remote victim %r (pid=%d, exit_code=%d, "
+ "cmdline=%r)",
remote_full_path,
self.host,
result.ProcessId,
diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py
index 9c18b2de3..232436cdf 100644
--- a/monkey/infection_monkey/exploit/zerologon.py
+++ b/monkey/infection_monkey/exploit/zerologon.py
@@ -1,6 +1,7 @@
"""
Zerologon, CVE-2020-1472
-Implementation based on https://github.com/dirkjanm/CVE-2020-1472/ and https://github.com/risksense/zerologon/.
+Implementation based on https://github.com/dirkjanm/CVE-2020-1472/ and
+https://github.com/risksense/zerologon/.
"""
import logging
@@ -54,7 +55,8 @@ class ZerologonExploiter(HostExploiter):
else:
LOG.info(
- "Exploit not attempted. Target is most likely patched, or an error was encountered."
+ "Exploit not attempted. Target is most likely patched, or an error was "
+ "encountered."
)
return False
@@ -131,7 +133,8 @@ class ZerologonExploiter(HostExploiter):
self.report_login_attempt(result=False, user=self.dc_name)
_exploited = False
LOG.info(
- f"Non-zero return code: {exploit_attempt_result['ErrorCode']}. Something went wrong."
+ f"Non-zero return code: {exploit_attempt_result['ErrorCode']}. Something "
+ f"went wrong."
)
return _exploited
@@ -194,7 +197,8 @@ class ZerologonExploiter(HostExploiter):
def get_all_user_creds(self) -> List[Tuple[str, Dict]]:
try:
options = OptionsForSecretsdump(
- target=f"{self.dc_name}$@{self.dc_ip}", # format for DC account - "NetBIOSName$@0.0.0.0"
+ # format for DC account - "NetBIOSName$@0.0.0.0"
+ target=f"{self.dc_name}$@{self.dc_ip}",
target_ip=self.dc_ip,
dc_ip=self.dc_ip,
)
@@ -221,7 +225,8 @@ class ZerologonExploiter(HostExploiter):
except Exception as e:
LOG.info(
- f"Exception occurred while dumping secrets to get some username and its password's NT hash: {str(e)}"
+ f"Exception occurred while dumping secrets to get some username and its "
+ f"password's NT hash: {str(e)}"
)
return None
@@ -310,7 +315,8 @@ class ZerologonExploiter(HostExploiter):
except Exception as e:
LOG.info(
- f"Exception occurred while dumping secrets to get original DC password's NT hash: {str(e)}"
+ f"Exception occurred while dumping secrets to get original DC password's NT "
+ f"hash: {str(e)}"
)
finally:
@@ -339,7 +345,8 @@ class ZerologonExploiter(HostExploiter):
+ "reg save HKLM\\SECURITY security.save"
)
- # Get HKLM keys locally (can't run these together because it needs to call do_get()).
+ # Get HKLM keys locally (can't run these together because it needs to call
+ # do_get()).
remote_shell.onecmd("get system.save")
remote_shell.onecmd("get sam.save")
remote_shell.onecmd("get security.save")
diff --git a/monkey/infection_monkey/exploit/zerologon_utils/dump_secrets.py b/monkey/infection_monkey/exploit/zerologon_utils/dump_secrets.py
index 9d2116d07..f76fe361b 100644
--- a/monkey/infection_monkey/exploit/zerologon_utils/dump_secrets.py
+++ b/monkey/infection_monkey/exploit/zerologon_utils/dump_secrets.py
@@ -132,8 +132,10 @@ class DumpSecrets:
self.connect()
except Exception as e:
if os.getenv("KRB5CCNAME") is not None and self.__do_kerberos is True:
- # SMBConnection failed. That might be because there was no way to log into the
- # target system. We just have a last resort. Hope we have tickets cached and that they
+ # SMBConnection failed. That might be because there was no way to
+ # log into the
+ # target system. We just have a last resort. Hope we have tickets
+ # cached and that they
# will work
LOG.debug(
"SMBConnection didn't work, hoping Kerberos will help (%s)"
@@ -162,11 +164,13 @@ class DumpSecrets:
and os.getenv("KRB5CCNAME") is not None
and self.__do_kerberos is True
):
- # Giving some hints here when SPN target name validation is set to something different to Off.
- # This will prevent establishing SMB connections using TGS for SPNs different to cifs/.
+ # Giving some hints here when SPN target name validation is set to
+ # something different to Off.
+ # This will prevent establishing SMB connections using TGS for SPNs
+ # different to cifs/.
LOG.error(
- "Policy SPN target name validation might be restricting full DRSUAPI dump."
- + "Try -just-dc-user"
+ "Policy SPN target name validation might be restricting full "
+ "DRSUAPI dump." + "Try -just-dc-user"
)
else:
LOG.error("RemoteOperations failed: %s" % str(e))
@@ -208,7 +212,8 @@ class DumpSecrets:
LOG.debug(traceback.print_exc())
LOG.error("LSA hashes extraction failed: %s" % str(e))
- # NTDS Extraction we can try regardless of RemoteOperations failing. It might still work.
+ # NTDS Extraction we can try regardless of RemoteOperations failing. It might
+ # still work.
if self.__is_remote is True:
if self.__use_VSS_method and self.__remote_ops is not None:
NTDS_file_name = self.__remote_ops.saveNTDS()
@@ -231,7 +236,8 @@ class DumpSecrets:
except Exception as e:
LOG.debug(traceback.print_exc())
if str(e).find("ERROR_DS_DRA_BAD_DN") >= 0:
- # We don't store the resume file if this error happened, since this error is related to lack
+ # We don't store the resume file if this error happened, since this error
+ # is related to lack
# of enough privileges to access DRSUAPI.
resume_file = self.__NTDS_hashes.getResumeSessionFile()
if resume_file is not None:
@@ -239,7 +245,8 @@ class DumpSecrets:
LOG.error(e)
if self.__use_VSS_method is False:
LOG.error(
- "Something wen't wrong with the DRSUAPI approach. Try again with -use-vss parameter"
+ "Something wen't wrong with the DRSUAPI approach. Try again with "
+ "-use-vss parameter"
)
self.cleanup()
except (Exception, KeyboardInterrupt) as e:
diff --git a/monkey/infection_monkey/exploit/zerologon_utils/options.py b/monkey/infection_monkey/exploit/zerologon_utils/options.py
index 32cdfe40f..0745dc4c6 100644
--- a/monkey/infection_monkey/exploit/zerologon_utils/options.py
+++ b/monkey/infection_monkey/exploit/zerologon_utils/options.py
@@ -35,9 +35,11 @@ class OptionsForSecretsdump:
target=None,
target_ip=None,
):
- # dc_ip is assigned in get_original_pwd_nthash() and get_admin_pwd_hashes() in ../zerologon.py
+ # dc_ip is assigned in get_original_pwd_nthash() and get_admin_pwd_hashes() in
+ # ../zerologon.py
self.dc_ip = dc_ip
- # just_dc becomes False, and sam, security, and system are assigned in get_original_pwd_nthash() in ../zerologon.py
+ # just_dc becomes False, and sam, security, and system are assigned in
+ # get_original_pwd_nthash() in ../zerologon.py
self.just_dc = just_dc
self.sam = sam
self.security = security
diff --git a/monkey/infection_monkey/exploit/zerologon_utils/remote_shell.py b/monkey/infection_monkey/exploit/zerologon_utils/remote_shell.py
index 3b635f6b5..3097610fb 100644
--- a/monkey/infection_monkey/exploit/zerologon_utils/remote_shell.py
+++ b/monkey/infection_monkey/exploit/zerologon_utils/remote_shell.py
@@ -134,8 +134,10 @@ class RemoteShell(cmd.Cmd):
self.__outputBuffer += data.decode(self.CODEC)
except UnicodeDecodeError:
LOG.error(
- "Decoding error detected, consider running chcp.com at the target,\nmap the result with "
- "https://docs.python.org/3/library/codecs.html#standard-encodings\nand then execute wmiexec.py "
+ "Decoding error detected, consider running chcp.com at the target,"
+ "\nmap the result with "
+ "https://docs.python.org/3/library/codecs.html#standard-encodings\nand "
+ "then execute wmiexec.py "
"again with -codec and the corresponding codec"
)
self.__outputBuffer += data.decode(self.CODEC, errors="replace")
diff --git a/monkey/infection_monkey/main.py b/monkey/infection_monkey/main.py
index e0c0eef08..9bdece16d 100644
--- a/monkey/infection_monkey/main.py
+++ b/monkey/infection_monkey/main.py
@@ -26,7 +26,8 @@ LOG_CONFIG = {
"disable_existing_loggers": False,
"formatters": {
"standard": {
- "format": "%(asctime)s [%(process)d:%(thread)d:%(levelname)s] %(module)s.%(funcName)s.%(lineno)d: %(message)s"
+ "format": "%(asctime)s [%(process)d:%(thread)d:%(levelname)s] %(module)s.%("
+ "funcName)s.%(lineno)d: %(message)s"
},
},
"handlers": {
@@ -71,8 +72,8 @@ def main():
print("Error loading config: %s, using default" % (e,))
else:
print(
- "Config file wasn't supplied and default path: %s wasn't found, using internal default"
- % (config_file,)
+ "Config file wasn't supplied and default path: %s wasn't found, using internal "
+ "default" % (config_file,)
)
print(
@@ -104,7 +105,8 @@ def main():
if WormConfiguration.use_file_logging:
if os.path.exists(log_path):
- # If log exists but can't be removed it means other monkey is running. This usually happens on upgrade
+ # If log exists but can't be removed it means other monkey is running. This usually
+ # happens on upgrade
# from 32bit to 64bit monkey on Windows. In all cases this shouldn't be a problem.
try:
os.remove(log_path)
diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py
index 7123d8b9e..c81a62517 100644
--- a/monkey/infection_monkey/monkey.py
+++ b/monkey/infection_monkey/monkey.py
@@ -227,7 +227,8 @@ class InfectionMonkey(object):
host_exploited = True
VictimHostTelem("T1210", ScanStatus.USED, machine=machine).send()
if exploiter.RUNS_AGENT_ON_SUCCESS:
- break # if adding machine to exploited, won't try other exploits on it
+ break # if adding machine to exploited, won't try other exploits
+ # on it
if not host_exploited:
self._fail_exploitation_machines.add(machine)
VictimHostTelem("T1210", ScanStatus.SCANNED, machine=machine).send()
@@ -244,7 +245,8 @@ class InfectionMonkey(object):
elif not WormConfiguration.alive:
LOG.info("Marked not alive from configuration")
- # if host was exploited, before continue to closing the tunnel ensure the exploited host had its chance to
+ # if host was exploited, before continue to closing the tunnel ensure the exploited
+ # host had its chance to
# connect to the tunnel
if len(self._exploited_machines) > 0:
time_to_sleep = WormConfiguration.keep_tunnel_open_time
@@ -261,7 +263,8 @@ class InfectionMonkey(object):
except PlannedShutdownException:
LOG.info(
- "A planned shutdown of the Monkey occurred. Logging the reason and finishing execution."
+ "A planned shutdown of the Monkey occurred. Logging the reason and finishing "
+ "execution."
)
LOG.exception("Planned shutdown, reason:")
diff --git a/monkey/infection_monkey/network/info.py b/monkey/infection_monkey/network/info.py
index 21adae9f8..c30f3d436 100644
--- a/monkey/infection_monkey/network/info.py
+++ b/monkey/infection_monkey/network/info.py
@@ -88,7 +88,8 @@ else:
continue
try:
ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x", iff))
- except IOError: # interface is present in routing tables but does not have any assigned IP
+ except IOError: # interface is present in routing tables but does not have any
+ # assigned IP
ifaddr = "0.0.0.0"
else:
addrfamily = struct.unpack("h", ifreq[16:18])[0]
diff --git a/monkey/infection_monkey/network/mssql_fingerprint.py b/monkey/infection_monkey/network/mssql_fingerprint.py
index 3113d278f..c743fa3a5 100644
--- a/monkey/infection_monkey/network/mssql_fingerprint.py
+++ b/monkey/infection_monkey/network/mssql_fingerprint.py
@@ -49,22 +49,21 @@ class MSSQLFinger(HostFinger):
data, server = sock.recvfrom(self.BUFFER_SIZE)
except socket.timeout:
LOG.info(
- "Socket timeout reached, maybe browser service on host: {0} doesnt exist".format(
- host
- )
+ "Socket timeout reached, maybe browser service on host: {0} doesnt "
+ "exist".format(host)
)
sock.close()
return False
except socket.error as e:
if e.errno == errno.ECONNRESET:
LOG.info(
- "Connection was forcibly closed by the remote host. The host: {0} is rejecting the packet.".format(
- host
- )
+ "Connection was forcibly closed by the remote host. The host: {0} is "
+ "rejecting the packet.".format(host)
)
else:
LOG.error(
- "An unknown socket error occurred while trying the mssql fingerprint, closing socket.",
+ "An unknown socket error occurred while trying the mssql fingerprint, "
+ "closing socket.",
exc_info=True,
)
sock.close()
@@ -82,7 +81,8 @@ class MSSQLFinger(HostFinger):
if len(instance_info) > 1:
host.services[self._SCANNED_SERVICE][instance_info[1]] = {}
for i in range(1, len(instance_info), 2):
- # Each instance's info is nested under its own name, if there are multiple instances
+ # Each instance's info is nested under its own name, if there are multiple
+ # instances
# each will appear under its own name
host.services[self._SCANNED_SERVICE][instance_info[1]][
instance_info[i - 1]
diff --git a/monkey/infection_monkey/network/network_scanner.py b/monkey/infection_monkey/network/network_scanner.py
index 0b8a75120..677466190 100644
--- a/monkey/infection_monkey/network/network_scanner.py
+++ b/monkey/infection_monkey/network/network_scanner.py
@@ -44,9 +44,11 @@ class NetworkScanner(object):
def _get_inaccessible_subnets_ips(self):
"""
For each of the machine's IPs, checks if it's in one of the subnets specified in the
- 'inaccessible_subnets' config value. If so, all other subnets in the config value shouldn't be accessible.
+ 'inaccessible_subnets' config value. If so, all other subnets in the config value
+ shouldn't be accessible.
All these subnets are returned.
- :return: A list of subnets that shouldn't be accessible from the machine the monkey is running on.
+ :return: A list of subnets that shouldn't be accessible from the machine the monkey is
+ running on.
"""
subnets_to_scan = []
if len(WormConfiguration.inaccessible_subnets) > 1:
@@ -54,7 +56,8 @@ class NetworkScanner(object):
if NetworkScanner._is_any_ip_in_subnet(
[str(x) for x in self._ip_addresses], subnet_str
):
- # If machine has IPs from 2 different subnets in the same group, there's no point checking the other
+ # If machine has IPs from 2 different subnets in the same group, there's no
+ # point checking the other
# subnet.
for other_subnet_str in WormConfiguration.inaccessible_subnets:
if other_subnet_str == subnet_str:
@@ -74,9 +77,12 @@ class NetworkScanner(object):
:param stop_callback: A callback to check at any point if we should stop scanning
:return: yields a sequence of VictimHost instances
"""
- # We currently use the ITERATION_BLOCK_SIZE as the pool size, however, this may not be the best decision
- # However, the decision what ITERATION_BLOCK_SIZE also requires balancing network usage (pps and bw)
- # Because we are using this to spread out IO heavy tasks, we can probably go a lot higher than CPU core size
+ # We currently use the ITERATION_BLOCK_SIZE as the pool size, however, this may not be
+ # the best decision
+ # However, the decision what ITERATION_BLOCK_SIZE also requires balancing network usage (
+ # pps and bw)
+ # Because we are using this to spread out IO heavy tasks, we can probably go a lot higher
+ # than CPU core size
# But again, balance
pool = Pool(ITERATION_BLOCK_SIZE)
victim_generator = VictimHostGenerator(
diff --git a/monkey/infection_monkey/network/ping_scanner.py b/monkey/infection_monkey/network/ping_scanner.py
index dd1577e47..73c89f841 100644
--- a/monkey/infection_monkey/network/ping_scanner.py
+++ b/monkey/infection_monkey/network/ping_scanner.py
@@ -59,7 +59,8 @@ class PingScanner(HostScanner, HostFinger):
ttl = int(regex_result.group(0))
if ttl <= LINUX_TTL:
host.os["type"] = "linux"
- else: # as far we we know, could also be OSX/BSD but lets handle that when it comes up.
+ else: # as far we we know, could also be OSX/BSD but lets handle that when it
+ # comes up.
host.os["type"] = "windows"
host.icmp = True
diff --git a/monkey/infection_monkey/network/postgresql_finger.py b/monkey/infection_monkey/network/postgresql_finger.py
index 16f6327f9..f19c128e8 100644
--- a/monkey/infection_monkey/network/postgresql_finger.py
+++ b/monkey/infection_monkey/network/postgresql_finger.py
@@ -51,12 +51,14 @@ class PostgreSQLFinger(HostFinger):
self.init_service(host.services, self._SCANNED_SERVICE, self.POSTGRESQL_DEFAULT_PORT)
host.services[self._SCANNED_SERVICE]["communication_encryption_details"] = (
"The PostgreSQL server was unexpectedly accessible with the credentials - "
- + f"user: '{self.CREDS['username']}' and password: '{self.CREDS['password']}'. Is this a honeypot?"
+ + f"user: '{self.CREDS['username']}' and password: '"
+ f"{self.CREDS['password']}'. Is this a honeypot?"
)
return True
except psycopg2.OperationalError as ex:
- # try block will throw an OperationalError since the credentials are wrong, which we then analyze
+ # try block will throw an OperationalError since the credentials are wrong, which we
+ # then analyze
try:
exception_string = str(ex)
diff --git a/monkey/infection_monkey/network/smbfinger.py b/monkey/infection_monkey/network/smbfinger.py
index 457d0213d..b035a053f 100644
--- a/monkey/infection_monkey/network/smbfinger.py
+++ b/monkey/infection_monkey/network/smbfinger.py
@@ -68,14 +68,16 @@ class SMBNegoFingerData(Packet):
("separator1", b"\x02"),
(
"dialect1",
- b"\x50\x43\x20\x4e\x45\x54\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31\x2e\x30\x00",
+ b"\x50\x43\x20\x4e\x45\x54\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d"
+ b"\x20\x31\x2e\x30\x00",
),
("separator2", b"\x02"),
("dialect2", b"\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00"),
("separator3", b"\x02"),
(
"dialect3",
- b"\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61\x00",
+ b"\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57\x6f\x72\x6b\x67\x72"
+ b"\x6f\x75\x70\x73\x20\x33\x2e\x31\x61\x00",
),
("separator4", b"\x02"),
("dialect4", b"\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00"),
@@ -104,12 +106,18 @@ class SMBSessionFingerData(Packet):
("bcc1", ""),
(
"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"
- 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"\x60\x48\x06\x06\x2b\x06\x01\x05\x05\x02\xa0\x3e\x30\x3c\xa0\x0e\x30\x0c"
+ b"\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"
+ b"\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"
+ b"\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"
+ b"\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"
+ b"\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"
+ b"\x00\x30\x00\x30\x00\x32\x00\x20\x00\x35"
b"\x00\x2e\x00\x31\x00\x00\x00\x00\x00",
),
]
diff --git a/monkey/infection_monkey/network/tcp_scanner.py b/monkey/infection_monkey/network/tcp_scanner.py
index 0547d315a..1260a590d 100644
--- a/monkey/infection_monkey/network/tcp_scanner.py
+++ b/monkey/infection_monkey/network/tcp_scanner.py
@@ -22,7 +22,8 @@ class TcpScanner(HostScanner, HostFinger):
def get_host_fingerprint(self, host, only_one_port=False):
"""
- 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 only_one_port: Currently unused.
:return: T/F if there is at least one open port.
diff --git a/monkey/infection_monkey/network/tools.py b/monkey/infection_monkey/network/tools.py
index 63f8604f8..2ccfeb35b 100644
--- a/monkey/infection_monkey/network/tools.py
+++ b/monkey/infection_monkey/network/tools.py
@@ -129,7 +129,8 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
possible_ports.append((port, sock))
continue
if err == 10035: # WSAEWOULDBLOCK is valid, see
- # https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29
+ # .aspx?f=255&MSPPError=-2147217396
possible_ports.append((port, sock))
continue
if err == 115: # EINPROGRESS 115 /* Operation now in progress */
@@ -164,7 +165,8 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
readable_sockets, _, _ = select.select(
[s[1] for s in connected_ports_sockets], [], [], 0
)
- # read first BANNER_READ bytes. We ignore errors because service might not send a decodable byte string.
+ # read first BANNER_READ bytes. We ignore errors because service might not send a
+ # decodable byte string.
banners = [
sock.recv(BANNER_READ).decode(errors="ignore")
if sock in readable_sockets
@@ -209,7 +211,8 @@ def _get_traceroute_bin_path():
Its been built using the buildroot utility with the following settings:
* Statically link to musl and all other required libs
* Optimize for size
- This is done because not all linux distros come with traceroute out-of-the-box, and to ensure it behaves as expected
+ This is done because not all linux distros come with traceroute out-of-the-box, and to ensure
+ it behaves as expected
:return: Path to traceroute executable
"""
@@ -223,7 +226,8 @@ def _parse_traceroute(output, regex, ttl):
:param regex: Regex for finding an IP address
:param ttl: Max TTL. Must be the same as the TTL used as param for traceroute.
:return: List of ips which are the hops on the way to the traceroute destination.
- If a hop's IP wasn't found by traceroute, instead of an IP, the array will contain None
+ If a hop's IP wasn't found by traceroute, instead of an IP, the array will
+ contain None
"""
ip_lines = output.split("\n")
trace_list = []
diff --git a/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py b/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py
index 97f8ede43..ecbebd4d0 100644
--- a/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py
+++ b/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py
@@ -27,7 +27,8 @@ logger = logging.getLogger(__name__)
class CommunicateAsNewUser(PBA):
"""
- This PBA creates a new user, and then creates HTTPS requests as that user. This is used for a Zero Trust test of the
+ This PBA creates a new user, and then creates HTTPS requests as that user. This is used for a
+ Zero Trust test of the
People pillar. See the relevant telemetry processing to see what findings are created.
"""
@@ -58,7 +59,8 @@ class CommunicateAsNewUser(PBA):
def get_commandline_for_http_request(url, is_windows=is_windows_os()):
if is_windows:
format_string = (
- 'powershell.exe -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; '
+ 'powershell.exe -command "[Net.ServicePointManager]::SecurityProtocol = ['
+ "Net.SecurityProtocolType]::Tls12; "
'Invoke-WebRequest {url} -UseBasicParsing"'
)
else:
diff --git a/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py b/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py
index 555de4667..782f85d13 100644
--- a/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py
+++ b/monkey/infection_monkey/post_breach/actions/use_signed_scripts.py
@@ -28,7 +28,8 @@ class SignedScriptProxyExecution(PBA):
super().run()
except Exception as e:
LOG.warning(
- f"An exception occurred on running PBA {POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC}: {str(e)}"
+ f"An exception occurred on running PBA "
+ f"{POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC}: {str(e)}"
)
finally:
cleanup_changes(original_comspec)
diff --git a/monkey/infection_monkey/post_breach/job_scheduling/windows_job_scheduling.py b/monkey/infection_monkey/post_breach/job_scheduling/windows_job_scheduling.py
index 4c4927419..9f44768d2 100644
--- a/monkey/infection_monkey/post_breach/job_scheduling/windows_job_scheduling.py
+++ b/monkey/infection_monkey/post_breach/job_scheduling/windows_job_scheduling.py
@@ -1,7 +1,9 @@
SCHEDULED_TASK_NAME = "monkey-spawn-cmd"
SCHEDULED_TASK_COMMAND = r"C:\windows\system32\cmd.exe"
-# Commands from: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1053.005/T1053.005.md
+
+# Commands from: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1053.005
+# /T1053.005.md
def get_windows_commands_to_schedule_jobs():
diff --git a/monkey/infection_monkey/post_breach/pba.py b/monkey/infection_monkey/post_breach/pba.py
index e9bf61935..a87cfec48 100644
--- a/monkey/infection_monkey/post_breach/pba.py
+++ b/monkey/infection_monkey/post_breach/pba.py
@@ -16,7 +16,8 @@ __author__ = "VakarisZ"
class PBA(Plugin):
"""
- 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.
"""
@staticmethod
diff --git a/monkey/infection_monkey/post_breach/setuid_setgid/linux_setuid_setgid.py b/monkey/infection_monkey/post_breach/setuid_setgid/linux_setuid_setgid.py
index 5a4a7f1dc..15809f481 100644
--- a/monkey/infection_monkey/post_breach/setuid_setgid/linux_setuid_setgid.py
+++ b/monkey/infection_monkey/post_breach/setuid_setgid/linux_setuid_setgid.py
@@ -1,11 +1,14 @@
TEMP_FILE = "$HOME/monkey-temp-file"
-# Commands from https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1548.001/T1548.001.md
+
+# Commands from https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1548.001
+# /T1548.001.md
def get_linux_commands_to_setuid_setgid():
return [
- f"touch {TEMP_FILE} && chown root {TEMP_FILE} && chmod u+s {TEMP_FILE} && chmod g+s {TEMP_FILE} &&",
+ f"touch {TEMP_FILE} && chown root {TEMP_FILE} && chmod u+s {TEMP_FILE} && chmod g+s "
+ f"{TEMP_FILE} &&",
'echo "Successfully changed setuid/setgid bits" &&',
f"rm {TEMP_FILE}",
]
diff --git a/monkey/infection_monkey/post_breach/shell_startup_files/shell_startup_files_modification.py b/monkey/infection_monkey/post_breach/shell_startup_files/shell_startup_files_modification.py
index 0be9ec369..604d7c198 100644
--- a/monkey/infection_monkey/post_breach/shell_startup_files/shell_startup_files_modification.py
+++ b/monkey/infection_monkey/post_breach/shell_startup_files/shell_startup_files_modification.py
@@ -1,7 +1,7 @@
-from infection_monkey.post_breach.shell_startup_files.linux.shell_startup_files_modification import (
+from infection_monkey.post_breach.shell_startup_files.linux.shell_startup_files_modification import ( # noqa: E501
get_linux_commands_to_modify_shell_startup_files,
)
-from infection_monkey.post_breach.shell_startup_files.windows.shell_startup_files_modification import (
+from infection_monkey.post_breach.shell_startup_files.windows.shell_startup_files_modification import ( # noqa: E501
get_windows_commands_to_modify_shell_startup_files,
)
diff --git a/monkey/infection_monkey/post_breach/shell_startup_files/windows/shell_startup_files_modification.py b/monkey/infection_monkey/post_breach/shell_startup_files/windows/shell_startup_files_modification.py
index 517692276..e65893095 100644
--- a/monkey/infection_monkey/post_breach/shell_startup_files/windows/shell_startup_files_modification.py
+++ b/monkey/infection_monkey/post_breach/shell_startup_files/windows/shell_startup_files_modification.py
@@ -26,6 +26,7 @@ def get_windows_commands_to_modify_shell_startup_files():
return [
"powershell.exe",
- "infection_monkey/post_breach/shell_startup_files/windows/modify_powershell_startup_file.ps1",
+ "infection_monkey/post_breach/shell_startup_files/windows"
+ "/modify_powershell_startup_file.ps1",
"-startup_file_path {0}",
], STARTUP_FILES_PER_USER
diff --git a/monkey/infection_monkey/post_breach/tests/actions/test_users_custom_pba.py b/monkey/infection_monkey/post_breach/tests/actions/test_users_custom_pba.py
index 2956c140f..e7da336eb 100644
--- a/monkey/infection_monkey/post_breach/tests/actions/test_users_custom_pba.py
+++ b/monkey/infection_monkey/post_breach/tests/actions/test_users_custom_pba.py
@@ -75,7 +75,6 @@ def test_command_windows_custom_file_and_cmd(
@pytest.fixture
def mock_UsersPBA_linux_custom_file(set_os_linux, fake_monkey_dir_path, monkeypatch):
-
monkeypatch.setattr("infection_monkey.config.WormConfiguration.custom_PBA_linux_cmd", None)
monkeypatch.setattr(
"infection_monkey.config.WormConfiguration.PBA_linux_filename",
@@ -91,7 +90,6 @@ def test_command_linux_custom_file(mock_UsersPBA_linux_custom_file):
@pytest.fixture
def mock_UsersPBA_windows_custom_file(set_os_windows, fake_monkey_dir_path, monkeypatch):
-
monkeypatch.setattr("infection_monkey.config.WormConfiguration.custom_PBA_windows_cmd", None)
monkeypatch.setattr(
"infection_monkey.config.WormConfiguration.PBA_windows_filename",
@@ -107,7 +105,6 @@ def test_command_windows_custom_file(mock_UsersPBA_windows_custom_file):
@pytest.fixture
def mock_UsersPBA_linux_custom_cmd(set_os_linux, fake_monkey_dir_path, monkeypatch):
-
monkeypatch.setattr(
"infection_monkey.config.WormConfiguration.custom_PBA_linux_cmd",
CUSTOM_LINUX_CMD,
@@ -123,7 +120,6 @@ def test_command_linux_custom_cmd(mock_UsersPBA_linux_custom_cmd):
@pytest.fixture
def mock_UsersPBA_windows_custom_cmd(set_os_windows, fake_monkey_dir_path, monkeypatch):
-
monkeypatch.setattr(
"infection_monkey.config.WormConfiguration.custom_PBA_windows_cmd",
CUSTOM_WINDOWS_CMD,
diff --git a/monkey/infection_monkey/post_breach/timestomping/linux/timestomping.py b/monkey/infection_monkey/post_breach/timestomping/linux/timestomping.py
index 4860e2d3e..07841d280 100644
--- a/monkey/infection_monkey/post_breach/timestomping/linux/timestomping.py
+++ b/monkey/infection_monkey/post_breach/timestomping/linux/timestomping.py
@@ -11,4 +11,5 @@ def get_linux_timestomping_commands():
]
-# Commands' source: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1070.006/T1070.006.md
+# Commands' source: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1070.006
+# /T1070.006.md
diff --git a/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.py b/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.py
index 952ae46c6..dbea6aaea 100644
--- a/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.py
+++ b/monkey/infection_monkey/post_breach/timestomping/windows/timestomping.py
@@ -5,4 +5,5 @@ def get_windows_timestomping_commands():
return "powershell.exe infection_monkey/post_breach/timestomping/windows/timestomping.ps1"
-# Commands' source: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1070.006/T1070.006.md
+# Commands' source: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1070.006
+# /T1070.006.md
diff --git a/monkey/infection_monkey/post_breach/trap_command/linux_trap_command.py b/monkey/infection_monkey/post_breach/trap_command/linux_trap_command.py
index 0b9c74b04..75d545140 100644
--- a/monkey/infection_monkey/post_breach/trap_command/linux_trap_command.py
+++ b/monkey/infection_monkey/post_breach/trap_command/linux_trap_command.py
@@ -1,5 +1,6 @@
def get_linux_trap_commands():
return [
- "trap 'echo \"Successfully used trap command\"' INT && kill -2 $$ ;", # trap and send SIGINT signal
+ # trap and send SIGINT signal
+ "trap 'echo \"Successfully used trap command\"' INT && kill -2 $$ ;",
"trap - INT", # untrap SIGINT
]
diff --git a/monkey/infection_monkey/pyinstaller_utils.py b/monkey/infection_monkey/pyinstaller_utils.py
index 2dd8325ce..f13f6f71b 100644
--- a/monkey/infection_monkey/pyinstaller_utils.py
+++ b/monkey/infection_monkey/pyinstaller_utils.py
@@ -6,7 +6,8 @@ __author__ = "itay.mizeretz"
def get_binaries_dir_path():
"""
- Gets the path to the binaries dir (files packaged in pyinstaller if it was used, infection_monkey dir otherwise)
+ Gets the path to the binaries dir (files packaged in pyinstaller if it was used,
+ infection_monkey dir otherwise)
:return: Binaries dir path
"""
if getattr(sys, "frozen", False):
diff --git a/monkey/infection_monkey/system_info/SSH_info_collector.py b/monkey/infection_monkey/system_info/SSH_info_collector.py
index 556b5472c..d7b204fed 100644
--- a/monkey/infection_monkey/system_info/SSH_info_collector.py
+++ b/monkey/infection_monkey/system_info/SSH_info_collector.py
@@ -72,7 +72,8 @@ class SSHCollector(object):
try:
with open(public) as f:
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]
if os.path.exists(private):
try:
diff --git a/monkey/infection_monkey/system_info/__init__.py b/monkey/infection_monkey/system_info/__init__.py
index 5fc91f371..765f298d2 100644
--- a/monkey/infection_monkey/system_info/__init__.py
+++ b/monkey/infection_monkey/system_info/__init__.py
@@ -29,7 +29,8 @@ class OperatingSystem(IntEnum):
class SystemInfoCollector(object):
"""
- A class that checks the current operating system and calls system information collecting modules accordingly
+ A class that checks the current operating system and calls system information collecting
+ modules accordingly
"""
def __init__(self):
@@ -113,5 +114,6 @@ class InfoCollector(object):
self.info["Azure"] = {}
self.info["Azure"]["usernames"] = [cred[0] for cred in azure_creds]
except Exception:
- # If we failed to collect azure info, no reason to fail all the collection. Log and continue.
+ # If we failed to collect azure info, no reason to fail all the collection. Log and
+ # continue.
LOG.error("Failed collecting Azure info.", exc_info=True)
diff --git a/monkey/infection_monkey/system_info/azure_cred_collector.py b/monkey/infection_monkey/system_info/azure_cred_collector.py
index 68cd05a4e..ca5d8064e 100644
--- a/monkey/infection_monkey/system_info/azure_cred_collector.py
+++ b/monkey/infection_monkey/system_info/azure_cred_collector.py
@@ -97,7 +97,8 @@ class AzureCollector(object):
# we're going to do as much of this in PS as we can.
ps_block = ";\n".join(
[
- '[System.Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null',
+ '[System.Reflection.Assembly]::LoadWithPartialName("System.Security") | '
+ "Out-Null",
'$base64 = "%s"' % protected_data,
"$content = [Convert]::FromBase64String($base64)",
"$env = New-Object Security.Cryptography.Pkcs.EnvelopedCms",
diff --git a/monkey/infection_monkey/system_info/collectors/process_list_collector.py b/monkey/infection_monkey/system_info/collectors/process_list_collector.py
index a95ac385b..12cdf8aeb 100644
--- a/monkey/infection_monkey/system_info/collectors/process_list_collector.py
+++ b/monkey/infection_monkey/system_info/collectors/process_list_collector.py
@@ -37,7 +37,8 @@ class ProcessListCollector(SystemInfoCollector):
"full_image_path": process.exe(),
}
except (psutil.AccessDenied, WindowsError):
- # we may be running as non root and some processes are impossible to acquire in Windows/Linux.
+ # we may be running as non root and some processes are impossible to acquire in
+ # Windows/Linux.
# In this case we'll just add what we know.
processes[process.pid] = {
"name": "null",
diff --git a/monkey/infection_monkey/system_info/netstat_collector.py b/monkey/infection_monkey/system_info/netstat_collector.py
index d35b4c1fb..b0acc6b65 100644
--- a/monkey/infection_monkey/system_info/netstat_collector.py
+++ b/monkey/infection_monkey/system_info/netstat_collector.py
@@ -1,4 +1,5 @@
-# Inspired by Giampaolo Rodola's psutil example from https://github.com/giampaolo/psutil/blob/master/scripts/netstat.py
+# Inspired by Giampaolo Rodola's psutil example from
+# https://github.com/giampaolo/psutil/blob/master/scripts/netstat.py
import logging
import socket
diff --git a/monkey/infection_monkey/system_info/system_info_collector.py b/monkey/infection_monkey/system_info/system_info_collector.py
index ac269f5b0..fe160de16 100644
--- a/monkey/infection_monkey/system_info/system_info_collector.py
+++ b/monkey/infection_monkey/system_info/system_info_collector.py
@@ -7,9 +7,12 @@ from infection_monkey.utils.plugins.plugin import Plugin
class SystemInfoCollector(Plugin, metaclass=ABCMeta):
"""
- ABC for system info collection. See system_info_collector_handler for more info. Basically, to implement a new system info
- collector, inherit from this class in an implementation in the infection_monkey.system_info.collectors class, and override
- the 'collect' method. Don't forget to parse your results in the Monkey Island and to add the collector to the configuration
+ ABC for system info collection. See system_info_collector_handler for more info. Basically,
+ to implement a new system info
+ collector, inherit from this class in an implementation in the
+ infection_monkey.system_info.collectors class, and override
+ the 'collect' method. Don't forget to parse your results in the Monkey Island and to add the
+ collector to the configuration
as well - see monkey_island.cc.services.processing.system_info_collectors for examples.
See the Wiki page "How to add a new System Info Collector to the Monkey?" for a detailed guide.
diff --git a/monkey/infection_monkey/system_info/system_info_collectors_handler.py b/monkey/infection_monkey/system_info/system_info_collectors_handler.py
index 9c883084c..c54286931 100644
--- a/monkey/infection_monkey/system_info/system_info_collectors_handler.py
+++ b/monkey/infection_monkey/system_info/system_info_collectors_handler.py
@@ -24,9 +24,8 @@ class SystemInfoCollectorsHandler(object):
# If we failed one collector, no need to stop execution. Log and continue.
LOG.error("Collector {} failed. Error info: {}".format(collector.name, e))
LOG.info(
- "All system info collectors executed. Total {} executed, out of which {} collected successfully.".format(
- len(self.collectors_list), successful_collections
- )
+ "All system info collectors executed. Total {} executed, out of which {} "
+ "collected successfully.".format(len(self.collectors_list), successful_collections)
)
SystemInfoTelem({"collectors": system_info_telemetry}).send()
diff --git a/monkey/infection_monkey/system_info/windows_cred_collector/test_pypykatz_handler.py b/monkey/infection_monkey/system_info/windows_cred_collector/test_pypykatz_handler.py
index f2d9565b1..4d3259e67 100644
--- a/monkey/infection_monkey/system_info/windows_cred_collector/test_pypykatz_handler.py
+++ b/monkey/infection_monkey/system_info/windows_cred_collector/test_pypykatz_handler.py
@@ -56,7 +56,8 @@ class TestPypykatzHandler(TestCase):
{
"credtype": "dpapi",
"key_guid": "9123-123ae123de4-121239-3123-421f",
- "masterkey": "6e81d0cfd5e9ec083cfbdaf4d25b9cc9cc6b72947f5e80920034d1275d8613532025975e"
+ "masterkey": "6e81d0cfd5e9ec083cfbdaf4d25b9cc9cc6b7294"
+ "7f5e80920034d1275d8613532025975e"
"f051e891c30e6e9af6db54500fedfed1c968389bf6262c77fbaa68c9",
"sha1_masterkey": "bbdabc3cd2f6bcbe3e2cee6ce4ce4cebcef4c6da",
"luid": 123086,
@@ -64,7 +65,8 @@ class TestPypykatzHandler(TestCase):
{
"credtype": "dpapi",
"key_guid": "9123-123ae123de4-121239-3123-421f",
- "masterkey": "6e81d0cfd5e9ec083cfbdaf4d25b9cc9cc6b72947f5e80920034d1275d8613532025975e"
+ "masterkey": "6e81d0cfd5e9ec083cfbdaf4d25b9cc9cc6b729"
+ "47f5e80920034d1275d8613532025975e"
"f051e891c30e6e9af6db54500fedfed1c968389bf6262c77fbaa68c9",
"sha1_masterkey": "bbdabc3cd2f6bcbe3e2cee6ce4ce4cebcef4c6da",
"luid": 123086,
@@ -72,7 +74,8 @@ class TestPypykatzHandler(TestCase):
{
"credtype": "dpapi",
"key_guid": "9123-123ae123de4-121239-3123-421f",
- "masterkey": "6e81d0cfd5e9ec083cfbdaf4d25b9cc9cc6b72947f5e80920034d1275d8613532025975e"
+ "masterkey": "6e81d0cfd5e9ec083cfbdaf4d25b9cc9cc6b72"
+ "947f5e80920034d1275d8613532025975e"
"f051e891c30e6e9af6db54500fedfed1c968389bf6262c77fbaa68c9",
"sha1_masterkey": "bbdabc3cd2f6bcbe3e2cee6ce4ce4cebcef4c6da",
"luid": 123086,
@@ -80,7 +83,8 @@ class TestPypykatzHandler(TestCase):
{
"credtype": "dpapi",
"key_guid": "9123-123ae123de4-121239-3123-421f",
- "masterkey": "6e81d0cfd5e9ec083cfbdaf4d25b9cc9cc6b72947f5e80920034d1275d8613532025975e"
+ "masterkey": "6e81d0cfd5e9ec083cfbdaf4d25b9cc9cc6b729"
+ "47f5e80920034d1275d8613532025975e"
"f051e891c30e6e9af6db54500fedfed1c968389bf6262c77fbaa68c9",
"sha1_masterkey": "bbdabc3cd2f6bcbe3e2cee6ce4ce4cebcef4c6da",
"luid": 123086,
diff --git a/monkey/infection_monkey/telemetry/attack/t1064_telem.py b/monkey/infection_monkey/telemetry/attack/t1064_telem.py
index f8cdf379c..de2333ca8 100644
--- a/monkey/infection_monkey/telemetry/attack/t1064_telem.py
+++ b/monkey/infection_monkey/telemetry/attack/t1064_telem.py
@@ -3,7 +3,8 @@ from infection_monkey.telemetry.attack.usage_telem import AttackTelem
class T1064Telem(AttackTelem):
def __init__(self, status, usage):
- # TODO: rename parameter "usage" to avoid confusion with parameter "usage" in UsageTelem techniques
+ # TODO: rename parameter "usage" to avoid confusion with parameter "usage" in UsageTelem
+ # techniques
"""
T1064 telemetry.
:param status: ScanStatus of technique
diff --git a/monkey/infection_monkey/telemetry/attack/t1197_telem.py b/monkey/infection_monkey/telemetry/attack/t1197_telem.py
index c5c98a9d0..e9fb7fca6 100644
--- a/monkey/infection_monkey/telemetry/attack/t1197_telem.py
+++ b/monkey/infection_monkey/telemetry/attack/t1197_telem.py
@@ -5,7 +5,8 @@ __author__ = "itay.mizeretz"
class T1197Telem(VictimHostTelem):
def __init__(self, status, machine, usage):
- # TODO: rename parameter "usage" to avoid confusion with parameter "usage" in UsageTelem techniques
+ # TODO: rename parameter "usage" to avoid confusion with parameter "usage" in UsageTelem
+ # techniques
"""
T1197 telemetry.
:param status: ScanStatus of technique
diff --git a/monkey/infection_monkey/telemetry/base_telem.py b/monkey/infection_monkey/telemetry/base_telem.py
index e179a24df..0fcf4b203 100644
--- a/monkey/infection_monkey/telemetry/base_telem.py
+++ b/monkey/infection_monkey/telemetry/base_telem.py
@@ -9,6 +9,7 @@ LOGGED_DATA_LENGTH = 300 # How many characters of telemetry data will be logged
__author__ = "itay.mizeretz"
+
# TODO: Rework the interface for telemetry; this class has too many responsibilities
# (i.e. too many reasons to change):
#
diff --git a/monkey/infection_monkey/tunnel.py b/monkey/infection_monkey/tunnel.py
index 83e03fec2..3fbfc5bdb 100644
--- a/monkey/infection_monkey/tunnel.py
+++ b/monkey/infection_monkey/tunnel.py
@@ -173,7 +173,8 @@ class MonkeyTunnel(Thread):
LOG.info("Stopping tunnel, waiting for clients: %s" % repr(self._clients))
- # wait till all of the tunnel clients has been disconnected, or no one used the tunnel in QUIT_TIMEOUT seconds
+ # wait till all of the tunnel clients has been disconnected, or no one used the tunnel in
+ # QUIT_TIMEOUT seconds
while self._clients and (time.time() - get_last_serve_time() < QUIT_TIMEOUT):
try:
search, address = self._broad_sock.recvfrom(BUFFER_READ)
diff --git a/monkey/infection_monkey/utils/auto_new_user.py b/monkey/infection_monkey/utils/auto_new_user.py
index 26c1c837c..f3ebda0af 100644
--- a/monkey/infection_monkey/utils/auto_new_user.py
+++ b/monkey/infection_monkey/utils/auto_new_user.py
@@ -8,8 +8,10 @@ class AutoNewUser(metaclass=abc.ABCMeta):
"""
RAII object to use for creating and using a new user. Use with `with`.
User will be created when the instance is instantiated.
- User will be available for use (log on for Windows, for example) at the start of the `with` scope.
- User will be removed (deactivated and deleted for Windows, for example) at the end of said `with` scope.
+ User will be available for use (log on for Windows, for example) at the start of the `with`
+ scope.
+ User will be removed (deactivated and deleted for Windows, for example) at the end of said
+ `with` scope.
Example:
# Created # Logged on
diff --git a/monkey/infection_monkey/utils/auto_new_user_factory.py b/monkey/infection_monkey/utils/auto_new_user_factory.py
index 898226d46..22c57c578 100644
--- a/monkey/infection_monkey/utils/auto_new_user_factory.py
+++ b/monkey/infection_monkey/utils/auto_new_user_factory.py
@@ -5,13 +5,15 @@ from infection_monkey.utils.windows.users import AutoNewWindowsUser
def create_auto_new_user(username, password, is_windows=is_windows_os()):
"""
- Factory method for creating an AutoNewUser. See AutoNewUser's documentation for more information.
+ Factory method for creating an AutoNewUser. See AutoNewUser's documentation for more
+ information.
Example usage:
with create_auto_new_user(username, PASSWORD) as new_user:
...
:param username: The username of the new user.
:param password: The password of the new user.
- :param is_windows: If True, a new Windows user is created. Otherwise, a Linux user is created. Leave blank for
+ :param is_windows: If True, a new Windows user is created. Otherwise, a Linux user is
+ created. Leave blank for
automatic detection.
:return: The new AutoNewUser object - use with a `with` scope.
"""
diff --git a/monkey/infection_monkey/utils/linux/users.py b/monkey/infection_monkey/utils/linux/users.py
index 9144a24ec..fa91fced8 100644
--- a/monkey/infection_monkey/utils/linux/users.py
+++ b/monkey/infection_monkey/utils/linux/users.py
@@ -14,7 +14,8 @@ def get_linux_commands_to_add_user(username):
"-M", # Do not create homedir
"--expiredate", # The date on which the user account will be disabled.
datetime.datetime.today().strftime("%Y-%m-%d"),
- "--inactive", # The number of days after a password expires until the account is permanently disabled.
+ # The number of days after a password expires until the account is permanently disabled.
+ "--inactive",
"0", # A value of 0 disables the account as soon as the password has expired
"-c", # Comment
"MONKEY_USER", # Comment
diff --git a/monkey/infection_monkey/utils/windows/users.py b/monkey/infection_monkey/utils/windows/users.py
index 9e5913673..d27b74547 100644
--- a/monkey/infection_monkey/utils/windows/users.py
+++ b/monkey/infection_monkey/utils/windows/users.py
@@ -47,12 +47,14 @@ class AutoNewWindowsUser(AutoNewUser):
import win32security
try:
- # Logon as new user: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-logonusera
+ # Logon as new user: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf
+ # -winbase-logonusera
self.logon_handle = win32security.LogonUser(
self.username,
".", # Use current domain.
self.password,
- win32con.LOGON32_LOGON_INTERACTIVE, # Logon type - interactive (normal user), since we're using a shell.
+ # Logon type - interactive (normal user), since we're using a shell.
+ win32con.LOGON32_LOGON_INTERACTIVE,
win32con.LOGON32_PROVIDER_DEFAULT,
) # Which logon provider to use - whatever Windows offers.
except Exception as err:
@@ -83,9 +85,13 @@ class AutoNewWindowsUser(AutoNewUser):
"Waiting for process to finish. Timeout: {}ms".format(WAIT_TIMEOUT_IN_MILLISECONDS)
)
- # https://social.msdn.microsoft.com/Forums/vstudio/en-US/b6d6a7ae-71e9-4edb-ac8f-408d2a41750d/what-events-on-a-process-handle-signal-satisify-waitforsingleobject?forum=vcgeneral
- # Ignoring return code, as we'll use `GetExitCode` to determine the state of the process later.
- _ = win32event.WaitForSingleObject( # Waits until the specified object is signaled, or time-out.
+ # https://social.msdn.microsoft.com/Forums/vstudio/en-US/b6d6a7ae-71e9-4edb-ac8f
+ # -408d2a41750d/what-events-on-a-process-handle-signal-satisify-waitforsingleobject
+ # ?forum=vcgeneral
+ # Ignoring return code, as we'll use `GetExitCode` to determine the state of the
+ # process later.
+ _ = win32event.WaitForSingleObject(
+ # Waits until the specified object is signaled, or time-out.
process_handle, # Ping process handle
WAIT_TIMEOUT_IN_MILLISECONDS, # Timeout in milliseconds
)
diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py
index b06494c21..1d9b7ce79 100644
--- a/monkey/monkey_island/cc/app.py
+++ b/monkey/monkey_island/cc/app.py
@@ -62,11 +62,13 @@ def serve_static_file(static_path):
try:
return send_from_directory(os.path.join(MONKEY_ISLAND_ABS_PATH, "cc/ui/dist"), static_path)
except NotFound:
- # Because react uses various urls for same index page, this is probably the user's intention.
+ # Because react uses various urls for same index page, this is probably the user's
+ # intention.
if static_path == HOME_FILE:
flask_restful.abort(
Response(
- "Page not found. Make sure you ran the npm script and the cwd is monkey\\monkey.",
+ "Page not found. Make sure you ran the npm script and the cwd is "
+ "monkey\\monkey.",
500,
)
)
@@ -82,11 +84,13 @@ def init_app_config(app, mongo_url):
# See https://flask-jwt-extended.readthedocs.io/en/stable/options
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = env_singleton.env.get_auth_expiration_time()
- # Invalidate the signature of JWTs if the server process restarts. This avoids the edge case of getting a JWT,
+ # Invalidate the signature of JWTs if the server process restarts. This avoids the edge case
+ # of getting a JWT,
# deciding to reset credentials and then still logging in with the old JWT.
app.config["JWT_SECRET_KEY"] = str(uuid.uuid4())
- # By default, Flask sorts keys of JSON objects alphabetically, which messes with the ATT&CK matrix in the
+ # By default, Flask sorts keys of JSON objects alphabetically, which messes with the ATT&CK
+ # matrix in the
# configuration. See https://flask.palletsprojects.com/en/1.1.x/config/#JSON_SORT_KEYS.
app.config["JSON_SORT_KEYS"] = False
@@ -101,7 +105,8 @@ def init_app_services(app):
database.init()
Database.init_db()
- # If running on AWS, this will initialize the instance data, which is used "later" in the execution of the island.
+ # If running on AWS, this will initialize the instance data, which is used "later" in the
+ # execution of the island.
RemoteRunAwsService.init()
diff --git a/monkey/monkey_island/cc/environment/aws.py b/monkey/monkey_island/cc/environment/aws.py
index 89e7b428d..c11e40436 100644
--- a/monkey/monkey_island/cc/environment/aws.py
+++ b/monkey/monkey_island/cc/environment/aws.py
@@ -5,7 +5,6 @@ __author__ = "itay.mizeretz"
class AwsEnvironment(Environment):
-
_credentials_required = True
def __init__(self, config):
diff --git a/monkey/monkey_island/cc/environment/password.py b/monkey/monkey_island/cc/environment/password.py
index 88d1f76f0..4a8a6d855 100644
--- a/monkey/monkey_island/cc/environment/password.py
+++ b/monkey/monkey_island/cc/environment/password.py
@@ -4,7 +4,6 @@ __author__ = "itay.mizeretz"
class PasswordEnvironment(Environment):
-
_credentials_required = True
def get_auth_users(self):
diff --git a/monkey/monkey_island/cc/environment/standard.py b/monkey/monkey_island/cc/environment/standard.py
index 8135e8e3f..35ca84a34 100644
--- a/monkey/monkey_island/cc/environment/standard.py
+++ b/monkey/monkey_island/cc/environment/standard.py
@@ -5,7 +5,6 @@ __author__ = "itay.mizeretz"
class StandardEnvironment(Environment):
-
_credentials_required = False
# SHA3-512 of '1234567890!@#$%^&*()_nothing_up_my_sleeve_1234567890!@#$%^&*()'
diff --git a/monkey/monkey_island/cc/environment/testing.py b/monkey/monkey_island/cc/environment/testing.py
index 2dd34a920..efa323fe8 100644
--- a/monkey/monkey_island/cc/environment/testing.py
+++ b/monkey/monkey_island/cc/environment/testing.py
@@ -4,7 +4,8 @@ from monkey_island.cc.environment import Environment, EnvironmentConfig
class TestingEnvironment(Environment):
"""
Use this environment for running Unit Tests.
- This will cause all mongo connections to happen via `mongomock` instead of using an actual mongodb instance.
+ This will cause all mongo connections to happen via `mongomock` instead of using an actual
+ mongodb instance.
"""
_credentials_required = True
diff --git a/monkey/monkey_island/cc/main.py b/monkey/monkey_island/cc/main.py
index 75d105f70..ba5ee856c 100644
--- a/monkey/monkey_island/cc/main.py
+++ b/monkey/monkey_island/cc/main.py
@@ -5,7 +5,8 @@ import time
from pathlib import Path
from threading import Thread
-# Add the monkey_island directory to the path, to make sure imports that don't start with "monkey_island." work.
+# Add the monkey_island directory to the path, to make sure imports that don't start with
+# "monkey_island." work.
from gevent.pywsgi import WSGIServer
MONKEY_ISLAND_DIR_BASE_PATH = str(Path(__file__).parent.parent)
@@ -48,7 +49,6 @@ def main(should_setup_only=False, server_config_filename=DEFAULT_SERVER_CONFIG_P
def start_island_server(should_setup_only):
-
mongo_url = os.environ.get("MONGO_URL", env_singleton.env.get_mongo_url())
wait_for_mongo_db_server(mongo_url)
assert_mongo_db_version(mongo_url)
diff --git a/monkey/monkey_island/cc/models/__init__.py b/monkey/monkey_island/cc/models/__init__.py
index c668be7ae..602d815c4 100644
--- a/monkey/monkey_island/cc/models/__init__.py
+++ b/monkey/monkey_island/cc/models/__init__.py
@@ -4,7 +4,8 @@ import monkey_island.cc.environment.environment_singleton as env_singleton
from .command_control_channel import CommandControlChannel # noqa: F401
-# Order of importing matters here, for registering the embedded and referenced documents before using them.
+# Order of importing matters here, for registering the embedded and referenced documents before
+# using them.
from .config import Config # noqa: F401
from .creds import Creds # noqa: F401
from .monkey import Monkey # noqa: F401
diff --git a/monkey/monkey_island/cc/models/attack/attack_mitigations.py b/monkey/monkey_island/cc/models/attack/attack_mitigations.py
index 3df6b839d..271b68461 100644
--- a/monkey/monkey_island/cc/models/attack/attack_mitigations.py
+++ b/monkey/monkey_island/cc/models/attack/attack_mitigations.py
@@ -8,7 +8,6 @@ from monkey_island.cc.services.attack.test_mitre_api_interface import MitreApiIn
class AttackMitigations(Document):
-
COLLECTION_NAME = "attack_mitigations"
technique_id = StringField(required=True, primary_key=True)
diff --git a/monkey/monkey_island/cc/models/attack/mitigation.py b/monkey/monkey_island/cc/models/attack/mitigation.py
index 3c096b618..626c1800a 100644
--- a/monkey/monkey_island/cc/models/attack/mitigation.py
+++ b/monkey/monkey_island/cc/models/attack/mitigation.py
@@ -5,7 +5,6 @@ from monkey_island.cc.services.attack.test_mitre_api_interface import MitreApiIn
class Mitigation(EmbeddedDocument):
-
name = StringField(required=True)
description = StringField(required=True)
url = StringField()
diff --git a/monkey/monkey_island/cc/models/edge.py b/monkey/monkey_island/cc/models/edge.py
index bb4f8a2c6..88858cfcb 100644
--- a/monkey/monkey_island/cc/models/edge.py
+++ b/monkey/monkey_island/cc/models/edge.py
@@ -2,7 +2,6 @@ from mongoengine import BooleanField, Document, DynamicField, ListField, ObjectI
class Edge(Document):
-
meta = {"allow_inheritance": True}
# SCHEMA
diff --git a/monkey/monkey_island/cc/models/monkey.py b/monkey/monkey_island/cc/models/monkey.py
index 90255099e..3bb3c57c9 100644
--- a/monkey/monkey_island/cc/models/monkey.py
+++ b/monkey/monkey_island/cc/models/monkey.py
@@ -26,8 +26,10 @@ MAX_MONKEYS_AMOUNT_TO_CACHE = 100
class Monkey(Document):
"""
This class has 2 main section:
- * The schema section defines the DB fields in the document. This is the data of the object.
- * The logic section defines complex questions we can ask about a single document which are asked multiple
+ * The schema section defines the DB fields in the document. This is the data of the
+ object.
+ * The logic section defines complex questions we can ask about a single document which
+ are asked multiple
times, somewhat like an API.
"""
@@ -42,7 +44,8 @@ class Monkey(Document):
ip_addresses = ListField(StringField())
keepalive = DateTimeField()
modifytime = DateTimeField()
- # TODO make "parent" an embedded document, so this can be removed and the schema explained (and validated) verbosely.
+ # TODO make "parent" an embedded document, so this can be removed and the schema explained (
+ # and validated) verbosely.
# This is a temporary fix, since mongoengine doesn't allow for lists of strings to be null
# (even with required=False of null=True).
# See relevant issue: https://github.com/MongoEngine/mongoengine/issues/1904
@@ -146,7 +149,8 @@ class Monkey(Document):
return {"ips": self.ip_addresses, "hostname": self.hostname}
@ring.lru(
- expire=1 # data has TTL of 1 second. This is useful for rapid calls for report generation.
+ # data has TTL of 1 second. This is useful for rapid calls for report generation.
+ expire=1
)
@staticmethod
def is_monkey(object_id):
diff --git a/monkey/monkey_island/cc/models/monkey_ttl.py b/monkey/monkey_island/cc/models/monkey_ttl.py
index e3025c250..74d38c639 100644
--- a/monkey/monkey_island/cc/models/monkey_ttl.py
+++ b/monkey/monkey_island/cc/models/monkey_ttl.py
@@ -7,10 +7,12 @@ class MonkeyTtl(Document):
"""
This model represents the monkey's TTL, and is referenced by the main Monkey document.
See https://docs.mongodb.com/manual/tutorial/expire-data/ and
- https://stackoverflow.com/questions/55994379/mongodb-ttl-index-doesnt-delete-expired-documents/56021663#56021663
+ https://stackoverflow.com/questions/55994379/mongodb-ttl-index-doesnt-delete-expired
+ -documents/56021663#56021663
for more information about how TTL indexing works and why this class is set up the way it is.
- If you wish to use this class, you can create it using the create_ttl_expire_in(seconds) function.
+ If you wish to use this class, you can create it using the create_ttl_expire_in(seconds)
+ function.
If you wish to create an instance of this class directly, see the inner implementation of
create_ttl_expire_in(seconds) to see how to do so.
"""
@@ -20,11 +22,13 @@ class MonkeyTtl(Document):
"""
Initializes a TTL object which will expire in expire_in_seconds seconds from when created.
Remember to call .save() on the object after creation.
- :param expiry_in_seconds: How long should the TTL be in the DB, in seconds. Please take into consideration
+ :param expiry_in_seconds: How long should the TTL be in the DB, in seconds. Please take
+ into consideration
that the cleanup thread of mongo might take extra time to delete the TTL from the DB.
"""
# Using UTC to make the mongodb TTL feature work. See
- # https://stackoverflow.com/questions/55994379/mongodb-ttl-index-doesnt-delete-expired-documents.
+ # https://stackoverflow.com/questions/55994379/mongodb-ttl-index-doesnt-delete-expired
+ # -documents.
return MonkeyTtl(expire_at=datetime.utcnow() + timedelta(seconds=expiry_in_seconds))
meta = {"indexes": [{"name": "TTL_index", "fields": ["expire_at"], "expireAfterSeconds": 0}]}
@@ -35,7 +39,8 @@ class MonkeyTtl(Document):
def create_monkey_ttl_document(expiry_duration_in_seconds):
"""
Create a new Monkey TTL document and save it as a document.
- :param expiry_duration_in_seconds: How long should the TTL last for. THIS IS A LOWER BOUND - depends on mongodb
+ :param expiry_duration_in_seconds: How long should the TTL last for. THIS IS A LOWER BOUND -
+ depends on mongodb
performance.
:return: The TTL document. To get its ID use `.id`.
"""
diff --git a/monkey/monkey_island/cc/models/test_monkey.py b/monkey/monkey_island/cc/models/test_monkey.py
index d21776f6f..92ad2fb90 100644
--- a/monkey/monkey_island/cc/models/test_monkey.py
+++ b/monkey/monkey_island/cc/models/test_monkey.py
@@ -26,7 +26,8 @@ class TestMonkey:
mia_monkey_ttl.save()
mia_monkey = Monkey(guid=str(uuid.uuid4()), dead=False, ttl_ref=mia_monkey_ttl.id)
mia_monkey.save()
- # Emulate timeout - ttl is manually deleted here, since we're using mongomock and not a real mongo instance.
+ # Emulate timeout - ttl is manually deleted here, since we're using mongomock and not a
+ # real mongo instance.
sleep(1)
mia_monkey_ttl.delete()
diff --git a/monkey/monkey_island/cc/models/zero_trust/event.py b/monkey/monkey_island/cc/models/zero_trust/event.py
index 727ec9a2a..3ffdb02b9 100644
--- a/monkey/monkey_island/cc/models/zero_trust/event.py
+++ b/monkey/monkey_island/cc/models/zero_trust/event.py
@@ -7,12 +7,15 @@ import common.common_consts.zero_trust_consts as zero_trust_consts
class Event(EmbeddedDocument):
"""
- This model represents a single event within a Finding (it is an EmbeddedDocument within Finding). It is meant to
+ This model represents a single event within a Finding (it is an EmbeddedDocument within
+ Finding). It is meant to
hold a detail of the Finding.
This class has 2 main section:
- * The schema section defines the DB fields in the document. This is the data of the object.
- * The logic section defines complex questions we can ask about a single document which are asked multiple
+ * The schema section defines the DB fields in the document. This is the data of the
+ object.
+ * The logic section defines complex questions we can ask about a single document which
+ are asked multiple
times, or complex action we will perform - somewhat like an API.
"""
diff --git a/monkey/monkey_island/cc/models/zero_trust/finding.py b/monkey/monkey_island/cc/models/zero_trust/finding.py
index 7ddf643fe..b1508430f 100644
--- a/monkey/monkey_island/cc/models/zero_trust/finding.py
+++ b/monkey/monkey_island/cc/models/zero_trust/finding.py
@@ -12,20 +12,24 @@ import common.common_consts.zero_trust_consts as zero_trust_consts
class Finding(Document):
"""
- This model represents a Zero-Trust finding: A result of a test the monkey/island might perform to see if a
+ This model represents a Zero-Trust finding: A result of a test the monkey/island might
+ perform to see if a
specific principle of zero trust is upheld or broken.
Findings might have the following statuses:
Failed ❌
Meaning that we are sure that something is wrong (example: segmentation issue).
Verify ⁉
- Meaning that we need the user to check something himself (example: 2FA logs, AV missing).
+ Meaning that we need the user to check something himself (example: 2FA logs,
+ AV missing).
Passed ✔
Meaning that we are sure that something is correct (example: Monkey failed exploiting).
This class has 2 main section:
- * The schema section defines the DB fields in the document. This is the data of the object.
- * The logic section defines complex questions we can ask about a single document which are asked multiple
+ * The schema section defines the DB fields in the document. This is the data of the
+ object.
+ * The logic section defines complex questions we can ask about a single document which
+ are asked multiple
times, or complex action we will perform - somewhat like an API.
"""
diff --git a/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py b/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py
index 62cfda504..3568e0ee1 100644
--- a/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py
+++ b/monkey/monkey_island/cc/models/zero_trust/monkey_finding_details.py
@@ -8,7 +8,6 @@ from monkey_island.cc.models.zero_trust.event import Event
class MonkeyFindingDetails(Document):
-
# SCHEMA
events = EmbeddedDocumentListField(document_type=Event, required=False)
diff --git a/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py
index cbc8c5f29..9f2b24d9d 100644
--- a/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py
+++ b/monkey/monkey_island/cc/models/zero_trust/scoutsuite_finding_details.py
@@ -4,7 +4,6 @@ from monkey_island.cc.models.zero_trust.scoutsuite_rule import ScoutSuiteRule
class ScoutSuiteFindingDetails(Document):
-
# SCHEMA
scoutsuite_rules = EmbeddedDocumentListField(document_type=ScoutSuiteRule, required=False)
diff --git a/monkey/monkey_island/cc/resources/T1216_pba_file_download.py b/monkey/monkey_island/cc/resources/T1216_pba_file_download.py
index 0ac69df6d..de79d2e72 100644
--- a/monkey/monkey_island/cc/resources/T1216_pba_file_download.py
+++ b/monkey/monkey_island/cc/resources/T1216_pba_file_download.py
@@ -8,7 +8,8 @@ from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH
class T1216PBAFileDownload(flask_restful.Resource):
"""
- File download endpoint used by monkey to download executable file for T1216 ("Signed Script Proxy Execution" PBA)
+ File download endpoint used by monkey to download executable file for T1216 ("Signed Script
+ Proxy Execution" PBA)
"""
def get(self):
diff --git a/monkey/monkey_island/cc/resources/auth/auth.py b/monkey/monkey_island/cc/resources/auth/auth.py
index 47d68fb1a..29d2d9e89 100644
--- a/monkey/monkey_island/cc/resources/auth/auth.py
+++ b/monkey/monkey_island/cc/resources/auth/auth.py
@@ -25,7 +25,8 @@ def init_jwt(app):
class Authenticate(flask_restful.Resource):
"""
- Resource for user authentication. The user provides the username and hashed password and we give them a JWT.
+ Resource for user authentication. The user provides the username and hashed password and we
+ give them a JWT.
See `AuthService.js` file for the frontend counterpart for this code.
"""
@@ -67,7 +68,8 @@ def jwt_required(fn):
try:
flask_jwt_extended.verify_jwt_in_request()
return fn(*args, **kwargs)
- # Catch authentication related errors in the verification or inside the called function. All other exceptions propagate
+ # Catch authentication related errors in the verification or inside the called function.
+ # All other exceptions propagate
except (JWTExtendedException, PyJWTError) as e:
return make_response({"error": f"Authentication error: {str(e)}"}, 401)
diff --git a/monkey/monkey_island/cc/resources/bootloader_test.py b/monkey/monkey_island/cc/resources/bootloader_test.py
index 83d780aa4..d8fd05451 100644
--- a/monkey/monkey_island/cc/resources/bootloader_test.py
+++ b/monkey/monkey_island/cc/resources/bootloader_test.py
@@ -43,12 +43,18 @@ class TestBootloader(TestCase):
b'{\x00"\x00s\x00y\x00s\x00t\x00e\x00m\x00"\x00:\x00"\x00w\x00i\x00n\x00d\x00o'
b'\x00w\x00s\x00"\x00,\x00 \x00"\x00o\x00s\x00_\x00v\x00e\x00r\x00s\x00i\x00o\x00n'
b'\x00"\x00:\x00"\x00w\x00i\x00n\x00d\x00o\x00w\x00s\x008\x00_\x00o\x00r\x00_\x00g\x00r'
- b'\x00e\x00a\x00t\x00e\x00r\x00"\x00,\x00 \x00"\x00h\x00o\x00s\x00t\x00n\x00a\x00m\x00e\x00"'
- b'\x00:\x00"\x00D\x00E\x00S\x00K\x00T\x00O\x00P\x00-\x00P\x00J\x00H\x00U\x003\x006\x00B\x00"'
- b'\x00,\x00 \x00"\x00t\x00u\x00n\x00n\x00e\x00l\x00"\x00:\x00f\x00a\x00l\x00s\x00e\x00,\x00 '
- b'\x00"\x00i\x00p\x00s\x00"\x00:\x00 \x00[\x00"\x001\x009\x002\x00.\x001\x006\x008\x00.\x005'
- b'\x006\x00.\x001\x00"\x00,\x00 \x00"\x001\x009\x002\x00.\x001\x006\x008\x00.\x002\x004\x009'
- b'\x00.\x001\x00"\x00,\x00 \x00"\x001\x009\x002\x00.\x001\x006\x008\x00.\x002\x001\x007\x00.'
+ b'\x00e\x00a\x00t\x00e\x00r\x00"\x00,\x00 '
+ b'\x00"\x00h\x00o\x00s\x00t\x00n\x00a\x00m\x00e\x00"'
+ b'\x00:\x00"\x00D\x00E\x00S\x00K\x00T\x00O\x00P\x00-\x00P\x00J\x00H\x00U\x003\x006'
+ b'\x00B\x00"'
+ b'\x00,\x00 \x00"\x00t\x00u\x00n\x00n\x00e\x00l\x00"\x00:\x00f\x00a\x00l\x00s\x00e'
+ b"\x00,\x00 "
+ b'\x00"\x00i\x00p\x00s\x00"\x00:\x00 \x00['
+ b'\x00"\x001\x009\x002\x00.\x001\x006\x008\x00.\x005'
+ b'\x006\x00.\x001\x00"\x00,\x00 '
+ b'\x00"\x001\x009\x002\x00.\x001\x006\x008\x00.\x002\x004\x009'
+ b'\x00.\x001\x00"\x00,\x00 '
+ b'\x00"\x001\x009\x002\x00.\x001\x006\x008\x00.\x002\x001\x007\x00.'
b'\x001\x00"\x00]\x00}\x00'
)
diff --git a/monkey/monkey_island/cc/resources/environment.py b/monkey/monkey_island/cc/resources/environment.py
index 03333b029..feb0c138c 100644
--- a/monkey/monkey_island/cc/resources/environment.py
+++ b/monkey/monkey_island/cc/resources/environment.py
@@ -16,6 +16,7 @@ class Environment(flask_restful.Resource):
if env_singleton.env.needs_registration():
env_singleton.set_to_standard()
logger.warning(
- "No user registered, Island on standard mode - no credentials required to access."
+ "No user registered, Island on standard mode - no credentials required to "
+ "access."
)
return {}
diff --git a/monkey/monkey_island/cc/resources/local_run.py b/monkey/monkey_island/cc/resources/local_run.py
index 727357ab3..d9dfc0e39 100644
--- a/monkey/monkey_island/cc/resources/local_run.py
+++ b/monkey/monkey_island/cc/resources/local_run.py
@@ -17,7 +17,6 @@ from monkey_island.cc.services.utils.network_utils import local_ip_addresses
__author__ = "Barak"
-
logger = logging.getLogger(__name__)
@@ -34,7 +33,8 @@ def run_local_monkey():
monkey_path = os.path.join(MONKEY_ISLAND_ABS_PATH, "cc", "binaries", result["filename"])
target_path = os.path.join(env_singleton.env.get_config().data_dir_abs_path, result["filename"])
- # copy the executable to temp path (don't run the monkey from its current location as it may delete itself)
+ # copy the executable to temp path (don't run the monkey from its current location as it may
+ # delete itself)
try:
copyfile(monkey_path, target_path)
os.chmod(target_path, stat.S_IRWXU | stat.S_IRWXG)
diff --git a/monkey/monkey_island/cc/resources/monkey_download.py b/monkey/monkey_island/cc/resources/monkey_download.py
index 5620425aa..c2b633c8e 100644
--- a/monkey/monkey_island/cc/resources/monkey_download.py
+++ b/monkey/monkey_island/cc/resources/monkey_download.py
@@ -65,9 +65,8 @@ def get_monkey_executable(host_os, machine):
logger.info("Monkey exec found for os: {0} and machine: {1}".format(host_os, machine))
return download
logger.warning(
- "No monkey executables could be found for the host os or machine or both: host_os: {0}, machine: {1}".format(
- host_os, machine
- )
+ "No monkey executables could be found for the host os or machine or both: host_os: {"
+ "0}, machine: {1}".format(host_os, machine)
)
return None
@@ -103,7 +102,8 @@ class MonkeyDownload(flask_restful.Resource):
@staticmethod
def log_executable_hashes():
"""
- Logs all the hashes of the monkey executables for debugging ease (can check what Monkey version you have etc.).
+ Logs all the hashes of the monkey executables for debugging ease (can check what Monkey
+ version you have etc.).
"""
filenames = set([x["filename"] for x in MONKEY_DOWNLOADS])
for filename in filenames:
diff --git a/monkey/monkey_island/cc/resources/test/clear_caches.py b/monkey/monkey_island/cc/resources/test/clear_caches.py
index 04c6b31d8..b8ebeb056 100644
--- a/monkey/monkey_island/cc/resources/test/clear_caches.py
+++ b/monkey/monkey_island/cc/resources/test/clear_caches.py
@@ -13,7 +13,8 @@ logger = logging.getLogger(__name__)
class ClearCaches(flask_restful.Resource):
"""
- Used for timing tests - we want to get actual execution time of functions in BlackBox without caching -
+ Used for timing tests - we want to get actual execution time of functions in BlackBox without
+ caching -
so we use this to clear the caches.
:note: DO NOT CALL THIS IN PRODUCTION CODE as this will slow down the user experience.
"""
diff --git a/monkey/monkey_island/cc/resources/test/utils/telem_store.py b/monkey/monkey_island/cc/resources/test/utils/telem_store.py
index 5920c8da3..574712cda 100644
--- a/monkey/monkey_island/cc/resources/test/utils/telem_store.py
+++ b/monkey/monkey_island/cc/resources/test/utils/telem_store.py
@@ -12,13 +12,11 @@ from monkey_island.cc.services.config import ConfigService
TELEM_SAMPLE_DIR = "./telem_sample"
MAX_SAME_CATEGORY_TELEMS = 10000
-
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class TestTelemStore:
-
TELEMS_EXPORTED = False
@staticmethod
diff --git a/monkey/monkey_island/cc/services/attack/attack_config.py b/monkey/monkey_island/cc/services/attack/attack_config.py
index faff5f71b..97eea098d 100644
--- a/monkey/monkey_island/cc/services/attack/attack_config.py
+++ b/monkey/monkey_island/cc/services/attack/attack_config.py
@@ -63,7 +63,8 @@ class AttackConfig(object):
@staticmethod
def set_arrays(attack_techniques, monkey_config, monkey_schema):
"""
- Sets exploiters/scanners/PBAs and other array type fields in monkey's config according to ATT&CK matrix
+ Sets exploiters/scanners/PBAs and other array type fields in monkey's config according to
+ ATT&CK matrix
:param attack_techniques: ATT&CK techniques dict. Format: {'T1110': True, ...}
:param monkey_config: Monkey island's configuration
:param monkey_schema: Monkey configuration schema
@@ -83,7 +84,8 @@ class AttackConfig(object):
@staticmethod
def set_booleans(attack_techniques, monkey_config, monkey_schema):
"""
- Sets boolean type fields, like "should use mimikatz?" in monkey's config according to ATT&CK matrix
+ Sets boolean type fields, like "should use mimikatz?" in monkey's config according to
+ ATT&CK matrix
:param attack_techniques: ATT&CK techniques dict. Format: {'T1110': True, ...}
:param monkey_config: Monkey island's configuration
:param monkey_schema: Monkey configuration schema
@@ -94,9 +96,11 @@ class AttackConfig(object):
@staticmethod
def r_set_booleans(path, value, attack_techniques, monkey_config):
"""
- Recursively walks trough monkey configuration (DFS) to find which boolean fields needs to be set and sets them
+ Recursively walks trough monkey configuration (DFS) to find which boolean fields needs to
+ be set and sets them
according to ATT&CK matrix.
- :param path: Property names that leads to current value. E.g. ['monkey', 'system_info', 'should_use_mimikatz']
+ :param path: Property names that leads to current value. E.g. ['monkey', 'system_info',
+ 'should_use_mimikatz']
:param value: Value of config property
:param attack_techniques: ATT&CK techniques dict. Format: {'T1110': True, ...}
:param monkey_config: Monkey island's configuration
@@ -130,7 +134,8 @@ class AttackConfig(object):
def set_bool_conf_val(path, val, monkey_config):
"""
Changes monkey's configuration by setting one of its boolean fields value
- :param path: Path to boolean value in monkey's configuration. ['monkey', 'system_info', 'should_use_mimikatz']
+ :param path: Path to boolean value in monkey's configuration. ['monkey', 'system_info',
+ 'should_use_mimikatz']
:param val: Boolean
:param monkey_config: Monkey's configuration
"""
diff --git a/monkey/monkey_island/cc/services/attack/attack_schema.py b/monkey/monkey_island/cc/services/attack/attack_schema.py
index f19295c5a..af27808a9 100644
--- a/monkey/monkey_island/cc/services/attack/attack_schema.py
+++ b/monkey/monkey_island/cc/services/attack/attack_schema.py
@@ -13,7 +13,8 @@ SCHEMA = {
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1059",
- "description": "Adversaries may use command-line interfaces to interact with systems "
+ "description": "Adversaries may use command-line interfaces to interact with "
+ "systems "
"and execute other software during the course of an operation.",
},
"T1129": {
@@ -22,8 +23,10 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1129",
- "description": "The Windows module loader can be instructed to load DLLs from arbitrary "
- "local paths and arbitrary Universal Naming Convention (UNC) network paths.",
+ "description": "The Windows module loader can be instructed to load DLLs from "
+ "arbitrary "
+ "local paths and arbitrary Universal Naming Convention (UNC) "
+ "network paths.",
"depends_on": ["T1078", "T1003"],
},
"T1106": {
@@ -60,8 +63,10 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1035",
- "description": "Adversaries may execute a binary, command, or script via a method "
- "that interacts with Windows services, such as the Service Control Manager.",
+ "description": "Adversaries may execute a binary, command, or script via a "
+ "method "
+ "that interacts with Windows services, such as the Service "
+ "Control Manager.",
"depends_on": ["T1210"],
},
"T1154": {
@@ -70,7 +75,8 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1154",
- "description": "Adversaries can use the trap command to register code to be executed "
+ "description": "Adversaries can use the trap command to register code to be "
+ "executed "
"when the shell encounters specific interrupts.",
},
},
@@ -88,7 +94,8 @@ SCHEMA = {
"link": "https://attack.mitre.org/techniques/T1156",
"description": "Adversaries may abuse shell scripts by "
"inserting arbitrary shell commands to gain persistence, which "
- "would be executed every time the user logs in or opens a new shell.",
+ "would be executed every time the user logs in or opens a new "
+ "shell.",
"depends_on": ["T1504"],
},
"T1136": {
@@ -117,8 +124,10 @@ SCHEMA = {
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1168/",
"description": "Linux supports multiple methods for creating pre-scheduled and "
- "periodic background jobs. Job scheduling can be used by adversaries to "
- "schedule running malicious code at some specified date and time.",
+ "periodic background jobs. Job scheduling can be used by "
+ "adversaries to "
+ "schedule running malicious code at some specified date and "
+ "time.",
"depends_on": ["T1053"],
},
"T1504": {
@@ -138,9 +147,12 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1053",
- "description": "Windows utilities can be used to schedule programs or scripts to "
- "be executed at a date and time. An adversary may use task scheduling to "
- "execute programs at system startup or on a scheduled basis for persistence.",
+ "description": "Windows utilities can be used to schedule programs or scripts "
+ "to "
+ "be executed at a date and time. An adversary may use task "
+ "scheduling to "
+ "execute programs at system startup or on a scheduled basis for "
+ "persistence.",
"depends_on": ["T1168"],
},
"T1166": {
@@ -149,7 +161,8 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1166",
- "description": "Adversaries can set the setuid or setgid bits to get code running in "
+ "description": "Adversaries can set the setuid or setgid bits to get code "
+ "running in "
"a different user’s context.",
},
},
@@ -193,7 +206,8 @@ SCHEMA = {
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1222",
- "description": "Adversaries may modify file permissions/attributes to evade intended DACLs.",
+ "description": "Adversaries may modify file permissions/attributes to evade "
+ "intended DACLs.",
},
"T1099": {
"title": "Timestomping",
@@ -201,8 +215,10 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1099",
- "description": "Adversaries may modify file time attributes to hide new/changes to existing "
- "files to avoid attention from forensic investigators or file analysis tools.",
+ "description": "Adversaries may modify file time attributes to hide "
+ "new/changes to existing "
+ "files to avoid attention from forensic investigators or file "
+ "analysis tools.",
},
"T1216": {
"title": "Signed script proxy execution",
@@ -210,7 +226,8 @@ SCHEMA = {
"value": False,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1216",
- "description": "Adversaries may use scripts signed with trusted certificates to "
+ "description": "Adversaries may use scripts signed with "
+ "trusted certificates to "
"proxy execution of malicious files on Windows systems.",
},
},
@@ -226,8 +243,10 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1110",
- "description": "Adversaries may use brute force techniques to attempt access to accounts "
- "when passwords are unknown or when password hashes are obtained.",
+ "description": "Adversaries may use brute force techniques to attempt access "
+ "to accounts "
+ "when passwords are unknown or when password hashes are "
+ "obtained.",
"depends_on": ["T1210", "T1021"],
},
"T1003": {
@@ -236,10 +255,13 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1003",
- "description": "Mapped with T1078 Valid Accounts because both techniques require"
+ "description": "Mapped with T1078 Valid Accounts because "
+ "both techniques require"
" same credential harvesting modules. "
- "Credential dumping is the process of obtaining account login and password "
- "information, normally in the form of a hash or a clear text password, "
+ "Credential dumping is the process of obtaining account login "
+ "and password "
+ "information, normally in the form of a hash or a clear text "
+ "password, "
"from the operating system and software.",
"depends_on": ["T1078"],
},
@@ -249,8 +271,10 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1145",
- "description": "Adversaries may gather private keys from compromised systems for use in "
- "authenticating to Remote Services like SSH or for use in decrypting "
+ "description": "Adversaries may gather private keys from compromised systems "
+ "for use in "
+ "authenticating to Remote Services like SSH or for use in "
+ "decrypting "
"other collected files such as email.",
"depends_on": ["T1110", "T1210"],
},
@@ -267,8 +291,10 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1087",
- "description": "Adversaries may attempt to get a listing of accounts on a system or "
- "within an environment. This information can help adversaries determine which "
+ "description": "Adversaries may attempt to get a listing of accounts on a "
+ "system or "
+ "within an environment. This information can help adversaries "
+ "determine which "
"accounts exist to aid in follow-on behavior.",
},
"T1018": {
@@ -277,8 +303,10 @@ SCHEMA = {
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1018",
- "description": "Adversaries will likely attempt to get a listing of other systems by IP address, "
- "hostname, or other logical identifier on a network for lateral movement.",
+ "description": "Adversaries will likely attempt to get a listing of other "
+ "systems by IP address, "
+ "hostname, or other logical identifier on a network for lateral"
+ " movement.",
},
"T1082": {
"title": "System information discovery",
@@ -288,7 +316,8 @@ SCHEMA = {
"link": "https://attack.mitre.org/techniques/T1082",
"depends_on": ["T1016", "T1005"],
"description": "An adversary may attempt to get detailed information about the "
- "operating system and hardware, including version, patches, hotfixes, "
+ "operating system and hardware, including version, patches, "
+ "hotfixes, "
"service packs, and architecture.",
},
"T1016": {
@@ -298,8 +327,10 @@ SCHEMA = {
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1016",
"depends_on": ["T1005", "T1082"],
- "description": "Adversaries will likely look for details about the network configuration "
- "and settings of systems they access or through information discovery"
+ "description": "Adversaries will likely look for details about the network "
+ "configuration "
+ "and settings of systems they access or through information "
+ "discovery"
" of remote systems.",
},
},
@@ -315,9 +346,12 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1210",
- "description": "Exploitation of a software vulnerability occurs when an adversary "
- "takes advantage of a programming error in a program, service, or within the "
- "operating system software or kernel itself to execute adversary-controlled code.",
+ "description": "Exploitation of a software vulnerability occurs when an "
+ "adversary "
+ "takes advantage of a programming error in a program, service, "
+ "or within the "
+ "operating system software or kernel itself to execute "
+ "adversary-controlled code.",
},
"T1075": {
"title": "Pass the hash",
@@ -325,7 +359,8 @@ SCHEMA = {
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1075",
- "description": "Pass the hash (PtH) is a method of authenticating as a user without "
+ "description": "Pass the hash (PtH) is a method of authenticating as a user "
+ "without "
"having access to the user's cleartext password.",
},
"T1105": {
@@ -361,8 +396,10 @@ SCHEMA = {
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1005",
"depends_on": ["T1016", "T1082"],
- "description": "Sensitive data can be collected from local system sources, such as the file system "
- "or databases of information residing on the system prior to Exfiltration.",
+ "description": "Sensitive data can be collected from local system sources, "
+ "such as the file system "
+ "or databases of information residing on the system prior to "
+ "Exfiltration.",
}
},
},
@@ -377,7 +414,8 @@ SCHEMA = {
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1090",
- "description": "A connection proxy is used to direct network traffic between systems "
+ "description": "A connection proxy is used to direct network traffic between "
+ "systems "
"or act as an intermediary for network communications.",
},
"T1065": {
@@ -387,7 +425,8 @@ SCHEMA = {
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1065",
"description": "Adversaries may conduct C2 communications over a non-standard "
- "port to bypass proxies and firewalls that have been improperly configured.",
+ "port to bypass proxies and firewalls that have been improperly "
+ "configured.",
},
"T1188": {
"title": "Multi-hop proxy",
@@ -411,7 +450,8 @@ SCHEMA = {
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1041",
- "description": "Data exfiltration is performed over the Command and Control channel.",
+ "description": "Data exfiltration is performed over the Command and Control "
+ "channel.",
}
},
},
diff --git a/monkey/monkey_island/cc/services/attack/mitre_api_interface.py b/monkey/monkey_island/cc/services/attack/mitre_api_interface.py
index fa0707b41..1a3025233 100644
--- a/monkey/monkey_island/cc/services/attack/mitre_api_interface.py
+++ b/monkey/monkey_island/cc/services/attack/mitre_api_interface.py
@@ -4,7 +4,6 @@ from stix2 import AttackPattern, CourseOfAction, FileSystemSource, Filter
class MitreApiInterface:
-
ATTACK_DATA_PATH = "monkey_island/cc/services/attack/attack_data/enterprise-attack"
@staticmethod
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py
index 0bf2e649b..27a4b55db 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py
@@ -8,7 +8,10 @@ __author__ = "VakarisZ"
class T1003(AttackTechnique):
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 = ""
used_msg = "Monkey successfully obtained some credentials from systems on the network."
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py
index d11a74b31..d13e55325 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py
@@ -5,7 +5,10 @@ __author__ = "VakarisZ"
class T1035(UsageTechnique):
tech_id = "T1035"
- unscanned_msg = "Monkey didn't try to interact with Windows services since it didn't run on any Windows machines."
+ unscanned_msg = (
+ "Monkey didn't try to interact with Windows services since it didn't run on "
+ "any Windows machines."
+ )
scanned_msg = "Monkey tried to interact with Windows services, but failed."
used_msg = "Monkey successfully interacted with Windows services."
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1166.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1166.py
index ab482f0f6..4ed2375a5 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1166.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1166.py
@@ -6,7 +6,10 @@ __author__ = "shreyamalviya"
class T1166(PostBreachTechnique):
tech_id = "T1166"
- unscanned_msg = "Monkey didn't try setting the setuid or setgid bits since it didn't run on any Linux machines."
+ unscanned_msg = (
+ "Monkey didn't try setting the setuid or setgid bits since it didn't run on "
+ "any Linux machines."
+ )
scanned_msg = "Monkey tried setting the setuid or setgid bits but failed."
used_msg = "Monkey successfully set the setuid or setgid bits."
pba_names = [POST_BREACH_SETUID_SETGID]
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1216.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1216.py
index 6ed73765a..62800ae20 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1216.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1216.py
@@ -9,17 +9,20 @@ class T1216(PostBreachTechnique):
unscanned_msg = (
"Monkey didn't attempt to execute an arbitrary program with the help of a "
+ "pre-existing signed script since it didn't run on any Windows machines. "
- + "If successful, this behavior could be abused by adversaries to execute malicious files that could "
- + "bypass application control and signature validation on systems."
+ + "If successful, this behavior could be abused by adversaries to execute malicious "
+ "files that could " + "bypass application control and signature validation on "
+ "systems."
)
scanned_msg = (
"Monkey attempted to execute an arbitrary program with the help of a "
+ "pre-existing signed script on Windows but failed. "
- + "If successful, this behavior could be abused by adversaries to execute malicious files that could "
- + "bypass application control and signature validation on systems."
+ + "If successful, this behavior could be abused by adversaries to execute malicious "
+ "files that could " + "bypass application control and signature validation on "
+ "systems."
)
used_msg = (
- "Monkey executed an arbitrary program with the help of a pre-existing signed script on Windows. "
+ "Monkey executed an arbitrary program with the help of a pre-existing signed script "
+ "on Windows. "
+ "This behavior could be abused by adversaries to execute malicious files that could "
+ "bypass application control and signature validation on systems."
)
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py
index d348c921b..f35fc970f 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py
@@ -6,7 +6,10 @@ __author__ = "shreyamalviya"
class T1504(PostBreachTechnique):
tech_id = "T1504"
- unscanned_msg = "Monkey didn't try modifying powershell startup files since it didn't run on any Windows machines."
+ unscanned_msg = (
+ "Monkey didn't try modifying powershell startup files since it didn't run on "
+ "any Windows machines."
+ )
scanned_msg = "Monkey tried modifying powershell startup files but failed."
used_msg = "Monkey successfully modified powershell startup files."
pba_names = [POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION]
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py
index 7cdf9010c..40a421d74 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py
@@ -9,7 +9,6 @@ from monkey_island.cc.services.attack.attack_config import AttackConfig
logger = logging.getLogger(__name__)
-
disabled_msg = (
"This technique has been disabled. "
+ "You can enable it from the [configuration page](../../configure)."
@@ -122,7 +121,8 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
def get_tech_base_data(cls):
"""
Gathers basic attack technique data into a dict.
- :return: dict E.g. {'message': 'Brute force used', 'status': 2, 'title': 'T1110 Brute force'}
+ :return: dict E.g. {'message': 'Brute force used', 'status': 2, 'title': 'T1110 Brute
+ force'}
"""
data = {}
status = cls.technique_status()
diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/pba_technique.py b/monkey/monkey_island/cc/services/attack/technique_reports/pba_technique.py
index 1366f0d3a..5460caf4c 100644
--- a/monkey/monkey_island/cc/services/attack/technique_reports/pba_technique.py
+++ b/monkey/monkey_island/cc/services/attack/technique_reports/pba_technique.py
@@ -20,7 +20,8 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
@classmethod
def get_pba_query(cls, post_breach_action_names):
"""
- :param post_breach_action_names: Names of post-breach actions with which the technique is associated
+ :param post_breach_action_names: Names of post-breach actions with which the technique is
+ associated
(example - `["Communicate as new user", "Backdoor user"]` for T1136)
:return: Mongo query that parses attack telemetries for a simple report component
(gets machines and post-breach action usage).
diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py
index d6fe0a3cb..d6b34e60b 100644
--- a/monkey/monkey_island/cc/services/config.py
+++ b/monkey/monkey_island/cc/services/config.py
@@ -49,8 +49,10 @@ class ConfigService:
def get_config(is_initial_config=False, should_decrypt=True, is_island=False):
"""
Gets the entire global config.
- :param is_initial_config: If True, the initial config will be returned instead of the current config.
- :param should_decrypt: If True, all config values which are set as encrypted will be decrypted.
+ :param is_initial_config: If True, the initial config will be returned instead of the
+ current config.
+ :param should_decrypt: If True, all config values which are set as encrypted will be
+ decrypted.
:param is_island: If True, will include island specific configuration parameters.
:return: The entire global config.
"""
@@ -70,8 +72,10 @@ class ConfigService:
def get_config_value(config_key_as_arr, is_initial_config=False, should_decrypt=True):
"""
Get a specific config value.
- :param config_key_as_arr: The config key as an array. e.g. ['basic', 'credentials', 'exploit_password_list'].
- :param is_initial_config: If True, returns the value of the initial config instead of the current config.
+ :param config_key_as_arr: The config key as an array. e.g. ['basic', 'credentials',
+ 'exploit_password_list'].
+ :param is_initial_config: If True, returns the value of the initial config instead of the
+ current config.
:param should_decrypt: If True, the value of the config key will be decrypted
(if it's in the list of encrypted config values).
:return: The value of the requested config key.
@@ -184,7 +188,8 @@ class ConfigService:
@staticmethod
def update_config(config_json, should_encrypt):
- # PBA file upload happens on pba_file_upload endpoint and corresponding config options are set there
+ # PBA file upload happens on pba_file_upload endpoint and corresponding config options
+ # are set there
config_json = ConfigService._filter_none_values(config_json)
monkey_island.cc.services.post_breach_files.set_config_PBA_files(config_json)
if should_encrypt:
@@ -330,7 +335,8 @@ class ConfigService:
config_arr = config
parent_config_arr = None
- # Because the config isn't flat, this for-loop gets the actual config value out of the config
+ # Because the config isn't flat, this for-loop gets the actual config value out of
+ # the config
for config_key_part in config_arr_as_array:
parent_config_arr = config_arr
config_arr = config_arr[config_key_part]
diff --git a/monkey/monkey_island/cc/services/config_schema/basic.py b/monkey/monkey_island/cc/services/config_schema/basic.py
index aaf2e570e..aba80e08a 100644
--- a/monkey/monkey_island/cc/services/config_schema/basic.py
+++ b/monkey/monkey_island/cc/services/config_schema/basic.py
@@ -40,7 +40,8 @@ BASIC = {
"uniqueItems": True,
"items": {"type": "string"},
"default": ["Administrator", "root", "user"],
- "description": "List of user names that will be used by exploiters that need credentials, like "
+ "description": "List of user names that will be used by exploiters that need "
+ "credentials, like "
"SSH brute-forcing.",
},
"exploit_password_list": {
@@ -57,7 +58,8 @@ BASIC = {
"111111",
"iloveyou",
],
- "description": "List of passwords that will be used by exploiters that need credentials, like "
+ "description": "List of passwords that will be used by exploiters that need "
+ "credentials, like "
"SSH brute-forcing.",
},
},
diff --git a/monkey/monkey_island/cc/services/config_schema/basic_network.py b/monkey/monkey_island/cc/services/config_schema/basic_network.py
index c515a8cbc..4512a7cc9 100644
--- a/monkey/monkey_island/cc/services/config_schema/basic_network.py
+++ b/monkey/monkey_island/cc/services/config_schema/basic_network.py
@@ -20,23 +20,28 @@ BASIC_NETWORK = {
"default": [],
"description": "List of IPs that the Monkey will not scan.",
"info": 'The Monkey scans its subnet if "Local network scan" is ticked. '
- 'Additionally the monkey scans machines according to "Scan target list".',
+ 'Additionally the monkey scans machines according to "Scan '
+ 'target list".',
},
"local_network_scan": {
"title": "Local network scan",
"type": "boolean",
"default": True,
- "description": "Determines whether the Monkey will scan the local subnets of machines it runs on, "
- 'in addition to the IPs that are configured manually in the "Scan target list".',
+ "description": "Determines whether the Monkey will scan the local subnets of "
+ "machines it runs on, "
+ "in addition to the IPs that are configured manually in the "
+ '"Scan target list".',
},
"depth": {
"title": "Scan depth",
"type": "integer",
"minimum": 1,
"default": 2,
- "description": "Amount of hops allowed for the Monkey to spread from the Island server. \n"
+ "description": "Amount of hops allowed for the Monkey to spread from the "
+ "Island server. \n"
+ WARNING_SIGN
- + " Note that setting this value too high may result in the Monkey propagating too far, "
+ + " Note that setting this value too high may result in the "
+ "Monkey propagating too far, "
'if the "Local network scan" is enabled.',
},
"subnet_scan_list": {
@@ -45,10 +50,12 @@ BASIC_NETWORK = {
"uniqueItems": True,
"items": {"type": "string", "format": IP_RANGE},
"default": [],
- "description": "List of targets the Monkey will try to scan. Targets can be IPs, subnets or hosts."
+ "description": "List of targets the Monkey will try to scan. Targets can be "
+ "IPs, subnets or hosts."
" Examples:\n"
'\tTarget a specific IP: "192.168.0.1"\n'
- '\tTarget a subnet using a network range: "192.168.0.5-192.168.0.20"\n'
+ "\tTarget a subnet using a network range: "
+ '"192.168.0.5-192.168.0.20"\n'
'\tTarget a subnet using an IP mask: "192.168.0.5/24"\n'
'\tTarget a specific host: "printer.example"',
},
@@ -64,16 +71,20 @@ BASIC_NETWORK = {
"uniqueItems": True,
"items": {"type": "string", "format": IP_RANGE},
"default": [],
- "description": "Test for network segmentation by providing a list of network segments "
+ "description": "Test for network segmentation by providing a list of network "
+ "segments "
"that should NOT be accessible to each other.\n\n"
"For example, if you configured the following three segments: "
'"10.0.0.0/24", "11.0.0.2/32", and "12.2.3.0/24", '
- "a Monkey running on 10.0.0.5 will try to access machines in the following subnets: "
- "11.0.0.2/32, 12.2.3.0/24. An alert on successful cross-segment connections "
+ "a Monkey running on 10.0.0.5 will try to access machines in "
+ "the following subnets: "
+ "11.0.0.2/32, 12.2.3.0/24. An alert on successful cross-segment "
+ "connections "
"will be shown in the reports. \n\n"
"Network segments can be IPs, subnets or hosts. Examples:\n"
'\tDefine a single-IP segment: "192.168.0.1"\n'
- '\tDefine a segment using a network range: "192.168.0.5-192.168.0.20"\n'
+ "\tDefine a segment using a network range: "
+ '"192.168.0.5-192.168.0.20"\n'
'\tDefine a segment using an subnet IP mask: "192.168.0.5/24"\n'
'\tDefine a single-host segment: "printer.example"',
}
diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py
index 88186e9ed..c450f8d2a 100644
--- a/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py
+++ b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py
@@ -4,7 +4,8 @@ EXPLOITER_CLASSES = {
"title": "Exploit class",
"description": "Click on exploiter to get more information about it."
+ WARNING_SIGN
- + " Note that using unsafe exploits may cause crashes of the exploited machine/service.",
+ + " Note that using unsafe exploits may cause crashes of the exploited "
+ "machine/service.",
"type": "string",
"anyOf": [
{
@@ -15,7 +16,8 @@ EXPLOITER_CLASSES = {
"attack_techniques": ["T1110", "T1075", "T1035"],
"info": "Brute forces using credentials provided by user and"
" hashes gathered by mimikatz.",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/smbexec/",
+ "link": "https://www.guardicore.com/infectionmonkey/docs/reference"
+ "/exploiters/smbexec/",
},
{
"type": "string",
@@ -24,8 +26,10 @@ EXPLOITER_CLASSES = {
"safe": True,
"attack_techniques": ["T1110", "T1106"],
"info": "Brute forces WMI (Windows Management Instrumentation) "
- "using credentials provided by user and hashes gathered by mimikatz.",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/wmiexec/",
+ "using credentials provided by user and hashes gathered by "
+ "mimikatz.",
+ "link": "https://www.guardicore.com/infectionmonkey/docs/reference"
+ "/exploiters/wmiexec/",
},
{
"type": "string",
@@ -35,16 +39,19 @@ EXPLOITER_CLASSES = {
"attack_techniques": ["T1110"],
"info": "Tries to brute force into MsSQL server and uses insecure "
"configuration to execute commands on server.",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/mssql/",
+ "link": "https://www.guardicore.com/infectionmonkey/docs/reference"
+ "/exploiters/mssql/",
},
{
"type": "string",
"enum": ["Ms08_067_Exploiter"],
"title": "MS08-067 Exploiter",
"safe": False,
- "info": "Unsafe exploiter, that might cause system crash due to the use of buffer overflow. "
+ "info": "Unsafe exploiter, that might cause system crash due to the use of buffer "
+ "overflow. "
"Uses MS08-067 vulnerability.",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/ms08-067/",
+ "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/ms08"
+ "-067/",
},
{
"type": "string",
@@ -52,8 +59,10 @@ EXPLOITER_CLASSES = {
"title": "SSH Exploiter",
"safe": True,
"attack_techniques": ["T1110", "T1145", "T1106"],
- "info": "Brute forces using credentials provided by user and SSH keys gathered from systems.",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sshexec/",
+ "info": "Brute forces using credentials provided by user and SSH keys "
+ "gathered from systems.",
+ "link": "https://www.guardicore.com/infectionmonkey/docs/reference"
+ "/exploiters/sshexec/",
},
{
"type": "string",
@@ -62,7 +71,8 @@ EXPLOITER_CLASSES = {
"safe": True,
"info": "CVE-2014-6271, based on logic from "
"https://github.com/nccgroup/shocker/blob/master/shocker.py .",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/shellshock/",
+ "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters"
+ "/shellshock/",
},
{
"type": "string",
@@ -70,7 +80,8 @@ EXPLOITER_CLASSES = {
"title": "SambaCry Exploiter",
"safe": True,
"info": "Bruteforces and searches for anonymous shares. Uses Impacket.",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sambacry/",
+ "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters"
+ "/sambacry/",
},
{
"type": "string",
@@ -78,7 +89,8 @@ EXPLOITER_CLASSES = {
"title": "ElasticGroovy Exploiter",
"safe": True,
"info": "CVE-2015-1427. Logic is based on Metasploit module.",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/elasticgroovy/",
+ "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters"
+ "/elasticgroovy/",
},
{
"type": "string",
@@ -95,7 +107,8 @@ EXPLOITER_CLASSES = {
"title": "WebLogic Exploiter",
"safe": True,
"info": "Exploits CVE-2017-10271 and CVE-2019-2725 vulnerabilities on WebLogic server.",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/weblogic/",
+ "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters"
+ "/weblogic/",
},
{
"type": "string",
@@ -103,7 +116,8 @@ EXPLOITER_CLASSES = {
"title": "Hadoop/Yarn Exploiter",
"safe": True,
"info": "Remote code execution on HADOOP server with YARN and default settings. "
- "Logic based on https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.",
+ "Logic based on "
+ "https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/hadoop/",
},
{
@@ -137,7 +151,8 @@ EXPLOITER_CLASSES = {
"password has been restored. If Infection Monkey fails to restore the "
"password automatically, you'll have to do it manually. For more "
"information, see the documentation.",
- "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/zerologon/",
+ "link": "https://www.guardicore.com/infectionmonkey"
+ "/docs/reference/exploiters/zerologon/",
},
],
}
diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/finger_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/finger_classes.py
index 88bf44130..01ebfe70c 100644
--- a/monkey/monkey_island/cc/services/config_schema/definitions/finger_classes.py
+++ b/monkey/monkey_island/cc/services/config_schema/definitions/finger_classes.py
@@ -47,7 +47,8 @@ FINGER_CLASSES = {
"enum": ["MSSQLFinger"],
"title": "MSSQLFinger",
"safe": True,
- "info": "Checks if Microsoft SQL service is running and tries to gather information about it.",
+ "info": "Checks if Microsoft SQL service is running and tries to gather "
+ "information about it.",
"attack_techniques": ["T1210"],
},
{
@@ -55,7 +56,7 @@ FINGER_CLASSES = {
"enum": ["ElasticFinger"],
"title": "ElasticFinger",
"safe": True,
- "info": "Checks if ElasticSearch is running and attempts to find it's version.",
+ "info": "Checks if ElasticSearch is running and attempts to find it's " "version.",
"attack_techniques": ["T1210"],
},
{
@@ -63,7 +64,8 @@ FINGER_CLASSES = {
"enum": ["PostgreSQLFinger"],
"title": "PostgreSQLFinger",
"safe": True,
- "info": "Checks if PostgreSQL service is running and if its communication is encrypted.",
+ "info": "Checks if PostgreSQL service is running and if "
+ "its communication is encrypted.",
"attack_techniques": ["T1210"],
},
],
diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py
index ea9b18aba..2c1104bcb 100644
--- a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py
+++ b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py
@@ -1,6 +1,7 @@
POST_BREACH_ACTIONS = {
"title": "Post breach actions",
- "description": "Runs scripts/commands on infected machines. These actions safely simulate what an adversary"
+ "description": "Runs scripts/commands on infected machines. These actions safely simulate what "
+ "an adversary"
"might do after breaching a new machine. Used in ATT&CK and Zero trust reports.",
"type": "string",
"anyOf": [
@@ -9,7 +10,7 @@ POST_BREACH_ACTIONS = {
"enum": ["BackdoorUser"],
"title": "Back door user",
"safe": True,
- "info": "Attempts to create a new user on the system and delete it afterwards.",
+ "info": "Attempts to create a new user on the system and delete it " "afterwards.",
"attack_techniques": ["T1136"],
},
{
@@ -17,7 +18,8 @@ POST_BREACH_ACTIONS = {
"enum": ["CommunicateAsNewUser"],
"title": "Communicate as new user",
"safe": True,
- "info": "Attempts to create a new user, create HTTPS requests as that user and delete the user "
+ "info": "Attempts to create a new user, create HTTPS requests as that "
+ "user and delete the user "
"afterwards.",
"attack_techniques": ["T1136"],
},
@@ -26,8 +28,10 @@ POST_BREACH_ACTIONS = {
"enum": ["ModifyShellStartupFiles"],
"title": "Modify shell startup files",
"safe": True,
- "info": "Attempts to modify shell startup files, like ~/.profile, ~/.bashrc, ~/.bash_profile "
- "in linux, and profile.ps1 in windows. Reverts modifications done afterwards.",
+ "info": "Attempts to modify shell startup files, like ~/.profile, "
+ "~/.bashrc, ~/.bash_profile "
+ "in linux, and profile.ps1 in windows. Reverts modifications done"
+ " afterwards.",
"attack_techniques": ["T1156", "T1504"],
},
{
@@ -43,7 +47,8 @@ POST_BREACH_ACTIONS = {
"enum": ["TrapCommand"],
"title": "Trap",
"safe": True,
- "info": "On Linux systems, attempts to trap an interrupt signal in order to execute a command "
+ "info": "On Linux systems, attempts to trap an interrupt signal in order "
+ "to execute a command "
"upon receiving that signal. Removes the trap afterwards.",
"attack_techniques": ["T1154"],
},
@@ -52,7 +57,8 @@ POST_BREACH_ACTIONS = {
"enum": ["ChangeSetuidSetgid"],
"title": "Setuid and Setgid",
"safe": True,
- "info": "On Linux systems, attempts to set the setuid and setgid bits of a new file. "
+ "info": "On Linux systems, attempts to set the setuid and setgid bits of "
+ "a new file. "
"Removes the file afterwards.",
"attack_techniques": ["T1166"],
},
@@ -69,7 +75,8 @@ POST_BREACH_ACTIONS = {
"enum": ["Timestomping"],
"title": "Timestomping",
"safe": True,
- "info": "Creates a temporary file and attempts to modify its time attributes. Removes the file afterwards.",
+ "info": "Creates a temporary file and attempts to modify its time "
+ "attributes. Removes the file afterwards.",
"attack_techniques": ["T1099"],
},
{
diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py
index 487166ec6..9a4a39050 100644
--- a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py
+++ b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py
@@ -17,7 +17,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
"enum": [ENVIRONMENT_COLLECTOR],
"title": "Environment collector",
"safe": True,
- "info": "Collects information about machine's environment (on premise/GCP/AWS).",
+ "info": "Collects information about machine's environment (on " "premise/GCP/AWS).",
"attack_techniques": ["T1082"],
},
{
@@ -33,7 +33,8 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
"enum": [AWS_COLLECTOR],
"title": "AWS collector",
"safe": True,
- "info": "If on AWS, collects more information about the AWS instance currently running on.",
+ "info": "If on AWS, collects more information about the AWS instance "
+ "currently running on.",
"attack_techniques": ["T1082"],
},
{
diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py
index 890e74efa..d03527b89 100644
--- a/monkey/monkey_island/cc/services/config_schema/internal.py
+++ b/monkey/monkey_island/cc/services/config_schema/internal.py
@@ -12,19 +12,22 @@ INTERNAL = {
"title": "Singleton mutex name",
"type": "string",
"default": "{2384ec59-0df8-4ab9-918c-843740924a28}",
- "description": "The name of the mutex used to determine whether the monkey is already running",
+ "description": "The name of the mutex used to determine whether the monkey is "
+ "already running",
},
"keep_tunnel_open_time": {
"title": "Keep tunnel open time",
"type": "integer",
"default": 60,
- "description": "Time to keep tunnel open before going down after last exploit (in seconds)",
+ "description": "Time to keep tunnel open before going down after last exploit "
+ "(in seconds)",
},
"monkey_dir_name": {
"title": "Monkey's directory name",
"type": "string",
"default": r"monkey_dir",
- "description": "Directory name for the directory which will contain all of the monkey files",
+ "description": "Directory name for the directory which will contain all of the"
+ " monkey files",
},
"started_on_island": {
"title": "Started on island",
@@ -43,7 +46,8 @@ INTERNAL = {
"title": "Max victims to find",
"type": "integer",
"default": 100,
- "description": "Determines the maximum number of machines the monkey is allowed to scan",
+ "description": "Determines the maximum number of machines the monkey is "
+ "allowed to scan",
},
"victims_max_exploit": {
"title": "Max victims to exploit",
@@ -52,7 +56,8 @@ INTERNAL = {
"description": "Determines the maximum number of machines the monkey"
" is allowed to successfully exploit. "
+ WARNING_SIGN
- + " Note that setting this value too high may result in the monkey propagating to "
+ + " Note that setting this value too high may result in the "
+ "monkey propagating to "
"a high number of machines",
},
"internet_services": {
@@ -61,7 +66,8 @@ INTERNAL = {
"uniqueItems": True,
"items": {"type": "string"},
"default": ["monkey.guardicore.com", "www.google.com"],
- "description": "List of internet services to try and communicate with to determine internet"
+ "description": "List of internet services to try and communicate with to "
+ "determine internet"
" connectivity (use either ip or domain)",
},
"self_delete_in_cleanup": {
@@ -108,7 +114,8 @@ INTERNAL = {
"uniqueItems": True,
"items": {"type": "string"},
"default": ["192.0.2.0:5000"],
- "description": "List of command servers/network interfaces to try to communicate with "
+ "description": "List of command servers/network interfaces to try to "
+ "communicate with "
"(format is :)",
},
"current_server": {
@@ -133,7 +140,8 @@ INTERNAL = {
"uniqueItems": True,
"items": {"type": "integer"},
"default": [80, 8080, 443, 8008, 7001, 9200],
- "description": "List of ports the monkey will check if are being used for HTTP",
+ "description": "List of ports the monkey will check if are being used "
+ "for HTTP",
},
"tcp_target_ports": {
"title": "TCP target ports",
@@ -154,7 +162,8 @@ INTERNAL = {
7001,
8088,
],
- "description": "List of TCP ports the monkey will check whether they're open",
+ "description": "List of TCP ports the monkey will check whether "
+ "they're open",
},
"tcp_scan_interval": {
"title": "TCP scan interval",
@@ -166,13 +175,15 @@ INTERNAL = {
"title": "TCP scan timeout",
"type": "integer",
"default": 3000,
- "description": "Maximum time (in milliseconds) to wait for TCP response",
+ "description": "Maximum time (in milliseconds) "
+ "to wait for TCP response",
},
"tcp_scan_get_banner": {
"title": "TCP scan - get banner",
"type": "boolean",
"default": True,
- "description": "Determines whether the TCP scan should try to get the banner",
+ "description": "Determines whether the TCP scan should try to get the "
+ "banner",
},
},
},
@@ -184,7 +195,8 @@ INTERNAL = {
"title": "Ping scan timeout",
"type": "integer",
"default": 1000,
- "description": "Maximum time (in milliseconds) to wait for ping response",
+ "description": "Maximum time (in milliseconds) to wait for ping "
+ "response",
}
},
},
@@ -238,48 +250,55 @@ INTERNAL = {
"title": "Dropper sets date",
"type": "boolean",
"default": True,
- "description": "Determines whether the dropper should set the monkey's file date to be the same as"
+ "description": "Determines whether the dropper should set the monkey's file "
+ "date to be the same as"
" another file",
},
"dropper_date_reference_path_windows": {
"title": "Dropper date reference path (Windows)",
"type": "string",
"default": "%windir%\\system32\\kernel32.dll",
- "description": "Determines which file the dropper should copy the date from if it's configured to do"
+ "description": "Determines which file the dropper should copy the date from if "
+ "it's configured to do"
" so on Windows (use fullpath)",
},
"dropper_date_reference_path_linux": {
"title": "Dropper date reference path (Linux)",
"type": "string",
"default": "/bin/sh",
- "description": "Determines which file the dropper should copy the date from if it's configured to do"
+ "description": "Determines which file the dropper should copy the date from if "
+ "it's configured to do"
" so on Linux (use fullpath)",
},
"dropper_target_path_linux": {
"title": "Dropper target path on Linux",
"type": "string",
"default": "/tmp/monkey",
- "description": "Determines where should the dropper place the monkey on a Linux machine",
+ "description": "Determines where should the dropper place the monkey on a "
+ "Linux machine",
},
"dropper_target_path_win_32": {
"title": "Dropper target path on Windows (32bit)",
"type": "string",
"default": "C:\\Windows\\temp\\monkey32.exe",
- "description": "Determines where should the dropper place the monkey on a Windows machine "
+ "description": "Determines where should the dropper place the monkey on a "
+ "Windows machine "
"(32bit)",
},
"dropper_target_path_win_64": {
"title": "Dropper target path on Windows (64bit)",
"type": "string",
"default": "C:\\Windows\\temp\\monkey64.exe",
- "description": "Determines where should the dropper place the monkey on a Windows machine "
+ "description": "Determines where should the dropper place the monkey on a "
+ "Windows machine "
"(64 bit)",
},
"dropper_try_move_first": {
"title": "Try to move first",
"type": "boolean",
"default": True,
- "description": "Determines whether the dropper should try to move itself instead of copying itself"
+ "description": "Determines whether the dropper should try to move itself "
+ "instead of copying itself"
" to target path",
},
},
@@ -316,7 +335,8 @@ INTERNAL = {
"title": "Send log to server",
"type": "boolean",
"default": True,
- "description": "Determines whether the monkey sends its log to the Monkey Island server",
+ "description": "Determines whether the monkey sends its log to the Monkey "
+ "Island server",
},
},
},
@@ -356,7 +376,8 @@ INTERNAL = {
"title": "Skip exploit if file exists",
"type": "boolean",
"default": False,
- "description": "Determines whether the monkey should skip the exploit if the monkey's file"
+ "description": "Determines whether the monkey should skip the exploit "
+ "if the monkey's file"
" is already on the remote machine",
}
},
@@ -410,7 +431,8 @@ INTERNAL = {
"/shares",
"/home",
],
- "description": "List of full paths to share folder for SambaCry to guess",
+ "description": "List of full paths to share folder for SambaCry to "
+ "guess",
},
"sambacry_shares_not_to_check": {
"title": "SambaCry shares not to check",
@@ -418,7 +440,8 @@ INTERNAL = {
"uniqueItems": True,
"items": {"type": "string"},
"default": ["IPC$", "print$"],
- "description": "These shares won't be checked when exploiting with SambaCry",
+ "description": "These shares won't be checked when exploiting with "
+ "SambaCry",
},
},
},
@@ -431,13 +454,15 @@ INTERNAL = {
"title": "SMB download timeout",
"type": "integer",
"default": 300,
- "description": "Timeout (in seconds) for SMB download operation (used in various exploits using SMB)",
+ "description": "Timeout (in seconds) for SMB download operation (used in "
+ "various exploits using SMB)",
},
"smb_service_name": {
"title": "SMB service name",
"type": "string",
"default": "InfectionMonkey",
- "description": "Name of the SMB service that will be set up to download monkey",
+ "description": "Name of the SMB service that will be set up to download "
+ "monkey",
},
},
},
@@ -450,7 +475,8 @@ INTERNAL = {
"title": "Export monkey telemetries",
"type": "boolean",
"default": False,
- "description": "Exports unencrypted telemetries that can be used for tests in development."
+ "description": "Exports unencrypted telemetries that "
+ "can be used for tests in development."
" Do not turn on!",
}
},
diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py
index 0d69c5aa4..e745da582 100644
--- a/monkey/monkey_island/cc/services/config_schema/monkey.py
+++ b/monkey/monkey_island/cc/services/config_schema/monkey.py
@@ -109,7 +109,8 @@ MONKEY = {
"type": "integer",
"default": 1,
"minimum": 1,
- "description": "Determines how many iterations of the monkey's full lifecycle should occur "
+ "description": "Determines how many iterations of the monkey's full lifecycle "
+ "should occur "
"(how many times to do the scan)",
},
"timeout_between_iterations": {
@@ -117,7 +118,8 @@ MONKEY = {
"type": "integer",
"default": 100,
"minimum": 0,
- "description": "Determines for how long (in seconds) should the monkey wait before starting another scan",
+ "description": "Determines for how long (in seconds) should the monkey wait "
+ "before starting another scan",
},
"retry_failed_explotation": {
"title": "Retry failed exploitation",
diff --git a/monkey/monkey_island/cc/services/edge/displayed_edge.py b/monkey/monkey_island/cc/services/edge/displayed_edge.py
index 67d42a3ab..3e038a088 100644
--- a/monkey/monkey_island/cc/services/edge/displayed_edge.py
+++ b/monkey/monkey_island/cc/services/edge/displayed_edge.py
@@ -36,8 +36,8 @@ class DisplayedEdgeService:
displayed_edge["ip_address"] = edge.ip_address
displayed_edge["services"] = services
displayed_edge["os"] = os
- # we need to deepcopy all mutable edge properties, because weak-reference link is made otherwise,
- # which is destroyed after method is exited and causes an error later.
+ # we need to deepcopy all mutable edge properties, because weak-reference link is made
+ # otherwise, which is destroyed after method is exited and causes an error later.
displayed_edge["exploits"] = deepcopy(edge.exploits)
displayed_edge["_label"] = edge.get_label()
return displayed_edge
diff --git a/monkey/monkey_island/cc/services/edge/test_displayed_edge.py b/monkey/monkey_island/cc/services/edge/test_displayed_edge.py
index 2938909c2..4c7ca36a7 100644
--- a/monkey/monkey_island/cc/services/edge/test_displayed_edge.py
+++ b/monkey/monkey_island/cc/services/edge/test_displayed_edge.py
@@ -44,7 +44,6 @@ EXPLOIT_DATA_MOCK = [
class TestDisplayedEdgeService:
def test_get_displayed_edges_by_to(self):
-
dst_id = ObjectId()
src_id = ObjectId()
diff --git a/monkey/monkey_island/cc/services/infection_lifecycle.py b/monkey/monkey_island/cc/services/infection_lifecycle.py
index 1f4c0e87e..e921adc3e 100644
--- a/monkey/monkey_island/cc/services/infection_lifecycle.py
+++ b/monkey/monkey_island/cc/services/infection_lifecycle.py
@@ -48,7 +48,8 @@ class InfectionLifecycle:
@staticmethod
def _on_finished_infection():
- # Checking is_report_being_generated here, because we don't want to wait to generate a report; rather,
+ # Checking is_report_being_generated here, because we don't want to wait to generate a
+ # report; rather,
# we want to skip and reply.
if not is_report_being_generated() and not ReportService.is_latest_report_exists():
safe_generate_reports()
diff --git a/monkey/monkey_island/cc/services/island_logs.py b/monkey/monkey_island/cc/services/island_logs.py
index 846b2e844..a145d09ad 100644
--- a/monkey/monkey_island/cc/services/island_logs.py
+++ b/monkey/monkey_island/cc/services/island_logs.py
@@ -13,7 +13,8 @@ class IslandLogService:
def get_log_file():
"""
This static function is a helper function for the monkey island log download function.
- It finds the logger handlers and checks if one of them is a fileHandler of any kind by checking if the handler
+ It finds the logger handlers and checks if one of them is a fileHandler of any kind by
+ checking if the handler
has the property handler.baseFilename.
:return:
a dict with the log file content.
diff --git a/monkey/monkey_island/cc/services/netmap/net_edge.py b/monkey/monkey_island/cc/services/netmap/net_edge.py
index 008fa5b54..1c0b649d0 100644
--- a/monkey/monkey_island/cc/services/netmap/net_edge.py
+++ b/monkey/monkey_island/cc/services/netmap/net_edge.py
@@ -28,7 +28,8 @@ class NetEdgeService:
count = 0
for monkey_id in monkey_ids:
count += 1
- # generating fake ID, because front end requires unique ID's for each edge. Collision improbable
+ # generating fake ID, because front end requires unique ID's for each edge. Collision
+ # improbable
fake_id = ObjectId(hex(count)[2:].zfill(24))
island_id = ObjectId("000000000000000000000000")
monkey_label = NodeService.get_label_for_endpoint(monkey_id)
@@ -61,7 +62,8 @@ class NetEdgeService:
count = 0
for monkey_id in monkey_ids:
count += 1
- # generating fake ID, because front end requires unique ID's for each edge. Collision improbable
+ # generating fake ID, because front end requires unique ID's for each edge. Collision
+ # improbable
fake_id = ObjectId(hex(count)[2:].zfill(24))
src_label = NodeService.get_label_for_endpoint(monkey_id)
dst_label = NodeService.get_label_for_endpoint(monkey_island_monkey["_id"])
diff --git a/monkey/monkey_island/cc/services/node.py b/monkey/monkey_island/cc/services/node.py
index 2c1fe731a..78c165503 100644
--- a/monkey/monkey_island/cc/services/node.py
+++ b/monkey/monkey_island/cc/services/node.py
@@ -160,7 +160,8 @@ class NodeService:
"label": label,
"group": monkey_group,
"os": NodeService.get_monkey_os(monkey),
- # The monkey is running IFF the group contains "_running". Therefore it's dead IFF the group does NOT
+ # The monkey is running IFF the group contains "_running". Therefore it's dead IFF
+ # the group does NOT
# contain "_running". This is a small optimisation, to not call "is_dead" twice.
"dead": "_running" not in monkey_group,
"domain_name": "",
diff --git a/monkey/monkey_island/cc/services/post_breach_files.py b/monkey/monkey_island/cc/services/post_breach_files.py
index 4215227ea..660d48487 100644
--- a/monkey/monkey_island/cc/services/post_breach_files.py
+++ b/monkey/monkey_island/cc/services/post_breach_files.py
@@ -15,7 +15,6 @@ PBA_WINDOWS_FILENAME_PATH = ["monkey", "post_breach", "PBA_windows_filename"]
PBA_LINUX_FILENAME_PATH = ["monkey", "post_breach", "PBA_linux_filename"]
UPLOADS_DIR_NAME = "userUploads"
-
ABS_UPLOAD_PATH = Path(MONKEY_ISLAND_ABS_PATH, "cc", UPLOADS_DIR_NAME)
diff --git a/monkey/monkey_island/cc/services/remote_run_aws.py b/monkey/monkey_island/cc/services/remote_run_aws.py
index e640110e0..553f4c72e 100644
--- a/monkey/monkey_island/cc/services/remote_run_aws.py
+++ b/monkey/monkey_island/cc/services/remote_run_aws.py
@@ -72,7 +72,8 @@ class RemoteRunAwsService:
"""
For all given instances, checks whether they're 32 or 64 bit.
:param instances: List of instances to check
- :return: Dictionary with instance ids as keys, and True/False as values. True if 64bit, False otherwise
+ :return: Dictionary with instance ids as keys, and True/False as values. True if 64bit,
+ False otherwise
"""
return CmdRunner.run_multiple_commands(
instances,
diff --git a/monkey/monkey_island/cc/services/reporting/aws_exporter.py b/monkey/monkey_island/cc/services/reporting/aws_exporter.py
index 1505b63aa..d08cdccd1 100644
--- a/monkey/monkey_island/cc/services/reporting/aws_exporter.py
+++ b/monkey/monkey_island/cc/services/reporting/aws_exporter.py
@@ -101,7 +101,8 @@ class AWSExporter(Exporter):
logger.debug("Client acquired: {0}".format(repr(security_hub_client)))
# Assumes the machine has the correct IAM role to do this, @see
- # https://github.com/guardicore/monkey/wiki/Monkey-Island:-Running-the-monkey-on-AWS-EC2-instances
+ # https://github.com/guardicore/monkey/wiki/Monkey-Island:-Running-the-monkey-on-AWS
+ # -EC2-instances
import_response = security_hub_client.batch_import_findings(Findings=findings_list)
logger.debug("Import findings response: {0}".format(repr(import_response)))
@@ -111,9 +112,8 @@ class AWSExporter(Exporter):
return False
except UnknownServiceError as e:
logger.warning(
- "AWS exporter called but AWS-CLI security hub service is not installed. Error: {}".format(
- e
- )
+ "AWS exporter called but AWS-CLI security hub service is not installed. "
+ "Error: {}".format(e)
)
return False
except Exception as e:
@@ -147,7 +147,8 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=5,
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}".format(issue["machine"], issue["dest"]),
instance_arn=instance_arn,
@@ -160,10 +161,12 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=10,
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 "
+ 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.".format(issue["username"]),
- recommendation="The machine {0} ({1}) is vulnerable to a SambaCry attack. The Monkey authenticated over the SMB "
+ 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,
@@ -175,10 +178,13 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=5,
- 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 "
+ 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(issue["username"]),
- recommendation="The machine {0}({1}) is vulnerable to a SMB attack. The Monkey used a pass-the-hash attack over "
+ 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(
issue["machine"], issue["ip_address"], issue["username"]
),
@@ -191,10 +197,13 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=1,
- 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 "
+ 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(issue["username"]),
- recommendation="The machine {0} ({1}) is vulnerable to a SSH attack. The Monkey authenticated over the SSH"
+ 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(issue["machine"], issue["ip_address"], issue["username"]),
instance_arn=instance_arn,
@@ -206,11 +215,13 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
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"]
),
- recommendation="The machine {machine} ({ip_address}) is vulnerable to a SSH attack. The Monkey authenticated "
+ 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(
machine=issue["machine"], ip_address=issue["ip_address"], ssh_key=issue["ssh_key"]
),
@@ -225,10 +236,10 @@ class AWSExporter(Exporter):
severity=10,
title="Elastic Search servers are vulnerable to CVE-2015-1427",
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(
- issue["machine"], issue["ip_address"]
- ),
+ 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(issue["machine"], issue["ip_address"]),
instance_arn=instance_arn,
instance_id=issue["aws_instance_id"] if "aws_instance_id" in issue else None,
)
@@ -238,8 +249,10 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=1,
- 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 "
+ 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.",
recommendation="The network can probably be segmented. A monkey instance on \
{0} in the networks {1} \
@@ -256,7 +269,8 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=1,
title="Multiple users have the same password",
- description="Some users are sharing passwords, this should be fixed by changing passwords.",
+ description="Some users are sharing passwords, this should be fixed by changing "
+ "passwords.",
recommendation="These users are sharing access password: {0}.".format(
issue["shared_with"]
),
@@ -272,7 +286,8 @@ class AWSExporter(Exporter):
title="Machines are vulnerable to 'Shellshock'",
description="Update your Bash to a ShellShock-patched version.",
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 "
+ "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"]
),
@@ -285,10 +300,13 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=1,
- 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 "
+ 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(issue["username"]),
- recommendation="The machine {0} ({1}) is vulnerable to a SMB attack. The Monkey authenticated over the SMB "
+ 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"]
),
@@ -301,10 +319,13 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=1,
- 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 "
+ 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.",
- recommendation="The machine {machine} ({ip_address}) is vulnerable to a WMI attack. The Monkey authenticated over "
+ 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"]
),
@@ -317,10 +338,13 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=1,
- 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 "
+ 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(issue["username"]),
- recommendation="The machine {machine} ({ip_address}) is vulnerable to a WMI attack. The Monkey used a "
+ 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(
machine=issue["machine"], ip_address=issue["ip_address"], username=issue["username"]
),
@@ -334,7 +358,8 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=1,
title="Multiple users have the same password.",
- description="Some domain users are sharing passwords, this should be fixed by changing passwords.",
+ description="Some domain users are sharing passwords, this should be fixed by "
+ "changing passwords.",
recommendation="These users are sharing access password: {shared_with}.".format(
shared_with=issue["shared_with"]
),
@@ -347,10 +372,13 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=1,
- 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 "
+ 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.",
- recommendation="Here is a list of machines which the account {username} is defined as an administrator: "
+ 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"]
),
@@ -363,9 +391,12 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=1,
- 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.",
- recommendation="The services: {services} have been found on the machine thus classifying it as a 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.",
+ 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"]
),
@@ -380,8 +411,10 @@ class AWSExporter(Exporter):
severity=10,
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.",
- 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 "
+ 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(
machine=issue["machine"], ip_address=issue["ip_address"]
),
@@ -395,10 +428,14 @@ class AWSExporter(Exporter):
return AWSExporter._build_generic_finding(
severity=10,
title="Oracle WebLogic servers are vulnerable to remote code execution.",
- 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.",
- 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 "
+ 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.",
+ 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(
machine=issue["machine"], ip_address=issue["ip_address"]
),
@@ -413,8 +450,10 @@ class AWSExporter(Exporter):
severity=10,
title="Hadoop/Yarn servers are vulnerable to remote code execution.",
description="Run Hadoop in secure mode, add Kerberos authentication.",
- recommendation="The Hadoop server at {machine} ({ip_address}) is vulnerable to remote code execution attack."
- "The attack was made possible due to default Hadoop/Yarn configuration being insecure.",
+ recommendation="The Hadoop server at {machine} ({ip_address}) is vulnerable to "
+ "remote code execution attack."
+ "The attack was made possible due to default Hadoop/Yarn "
+ "configuration being insecure.",
instance_arn=instance_arn,
instance_id=issue["aws_instance_id"] if "aws_instance_id" in issue else None,
)
diff --git a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py
index e60886b34..03e5ce8b1 100644
--- a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py
+++ b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py
@@ -2,16 +2,16 @@ from dataclasses import dataclass
from enum import Enum
from typing import Type
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.cred_exploit import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.cred_exploit import ( # noqa: E501
CredExploitProcessor,
)
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import ( # noqa: E501
ExploitProcessor,
)
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.shellshock_exploit import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.shellshock_exploit import ( # noqa: E501
ShellShockExploitProcessor,
)
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.zerologon import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.zerologon import ( # noqa: E501
ZerologonExploitProcessor,
)
diff --git a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/cred_exploit.py b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/cred_exploit.py
index 842fe9eb2..05c9233fe 100644
--- a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/cred_exploit.py
+++ b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/cred_exploit.py
@@ -1,8 +1,8 @@
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_report_info import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_report_info import ( # noqa: E501
CredentialType,
ExploiterReportInfo,
)
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import ( # noqa: E501
ExploitProcessor,
)
diff --git a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/exploit.py b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/exploit.py
index 1b29fc773..ad249d58a 100644
--- a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/exploit.py
+++ b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/exploit.py
@@ -1,5 +1,5 @@
from monkey_island.cc.services.node import NodeService
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_report_info import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_report_info import ( # noqa: E501
ExploiterReportInfo,
)
diff --git a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/shellshock_exploit.py b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/shellshock_exploit.py
index cd627eb5c..bd047fbf5 100644
--- a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/shellshock_exploit.py
+++ b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/shellshock_exploit.py
@@ -1,4 +1,4 @@
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import ( # noqa: E501
ExploiterReportInfo,
ExploitProcessor,
)
diff --git a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/zerologon.py b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/zerologon.py
index d9c9d7d49..0b99fc87d 100644
--- a/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/zerologon.py
+++ b/monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/processors/zerologon.py
@@ -1,4 +1,4 @@
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import ( # noqa: E501
ExploiterReportInfo,
ExploitProcessor,
)
diff --git a/monkey/monkey_island/cc/services/reporting/pth_report.py b/monkey/monkey_island/cc/services/reporting/pth_report.py
index 99c5a7467..69b3d9677 100644
--- a/monkey/monkey_island/cc/services/reporting/pth_report.py
+++ b/monkey/monkey_island/cc/services/reporting/pth_report.py
@@ -19,7 +19,8 @@ class PTHReportService(object):
@staticmethod
def __dup_passwords_mongoquery():
"""
- This function builds and queries the mongoDB for users that are using the same passwords. this is done
+ This function builds and queries the mongoDB for users that are using the same
+ passwords. this is done
by comparing the NTLM hash found for each user by mimikatz.
:return:
A list of mongo documents (dicts in python) that look like this:
@@ -53,7 +54,8 @@ class PTHReportService(object):
@staticmethod
def __get_admin_on_machines_format(admin_on_machines, domain_name):
"""
- This function finds for each admin user, which machines its an admin of, and compile them to a list.
+ This function finds for each admin user, which machines its an admin of, and compile them
+ to a list.
:param admin_on_machines: A list of "monkey" documents "_id"s
:param domain_name: The admins' domain name
:return:
@@ -65,8 +67,10 @@ class PTHReportService(object):
@staticmethod
def __strong_users_on_crit_query():
"""
- This function build and query the mongoDB for users that mimikatz was able to find cached NTLM hashes and
- are administrators on machines with services predefined as important services thus making these machines
+ This function build and query the mongoDB for users that mimikatz was able to find
+ cached NTLM hashes and
+ are administrators on machines with services predefined as important services thus
+ making these machines
critical.
:return:
A list of said users
@@ -140,8 +144,10 @@ class PTHReportService(object):
def get_shared_admins_nodes():
# This mongo queries users the best solution to figure out if an array
- # object has at least two objects in it, by making sure any value exists in the array index 1.
- # Excluding the name Administrator - its spamming the lists and not a surprise the domain Administrator account
+ # object has at least two objects in it, by making sure any value exists in the array
+ # index 1.
+ # Excluding the name Administrator - its spamming the lists and not a surprise the domain
+ # Administrator account
# is shared.
admins = mongo.db.groupsandusers.find(
{
diff --git a/monkey/monkey_island/cc/services/reporting/report.py b/monkey/monkey_island/cc/services/reporting/report.py
index 87a99a2ad..ade56e64e 100644
--- a/monkey/monkey_island/cc/services/reporting/report.py
+++ b/monkey/monkey_island/cc/services/reporting/report.py
@@ -22,13 +22,13 @@ from monkey_island.cc.services.configuration.utils import (
get_config_network_segments_as_subnet_groups,
)
from monkey_island.cc.services.node import NodeService
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_descriptor_enum import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_descriptor_enum import ( # noqa: E501
ExploiterDescriptorEnum,
)
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.cred_exploit import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.cred_exploit import ( # noqa: E501
CredentialType,
)
-from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import (
+from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import ( # noqa: E501
ExploiterReportInfo,
)
from monkey_island.cc.services.reporting.pth_report import PTHReportService
@@ -384,10 +384,13 @@ class ReportService:
@staticmethod
def get_cross_segment_issues_of_single_machine(source_subnet_range, target_subnet_range):
"""
- Gets list of cross segment issues of a single machine. Meaning a machine has an interface for each of the
+ Gets list of cross segment issues of a single machine. Meaning a machine has an interface
+ for each of the
subnets.
- :param source_subnet_range: The subnet range which shouldn't be able to access target_subnet.
- :param target_subnet_range: The subnet range which shouldn't be accessible from source_subnet.
+ :param source_subnet_range: The subnet range which shouldn't be able to access
+ target_subnet.
+ :param target_subnet_range: The subnet range which shouldn't be accessible from
+ source_subnet.
:return:
"""
cross_segment_issues = []
@@ -426,7 +429,8 @@ class ReportService:
def get_cross_segment_issues_per_subnet_pair(scans, source_subnet, target_subnet):
"""
Gets list of cross segment issues from source_subnet to target_subnet.
- :param scans: List of all scan telemetry entries. Must have monkey_guid, ip_addr and services.
+ :param scans: List of all scan telemetry entries. Must have monkey_guid,
+ ip_addr and services.
This should be a PyMongo cursor object.
:param source_subnet: The subnet which shouldn't be able to access target_subnet.
:param target_subnet: The subnet which shouldn't be accessible from source_subnet.
@@ -468,7 +472,8 @@ class ReportService:
def get_cross_segment_issues_per_subnet_group(scans, subnet_group):
"""
Gets list of cross segment issues within given subnet_group.
- :param scans: List of all scan telemetry entries. Must have monkey_guid, ip_addr and services.
+ :param scans: List of all scan telemetry entries. Must have monkey_guid,
+ ip_addr and services.
This should be a PyMongo cursor object.
:param subnet_group: List of subnets which shouldn't be accessible from each other.
:return: Cross segment issues regarding the subnets in the group.
@@ -708,7 +713,8 @@ class ReportService:
@staticmethod
def encode_dot_char_before_mongo_insert(report_dict):
"""
- mongodb doesn't allow for '.' and '$' in a key's name, this function replaces the '.' char with the unicode
+ mongodb doesn't allow for '.' and '$' in a key's name, this function replaces the '.'
+ char with the unicode
,,, combo instead.
:return: dict with formatted keys with no dots.
"""
@@ -719,7 +725,8 @@ class ReportService:
def is_latest_report_exists():
"""
This function checks if a monkey report was already generated and if it's the latest one.
- :return: True if report is the latest one, False if there isn't a report or its not the latest.
+ :return: True if report is the latest one, False if there isn't a report or its not the
+ latest.
"""
latest_report_doc = mongo.db.report.find_one({}, {"meta.latest_monkey_modifytime": 1})
diff --git a/monkey/monkey_island/cc/services/reporting/report_generation_synchronisation.py b/monkey/monkey_island/cc/services/reporting/report_generation_synchronisation.py
index dec13e6d6..38f7ee9cb 100644
--- a/monkey/monkey_island/cc/services/reporting/report_generation_synchronisation.py
+++ b/monkey/monkey_island/cc/services/reporting/report_generation_synchronisation.py
@@ -4,8 +4,10 @@ from gevent.lock import BoundedSemaphore
logger = logging.getLogger(__name__)
-# These are pseudo-singletons - global Locks. These locks will allow only one thread to generate a report at a time.
-# Report generation can be quite slow if there is a lot of data, and the UI queries the Root service often; without
+# These are pseudo-singletons - global Locks. These locks will allow only one thread to generate
+# a report at a time.
+# Report generation can be quite slow if there is a lot of data, and the UI queries the Root
+# service often; without
# the locks, these requests would accumulate, overload the server, eventually causing it to crash.
logger.debug("Initializing report generation locks.")
__report_generating_lock = BoundedSemaphore()
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/state.py b/monkey/monkey_island/cc/services/telemetry/processing/state.py
index 8749cc730..87e7797c2 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/state.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/state.py
@@ -23,5 +23,6 @@ def process_state_telemetry(telemetry_json):
if telemetry_json["data"]["version"]:
logger.info(
- f"monkey {telemetry_json['monkey_guid']} has version {telemetry_json['data']['version']}"
+ f"monkey {telemetry_json['monkey_guid']} has version "
+ f"{telemetry_json['data']['version']}"
)
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info.py
index 3313b763d..73a81e332 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/system_info.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info.py
@@ -3,7 +3,7 @@ import logging
from monkey_island.cc.server_utils.encryptor import get_encryptor
from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.services.node import NodeService
-from monkey_island.cc.services.telemetry.processing.system_info_collectors.system_info_telemetry_dispatcher import (
+from monkey_island.cc.services.telemetry.processing.system_info_collectors.system_info_telemetry_dispatcher import ( # noqa: E501
SystemInfoTelemetryDispatcher,
)
from monkey_island.cc.services.wmi_handler import WMIHandler
@@ -20,7 +20,8 @@ def process_system_info_telemetry(telemetry_json):
dispatcher.dispatch_collector_results_to_relevant_processors,
]
- # Calling safe_process_telemetry so if one of the stages fail, we log and move on instead of failing the rest of
+ # Calling safe_process_telemetry so if one of the stages fail, we log and move on instead of
+ # failing the rest of
# them, as they are independent.
for stage in telemetry_processing_stages:
safe_process_telemetry(stage, telemetry_json)
@@ -44,7 +45,8 @@ def process_ssh_info(telemetry_json):
ssh_info = telemetry_json["data"]["ssh_info"]
encrypt_system_info_ssh_keys(ssh_info)
if telemetry_json["data"]["network_info"]["networks"]:
- # We use user_name@machine_ip as the name of the ssh key stolen, thats why we need ip from telemetry
+ # We use user_name@machine_ip as the name of the ssh key stolen, thats why we need ip
+ # from telemetry
add_ip_to_ssh_keys(telemetry_json["data"]["network_info"]["networks"][0], ssh_info)
add_system_info_ssh_keys_to_config(ssh_info)
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
index 894bdce75..7ce4b6fcf 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py
@@ -47,7 +47,8 @@ class SystemInfoTelemetryDispatcher(object):
def dispatch_collector_results_to_relevant_processors(self, telemetry_json):
"""
- If the telemetry has collectors' results, dispatches the results to the relevant processing functions.
+ If the telemetry has collectors' results, dispatches the results to the relevant
+ processing functions.
:param telemetry_json: Telemetry sent from the Monkey
"""
if "collectors" in telemetry_json["data"]:
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/test_environment.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/test_environment.py
index f1e53d5f4..042f5b874 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/test_environment.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/test_environment.py
@@ -1,7 +1,7 @@
import uuid
from monkey_island.cc.models import Monkey
-from monkey_island.cc.services.telemetry.processing.system_info_collectors.system_info_telemetry_dispatcher import (
+from monkey_island.cc.services.telemetry.processing.system_info_collectors.system_info_telemetry_dispatcher import ( # noqa: E501
SystemInfoTelemetryDispatcher,
)
diff --git a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/test_system_info_telemetry_dispatcher.py b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/test_system_info_telemetry_dispatcher.py
index 0335c6e65..6829daf4b 100644
--- a/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/test_system_info_telemetry_dispatcher.py
+++ b/monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/test_system_info_telemetry_dispatcher.py
@@ -3,7 +3,7 @@ import uuid
import pytest
from monkey_island.cc.models import Monkey
-from monkey_island.cc.services.telemetry.processing.system_info_collectors.system_info_telemetry_dispatcher import (
+from monkey_island.cc.services.telemetry.processing.system_info_collectors.system_info_telemetry_dispatcher import ( # noqa: E501
SystemInfoTelemetryDispatcher,
process_aws_telemetry,
)
@@ -15,7 +15,6 @@ TEST_SYS_INFO_TO_PROCESSING = {
class TestSystemInfoTelemetryDispatcher:
def test_dispatch_to_relevant_collector_bad_inputs(self):
-
dispatcher = SystemInfoTelemetryDispatcher(TEST_SYS_INFO_TO_PROCESSING)
# Bad format telem JSONs - throws
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/communicate_as_new_user.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/communicate_as_new_user.py
index 74007b5fd..6a3ec30aa 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/communicate_as_new_user.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/communicate_as_new_user.py
@@ -5,7 +5,10 @@ from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_finding_serv
)
COMM_AS_NEW_USER_FAILED_FORMAT = "Monkey on {} couldn't communicate as new user. Details: {}"
-COMM_AS_NEW_USER_SUCCEEDED_FORMAT = "New user created by Monkey on {} successfully tried to communicate with the internet. Details: {}"
+COMM_AS_NEW_USER_SUCCEEDED_FORMAT = (
+ "New user created by Monkey on {} successfully tried to "
+ "communicate with the internet. Details: {}"
+)
def check_new_user_communication(current_monkey, success, message):
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/data_endpoints.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/data_endpoints.py
index e4accdff7..d2634ae86 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/data_endpoints.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/data_endpoints.py
@@ -43,7 +43,8 @@ def check_open_data_endpoints(telemetry_json):
events.append(
Event.create_event(
title="Scan telemetry analysis",
- message="Service {} on {} recognized as an open data endpoint! Service details: {}".format(
+ message="Service {} on {} recognized as an open data endpoint! "
+ "Service details: {}".format(
service_data["display_name"],
telemetry_json["data"]["machine"]["ip_addr"],
json.dumps(service_data),
@@ -56,7 +57,8 @@ def check_open_data_endpoints(telemetry_json):
events.append(
Event.create_event(
title="Scan telemetry analysis",
- message="Service {} on {} recognized as an open data endpoint! Service details: {}".format(
+ message="Service {} on {} recognized as an open data endpoint! "
+ "Service details: {}".format(
service_data["display_name"],
telemetry_json["data"]["machine"]["ip_addr"],
json.dumps(service_data),
@@ -69,7 +71,8 @@ def check_open_data_endpoints(telemetry_json):
events.append(
Event.create_event(
title="Scan telemetry analysis",
- message="Service {} on {} recognized as an open data endpoint! Service details: {}".format(
+ message="Service {} on {} recognized as an open data endpoint! "
+ "Service details: {}".format(
service_data["display_name"],
telemetry_json["data"]["machine"]["ip_addr"],
json.dumps(service_data),
diff --git a/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/segmentation.py b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/segmentation.py
index acc3e6bfa..d26e2bd69 100644
--- a/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/segmentation.py
+++ b/monkey/monkey_island/cc/services/telemetry/zero_trust_checks/segmentation.py
@@ -18,7 +18,8 @@ SEGMENTATION_DONE_EVENT_TEXT = (
)
SEGMENTATION_VIOLATION_EVENT_TEXT = (
- "Segmentation violation! Monkey on '{hostname}', with the {source_ip} IP address (in segment {source_seg}) "
+ "Segmentation violation! Monkey on '{hostname}', with the {source_ip} IP address (in segment "
+ "{source_seg}) "
"managed to communicate cross segment to {target_ip} (in segment {target_seg})."
)
@@ -51,7 +52,8 @@ def is_segmentation_violation(
:param target_ip: The target with which the current monkey communicated with.
:param source_subnet: The segment the monkey belongs to.
:param target_subnet: Another segment which the monkey isn't supposed to communicate with.
- :return: True if this is a violation of segmentation between source_subnet and target_subnet; Otherwise, False.
+ :return: True if this is a violation of segmentation between source_subnet and
+ target_subnet; Otherwise, False.
"""
if source_subnet == target_subnet:
return False
@@ -102,7 +104,8 @@ def create_or_add_findings_for_all_pairs(all_subnets, current_monkey):
# Get all the other subnets.
other_subnets = list(set(all_subnets) - set(this_monkey_subnets))
- # Calculate the cartesian product - (this monkey subnets X other subnets). These pairs are the pairs that the monkey
+ # Calculate the cartesian product - (this monkey subnets X other subnets). These pairs are
+ # the pairs that the monkey
# should have tested.
all_subnets_pairs_for_this_monkey = itertools.product(this_monkey_subnets, other_subnets)
diff --git a/monkey/monkey_island/cc/services/tests/reporting/test_report.py b/monkey/monkey_island/cc/services/tests/reporting/test_report.py
index 6cdc9befd..65f5d2758 100644
--- a/monkey/monkey_island/cc/services/tests/reporting/test_report.py
+++ b/monkey/monkey_island/cc/services/tests/reporting/test_report.py
@@ -43,7 +43,6 @@ EXPLOIT_TELEMETRY_TELEM = {
},
}
-
SYSTEM_INFO_TELEMETRY_TELEM = {
"_id": TELEM_ID["system_info_creds"],
"monkey_guid": MONKEY_GUID,
diff --git a/monkey/monkey_island/cc/services/tests/test_config.py b/monkey/monkey_island/cc/services/tests/test_config.py
index c43a13be9..c5e30dbd2 100644
--- a/monkey/monkey_island/cc/services/tests/test_config.py
+++ b/monkey/monkey_island/cc/services/tests/test_config.py
@@ -6,6 +6,7 @@ from monkey_island.cc.services.config import ConfigService
IPS = ["0.0.0.0", "9.9.9.9"]
PORT = 9999
+
# If tests fail because config path is changed, sync with
# monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunOptions.js
diff --git a/monkey/monkey_island/cc/services/utils/network_utils.py b/monkey/monkey_island/cc/services/utils/network_utils.py
index ba3c76939..997fc815c 100644
--- a/monkey/monkey_island/cc/services/utils/network_utils.py
+++ b/monkey/monkey_island/cc/services/utils/network_utils.py
@@ -60,10 +60,13 @@ def is_local_ips(ips: List) -> bool:
return collections.Counter(ips) == collections.Counter(filtered_local_ips)
-# The local IP addresses list should not change often. Therefore, we can cache the result and never call this function
-# more than once. This stopgap measure is here since this function is called a lot of times during the report
+# The local IP addresses list should not change often. Therefore, we can cache the result and
+# never call this function
+# more than once. This stopgap measure is here since this function is called a lot of times
+# during the report
# generation.
-# This means that if the interfaces of the Island machine change, the Island process needs to be restarted.
+# This means that if the interfaces of the Island machine change, the Island process needs to be
+# restarted.
@lru(maxsize=1)
def local_ip_addresses():
ip_list = []
@@ -73,10 +76,13 @@ def local_ip_addresses():
return ip_list
-# The subnets list should not change often. Therefore, we can cache the result and never call this function
-# more than once. This stopgap measure is here since this function is called a lot of times during the report
+# The subnets list should not change often. Therefore, we can cache the result and never call
+# this function
+# more than once. This stopgap measure is here since this function is called a lot of times
+# during the report
# generation.
-# This means that if the interfaces or subnets of the Island machine change, the Island process needs to be restarted.
+# This means that if the interfaces or subnets of the Island machine change, the Island process
+# needs to be restarted.
@lru(maxsize=1)
def get_subnets():
subnets = []
diff --git a/monkey/monkey_island/cc/services/wmi_handler.py b/monkey/monkey_island/cc/services/wmi_handler.py
index fe401ce38..ede0bc167 100644
--- a/monkey/monkey_island/cc/services/wmi_handler.py
+++ b/monkey/monkey_island/cc/services/wmi_handler.py
@@ -148,7 +148,8 @@ class WMIHandler(object):
if not mongo.db.groupsandusers.find_one({"SID": entity["SID"]}):
mongo.db.groupsandusers.insert_one(entity)
else:
- # if entity is domain entity, add the monkey id of current machine to secrets_location.
+ # if entity is domain entity, add the monkey id of current machine to
+ # secrets_location.
# (found on this machine)
if entity.get("NTLM_secret"):
mongo.db.groupsandusers.update_one(
diff --git a/monkey/monkey_island/cc/services/zero_trust/monkey_findings/monkey_zt_finding_service.py b/monkey/monkey_island/cc/services/zero_trust/monkey_findings/monkey_zt_finding_service.py
index 68f09fbe9..6c8063eca 100644
--- a/monkey/monkey_island/cc/services/zero_trust/monkey_findings/monkey_zt_finding_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/monkey_findings/monkey_zt_finding_service.py
@@ -12,10 +12,12 @@ class MonkeyZTFindingService:
@staticmethod
def create_or_add_to_existing(test: str, status: str, events: List[Event]):
"""
- Create a new finding or add the events to an existing one if it's the same (same meaning same status and same
+ Create a new finding or add the events to an existing one if it's the same (same meaning
+ same status and same
test).
- :raises: Assertion error if this is used when there's more then one finding which fits the query - this is not
+ :raises: Assertion error if this is used when there's more then one finding which fits
+ the query - this is not
when this function should be used.
"""
existing_findings = list(MonkeyFinding.objects(test=test, status=status))
diff --git a/monkey/monkey_island/cc/services/zero_trust/monkey_findings/test_monkey_zt_details_service.py b/monkey/monkey_island/cc/services/zero_trust/monkey_findings/test_monkey_zt_details_service.py
index 191685779..4440d822e 100644
--- a/monkey/monkey_island/cc/services/zero_trust/monkey_findings/test_monkey_zt_details_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/monkey_findings/test_monkey_zt_details_service.py
@@ -7,7 +7,8 @@ from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_details_serv
def test__remove_redundant_events(monkeypatch):
monkeypatch.setattr(monkey_zt_details_service, "MAX_EVENT_FETCH_CNT", 6)
- # No events are redundant, 8 events in the database, but we display only 6 (3 latest and 3 oldest)
+ # No events are redundant, 8 events in the database, but we display only 6 (3 latest and 3
+ # oldest)
latest_events = ["6", "7", "8"]
_do_redundant_event_removal_test(latest_events, 8, ["6", "7", "8"])
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/cloudformation_rules.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/cloudformation_rules.py
index c08c7b614..c8dbffb46 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/cloudformation_rules.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/cloudformation_rules.py
@@ -4,6 +4,5 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name
class CloudformationRules(RuleNameEnum):
-
# Service Security
CLOUDFORMATION_STACK_WITH_ROLE = "cloudformation-stack-with-role"
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/ses_rules.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/ses_rules.py
index d1894144d..a73e00478 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/ses_rules.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/ses_rules.py
@@ -4,7 +4,6 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name
class SESRules(RuleNameEnum):
-
# Permissive policies
SES_IDENTITY_WORLD_SENDRAWEMAIL_POLICY = "ses-identity-world-SendRawEmail-policy"
SES_IDENTITY_WORLD_SENDEMAIL_POLICY = "ses-identity-world-SendEmail-policy"
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/sns_rules.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/sns_rules.py
index 47e49a0d1..09d410239 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/sns_rules.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/sns_rules.py
@@ -4,7 +4,6 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name
class SNSRules(RuleNameEnum):
-
# Permissive policies
SNS_TOPIC_WORLD_SUBSCRIBE_POLICY = "sns-topic-world-Subscribe-policy"
SNS_TOPIC_WORLD_SETTOPICATTRIBUTES_POLICY = "sns-topic-world-SetTopicAttributes-policy"
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/sqs_rules.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/sqs_rules.py
index 84190ceb3..44e666f96 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/sqs_rules.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/consts/rule_names/sqs_rules.py
@@ -4,7 +4,6 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rule_name
class SQSRules(RuleNameEnum):
-
# Permissive policies
SQS_QUEUE_WORLD_SENDMESSAGE_POLICY = "sqs-queue-world-SendMessage-policy"
SQS_QUEUE_WORLD_RECEIVEMESSAGE_POLICY = "sqs-queue-world-ReceiveMessage-policy"
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_parser.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_parser.py
index 134ed3500..7db9a5988 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_parser.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_parser.py
@@ -2,7 +2,7 @@ from enum import Enum
from common.utils.code_utils import get_value_from_dict
from common.utils.exceptions import RulePathCreatorNotFound
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators_list import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators_list import ( # noqa: E501
RULE_PATH_CREATORS_LIST,
)
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudformation_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudformation_rule_path_creator.py
index 40e438eba..55f718608 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudformation_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudformation_rule_path_creator.py
@@ -2,12 +2,11 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.cloudform
CloudformationRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class CloudformationRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.CLOUDFORMATION
supported_rules = CloudformationRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudtrail_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudtrail_rule_path_creator.py
index 928cd138e..1f764ec8b 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudtrail_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudtrail_rule_path_creator.py
@@ -2,12 +2,11 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.cloudtrai
CloudTrailRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class CloudTrailRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.CLOUDTRAIL
supported_rules = CloudTrailRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudwatch_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudwatch_rule_path_creator.py
index 4d45c878e..573d129ee 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudwatch_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/cloudwatch_rule_path_creator.py
@@ -2,12 +2,11 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.cloudwatc
CloudWatchRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class CloudWatchRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.CLOUDWATCH
supported_rules = CloudWatchRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/config_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/config_rule_path_creator.py
index b5607cbe8..45cc2e3d6 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/config_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/config_rule_path_creator.py
@@ -2,12 +2,11 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.config_ru
ConfigRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class ConfigRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.CONFIG
supported_rules = ConfigRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/ec2_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/ec2_rule_path_creator.py
index 8d951f656..41e42180b 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/ec2_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/ec2_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.ec2_rules import EC2Rules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class EC2RulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.EC2
supported_rules = EC2Rules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/elb_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/elb_rule_path_creator.py
index 4af6e351b..65b320292 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/elb_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/elb_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.elb_rules import ELBRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class ELBRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.ELB
supported_rules = ELBRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/elbv2_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/elbv2_rule_path_creator.py
index 935a8678e..8a560f401 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/elbv2_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/elbv2_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.elbv2_rules import ELBv2Rules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class ELBv2RulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.ELB_V2
supported_rules = ELBv2Rules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/iam_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/iam_rule_path_creator.py
index f355dd8e2..0ab9e686f 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/iam_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/iam_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.iam_rules import IAMRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class IAMRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.IAM
supported_rules = IAMRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/rds_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/rds_rule_path_creator.py
index be4b043d7..56252a3f6 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/rds_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/rds_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.rds_rules import RDSRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class RDSRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.RDS
supported_rules = RDSRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/redshift_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/redshift_rule_path_creator.py
index dfa954638..90ba44308 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/redshift_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/redshift_rule_path_creator.py
@@ -2,12 +2,11 @@ from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.redshift_
RedshiftRules,
)
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class RedshiftRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.REDSHIFT
supported_rules = RedshiftRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/s3_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/s3_rule_path_creator.py
index f06b2554f..aa6f101aa 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/s3_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/s3_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.s3_rules import S3Rules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class S3RulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.S3
supported_rules = S3Rules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/ses_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/ses_rule_path_creator.py
index 7ded2918f..4530aa097 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/ses_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/ses_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.ses_rules import SESRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class SESRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.SES
supported_rules = SESRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/sns_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/sns_rule_path_creator.py
index 6eda4fcef..bb619f92f 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/sns_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/sns_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.sns_rules import SNSRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class SNSRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.SNS
supported_rules = SNSRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/sqs_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/sqs_rule_path_creator.py
index e4979caf5..19229c1d6 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/sqs_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/sqs_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.sqs_rules import SQSRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class SQSRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.SQS
supported_rules = SQSRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/vpc_rule_path_creator.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/vpc_rule_path_creator.py
index 9daad607e..7f3cfecde 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/vpc_rule_path_creator.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators/vpc_rule_path_creator.py
@@ -1,11 +1,10 @@
from monkey_island.cc.services.zero_trust.scoutsuite.consts.rule_names.vpc_rules import VPCRules
from monkey_island.cc.services.zero_trust.scoutsuite.consts.service_consts import SERVICE_TYPES
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.abstract_rule_path_creator import ( # noqa: E501
AbstractRulePathCreator,
)
class VPCRulePathCreator(AbstractRulePathCreator):
-
service_type = SERVICE_TYPES.VPC
supported_rules = VPCRules
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py
index 8ad561ece..d724ca584 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/rule_path_building/rule_path_creators_list.py
@@ -1,46 +1,46 @@
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.cloudformation_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.cloudformation_rule_path_creator import ( # noqa: E501
CloudformationRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.cloudtrail_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.cloudtrail_rule_path_creator import ( # noqa: E501
CloudTrailRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.cloudwatch_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.cloudwatch_rule_path_creator import ( # noqa: E501
CloudWatchRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.config_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.config_rule_path_creator import ( # noqa: E501
ConfigRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.ec2_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.ec2_rule_path_creator import ( # noqa: E501
EC2RulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.elb_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.elb_rule_path_creator import ( # noqa: E501
ELBRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.elbv2_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.elbv2_rule_path_creator import ( # noqa: E501
ELBv2RulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.iam_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.iam_rule_path_creator import ( # noqa: E501
IAMRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.rds_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.rds_rule_path_creator import ( # noqa: E501
RDSRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.redshift_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.redshift_rule_path_creator import ( # noqa: E501
RedshiftRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.s3_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.s3_rule_path_creator import ( # noqa: E501
S3RulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.ses_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.ses_rule_path_creator import ( # noqa: E501
SESRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.sns_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.sns_rule_path_creator import ( # noqa: E501
SNSRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.sqs_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.sqs_rule_path_creator import ( # noqa: E501
SQSRulePathCreator,
)
-from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.vpc_rule_path_creator import (
+from monkey_island.cc.services.zero_trust.scoutsuite.data_parsing.rule_path_building.rule_path_creators.vpc_rule_path_creator import ( # noqa: E501
VPCRulePathCreator,
)
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/test_rule_parser.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/test_rule_parser.py
index 15a0b4b11..daaabf430 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/test_rule_parser.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/data_parsing/test_rule_parser.py
@@ -17,7 +17,8 @@ ALL_PORTS_OPEN = EC2Rules.SECURITY_GROUP_ALL_PORTS_TO_ALL
EXPECTED_RESULT = {
"description": "Security Group Opens All Ports to All",
- "path": "ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id.cidrs.id.CIDR",
+ "path": "ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id"
+ ".cidrs.id.CIDR",
"level": "danger",
"display_path": "ec2.regions.id.vpcs.id.security_groups.id",
"items": [
diff --git a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/test_scoutsuite_rule_service.py b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/test_scoutsuite_rule_service.py
index 04e085eb1..fa3ca9835 100644
--- a/monkey/monkey_island/cc/services/zero_trust/scoutsuite/test_scoutsuite_rule_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/scoutsuite/test_scoutsuite_rule_service.py
@@ -22,10 +22,14 @@ example_scoutsuite_data = {
".rules.ingress.protocols.ALL.ports.1-65535.cidrs.0.CIDR",
],
"level": "danger",
- "path": "ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id.cidrs.id.CIDR",
- "rationale": "It was detected that all ports in the security group are open, and any source IP address"
- " could send traffic to these ports, which creates a wider attack surface for resources "
- "assigned to it. Open ports should be reduced to the minimum needed to correctly",
+ "path": "ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id"
+ ".cidrs.id.CIDR",
+ "rationale": "It was detected that all ports in the security group are open, "
+ "and any source IP address"
+ " could send traffic to these ports, which creates a wider attack surface "
+ "for resources "
+ "assigned to it. Open ports should be reduced to the minimum needed to "
+ "correctly",
"references": [],
"remediation": None,
"service": "EC2",
diff --git a/monkey/monkey_island/cc/services/zero_trust/test_common/raw_scoutsute_data.py b/monkey/monkey_island/cc/services/zero_trust/test_common/raw_scoutsute_data.py
index 978209671..9905868af 100644
--- a/monkey/monkey_island/cc/services/zero_trust/test_common/raw_scoutsute_data.py
+++ b/monkey/monkey_island/cc/services/zero_trust/test_common/raw_scoutsute_data.py
@@ -127,7 +127,8 @@ RAW_SCOUTSUITE_DATA = {
"checked_items": 179,
"flagged_items": 2,
"service": "EC2",
- "rationale": "It was detected that all ports in the security group are open <...>",
+ "rationale": "It was detected that all ports in the security group are "
+ "open <...>",
"remediation": None,
"compliance": None,
"references": None,
diff --git a/monkey/monkey_island/cc/services/zero_trust/test_common/scoutsuite_finding_data.py b/monkey/monkey_island/cc/services/zero_trust/test_common/scoutsuite_finding_data.py
index 4e428794d..2302b68e9 100644
--- a/monkey/monkey_island/cc/services/zero_trust/test_common/scoutsuite_finding_data.py
+++ b/monkey/monkey_island/cc/services/zero_trust/test_common/scoutsuite_finding_data.py
@@ -15,16 +15,22 @@ RULES = [
description="Security Group Opens All Ports to All",
flagged_items=2,
items=[
- "ec2.regions.eu-central-1.vpcs.vpc-0ee259b1a13c50229.security_groups.sg-035779fe5c293fc72"
+ "ec2.regions.eu-central-1.vpcs.vpc-0ee259b1a13c50229.security_groups.sg"
+ "-035779fe5c293fc72"
".rules.ingress.protocols.ALL.ports.1-65535.cidrs.2.CIDR",
- "ec2.regions.eu-central-1.vpcs.vpc-00015526b6695f9aa.security_groups.sg-019eb67135ec81e65"
+ "ec2.regions.eu-central-1.vpcs.vpc-00015526b6695f9aa.security_groups.sg"
+ "-019eb67135ec81e65"
".rules.ingress.protocols.ALL.ports.1-65535.cidrs.0.CIDR",
],
level="danger",
- path="ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id.cidrs.id.CIDR",
- rationale="It was detected that all ports in the security group are open, and any source IP address"
- " could send traffic to these ports, which creates a wider attack surface for resources "
- "assigned to it. Open ports should be reduced to the minimum needed to correctly",
+ path="ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id.cidrs"
+ ".id.CIDR",
+ rationale="It was detected that all ports in the security group are open, "
+ "and any source IP address"
+ " could send traffic to these ports, which creates a wider attack surface "
+ "for resources "
+ "assigned to it. Open ports should be reduced to the minimum needed to "
+ "correctly",
references=[],
remediation=None,
service="EC2",
@@ -43,7 +49,8 @@ RULES = [
description="Security Group Opens RDP Port to All",
flagged_items=7,
items=[
- "ec2.regions.eu-central-1.vpcs.vpc-076500a2138ee09da.security_groups.sg-00bdef5951797199c"
+ "ec2.regions.eu-central-1.vpcs.vpc-076500a2138ee09da.security_groups.sg"
+ "-00bdef5951797199c"
".rules.ingress.protocols.TCP.ports.3389.cidrs.0.CIDR",
"ec2.regions.eu-central-1.vpcs.vpc-d33026b8.security_groups.sg-007931ba8a364e330"
".rules.ingress.protocols.TCP.ports.3389.cidrs.0.CIDR",
@@ -55,14 +62,19 @@ RULES = [
".rules.ingress.protocols.TCP.ports.3389.cidrs.0.CIDR",
"ec2.regions.us-east-1.vpcs.vpc-9e56cae4.security_groups.sg-0dc253aa79062835a"
".rules.ingress.protocols.TCP.ports.3389.cidrs.0.CIDR",
- "ec2.regions.us-east-1.vpcs.vpc-002d543353cd4e97d.security_groups.sg-01902f153d4f938da"
+ "ec2.regions.us-east-1.vpcs.vpc-002d543353cd4e97d.security_groups.sg"
+ "-01902f153d4f938da"
".rules.ingress.protocols.TCP.ports.3389.cidrs.0.CIDR",
],
level="danger",
- path="ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id.cidrs.id.CIDR",
- rationale="The security group was found to be exposing a well-known port to all source addresses."
- " Well-known ports are commonly probed by automated scanning tools, and could be an indicator "
- "of sensitive services exposed to Internet. If such services need to be expos",
+ path="ec2.regions.id.vpcs.id.security_groups.id.rules.id.protocols.id.ports.id.cidrs"
+ ".id.CIDR",
+ rationale="The security group was found to be exposing a well-known port to all "
+ "source addresses."
+ " Well-known ports are commonly probed by automated scanning tools, "
+ "and could be an indicator "
+ "of sensitive services exposed to Internet. If such services need to be "
+ "expos",
references=[],
remediation="Remove the inbound rules that expose open ports",
service="EC2",
diff --git a/monkey/monkey_island/cc/services/zero_trust/zero_trust_report/principle_service.py b/monkey/monkey_island/cc/services/zero_trust/zero_trust_report/principle_service.py
index 671d1da44..3fdc4aee1 100644
--- a/monkey/monkey_island/cc/services/zero_trust/zero_trust_report/principle_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/zero_trust_report/principle_service.py
@@ -56,7 +56,8 @@ class PrincipleService:
@staticmethod
def __get_lcd_worst_status_for_test(all_findings_for_test):
"""
- :param all_findings_for_test: All findings of a specific test (get this using Finding.objects(test={A_TEST}))
+ :param all_findings_for_test: All findings of a specific test (get this using
+ Finding.objects(test={A_TEST}))
:return: the "worst" (i.e. most severe) status out of the given findings.
lcd stands for lowest common denominator.
"""
diff --git a/monkey/monkey_island/cc/services/zero_trust/zero_trust_report/test_pillar_service.py b/monkey/monkey_island/cc/services/zero_trust/zero_trust_report/test_pillar_service.py
index 36691e00e..3b6da848f 100644
--- a/monkey/monkey_island/cc/services/zero_trust/zero_trust_report/test_pillar_service.py
+++ b/monkey/monkey_island/cc/services/zero_trust/zero_trust_report/test_pillar_service.py
@@ -13,7 +13,7 @@ from common.common_consts.zero_trust_consts import (
WORKLOADS,
)
from monkey_island.cc.services.zero_trust.zero_trust_report.pillar_service import PillarService
-from monkey_island.cc.services.zero_trust.zero_trust_report.test_common.example_finding_data import (
+from monkey_island.cc.services.zero_trust.zero_trust_report.test_common.example_finding_data import ( # noqa: E501
save_example_findings,
)
from monkey_island.cc.test_common.fixtures import FixtureEnum
diff --git a/monkey/monkey_island/pyinstaller_hooks/hook-stix2.py b/monkey/monkey_island/pyinstaller_hooks/hook-stix2.py
index e5e7ecb5a..785d6a36b 100644
--- a/monkey/monkey_island/pyinstaller_hooks/hook-stix2.py
+++ b/monkey/monkey_island/pyinstaller_hooks/hook-stix2.py
@@ -1,4 +1,5 @@
-# Workaround for packaging Monkey Island using PyInstaller. See https://github.com/oasis-open/cti-python-stix2/issues/218
+# Workaround for packaging Monkey Island using PyInstaller. See
+# https://github.com/oasis-open/cti-python-stix2/issues/218
import os