Exemple #1
0
    def collect(self) -> dict:
        logger.info("Collecting AWS info")
        aws = AwsInstance()
        info = {}
        if aws.is_instance():
            logger.info("Machine is an AWS instance")
            info = \
                {
                    'instance_id': aws.get_instance_id()
                }
        else:
            logger.info("Machine is NOT an AWS instance")

        return info
Exemple #2
0
def get_test_aws_instance(
    text={
        "instance_id": None,
        "region": None,
        "account_id": None
    },
    exception={
        "instance_id": None,
        "region": None,
        "account_id": None
    },
):
    with requests_mock.Mocker() as m:
        # request made to get instance_id
        url = f"{AWS_LATEST_METADATA_URI_PREFIX}meta-data/instance-id"
        m.get(url, text=text["instance_id"]) if text["instance_id"] else m.get(
            url, exc=exception["instance_id"])

        # request made to get region
        url = f"{AWS_LATEST_METADATA_URI_PREFIX}meta-data/placement/availability-zone"
        m.get(url, text=text["region"]) if text["region"] else m.get(
            url, exc=exception["region"])

        # request made to get account_id
        url = f"{AWS_LATEST_METADATA_URI_PREFIX}dynamic/instance-identity/document"
        m.get(url, text=text["account_id"]) if text["account_id"] else m.get(
            url, exc=exception["account_id"])

        test_aws_instance_object = AwsInstance()
        return test_aws_instance_object
Exemple #3
0
 def try_init_aws_instance():
     # noinspection PyBroadException
     try:
         RemoteRunAwsService.aws_instance = AwsInstance()
     except Exception:
         logger.error("Failed init aws instance. Exception info: ",
                      exc_info=True)
Exemple #4
0
    def collect(self) -> dict:
        logger.info("Collecting AWS info")
        if is_running_on_island():
            logger.info("Attempting to scan AWS security with ScoutSuite.")
            scan_cloud_security(cloud_type=CloudProviders.AWS)
        else:
            logger.info("Didn't scan AWS security with ScoutSuite, because not on island.")
        aws = AwsInstance()
        info = {}
        if aws.is_instance():
            logger.info("Machine is an AWS instance")
            info = {"instance_id": aws.get_instance_id()}
        else:
            logger.info("Machine is NOT an AWS instance")

        return info
Exemple #5
0
    def handle_report(report_json):

        findings_list = []
        issues_list = report_json["recommendations"]["issues"]
        if not issues_list:
            logger.info(
                "No issues were found by the monkey, no need to send anything")
            return True

        # Not suppressing error here on purpose.
        current_aws_region = AwsInstance().get_region()

        for machine in issues_list:
            for issue in issues_list[machine]:
                try:
                    if "aws_instance_id" in issue:
                        findings_list.append(
                            AWSExporter._prepare_finding(
                                issue, current_aws_region))
                except AWSExporter.FindingNotFoundError as e:
                    logger.error(e)

        if not AWSExporter._send_findings(findings_list, current_aws_region):
            logger.error("Exporting findings to aws failed")
            return False

        return True
Exemple #6
0
def get_test_aws_instance(text={
    'instance_id': None,
    'region': None,
    'account_id': None
},
                          exception={
                              'instance_id': None,
                              'region': None,
                              'account_id': None
                          }):
    with requests_mock.Mocker() as m:
        # request made to get instance_id
        url = f'{AWS_LATEST_METADATA_URI_PREFIX}meta-data/instance-id'
        m.get(url, text=text['instance_id']) if text['instance_id'] else m.get(
            url, exc=exception['instance_id'])

        # request made to get region
        url = f'{AWS_LATEST_METADATA_URI_PREFIX}meta-data/placement/availability-zone'
        m.get(url, text=text['region']) if text['region'] else m.get(
            url, exc=exception['region'])

        # request made to get account_id
        url = f'{AWS_LATEST_METADATA_URI_PREFIX}dynamic/instance-identity/document'
        m.get(url, text=text['account_id']) if text['account_id'] else m.get(
            url, exc=exception['account_id'])

        test_aws_instance_object = AwsInstance()
        return test_aws_instance_object
Exemple #7
0
    def get_instances():
        """
        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.

        :raises: botocore.exceptions.ClientError if can't describe local instance information.
        :return: All visible instances from this instance
        """
        current_instance = AwsInstance()
        local_ssm_client = boto3.client("ssm", current_instance.get_region())
        try:
            response = local_ssm_client.describe_instance_information()

            filtered_instances_data = filter_instance_data_from_aws_response(response)
            return filtered_instances_data
        except botocore.exceptions.ClientError as e:
            logger.warning("AWS client error while trying to get instances: " + e)
            raise e
Exemple #8
0
class AwsEnvironment(Environment):

    _credentials_required = True

    def __init__(self, config):
        super(AwsEnvironment, self).__init__(config)
        # Not suppressing error here on purpose. This is critical if we're on AWS env.
        self.aws_info = AwsInstance()
        self._instance_id = self._get_instance_id()
        self.region = self._get_region()

    def _get_instance_id(self):
        return self.aws_info.get_instance_id()

    def _get_region(self):
        return self.aws_info.get_region()

    def get_auth_users(self):
        if self._is_registered():
            return self._config.get_users()
        else:
            return []
Exemple #9
0
    def _prepare_finding(issue, region):
        findings_dict = {
            'island_cross_segment':
            AWSExporter._handle_island_cross_segment_issue,
            'ssh': AWSExporter._handle_ssh_issue,
            'shellshock': AWSExporter._handle_shellshock_issue,
            'tunnel': AWSExporter._handle_tunnel_issue,
            'elastic': AWSExporter._handle_elastic_issue,
            'smb_password': AWSExporter._handle_smb_password_issue,
            'smb_pth': AWSExporter._handle_smb_pth_issue,
            'sambacry': AWSExporter._handle_sambacry_issue,
            'shared_passwords': AWSExporter._handle_shared_passwords_issue,
            'wmi_password': AWSExporter._handle_wmi_password_issue,
            'wmi_pth': AWSExporter._handle_wmi_pth_issue,
            'ssh_key': AWSExporter._handle_ssh_key_issue,
            'shared_passwords_domain':
            AWSExporter._handle_shared_passwords_domain_issue,
            'shared_admins_domain':
            AWSExporter._handle_shared_admins_domain_issue,
            'strong_users_on_crit':
            AWSExporter._handle_strong_users_on_crit_issue,
            'struts2': AWSExporter._handle_struts2_issue,
            'weblogic': AWSExporter._handle_weblogic_issue,
            'hadoop': AWSExporter._handle_hadoop_issue,
            # azure and conficker are not relevant issues for an AWS env
        }

        configured_product_arn = EnvironmentConfig.get_from_file().aws.get(
            'sec_hub_product_arn', '')
        product_arn = 'arn:aws:securityhub:{region}:{arn}'.format(
            region=region, arn=configured_product_arn)
        instance_arn = 'arn:aws:ec2:' + str(region) + ':instance:{instance_id}'
        # Not suppressing error here on purpose.
        account_id = AwsInstance().get_account_id()
        logger.debug("aws account id acquired: {}".format(account_id))

        finding = {
            "SchemaVersion": "2018-10-08",
            "Id": uuid.uuid4().hex,
            "ProductArn": product_arn,
            "GeneratorId": issue['type'],
            "AwsAccountId": account_id,
            "RecordState": "ACTIVE",
            "Types": ["Software and Configuration Checks/Vulnerabilities/CVE"],
            "CreatedAt": datetime.now().isoformat() + 'Z',
            "UpdatedAt": datetime.now().isoformat() + 'Z',
        }
        return AWSExporter.merge_two_dicts(
            finding, findings_dict[issue['type']](issue, instance_arn))
Exemple #10
0
def not_found_request_mock_instance():
    with requests_mock.Mocker() as m:
        # request made to get instance_id
        url = f"{AWS_LATEST_METADATA_URI_PREFIX}meta-data/instance-id"
        m.get(url, status_code=404)

        # request made to get region
        url = f"{AWS_LATEST_METADATA_URI_PREFIX}meta-data/placement/availability-zone"
        m.get(url)

        # request made to get account_id
        url = f"{AWS_LATEST_METADATA_URI_PREFIX}dynamic/instance-identity/document"
        m.get(url)

        not_found_aws_instance_object = AwsInstance()
        return not_found_aws_instance_object
Exemple #11
0
    def handle_report(report_json):

        findings_list = []
        issues_list = report_json['recommendations']['issues']
        if not issues_list:
            logger.info('No issues were found by the monkey, no need to send anything')
            return True

        # Not suppressing error here on purpose.
        current_aws_region = AwsInstance().get_region()

        for machine in issues_list:
            for issue in issues_list[machine]:
                if issue.get('aws_instance_id', None):
                    findings_list.append(AWSExporter._prepare_finding(issue, current_aws_region))

        if not AWSExporter._send_findings(findings_list, current_aws_region):
            logger.error('Exporting findings to aws failed')
            return False

        return True
Exemple #12
0
 def __init__(self, config):
     super(AwsEnvironment, self).__init__(config)
     # Not suppressing error here on purpose. This is critical if we're on AWS env.
     self.aws_info = AwsInstance()
Exemple #13
0
from typing import List

from common.cloud.aws.aws_instance import AwsInstance
from common.cloud.azure.azure_instance import AzureInstance
from common.cloud.gcp.gcp_instance import GcpInstance
from common.cloud.instance import CloudInstance

all_cloud_instances = [AwsInstance(), AzureInstance(), GcpInstance()]


def get_all_cloud_instances() -> List[CloudInstance]:
    return all_cloud_instances
Exemple #14
0
    def _prepare_finding(issue, region):
        findings_dict = {
            "island_cross_segment":
            AWSExporter._handle_island_cross_segment_issue,
            ExploiterDescriptorEnum.SSH.value.class_name: {
                CredentialType.PASSWORD.value: AWSExporter._handle_ssh_issue,
                CredentialType.KEY.value: AWSExporter._handle_ssh_key_issue,
            },
            ExploiterDescriptorEnum.SHELLSHOCK.value.class_name:
            AWSExporter._handle_shellshock_issue,  # noqa:E501
            "tunnel":
            AWSExporter._handle_tunnel_issue,
            ExploiterDescriptorEnum.ELASTIC.value.class_name:
            AWSExporter._handle_elastic_issue,
            ExploiterDescriptorEnum.SMB.value.class_name: {
                CredentialType.PASSWORD.value:
                AWSExporter._handle_smb_password_issue,
                CredentialType.HASH.value: AWSExporter._handle_smb_pth_issue,
            },
            ExploiterDescriptorEnum.SAMBACRY.value.class_name:
            AWSExporter._handle_sambacry_issue,
            "shared_passwords":
            AWSExporter._handle_shared_passwords_issue,
            ExploiterDescriptorEnum.WMI.value.class_name: {
                CredentialType.PASSWORD.value:
                AWSExporter._handle_wmi_password_issue,
                CredentialType.HASH.value: AWSExporter._handle_wmi_pth_issue,
            },
            "shared_passwords_domain":
            AWSExporter._handle_shared_passwords_domain_issue,
            "shared_admins_domain":
            AWSExporter._handle_shared_admins_domain_issue,
            "strong_users_on_crit":
            AWSExporter._handle_strong_users_on_crit_issue,
            ExploiterDescriptorEnum.STRUTS2.value.class_name:
            AWSExporter._handle_struts2_issue,
            ExploiterDescriptorEnum.WEBLOGIC.value.class_name:
            AWSExporter._handle_weblogic_issue,
            ExploiterDescriptorEnum.HADOOP.value.class_name:
            AWSExporter._handle_hadoop_issue,
            # azure and conficker are not relevant issues for an AWS env
        }

        configured_product_arn = INFECTION_MONKEY_ARN
        product_arn = "arn:aws:securityhub:{region}:{arn}".format(
            region=region, arn=configured_product_arn)
        instance_arn = "arn:aws:ec2:" + str(region) + ":instance:{instance_id}"
        # Not suppressing error here on purpose.
        account_id = AwsInstance().get_account_id()
        logger.debug("aws account id acquired: {}".format(account_id))

        aws_finding = {
            "SchemaVersion": "2018-10-08",
            "Id": uuid.uuid4().hex,
            "ProductArn": product_arn,
            "GeneratorId": issue["type"],
            "AwsAccountId": account_id,
            "RecordState": "ACTIVE",
            "Types": ["Software and Configuration Checks/Vulnerabilities/CVE"],
            "CreatedAt": datetime.now().isoformat() + "Z",
            "UpdatedAt": datetime.now().isoformat() + "Z",
        }

        processor = AWSExporter._get_issue_processor(findings_dict, issue)

        return AWSExporter.merge_two_dicts(aws_finding,
                                           processor(issue, instance_arn))