diff --git a/docs/content/en/integrations/parsers/file/aws_inspector2.md b/docs/content/en/integrations/parsers/file/aws_inspector2.md new file mode 100644 index 00000000000..d7507b61688 --- /dev/null +++ b/docs/content/en/integrations/parsers/file/aws_inspector2.md @@ -0,0 +1,24 @@ +--- +title: "AWS Inspector2 Scanner" +toc_hide: true +--- + +### File Types +AWS Inspector2 report can be imported in json format. Inspector2 name comes from API calls to "modern" Inspector API - `aws inspector2` as opposite to Classic Inspector (previous version of the service), this is an example of how such report can be generated: `aws inspector2 list-findings --filter-criteria '{"resourceId":[{"comparison":"EQUALS","value":"i-instance_id_here"}]}' --region us-east-1 > inspector2_findings.json` + + +This parser can help to get findings in a delegated admin account for AWS Inspector or in a standalone AWS account. The parser is developed mostly for a scenario where findings are obtained for a specific resource like an ECR image or an instance, and uploaded to a test in a DefectDojo engagement that represents a branch from a git repository. + + +A minimal valid json file with no findings: + +```json +{ + "findings": [] +} +``` + +Detailed API response format can be obtained [here](https://docs.aws.amazon.com/inspector/v2/APIReference/API_Finding.html) + +### Sample Scan Data +Sample AWS Inspector2 findings can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/aws_inspector2). diff --git a/dojo/settings/.settings.dist.py.sha256sum b/dojo/settings/.settings.dist.py.sha256sum index 2a9d5c52e55..9206f7bf5ed 100644 --- a/dojo/settings/.settings.dist.py.sha256sum +++ b/dojo/settings/.settings.dist.py.sha256sum @@ -1 +1 @@ -6a90a111e2b89eb2c400945c80ff76c64b135d78b84fdf6b09a6b83569946904 +4b0c6ee05222e622f74d80c8e93504aba986ad0b187aab305ff7ecef89080f11 diff --git a/dojo/settings/settings.dist.py b/dojo/settings/settings.dist.py index d84a64b047f..91f72e40c19 100644 --- a/dojo/settings/settings.dist.py +++ b/dojo/settings/settings.dist.py @@ -1283,6 +1283,7 @@ def saml2_attrib_map_format(dict): "Kiuwan SCA Scan": ["description", "severity", "component_name", "component_version", "cwe"], "Rapplex Scan": ["title", "endpoints", "severity"], "AppCheck Web Application Scanner": ["title", "severity"], + "AWS Inspector2 Scan": ["title", "severity", "description"], "Legitify Scan": ["title", "endpoints", "severity"], "ThreatComposer Scan": ["title", "description"], "Invicti Scan": ["title", "description", "severity"], @@ -1350,6 +1351,7 @@ def saml2_attrib_map_format(dict): "Wazuh": True, "Nuclei Scan": True, "Threagile risks report": True, + "AWS Inspector2 Scan": True, } # List of fields that are known to be usable in hash_code computation) @@ -1510,6 +1512,7 @@ def saml2_attrib_map_format(dict): "Kiuwan SCA Scan": DEDUPE_ALGO_HASH_CODE, "Rapplex Scan": DEDUPE_ALGO_HASH_CODE, "AppCheck Web Application Scanner": DEDUPE_ALGO_HASH_CODE, + "AWS Inspector2 Scan": DEDUPE_ALGO_UNIQUE_ID_FROM_TOOL_OR_HASH_CODE, "Legitify Scan": DEDUPE_ALGO_HASH_CODE, "ThreatComposer Scan": DEDUPE_ALGO_UNIQUE_ID_FROM_TOOL_OR_HASH_CODE, "Invicti Scan": DEDUPE_ALGO_HASH_CODE, diff --git a/dojo/tools/aws_inspector2/__init__.py b/dojo/tools/aws_inspector2/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dojo/tools/aws_inspector2/parser.py b/dojo/tools/aws_inspector2/parser.py new file mode 100644 index 00000000000..863c9ebc18a --- /dev/null +++ b/dojo/tools/aws_inspector2/parser.py @@ -0,0 +1,255 @@ +import json +from datetime import UTC, datetime + +from dateutil import parser as date_parser + +from dojo.models import Endpoint, Finding + + +class AWSInspector2Parser: + + """Import AWS Inspector2 json.""" + + def get_scan_types(self): + return ["AWS Inspector2 Scan"] + + def get_label_for_scan_types(self, scan_type): + return "AWS Inspector2 Scan" + + def get_description_for_scan_types(self, scan_type): + return "AWS Inspector2 report file can be imported in JSON format (aws inspector2 list-findings)." + + def get_findings(self, file, test): + tree = json.load(file) + raw_findings = tree.get("findings", None) + if not isinstance(raw_findings, list): + msg = "Incorrect Inspector2 report format" + raise TypeError(msg) + self.test = test + findings = [] + for raw_finding in raw_findings: + finding = self.get_base_finding(raw_finding) + # type specific details + finding_type = raw_finding.get("type", None) + if finding_type == "PACKAGE_VULNERABILITY": + finding = self.get_package_vulnerability(finding, raw_finding) + elif finding_type == "CODE_VULNERABILITY": + finding = self.get_code_vulnerability(finding, raw_finding) + elif finding_type == "NETWORK_REACHABILITY": + finding = self.get_network_reachability(finding, raw_finding) + else: + msg = "Incorrect Inspector2 report format" + raise TypeError(msg) + # process the endpoints + finding = self.process_endpoints(finding, raw_finding) + findings.append(finding) + + return findings + + def get_severity(self, severity_string): + if severity_string == "UNTRIAGED": + severity_string = "Info" + return severity_string.title() + + def get_base_finding(self, raw_finding: dict) -> Finding: + # basic fields + finding_id = raw_finding.get("findingArn") + title = raw_finding.get("title", "The title could not be identified...") + description = "" + if (aws_account := raw_finding.get("awsAccountId")) is not None: + description += f"**AWS Account**: {aws_account}\n" + if finding_id is not None: + description += f"**Finding ARN**: {finding_id}\n" + if (inspector_score := raw_finding.get("inspectorScore")) is not None: + description += f"Inspector score: {inspector_score}\n" + if (discovered_at := raw_finding.get("firstObservedAt")) is not None: + description += f"Discovered at: {discovered_at}\n" + if (last_seen_at := raw_finding.get("lastObservedAt")) is not None: + description += f"Last seen: {last_seen_at}\n" + if (orig_description := raw_finding.get("description")) is not None: + description += f"Original description: \n{orig_description}\n" + finding = Finding( + title=title, + test=self.test, + description=description, + severity=self.get_severity(raw_finding.get("severity", "Info")), + unique_id_from_tool=finding_id, + static_finding=True, + dynamic_finding=False, + ) + # set mitigation status + if raw_finding.get("status", "ACTIVE") == "ACTIVE": + mitigated = None + is_mitigated = False + active = True + else: + is_mitigated = True + active = False + if (last_observed := raw_finding.get("lastObservedAt", None)) is not None: + mitigated = date_parser(last_observed) + else: + mitigated = datetime.now(UTC) + finding.active = active + finding.is_mitigated = is_mitigated + finding.mitigated = mitigated + # EPSS + finding.epss_score = raw_finding.get("epss", {}).get("score", None) + + return finding + + def get_package_vulnerability(self, finding: Finding, raw_finding: dict) -> Finding: + vulnerability_details = raw_finding.get("packageVulnerabilityDetails", {}) + vulnerability_packages_descriptions = "\n".join( + [ + ( + f'*Vulnerable package*: {vulnerability_package.get("name", "N/A")}\n' + f'\tpackage manager: {vulnerability_package.get("packageManager", "N/A")}\n' + f'\tversion: {vulnerability_package.get("version", "N/A")}\n' + f'\tfixed version: {vulnerability_package.get("fixedInVersion", "N/A")}\n' + f'\tremediation: {vulnerability_package.get("remediation", "N/A")}\n' + ) + for vulnerability_package in vulnerability_details.get("vulnerablePackages", []) + ], + ) + if (vulnerability_id := vulnerability_details.get("vulnerabilityId", None)) is not None: + finding.unsaved_vulnerability_ids = [vulnerability_id] + vulnerability_source = vulnerability_details.get("source") + vulnerability_source_url = vulnerability_details.get("sourceUrl") + # populate fields + if vulnerability_source is not None and vulnerability_source_url is not None: + finding.url = vulnerability_source_url + finding.description += ( + "\n**Additional info**\n" + f"Vulnerability info from: {vulnerability_source} {vulnerability_source_url}\n" + "Affected packages:\n" + f"{vulnerability_packages_descriptions}\n" + ) + + return finding + + def get_code_vulnerability(self, finding: Finding, raw_finding: dict) -> Finding: + cwes = raw_finding.get("cwes", []) + detector_id = raw_finding.get("detectorId", "N/A") + detector_name = raw_finding.get("detectorName", "N/A") + file_path_info = raw_finding.get("filePath", {}) + file_name = file_path_info.get("fileName", "N/A") + file_path = file_path_info.get("filePath", "N/A") + start_line = file_path_info.get("startLine", "N/A") + end_line = file_path_info.get("endLine", "N/A") + detector_tags = ", ".join(raw_finding.get("detectorTags", [])) + reference_urls = ", ".join(raw_finding.get("referenceUrls", [])) + rule_id = raw_finding.get("ruleId", "N/A") + layer_arn = raw_finding.get("sourceLambdaLayerArn", "N/A") + string_cwes = ", ".join(cwes) + # populate fields + finding.cwe = cwes[0] if cwes else None + finding.file_path = f"{file_path}{file_name}" + finding.sast_source_file_path = f"{file_path}{file_name}" + finding.line = start_line + finding.sast_source_line = start_line + finding.description += ( + "\n**Additional info**\n" + f"CWEs: {string_cwes}\n" + f"Vulnerability info from: {detector_id} {detector_name}\n" + f"Rule: {rule_id}\n" + f"Lines: {start_line} - {end_line}\n" + f"Tags: {detector_tags or 'N/A'}\n" + f"URLs: {reference_urls or 'N/A'}\n" + f"Lambda layer ARN: {layer_arn}\n" + ) + + return finding + + def get_network_reachability(self, finding: Finding, raw_finding: dict) -> Finding: + network_path_info = raw_finding.get("networkPath", {}) + network_path_steps = network_path_info.get("steps", []) + steps_descriptions = "\n".join( + [ + f'steps:\n{step_number}: {step.get("componentId", "N/A")} {step.get("componentType", "N/A")}' + for step_number, step in enumerate(network_path_steps) + ], + ) + open_port_range_info = raw_finding.get("openPortRange", {}) + port_range_start = open_port_range_info.get("begin", "N/A") + port_range_end = open_port_range_info.get("end", "N/A") + protocol = raw_finding.get("protocol", "N/A") + finding.description += ( + "\n**Additional info**\n" + f"protocol {protocol}, port range {port_range_start} - {port_range_end}" + f"{steps_descriptions}\n" + ) + + return finding + + def process_endpoints(self, finding: Finding, raw_finding: dict) -> Finding: + impact = [] + endpoints = [] + for resource_info in raw_finding.get("resources", {}): + resource_type = resource_info.get("type", None) + resource_id = resource_info.get("id", "N/A") + resource_details = resource_info.get("details", {}) + endpoint_host = f"{resource_type} - {resource_id}" + if resource_type == "AWS_EC2_INSTANCE": + aws_account = raw_finding.get("awsAccountId") + resource_region = resource_info.get("region", "N/A") + endpoint_host = resource_id + ec2_instance_details = resource_details.get("awsEc2Instance", None) + if ec2_instance_details: + impact.extend( + ( + f"ARN: {resource_id}", + f"Image ID: {ec2_instance_details.get('imageId', 'N/A')}", + f"IPv4 address: {ec2_instance_details.get('ipV4Addresses', 'N/A')}", + f"Subnet: {ec2_instance_details.get('subnetId', 'N/A')}", + f"VPC: {ec2_instance_details.get('vpcId', 'N/A')}", + f"Region: {resource_region}", + f"AWS Account: {aws_account}", + f"Launched at: {ec2_instance_details.get('launchedAt', 'N/A')}", + "---", + ), + ) + elif resource_type == "AWS_ECR_CONTAINER_IMAGE": + image_id = resource_id.split("repository/")[1].replace("sha256:", "").replace("/", "-") + endpoint_host = image_id + ecr_image_details = resource_details.get("awsEcrContainerImage", None) + if ecr_image_details: + impact.extend( + ( + f"ARN: {resource_id}", + f"Registry: {ecr_image_details.get('registry', 'N/A')}", + f"Repository: {ecr_image_details.get('repositoryName', 'N/A')}", + f"Hash: {ecr_image_details.get('imageHash', 'N/A')}", + f"Author: {ecr_image_details.get('author', 'N/A')}", + f"Pushed at: {ecr_image_details.get('pushedAt', 'N/A')}", + "---", + ), + ) + elif resource_type == "AWS_ECR_REPOSITORY": + # no corresponding + # key present in + # https://docs.aws.amazon.com/inspector/v2/APIReference/API_ResourceDetails.html + pass + elif resource_type == "AWS_LAMBDA_FUNCTION": + lambda_id = resource_id.split("function:")[1].replace(":", "-").replace("/", "-") + endpoint_host = lambda_id + lambda_details = resource_details.get("awsLambdaFunction", None) + if lambda_details: + impact.extend( + ( + f"ARN: {resource_id}", + f"Name: {lambda_details.get('functionName', 'N/A')}", + f"Version: {lambda_details.get('version', 'N/A')}", + f"Runtime: {lambda_details.get('runtime', 'N/A')}", + f"Hash: {lambda_details.get('codeSha256', 'N/A')}", + f"Pushed at: {lambda_details.get('lastModifiedAt', 'N/A')}", + ), + ) + else: + msg = "Incorrect Inspector2 report format" + raise TypeError(msg) + endpoints.append(Endpoint(host=endpoint_host)) + finding.impact = "\n".join(impact) + finding.unsaved_endpoints = [] + finding.unsaved_endpoints.extend(endpoints) + + return finding diff --git a/unittests/scans/aws_inspector2/aws_inspector2_many_vul.json b/unittests/scans/aws_inspector2/aws_inspector2_many_vul.json new file mode 100644 index 00000000000..c3083037c69 --- /dev/null +++ b/unittests/scans/aws_inspector2/aws_inspector2_many_vul.json @@ -0,0 +1,680 @@ +{ + "findings": [ + { + "awsAccountId": "012345678901", + "description": "A memory leak flaw was found in the Linux kernel in the ccp_run_aes_gcm_cmd() function in drivers/crypto/ccp/ccp-ops.c, which allows attackers to cause a denial of service (memory consumption). This vulnerability is similar with the older CVE-2019-18808.", + "epss": { + "score": 0.00075 + }, + "exploitAvailable": "NO", + "findingArn": "arn:aws:inspector2:us-east-1:012345678901:finding/00037f625ee77ac186869f906eb73366", + "firstObservedAt": "2024-02-02T16:30:33.045000+01:00", + "fixAvailable": "YES", + "inspectorScore": 5.5, + "inspectorScoreDetails": { + "adjustedCvss": { + "adjustments": [], + "cvssSource": "NVD", + "score": 5.5, + "scoreSource": "NVD", + "scoringVector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H", + "version": "3.1" + } + }, + "lastObservedAt": "2024-06-14T04:03:53.051000+02:00", + "packageVulnerabilityDetails": { + "cvss": [ + { + "baseScore": 5.5, + "scoringVector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H", + "source": "NVD", + "version": "3.1" + } + ], + "referenceUrls": [], + "relatedVulnerabilities": [], + "source": "DEBIAN_CVE", + "sourceUrl": "https://security-tracker.debian.org/tracker/CVE-2021-3744", + "vendorSeverity": "unimportant", + "vulnerabilityId": "CVE-2021-3744", + "vulnerablePackages": [ + { + "arch": "AMD64", + "epoch": 0, + "fixedInVersion": "0:4.19.232-1", + "name": "linux", + "packageManager": "OS", + "release": "2", + "remediation": "apt-get update && apt-get upgrade", + "sourceLayerHash": "sha256:11a88e76431345b48525c4e4d58d497810019f4bafdb5e2bd56dc34a05e09cc3", + "version": "4.19.118" + } + ] + }, + "remediation": { + "recommendation": { + "text": "None Provided" + } + }, + "resources": [ + { + "details": { + "awsEcrContainerImage": { + "architecture": "amd64", + "author": "John D ", + "imageHash": "sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "imageTags": [ + "2.3.0" + ], + "platform": "DEBIAN_10", + "pushedAt": "2020-06-10T11:30:35+02:00", + "registry": "012345678901", + "repositoryName": "my-awesome-docker-image" + } + }, + "id": "arn:aws:ecr:us-east-1:012345678901:repository/my-awesome-docker-image/sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "partition": "aws", + "region": "us-east-1", + "tags": {}, + "type": "AWS_ECR_CONTAINER_IMAGE" + } + ], + "severity": "MEDIUM", + "status": "ACTIVE", + "title": "CVE-2021-3744 - linux", + "type": "PACKAGE_VULNERABILITY", + "updatedAt": "2024-06-14T04:03:53.051000+02:00" + }, + { + "awsAccountId": "012345678901", + "description": "In the Linux kernel, the following vulnerability has been resolved: fpga: manager: add owner module and take its refcount The current implementation of the fpga manager assumes that the low-level module registers a driver for the parent device and uses its owner pointer to take the module's refcount. This approach is problematic since it can lead to a null pointer dereference while attempting to get the manager if the parent device does not have a driver. To address this problem, add a module owner pointer to the fpga_manager struct and use it to take the module's refcount. Modify the functions for registering the manager to take an additional owner module parameter and rename them to avoid conflicts. Use the old function names for helper macros that automatically set the module that registers the manager as the owner. This ensures compatibility with existing low-level control modules and reduces the chances of registering a manager without setting the owner. Also, update the documentation to keep it cons", + "epss": { + "score": 0.00045 + }, + "exploitAvailable": "NO", + "findingArn": "arn:aws:inspector2:us-east-1:012345678901:finding/00222d5d29811496c48d6e3a6f6e2bf7", + "firstObservedAt": "2024-06-27T00:56:32.023000+02:00", + "fixAvailable": "NO", + "lastObservedAt": "2024-06-27T00:56:32.023000+02:00", + "packageVulnerabilityDetails": { + "cvss": [], + "referenceUrls": [], + "relatedVulnerabilities": [], + "source": "DEBIAN_CVE", + "sourceUrl": "https://security-tracker.debian.org/tracker/CVE-2024-37021", + "vendorSeverity": "not yet assigned", + "vulnerabilityId": "CVE-2024-37021", + "vulnerablePackages": [ + { + "arch": "AMD64", + "epoch": 0, + "fixedInVersion": "NotAvailable", + "name": "linux", + "packageManager": "OS", + "release": "2", + "remediation": "NotAvailable", + "sourceLayerHash": "sha256:11a88e76431345b48525c4e4d58d497810019f4bafdb5e2bd56dc34a05e09cc3", + "version": "4.19.118" + } + ] + }, + "remediation": { + "recommendation": { + "text": "None Provided" + } + }, + "resources": [ + { + "details": { + "awsEcrContainerImage": { + "architecture": "amd64", + "author": "John D ", + "imageHash": "sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "imageTags": [ + "2.3.0" + ], + "platform": "DEBIAN_10", + "pushedAt": "2020-06-10T11:30:35+02:00", + "registry": "012345678901", + "repositoryName": "my-awesome-docker-image" + } + }, + "id": "arn:aws:ecr:us-east-1:012345678901:repository/my-awesome-docker-image/sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "partition": "aws", + "region": "us-east-1", + "tags": {}, + "type": "AWS_ECR_CONTAINER_IMAGE" + } + ], + "severity": "UNTRIAGED", + "status": "ACTIVE", + "title": "CVE-2024-37021 - linux", + "type": "PACKAGE_VULNERABILITY", + "updatedAt": "2024-06-27T00:56:32.023000+02:00" + }, + { + "awsAccountId": "012345678901", + "description": "A flaw use-after-free in function sco_sock_sendmsg() of the Linux kernel HCI subsystem was found in the way user calls ioct UFFDIO_REGISTER or other way triggers race condition of the call sco_conn_del() together with the call sco_sock_sendmsg() with the expected controllable faulting memory page. A privileged local user could use this flaw to crash the system or escalate their privileges on the system.", + "epss": { + "score": 0.00042 + }, + "exploitAvailable": "NO", + "findingArn": "arn:aws:inspector2:us-east-1:012345678901:finding/00264176c0e6a64e6465830320e8ccd9", + "firstObservedAt": "2024-02-02T16:30:33.045000+01:00", + "fixAvailable": "YES", + "inspectorScore": 7.0, + "inspectorScoreDetails": { + "adjustedCvss": { + "adjustments": [], + "cvssSource": "NVD", + "score": 7.0, + "scoreSource": "NVD", + "scoringVector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H", + "version": "3.1" + } + }, + "lastObservedAt": "2024-06-14T04:03:53.051000+02:00", + "packageVulnerabilityDetails": { + "cvss": [ + { + "baseScore": 7.0, + "scoringVector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H", + "source": "NVD", + "version": "3.1" + } + ], + "referenceUrls": [], + "relatedVulnerabilities": [], + "source": "DEBIAN_CVE", + "sourceUrl": "https://security-tracker.debian.org/tracker/CVE-2021-3640", + "vendorSeverity": "not yet assigned", + "vulnerabilityId": "CVE-2021-3640", + "vulnerablePackages": [ + { + "arch": "AMD64", + "epoch": 0, + "fixedInVersion": "0:4.19.232-1", + "name": "linux", + "packageManager": "OS", + "release": "2", + "remediation": "apt-get update && apt-get upgrade", + "sourceLayerHash": "sha256:11a88e76431345b48525c4e4d58d497810019f4bafdb5e2bd56dc34a05e09cc3", + "version": "4.19.118" + } + ] + }, + "remediation": { + "recommendation": { + "text": "None Provided" + } + }, + "resources": [ + { + "details": { + "awsEcrContainerImage": { + "architecture": "amd64", + "author": "John D ", + "imageHash": "sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "imageTags": [ + "2.3.0" + ], + "platform": "DEBIAN_10", + "pushedAt": "2020-06-10T11:30:35+02:00", + "registry": "012345678901", + "repositoryName": "my-awesome-docker-image" + } + }, + "id": "arn:aws:ecr:us-east-1:012345678901:repository/my-awesome-docker-image/sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "partition": "aws", + "region": "us-east-1", + "tags": {}, + "type": "AWS_ECR_CONTAINER_IMAGE" + } + ], + "severity": "HIGH", + "status": "ACTIVE", + "title": "CVE-2021-3640 - linux", + "type": "PACKAGE_VULNERABILITY", + "updatedAt": "2024-06-14T04:03:53.051000+02:00" + }, + { + "awsAccountId": "012345678901", + "description": "In the Linux kernel, the following vulnerability has been resolved: net:emac/emac-mac: Fix a use after free in emac_mac_tx_buf_send In emac_mac_tx_buf_send, it calls emac_tx_fill_tpd(..,skb,..). If some error happens in emac_tx_fill_tpd(), the skb will be freed via dev_kfree_skb(skb) in error branch of emac_tx_fill_tpd(). But the freed skb is still used via skb->len by netdev_sent_queue(,skb->len). As i observed that emac_tx_fill_tpd() haven't modified the value of skb->len, thus my patch assigns skb->len to 'len' before the possible free and use 'len' instead of skb->len later.", + "epss": { + "score": 0.00044 + }, + "exploitAvailable": "NO", + "findingArn": "arn:aws:inspector2:us-east-1:012345678901:finding/0027f58875add9818da30aaf4d8d69a3", + "firstObservedAt": "2024-03-05T00:56:23.134000+01:00", + "fixAvailable": "YES", + "lastObservedAt": "2024-06-14T04:03:53.051000+02:00", + "packageVulnerabilityDetails": { + "cvss": [], + "referenceUrls": [], + "relatedVulnerabilities": [], + "source": "DEBIAN_CVE", + "sourceUrl": "https://security-tracker.debian.org/tracker/CVE-2021-47013", + "vendorSeverity": "not yet assigned", + "vulnerabilityId": "CVE-2021-47013", + "vulnerablePackages": [ + { + "arch": "AMD64", + "epoch": 0, + "fixedInVersion": "0:4.19.194-1", + "name": "linux", + "packageManager": "OS", + "release": "2", + "remediation": "apt-get update && apt-get upgrade", + "sourceLayerHash": "sha256:11a88e76431345b48525c4e4d58d497810019f4bafdb5e2bd56dc34a05e09cc3", + "version": "4.19.118" + } + ] + }, + "remediation": { + "recommendation": { + "text": "None Provided" + } + }, + "resources": [ + { + "details": { + "awsEcrContainerImage": { + "architecture": "amd64", + "author": "John D ", + "imageHash": "sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "imageTags": [ + "2.3.0" + ], + "platform": "DEBIAN_10", + "pushedAt": "2020-06-10T11:30:35+02:00", + "registry": "012345678901", + "repositoryName": "my-awesome-docker-image" + } + }, + "id": "arn:aws:ecr:us-east-1:012345678901:repository/my-awesome-docker-image/sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "partition": "aws", + "region": "us-east-1", + "tags": {}, + "type": "AWS_ECR_CONTAINER_IMAGE" + } + ], + "severity": "UNTRIAGED", + "status": "ACTIVE", + "title": "CVE-2021-47013 - linux", + "type": "PACKAGE_VULNERABILITY", + "updatedAt": "2024-06-14T04:03:53.051000+02:00" + }, + { + "awsAccountId": "012345678901", + "description": "In libxml2 before 2.9.14, several buffer handling functions in buf.c (xmlBuf*) and tree.c (xmlBuffer*) don't check for integer overflows. This can result in out-of-bounds memory writes. Exploitation requires a victim to open a crafted, multi-gigabyte XML file. Other software using libxml2's buffer functions, for example libxslt through 1.1.35, is affected as well.", + "epss": { + "score": 0.0015 + }, + "exploitAvailable": "NO", + "findingArn": "arn:aws:inspector2:us-east-1:012345678901:finding/00657fce9f7e60372fcfda10e636c2b0", + "firstObservedAt": "2024-02-02T16:30:33.045000+01:00", + "fixAvailable": "YES", + "inspectorScore": 6.5, + "inspectorScoreDetails": { + "adjustedCvss": { + "adjustments": [], + "cvssSource": "NVD", + "score": 6.5, + "scoreSource": "NVD", + "scoringVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", + "version": "3.1" + } + }, + "lastObservedAt": "2024-02-02T16:30:33.045000+01:00", + "packageVulnerabilityDetails": { + "cvss": [ + { + "baseScore": 6.5, + "scoringVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", + "source": "NVD", + "version": "3.1" + } + ], + "referenceUrls": [ + "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1010526" + ], + "relatedVulnerabilities": [], + "source": "DEBIAN_CVE", + "sourceUrl": "https://security-tracker.debian.org/tracker/CVE-2022-29824", + "vendorSeverity": "not yet assigned", + "vulnerabilityId": "CVE-2022-29824", + "vulnerablePackages": [ + { + "arch": "AMD64", + "epoch": 0, + "fixedInVersion": "0:2.9.4+dfsg1-7+deb10u4", + "name": "libxml2", + "packageManager": "OS", + "release": "7+b3", + "remediation": "apt-get update && apt-get upgrade", + "sourceLayerHash": "sha256:11a88e76431345b48525c4e4d58d497810019f4bafdb5e2bd56dc34a05e09cc3", + "version": "2.9.4+dfsg1" + }, + { + "arch": "AMD64", + "epoch": 0, + "fixedInVersion": "0:2.9.4+dfsg1-7+deb10u4", + "name": "libxml2", + "packageManager": "OS", + "release": "7", + "remediation": "apt-get update && apt-get upgrade", + "sourceLayerHash": "sha256:11a88e76431345b48525c4e4d58d497810019f4bafdb5e2bd56dc34a05e09cc3", + "version": "2.9.4+dfsg1" + } + ] + }, + "remediation": { + "recommendation": { + "text": "None Provided" + } + }, + "resources": [ + { + "details": { + "awsEcrContainerImage": { + "architecture": "amd64", + "author": "John D ", + "imageHash": "sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "imageTags": [ + "2.3.0" + ], + "platform": "DEBIAN_10", + "pushedAt": "2020-06-10T11:30:35+02:00", + "registry": "012345678901", + "repositoryName": "my-awesome-docker-image" + } + }, + "id": "arn:aws:ecr:us-east-1:012345678901:repository/my-awesome-docker-image/sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "partition": "aws", + "region": "us-east-1", + "tags": {}, + "type": "AWS_ECR_CONTAINER_IMAGE" + } + ], + "severity": "MEDIUM", + "status": "ACTIVE", + "title": "CVE-2022-29824 - libxml2, libxml2", + "type": "PACKAGE_VULNERABILITY", + "updatedAt": "2024-02-02T16:30:33.045000+01:00" + }, + { + "awsAccountId": "012345678901", + "description": "An array indexing vulnerability was found in the netfilter subsystem of the Linux kernel. A missing macro could lead to a miscalculation of the `h->nets` array offset, providing attackers with the primitive to arbitrarily increment/decrement a memory buffer out-of-bound. This issue may allow a local user to crash the system or potentially escalate their privileges on the system.", + "epss": { + "score": 0.00044 + }, + "exploitAvailable": "YES", + "exploitabilityDetails": { + "lastKnownExploitAt": "2024-07-30T09:04:56+02:00" + }, + "findingArn": "arn:aws:inspector2:us-east-1:012345678901:finding/00679d1d8da777d13bdd24b20c403aac", + "firstObservedAt": "2024-02-02T16:30:33.045000+01:00", + "fixAvailable": "YES", + "inspectorScore": 7.8, + "inspectorScoreDetails": { + "adjustedCvss": { + "adjustments": [], + "cvssSource": "NVD", + "score": 7.8, + "scoreSource": "NVD", + "scoringVector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + "version": "3.1" + } + }, + "lastObservedAt": "2024-07-31T17:59:32+02:00", + "packageVulnerabilityDetails": { + "cvss": [ + { + "baseScore": 7.8, + "scoringVector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + "source": "NVD", + "version": "3.1" + } + ], + "referenceUrls": [], + "relatedVulnerabilities": [], + "source": "DEBIAN_CVE", + "sourceUrl": "https://security-tracker.debian.org/tracker/CVE-2023-42753", + "vendorSeverity": "not yet assigned", + "vulnerabilityId": "CVE-2023-42753", + "vulnerablePackages": [ + { + "arch": "AMD64", + "epoch": 0, + "fixedInVersion": "0:4.19.304-1", + "name": "linux", + "packageManager": "OS", + "release": "2", + "remediation": "apt-get update && apt-get upgrade", + "sourceLayerHash": "sha256:11a88e76431345b48525c4e4d58d497810019f4bafdb5e2bd56dc34a05e09cc3", + "version": "4.19.118" + } + ] + }, + "remediation": { + "recommendation": { + "text": "None Provided" + } + }, + "resources": [ + { + "details": { + "awsEcrContainerImage": { + "architecture": "amd64", + "author": "John D ", + "imageHash": "sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "imageTags": [ + "2.3.0" + ], + "platform": "DEBIAN_10", + "pushedAt": "2020-06-10T11:30:35+02:00", + "registry": "012345678901", + "repositoryName": "my-awesome-docker-image" + } + }, + "id": "arn:aws:ecr:us-east-1:012345678901:repository/my-awesome-docker-image/sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "partition": "aws", + "region": "us-east-1", + "tags": {}, + "type": "AWS_ECR_CONTAINER_IMAGE" + } + ], + "severity": "HIGH", + "status": "ACTIVE", + "title": "CVE-2023-42753 - linux", + "type": "PACKAGE_VULNERABILITY", + "updatedAt": "2024-07-31T17:59:32+02:00" + }, + { + "awsAccountId": "012345678901", + "description": "An issue was discovered in the Linux kernel before 5.11.8. kernel/bpf/verifier.c performs undesirable out-of-bounds speculation on pointer arithmetic, leading to side-channel attacks that defeat Spectre mitigations and obtain sensitive information from kernel memory, aka CID-f232326f6966. This affects pointer types that do not define a ptr_limit.", + "epss": { + "score": 0.00047 + }, + "exploitAvailable": "YES", + "exploitabilityDetails": { + "lastKnownExploitAt": "2024-07-15T18:13:11+02:00" + }, + "findingArn": "arn:aws:inspector2:us-east-1:012345678901:finding/0068a17c3e52bcf1bf60921d799fae20", + "firstObservedAt": "2024-02-02T16:30:33.045000+01:00", + "fixAvailable": "YES", + "inspectorScore": 4.7, + "inspectorScoreDetails": { + "adjustedCvss": { + "adjustments": [], + "cvssSource": "NVD", + "score": 4.7, + "scoreSource": "NVD", + "scoringVector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N", + "version": "3.1" + } + }, + "lastObservedAt": "2024-07-31T17:59:32+02:00", + "packageVulnerabilityDetails": { + "cvss": [ + { + "baseScore": 4.7, + "scoringVector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N", + "source": "NVD", + "version": "3.1" + } + ], + "referenceUrls": [], + "relatedVulnerabilities": [], + "source": "DEBIAN_CVE", + "sourceUrl": "https://security-tracker.debian.org/tracker/CVE-2020-27170", + "vendorSeverity": "unimportant", + "vulnerabilityId": "CVE-2020-27170", + "vulnerablePackages": [ + { + "arch": "AMD64", + "epoch": 0, + "fixedInVersion": "0:4.19.181-1", + "name": "linux", + "packageManager": "OS", + "release": "2", + "remediation": "apt-get update && apt-get upgrade", + "sourceLayerHash": "sha256:11a88e76431345b48525c4e4d58d497810019f4bafdb5e2bd56dc34a05e09cc3", + "version": "4.19.118" + } + ] + }, + "remediation": { + "recommendation": { + "text": "None Provided" + } + }, + "resources": [ + { + "details": { + "awsEcrContainerImage": { + "architecture": "amd64", + "author": "John D ", + "imageHash": "sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "imageTags": [ + "2.3.0" + ], + "platform": "DEBIAN_10", + "pushedAt": "2020-06-10T11:30:35+02:00", + "registry": "012345678901", + "repositoryName": "my-awesome-docker-image" + } + }, + "id": "arn:aws:ecr:us-east-1:012345678901:repository/my-awesome-docker-image/sha256:d667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "partition": "aws", + "region": "us-east-1", + "tags": {}, + "type": "AWS_ECR_CONTAINER_IMAGE" + } + ], + "severity": "MEDIUM", + "status": "ACTIVE", + "title": "CVE-2020-27170 - linux", + "type": "PACKAGE_VULNERABILITY", + "updatedAt": "2024-07-31T17:59:32+02:00" + }, + { + "awsAccountId": "012345678901", + "description": "The xz_decomp function in xzlib.c in libxml2 2.9.1 does not properly detect compression errors, which allows context-dependent attackers to cause a denial of service (process hang) via crafted XML data.", + "epss": { + "score": 0.0097 + }, + "exploitAvailable": "NO", + "findingArn": "arn:aws:inspector2:us-east-1:012345678901:finding/000e155e74c3ccb3b2e13d08a65ccafc", + "firstObservedAt": "2023-07-30T11:11:39.233000+02:00", + "fixAvailable": "YES", + "lastObservedAt": "2024-03-19T15:31:08.006000+01:00", + "packageVulnerabilityDetails": { + "cvss": [ + { + "baseScore": 2.6, + "scoringVector": "AV:N/AC:H/Au:N/C:N/I:N/A:P", + "source": "NVD", + "version": "2.0" + } + ], + "referenceUrls": [ + "https://security.gentoo.org/glsa/201701-37", + "https://support.apple.com/HT206168", + "https://support.apple.com/HT206167", + "https://bugzilla.gnome.org/show_bug.cgi?id=757466", + "https://support.apple.com/HT206166", + "https://support.apple.com/HT206169" + ], + "relatedVulnerabilities": [], + "source": "NVD", + "sourceUrl": "https://nvd.nist.gov/vuln/detail/CVE-2015-8035", + "vendorCreatedAt": "2015-11-18T17:59:09+01:00", + "vendorSeverity": "LOW", + "vendorUpdatedAt": "2019-03-08T17:06:36+01:00", + "vulnerabilityId": "CVE-2015-8035", + "vulnerablePackages": [ + { + "arch": "X86_64", + "epoch": 0, + "fixedInVersion": "0:2.9.1-6.el7.4", + "name": "libxml2", + "packageManager": "OS", + "release": "6.el7_2.3", + "remediation": "yum update libxml2", + "version": "2.9.1" + }, + { + "arch": "X86_64", + "epoch": 0, + "fixedInVersion": "0:2.9.1-6.el7.4", + "name": "libxml2-python", + "packageManager": "OS", + "release": "6.el7_2.3", + "remediation": "yum update libxml2-python", + "version": "2.9.1" + } + ] + }, + "remediation": { + "recommendation": { + "text": "None Provided" + } + }, + "resources": [ + { + "details": { + "awsEc2Instance": { + "iamInstanceProfileArn": "arn:aws:iam::012345678901:instance-profile/AmazonEC2RoleforSSM", + "imageId": "ami-01234567890abcdef", + "ipV4Addresses": [ + "8.84.11.16", + "10.52.88.71" + ], + "ipV6Addresses": [], + "keyName": "my-key", + "launchedAt": "2023-07-30T17:07:50+02:00", + "platform": "CENTOS_7", + "subnetId": "subnet-01234567890abcdef", + "type": "t3a.2xlarge", + "vpcId": "vpc-01234567890abcdef" + } + }, + "id": "i-0b22a22eec53b9321", + "partition": "aws", + "region": "us-east-1", + "tags": { + "Backup_Policy": "Monthly", + "Name": "my-instance" + }, + "type": "AWS_EC2_INSTANCE" + } + ], + "severity": "LOW", + "status": "ACTIVE", + "title": "CVE-2015-8035 - libxml2, libxml2-python", + "type": "PACKAGE_VULNERABILITY", + "updatedAt": "2024-03-19T15:31:08.006000+01:00" + } + ] +} \ No newline at end of file diff --git a/unittests/scans/aws_inspector2/aws_inspector2_one_vul.json b/unittests/scans/aws_inspector2/aws_inspector2_one_vul.json new file mode 100644 index 00000000000..dac01fadd20 --- /dev/null +++ b/unittests/scans/aws_inspector2/aws_inspector2_one_vul.json @@ -0,0 +1,89 @@ +{ + "findings": [ + { + "awsAccountId": "012345678901", + "description": "A memory leak flaw was found in the Linux kernel in the ccp_run_aes_gcm_cmd() function in drivers/crypto/ccp/ccp-ops.c, which allows attackers to cause a denial of service (memory consumption). This vulnerability is similar with the older CVE-2019-18808.", + "epss": { + "score": 0.00075 + }, + "exploitAvailable": "NO", + "findingArn": "arn:aws:inspector2:us-east-1:012345678901:finding/00031f625ee77ac186869f906eb73366", + "firstObservedAt": "2024-02-02T16:30:33.045000+01:00", + "fixAvailable": "YES", + "inspectorScore": 5.5, + "inspectorScoreDetails": { + "adjustedCvss": { + "adjustments": [], + "cvssSource": "NVD", + "score": 5.5, + "scoreSource": "NVD", + "scoringVector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H", + "version": "3.1" + } + }, + "lastObservedAt": "2024-06-14T04:03:53.051000+02:00", + "packageVulnerabilityDetails": { + "cvss": [ + { + "baseScore": 5.5, + "scoringVector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H", + "source": "NVD", + "version": "3.1" + } + ], + "referenceUrls": [], + "relatedVulnerabilities": [], + "source": "DEBIAN_CVE", + "sourceUrl": "https://security-tracker.debian.org/tracker/CVE-2021-3744", + "vendorSeverity": "unimportant", + "vulnerabilityId": "CVE-2021-3744", + "vulnerablePackages": [ + { + "arch": "AMD64", + "epoch": 0, + "fixedInVersion": "0:4.19.232-1", + "name": "linux", + "packageManager": "OS", + "release": "2", + "remediation": "apt-get update && apt-get upgrade", + "sourceLayerHash": "sha256:11a88e76431345b48525c4e4d58d497810019f4bafdb5e2bd56dc34a05e09cc3", + "version": "4.19.118" + } + ] + }, + "remediation": { + "recommendation": { + "text": "None Provided" + } + }, + "resources": [ + { + "details": { + "awsEcrContainerImage": { + "architecture": "amd64", + "author": "John D ", + "imageHash": "sha256:c667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "imageTags": [ + "2.3.0" + ], + "platform": "DEBIAN_10", + "pushedAt": "2020-06-10T11:30:35+02:00", + "registry": "012345678901", + "repositoryName": "my-awesome-docker-image" + } + }, + "id": "arn:aws:ecr:us-east-1:012345678901:repository/my-awesome-docker-image/sha256:c667ad018b538adadb5bd1db75836c8561b23bc7d31d9cd8941fa74f5df93802", + "partition": "aws", + "region": "us-east-1", + "tags": {}, + "type": "AWS_ECR_CONTAINER_IMAGE" + } + ], + "severity": "MEDIUM", + "status": "ACTIVE", + "title": "CVE-2021-3744 - linux", + "type": "PACKAGE_VULNERABILITY", + "updatedAt": "2024-06-14T04:03:53.051000+02:00" + } + ] +} \ No newline at end of file diff --git a/unittests/scans/aws_inspector2/aws_inspector2_zero_vul.json b/unittests/scans/aws_inspector2/aws_inspector2_zero_vul.json new file mode 100644 index 00000000000..1ed172b30bc --- /dev/null +++ b/unittests/scans/aws_inspector2/aws_inspector2_zero_vul.json @@ -0,0 +1,3 @@ +{ + "findings": [] +} \ No newline at end of file diff --git a/unittests/scans/aws_inspector2/empty_with_error.json b/unittests/scans/aws_inspector2/empty_with_error.json new file mode 100644 index 00000000000..9e26dfeeb6e --- /dev/null +++ b/unittests/scans/aws_inspector2/empty_with_error.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/unittests/tools/test_aws_inspector2_parser.py b/unittests/tools/test_aws_inspector2_parser.py new file mode 100644 index 00000000000..f023bec88a2 --- /dev/null +++ b/unittests/tools/test_aws_inspector2_parser.py @@ -0,0 +1,46 @@ +from django.test import TestCase + +from dojo.models import Test +from dojo.tools.aws_inspector2.parser import AWSInspector2Parser + + +class TestAWSInspector2Parser(TestCase): + + def test_aws_inspector2_parser_with_no_vuln_has_no_findings(self): + with open("unittests/scans/aws_inspector2/aws_inspector2_zero_vul.json", encoding="utf-8") as testfile: + parser = AWSInspector2Parser() + findings = parser.get_findings(testfile, Test()) + testfile.close() + self.assertEqual(0, len(findings)) + + def test_aws_inspector2_parser_with_one_vuln_has_one_findings(self): + with open("unittests/scans/aws_inspector2/aws_inspector2_one_vul.json", encoding="utf-8") as testfile: + parser = AWSInspector2Parser() + findings = parser.get_findings(testfile, Test()) + testfile.close() + for finding in findings: + for endpoint in finding.unsaved_endpoints: + endpoint.clean() + self.assertEqual(1, len(findings)) + self.assertEqual("CVE-2021-3744 - linux", findings[0].title) + self.assertEqual("Medium", findings[0].severity) + + def test_aws_inspector2_parser_with_many_vuln_has_many_findings(self): + with open("unittests/scans/aws_inspector2/aws_inspector2_many_vul.json", encoding="utf-8") as testfile: + parser = AWSInspector2Parser() + findings = parser.get_findings(testfile, Test()) + testfile.close() + for finding in findings: + for endpoint in finding.unsaved_endpoints: + endpoint.clean() + self.assertEqual(8, len(findings)) + + def test_aws_inspector2_parser_empty_with_error(self): + with self.assertRaises(TypeError) as context: + with open("unittests/scans/aws_inspector2/empty_with_error.json", encoding="utf-8") as testfile: + parser = AWSInspector2Parser() + parser.get_findings(testfile, Test()) + testfile.close() + self.assertTrue( + "Incorrect Inspector2 report format" in str(context.exception), + )