Category: Threat Intel
Tags: shodan, osint, reconnaissance, iot-security, attack-surface
Every device connected to the internet is broadcasting something. A web server announces its software version. A database helpfully confirms it has no authentication. An industrial control system cheerfully waves at anyone who asks. Shodan is the search engine that catalogues all of this -- the Google of internet-connected devices, except instead of finding recipes and cat videos, it finds exposed MongoDB instances and unprotected SCADA systems.
Shodan continuously scans the entire IPv4 address space, grabbing banners from every responding port and indexing the results. It's an invaluable tool for security professionals mapping attack surfaces, and an equally invaluable reminder that a terrifying number of devices are connected to the internet with all the security of a screen door on a submarine.
Getting Started
Installation and API Key
pip install shodan
shodan init YOUR_API_KEY
shodan info # Check credits and plan
Free accounts get limited results and scan credits. Academic and small business plans unlock the full dataset. The API key gates everything -- CLI, web interface, and Python library all use it.
CLI Basics
# Search for a term
shodan search apache
# Look up a specific host
shodan host 8.8.8.8
# Count results without consuming query credits
shodan count "port:3389 country:US"
# Download results for offline analysis
shodan download results "product:nginx"
shodan parse --fields ip_str,port,org results.json.gz
# Scan a specific IP (uses scan credits)
shodan scan submit 1.2.3.4
# Real-time stream (enterprise plans)
shodan stream --fields ip_str,port,data
The count command is your best friend during initial research -- it tells you how many results exist without burning query credits. Use it to refine filters before committing to a full search.
Search Filters
Shodan's power lies in its filter system. Combine filters to narrow results from millions to the specific devices you're looking for.
Core Filters
| Filter | Example | What It Finds |
|---|---|---|
port: |
port:22 |
Services on a specific port |
org: |
org:"Google" |
Devices owned by an organisation |
country: |
country:DE |
Devices in a country (two-letter code) |
city: |
city:"London" |
Devices in a city |
product: |
product:nginx |
Specific software |
version: |
version:1.6.2 |
Specific software version |
os: |
os:"Windows 10" |
Operating system |
net: |
net:192.168.0.0/24 |
CIDR range |
hostname: |
hostname:example.com |
Reverse DNS hostname |
vuln: |
vuln:CVE-2021-44228 |
Known vulnerability (paid plans) |
Web and Certificate Filters
| Filter | Example | What It Finds |
|---|---|---|
http.title: |
http.title:"Dashboard" |
HTTP page title |
http.status: |
http.status:200 |
HTTP response code |
http.component: |
http.component:jQuery |
Web technology in use |
ssl.cert.subject.cn: |
ssl.cert.subject.cn:example.com |
SSL certificate common name |
ssl.cert.expired: |
ssl.cert.expired:true |
Expired certificates |
has_screenshot: |
has_screenshot:true |
Has VNC/RDP screenshot |
Combining Filters
# Apache servers in Germany running version 2.4
product:apache version:2.4 country:DE
# Windows RDP exposed to the internet in the US
port:3389 country:US os:"Windows"
# Nginx servers with expired SSL certificates
product:nginx ssl.cert.expired:true
# Devices on a specific network range running SSH
net:203.0.113.0/24 port:22
Dorks for Finding Exposed Services
This is where Shodan gets both useful and slightly terrifying. These queries find real, exposed services -- which is exactly why they should only be used for authorised security assessments and research.
Exposed Databases
# MongoDB with no authentication (there are always thousands)
port:27017 "MongoDB Server Information"
# Elasticsearch clusters wide open
port:9200 "elasticsearch"
# Redis without AUTH
port:6379 "redis_version"
# PostgreSQL accepting connections
port:5432 "PostgreSQL"
# MySQL greeting the world
product:MySQL port:3306
The number of production databases directly exposed to the internet is genuinely alarming. MongoDB alone has been responsible for enough data breaches to fill a very depressing spreadsheet.
Industrial Control Systems
# Modbus (ICS protocol with no authentication by design)
port:502 "Modbus"
# BACnet (building automation)
port:47808 "BACnet"
# DNP3 (power grid protocol)
port:20000 "DNP3"
# Vendor-specific
"Schneider Electric"
"Siemens, SIMATIC"
Finding internet-exposed ICS systems is less "if" and more "how many." These protocols were designed for isolated networks decades before anyone considered connecting them to the internet. See ICS/OT Security 102: Protocols for why this keeps security professionals awake at night.
Remote Access
# RDP with screenshots
port:3389 has_screenshot:true country:US
# VNC with no authentication
"authentication disabled" port:5900
# Default credential web interfaces
"default password" port:80
http.title:"RouterOS" port:8291
Webcams and IoT
# RTSP cameras
has_screenshot:true port:554
# Webcam software
webcamxp
"Server: yawcam"
# Printers (yes, internet-connected printers)
port:9100 "HP"
Python API
For anything beyond quick lookups, the Python API provides programmatic access to Shodan's full dataset.
import shodan
api = shodan.Shodan('YOUR_API_KEY')
# Basic search
results = api.search('apache')
print(f"Total results: {results['total']}")
for match in results['matches']:
print(f"{match['ip_str']}:{match['port']} - {match.get('org', 'N/A')}")
# Host lookup with full detail
host = api.host('8.8.8.8')
print(f"OS: {host.get('os', 'Unknown')}")
print(f"Ports: {host['ports']}")
for item in host['data']:
print(f" {item['port']}/{item['transport']}: {item.get('product', '?')}")
# Count without using query credits
count = api.count('port:22 country:GB')
print(f"SSH servers in the UK: {count['total']}")
# DNS resolution
resolved = api.dns.resolve(['google.com', 'cloudflare.com'])
for domain, ip in resolved.items():
print(f"{domain} -> {ip}")
# Vulnerability search
exploits = api.exploits.search('apache 2.4')
for e in exploits['matches']:
cves = e.get('cve', ['N/A'])
print(f"{cves} - {e['description'][:80]}")
Practical: Monitor Your Own Attack Surface
import shodan
api = shodan.Shodan('YOUR_API_KEY')
ORG_NAME = "Your Organisation"
results = api.search(f'org:"{ORG_NAME}"')
print(f"Internet-facing assets for {ORG_NAME}: {results['total']}")
for match in results['matches']:
port = match['port']
product = match.get('product', 'Unknown')
vulns = match.get('vulns', {})
print(f" {match['ip_str']}:{port} - {product}")
if vulns:
print(f" Vulnerabilities: {', '.join(vulns.keys())}")
Shodan Monitor
Continuous monitoring alerts you when new services appear on your network -- or when existing ones change. Useful for catching shadow IT, misconfigured deployments, and that one developer who keeps exposing test databases to the internet.
# Create a monitoring alert for your network
shodan alert create "Production Network" 203.0.113.0/24
# List active alerts
shodan alert list
# Available trigger types
shodan alert triggers
# Enable notifications for new services
shodan alert enable <alert-id> new_service
# Check alert status
shodan alert info <alert-id>
Combine with the Python API for automated alerting:
alerts = api.alerts()
for alert in alerts:
print(f"Alert: {alert['name']} - {alert['size']} IPs monitored")
Defensive Takeaways
Shodan doesn't create exposure -- it reveals it. If Shodan can find your exposed database, so can everyone else. Some practical steps:
- Search for yourself first. Run
org:"Your Company"and see what Shodan already knows about your infrastructure - Set up Shodan Monitor for your IP ranges. Know before an attacker does
- Close unnecessary ports. If a service doesn't need internet access, it shouldn't have it
- Check SSL certificates. Expired certs signal neglected infrastructure
- Audit IoT and OT devices. These are frequently deployed without security review and forgotten about
- OSINT 101: Dark Web Investigations -- when surface-level OSINT isn't enough
- Offensive Security 102: Reconnaissance -- where Shodan fits in the recon phase
- ICS/OT Security 102: Protocols -- why those Modbus results are so concerning
- Cloud Security 101: Architecture -- securing what Shodan can see in the cloud




