Back to Checks
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 CloudRun
prowler aws --checks ec2_elastic_ip_shodanRecommendation
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