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
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
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)
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
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
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
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
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 []
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))
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
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
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()
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
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))