Back to Checks
aws

EC2 Elastic IP address is not listed in Shodan

ec2_elastic_ip_shodan
Service: ec2Severity: medium
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:AwsEc2Eip

EC2 Elastic IPs are compared with Shodan's index to identify publicly reachable addresses that have been scanned and cataloged, including metadata such as open ports, ISP, and geolocation

Risk

Being listed on Shodan confirms Internet exposure and reveals open services, versions, and banners. Adversaries can rapidly target these hosts for credential attacks and CVE exploits, threatening confidentiality (data access), integrity (system takeover), and availability (service disruption).

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks ec2_elastic_ip_shodan

Recommendation

Reduce attack surface with defense in depth:

  • Avoid public exposure; use private networking or proxies
  • Enforce least-privilege ingress rules; close unused ports
  • Patch and harden services; limit verbose banners
  • Rotate exposed IPs and continuously monitor external visibility

Remediation

Other

1In the AWS Console, go to EC2
2In the left pane, select Network & Security > Elastic IPs
3Select the flagged Elastic IP
4If it is associated: click Actions > Disassociate Elastic IP address > Disassociate
5Click Actions > Release Elastic IP address > Release

Check Code

import shodan

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.lib.logger import logger
from prowler.providers.aws.services.ec2.ec2_client import ec2_client


class ec2_elastic_ip_shodan(Check):
    def execute(self):
        findings = []
        shodan_api_key = ec2_client.audit_config.get("shodan_api_key")
        if shodan_api_key:
            api = shodan.Shodan(shodan_api_key)
            for eip in ec2_client.elastic_ips:
                report = Check_Report_AWS(metadata=self.metadata(), resource=eip)
                if eip.public_ip:
                    try:
                        shodan_info = api.host(eip.public_ip)
                        report.status = "FAIL"
                        report.status_extended = f"Elastic IP {eip.public_ip} listed in Shodan with open ports {str(shodan_info['ports'])} and ISP {shodan_info['isp']} in {shodan_info['country_name']}. More info at https://www.shodan.io/host/{eip.public_ip}."
                        report.resource_id = eip.public_ip
                        findings.append(report)
                    except shodan.APIError as error:
                        if "No information available for that IP" in error.value:
                            report.status = "PASS"
                            report.status_extended = (
                                f"Elastic IP {eip.public_ip} is not listed in Shodan."
                            )
                            report.resource_id = eip.public_ip
                            findings.append(report)
                            continue
                        else:
                            logger.error(f"Unknown Shodan API Error: {error.value}")

        else:
            logger.error(
                "No Shodan API Key -- Please input a Shodan API Key with -N/--shodan or in config.yaml"
            )
        return findings