Shodan CLI is the official command-line client for Shodan, widely known as “the search engine for internet-connected devices.” While Shodan.io is best known for its web interface, the CLI tool allows penetration testers and researchers to programmatically query Shodan’s enormous database of pre-scanned internet-facing hosts — including their open ports, running services, banners, SSL certificates, and known vulnerabilities — directly from a terminal or automated script, without sending a single packet to the target themselves. This makes Shodan CLI an entirely passive reconnaissance technique, since all data comes from Shodan’s own pre-existing internet-wide scans rather than live probes against the target.
Installation
Shodan CLI is a Python package installed via pip.
# Install via pip (Kali/Debian/any Linux with Python 3)
pip3 install shodan --break-system-packages
# Verify installation
shodan version
An API key (free tier available, with expanded features on paid plans) is required and is configured once:
shodan init YOUR_API_KEY
Syntax
shodan COMMAND [OPTIONS] [ARGUMENTS]
Command-Line Options
Top-level commands:
| Command | Description |
|---|---|
shodan init KEY | Initialize the CLI with your Shodan API key |
shodan info | Display information about your account/API plan and query credits |
shodan search QUERY | Search Shodan’s database using a query string |
shodan count QUERY | Return only the total number of results for a query (does not use query credits) |
shodan host IP | Show all known information about a specific IP address |
shodan download FILE QUERY | Download raw search results to a compressed file for offline processing |
shodan parse FILE | Parse a previously downloaded .json.gz result file |
shodan scan submit IP | Submit an IP/network for Shodan to actively scan (requires scan credits) |
shodan scan list | List your submitted scan requests and their status |
shodan alert create | Create a network monitoring alert for a given IP range |
shodan myip | Show your current public IP address as seen by Shodan |
shodan stats QUERY | Show summary/faceted statistics for a search query |
shodan domain DOMAIN | Show subdomains and DNS data known to Shodan for a domain |
shodan honeyscore IP | Estimate the probability that a given IP is a honeypot |
Common flags used with search/count/download:
| Flag | Description |
|---|---|
--fields FIELD1,FIELD2 | Specify which fields to display in output |
--limit NUM | Limit the number of results returned |
--separator STR | Field separator character for output |
-- facets FACET1,FACET2 | Return aggregated statistics grouped by field (e.g., country, org) |
Basic Usage
shodan search apache
Expected output:
93.184.216.34 80 Example Hosting US Apache httpd 2.4.41
203.0.113.5 443 Some ISP DE Apache httpd 2.4.52
Practical Examples
Example 1 — Basic keyword search
shodan search nginx
198.51.100.10 80 Example Cloud US nginx 1.18.0
198.51.100.44 443 Example Cloud US nginx 1.20.1
Example 2 — Search for a specific organization’s exposed hosts
shodan search 'org:"Example Corp"'
93.184.216.34 443 Example Corp US nginx
93.184.216.90 22 Example Corp US OpenSSH 8.2
Example 3 — Get only the result count (no credits used)
shodan count 'apache country:"US"'
1,204,532
Example 4 — Look up all known info for a specific IP
shodan host 93.184.216.34
93.184.216.34
Hostnames: example.com
Country: United States
Organization: Example Hosting
Ports: 80, 443
80/tcp Apache httpd 2.4.41
443/tcp Apache httpd 2.4.41 (SSL cert CN=example.com)
Example 5 — Search for exposed hosts by domain
shodan domain example.com
Domain: example.com
Subdomains found:
www.example.com
mail.example.com
dev.example.com
Example 6 — Search using specific field filters
shodan search 'port:3389 country:"US"' --limit 5
203.0.113.10 3389 Example ISP US RDP (Windows)
203.0.113.55 3389 Example ISP US RDP (Windows)
Example 7 — Statistics/faceted search (top countries running a service)
shodan stats --facets country 'product:"MySQL"'
Top Values for Facet: country
US 124,552
CN 98,341
DE 45,102
Example 8 — Download raw results for offline analysis
shodan download results 'apache country:"US"' --limit 1000
Downloading: 1000 results to results.json.gz
Example 9 — Parse a downloaded results file
shodan parse --fields ip_str,port,org results.json.gz
198.51.100.10 80 Example Cloud
198.51.100.44 443 Example Cloud
Example 10 — Check honeypot probability for a suspicious IP
shodan honeyscore 198.51.100.99
0.9 — Likely a honeypot
Common Use Cases
- Passive discovery of a target organization’s internet-facing infrastructure without sending any packets directly to it.
- Identifying outdated/vulnerable software versions running on exposed services (e.g., old Apache, unpatched RDP, exposed databases).
- Attack-surface monitoring — setting up alerts (
shodan alert create) to be notified when new services appear on a monitored IP range. - Verifying whether internal systems (databases, IoT devices, industrial control systems) are unintentionally exposed to the public internet.
- Threat intelligence — checking if a suspicious IP might be a honeypot before interacting further with it.
Automation with Bash
Automated exposure check for a target organization:
#!/bin/bash
# shodan_org_check.sh
ORG="$1"
echo "[*] Searching Shodan for organization: $ORG"
shodan search "org:\"$ORG\"" --fields ip_str,port,org,product > "${ORG// /_}_shodan_results.txt"
cat "${ORG// /_}_shodan_results.txt"
Scheduled monitoring script comparing new exposures over time:
#!/bin/bash
# shodan_monitor.sh
QUERY='org:"Example Corp"'
DATE=$(date +%F)
shodan search "$QUERY" --fields ip_str,port > "shodan_${DATE}.txt"
PREV=$(ls -t shodan_*.txt 2>/dev/null | sed -n 2p)
if [ -n "$PREV" ]; then
echo "[*] New exposures since last scan:"
comm -13 <(sort "$PREV") <(sort "shodan_${DATE}.txt")
fi
Tips and Best Practices
- Use
shodan countliberally during query development — it does not consume query credits, letting you refine complex search filters before running the credit-consumingsearchcommand. - Combine multiple filters (
org:,port:,country:,product:) for precise, high-signal results rather than broad single-keyword searches. - Set up
shodan alert createfor continuous monitoring of your own organization’s IP ranges as a proactive external attack-surface management practice. - Remember that Shodan’s data reflects its last scan date, which can be days, weeks, or months old — always cross-verify critical findings with a live, authorized scan before reporting.
- Use the
--fieldsflag to keep output clean and script-parseable rather than relying on the default verbose format.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
Error: Invalid API key | API key not initialized or expired | Run shodan init YOUR_API_KEY again with a valid key from your Shodan account dashboard |
Error: No query credits available | Free-tier daily query credit limit exhausted | Wait for daily credit reset, or upgrade to a paid Shodan membership/API plan |
| Search returns 0 results unexpectedly | Overly specific or malformed query syntax | Simplify the query incrementally; verify filter syntax against Shodan’s search filter documentation |
shodan host IP returns “no information available” | Shodan has never scanned that IP, or it’s not internet-facing | Use shodan scan submit IP (uses scan credits) to request a fresh scan, if authorized |
| Data appears outdated compared to current live state | Shodan’s dataset reflects its last scan timestamp | Check the last_update field in results; request a rescan if current data is critical |
References
- Official Shodan CLI documentation: https://cli.shodan.io/
- Shodan search filter reference: https://www.shodan.io/search/filters
- Shodan API documentation: https://developer.shodan.io/api
- Kali Linux tool page: https://www.kali.org/tools/shodan/