Passive external reconnaissance tool for public IPv4 addresses using the Shodan API. Returns open ports, service banners, product versions, SSL/TLS certificate details, geolocation, ASN, and CVE exposure — without sending any traffic to the target.
Built as part of a GRC and information security home lab portfolio.
- Third-party vendor risk assessments — gain an independent, passive view of a vendor's external attack surface without relying solely on self-attestation
- Attack surface discovery — enumerate what services and ports are exposed on known IP ranges
- SSL/TLS certificate monitoring — surface near-expiry or already-expired certificates across vendor infrastructure
- CVE exposure identification — identify vulnerable service versions via Shodan's banner fingerprinting
NIST CSF alignment:
ID.AM— Asset inventory and external footprint visibilityID.RA— Risk identification via CVE and banner fingerprinting
Enter IP address to look up: 1.1.1.1
==================================================
IP: 1.1.1.1
Hostnames: one.one.one.one
Organization: APNIC and Cloudflare DNS Resolver project
ISP: Cloudflare, Inc.
ASN: AS13335
Country: Australia
City: Brisbane
Open Ports: [53, 80, 443, 2082, 2083, 2086, 2087, 8080, 8443, 8880]
Last Updated: 2026-05-07T11:40:14.110440
Tags: ['vpn']
Vulns: none detected
==================================================
--- Service Banners ---
Port 443/TCP | https
Product: CloudFlare
CPE: ['cpe:/a:cloudflare:cloudflare']
SSL CN: cloudflare-dns.com
SSL Exp: 2026-12-21 (224 days remaining)
- Python 3.7+
- Shodan API key (free tier at account.shodan.io)
pip install shodan python-dotenv
-
Clone the repository:
git clone https://github.com/aarondutton-grc/shodan-host-lookup.git cd shodan-host-lookup -
Create a
.envfile in the project root:SHODAN_API_KEY=your_key_here -
Run the script:
python ShodanHostLookup.py
The script validates input before making any API calls:
- Rejects non-IPv4 input (hostnames, strings, malformed addresses)
- Rejects private, loopback, link-local, multicast, reserved, and RFC 5737 documentation ranges using Python's stdlib
ipaddressmodule — these will never have Shodan data and would otherwise return a 403
| Behavior | Detail |
|---|---|
| Query credits | ~100/month on free tier |
| Cached IPs | High-traffic IPs (8.8.8.8, 1.1.1.1) are often served from Shodan cache and may not consume a credit |
| 403 on valid IP | Either no Shodan data exists for that IP, or monthly credit limit reached |
| Hostname lookups | Not supported on the free tier — IPv4 addresses only |
Safe IPs for testing:
| IP | Host | Notes |
|---|---|---|
8.8.8.8 |
Google DNS | Clean, minimal exposure, usually cached |
1.1.1.1 |
Cloudflare DNS | Clean, usually cached |
45.33.32.156 |
scanme.nmap.org | Intentionally open, many CVEs — burns a credit |
203.0.113.0 |
RFC 5737 TEST-NET-3 | Blocked pre-API — tests reserved IP handling |
- Python API integration with key management via
python-dotenv - Input validation using regex and stdlib
ipaddressmodule (RFC 1918, RFC 5737) - Defensive coding for inconsistent API response schemas (CVE field returned as dict or list depending on IP)
- SSL/TLS certificate expiry parsing from ASN.1 format with human-readable output
- GRC-framed security tooling aligned to NIST CSF ID.AM and ID.RA
- Passive external reconnaissance methodology applicable to third-party vendor risk assessments
MIT — see LICENSE
Aaron Dutton