0x00 Introduction

---

Shodan is a search engine for network devices. Using the Shodan API for searches not only provides richer data but also enables automated analysis by integrating with your own programs.

This article will introduce considerations when using the Shodan API, share usage insights, and script development techniques.

0x01 This article will cover the following topics

---

  • Basic usage of the Shodan API
  • Using Python to call the Shodan API to obtain search results
  • Further processing of search results
  • Differences between the three types of credits
  • Exporting search results from the Shodan website and further processing

0x02 Basic usage of the Shodan API

---

1. Register an account and obtain an API Key

Test API Key is: SkVS0RAbiTQpzzEsahqnq2Hv6SwjUfs3

2. Install Python package

pip install shodan

3. Obtain search results via Shodan CLI

Reference materials:

https://cli.shodan.io/

Note:

Only 100 search results are available without payment

CLI stands for command-line interface, which is Shodan's command-line mode

On Windows systems, using pip install generates the file Shodan.exe in the same directory

As shown in the figure below

Alt text

(1) Initialization

shodan init

The actual command is:

shodan init SkVS0RAbiTQpzzEsahqnq2Hv6SwjUfs3

as shown in the figure below

Alt text

(2) Search for the quantity of specified content (apache)

shodan count apache

as shown in the figure below

Alt text

Obtain result 23803090

(3) Search for information on specified content (apache)

shodan search --fields ip_str,port,org,hostnames apache

Search keyword: apache

Output: ip_str,port,org,hostnames

(4) Download search results for specified content (apache)

shodan download result apache

Search keyword: apache

Save file name: result.json.gz

As shown in the figure below

Alt text

(5) Parse the file to obtain search results

shodan parse --fields ip_str,port,org --separator , result.json.gz

As shown in the figure below

Alt text

(6) Search for information on a specified IP

shodan host 189.201.128.250

As shown in the figure below

Alt text

0x03 Differences between the three types of credits

---

Shodan has three types of credits:

  • Export credits
  • Query credits
  • Scan credits

Official documentation:

https://help.shodan.io/the-basics/credit-types-explained

Simple explanation:

Export Credits

Used when downloading data from the Shodan official website

1 export credit = 10,000 results

Note:

Exporting results consumes one credit per export, regardless of the number of results obtained, up to a maximum of 10,000 results

Does not renew at the beginning of the month

Query Credits

Used when calling the Shodan API

1 query credit = 100 results

Renews at the beginning of the month, meaning if you only purchase a one-month membership, it will reset to zero the following month

Scan Credits

Used when calling the Shodan API

1 scan credit = 1 IP

Updated at the beginning of the month

0x04 Obtaining search results by calling the Shodan API via Python

---

Note:

Without payment, not only are search filters unavailable, but only 100 search results can be obtained

(1) Search for information on specified content (Apache)

Python code is as follows:

import shodan
SHODAN_API_KEY = "SkVS0RAbiTQpzzEsahqnq2Hv6SwjUfs3"
api = shodan.Shodan(SHODAN_API_KEY)
try:
results = api.search('Apache')
print 'Results found: %s' % results['total']
for result in results['matches']:
print ("%s:%s|%s|%s"%(result['ip_str'],result['port'],result['location']['country_name'],result['hostnames']))
except shodan.APIError, e:
print 'Error: %s' % e

As shown in the figure below

Alt text

If not paid, search filters cannot be used, such as Apache country:"US"

(2) Search for specified content and write the obtained IPs to a file

Python code is as follows:

import shodan
SHODAN_API_KEY = "SkVS0RAbiTQpzzEsahqnq2Hv6SwjUfs3"
api = shodan.Shodan(SHODAN_API_KEY)
file_object = open('ip.txt', 'w')
try:
results = api.search('Apache')
print 'Results found: %s' % results['total']
for result in results['matches']:
# print result['ip_str']
file_object.writelines(result['ip_str']+'\n')
except shodan.APIError, e:
print 'Error: %s' % e
file_object.close()

(3) Specify search criteria via command line arguments and write the found IPs to a file

Python code is as follows:

import shodan
import sys
SHODAN_API_KEY = "SkVS0RAbiTQpzzEsahqnq2Hv6SwjUfs3"
api = shodan.Shodan(SHODAN_API_KEY)
if len(sys.argv)<2:
print '[!]Wrong parameter'
sys.exit(0)
print '[*]Search string: %s' % sys.argv[1]

file_object = open('ip.txt', 'w')
try:
results = api.search(sys.argv[1])
print '[+]Results found: %s' % results['total']
for result in results['matches']:
# print result['ip_str']
file_object.writelines(result['ip_str']+'\n')
except shodan.APIError, e:
print 'Error: %s' % e
file_object.close()

Command line parameters:

search.py apache

Note:

If searching for multiple keywords, enclose the search criteria in quotes, for example:

search.py "apache country:US"

(4) Read IP list from file and reverse lookup IP information

Python code is as follows:

import shodan
import sys
reload(sys)
sys.setdefaultencoding('utf8')
SHODAN_API_KEY = "SkVS0RAbiTQpzzEsahqnq2Hv6SwjUfs3"
api = shodan.Shodan(SHODAN_API_KEY)
def searchip(str):
try:
host = api.host(str)
except shodan.exception.APIError:
print "[!]No information available"
print "---------------------------------------------"
return
else:
# Print general info
try:
print "IP: %s\r\nOrganization: %s\r\nOperating System: %s" % (host['ip_str'], host.get('org', 'n/a'), host.get('os', 'n/a'))
except UnicodeEncodeError:
print "[!]UnicodeEncode Error\r\n"
else:
# Print all banners
for item in host['data']:
print "Port: %s\r\nBanner: %s" % (item['port'], item['data'])
print "---------------------------------------------"
return
file_object = open('ip.txt', 'r')
for line in file_object:
searchip(line)

0x05 Download search results via Shodan official website

---

Export credits are used when downloading data via the Shodan official website, as shown in the figure below

Alt text

Each query consumes one export credit, regardless of the number of results, with a maximum of 10,000

Select json as the export format

(1) Extract IPs from the downloaded json result file

Python code is as follows:

import json
file_object = open("shodan_data.json", 'r')
for line in file_object:
data = json.loads(line)
print (data["ip_str"])
file_object.close()

(2) Extract IP and port of specified country from downloaded json result file

Country code is in secondary element, corresponding structure: data["location"]["country_code"]

Python code:

import json
import sys
import re
def search(country):
file_object = open("shodan_data.json", 'r')
file_object2 = open(country+".txt", 'w')
for line in file_object:
data = json.loads(line)
if re.search(data["location"]["country_code"], country, re.IGNORECASE):
str1 = "%s:%s" % (data["ip_str"],data["port"])
print str1
file_object2.writelines(str1+'\n')
file_object.close()
file_object2.close()
if __name__ == "__main__":
if len(sys.argv)<2:
print ('[!]Wrong parameter')
sys.exit(0)
else:
print ('[*]Search country code: %s' % sys.argv[1])
search(sys.argv[1])
print ("[+]Done")

Command line arguments:

search.py US

Generate file US.txt, save IP and corresponding ports

0x06 Summary

---

This article introduces the usage of the Shodan API, sharing insights and Python script development techniques. When opting for a paid purchase, remember to distinguish between the three types of credits (credits).