Class: Shodanz::API::REST

Inherits:
Object
  • Object
show all
Defined in:
lib/shodanz/apis/rest.rb

Overview

The REST API provides methods to search Shodan, look up hosts, get summary information on queries and a variety of other utilities. This requires you to have an API key which you can get from Shodan.

Constant Summary collapse

URL =

The path to the REST API endpoint.

"https://api.shodan.io/"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key: ENV['SHODAN_API_KEY']) ⇒ REST

Returns a new instance of REST.

Parameters:

  • key (String) (defaults to: ENV['SHODAN_API_KEY'])

    SHODAN API key, defaulted to the SHODAN_API_KEY enviroment variable.



17
18
19
20
# File 'lib/shodanz/apis/rest.rb', line 17

def initialize(key: ENV['SHODAN_API_KEY'])
  self.key = key
  warn "No key has been found or provided!" unless self.key?
end

Instance Attribute Details

#keyObject

Returns the value of attribute key.



11
12
13
# File 'lib/shodanz/apis/rest.rb', line 11

def key
  @key
end

Instance Method Details

#community_queries(**params) ⇒ Object

Use this method to obtain a list of search queries that users have saved in Shodan.



125
126
127
# File 'lib/shodanz/apis/rest.rb', line 125

def community_queries(**params)
  get('shodan/query', params)
end

#crawl_for(**params) ⇒ Object

Use this method to request Shodan to crawl the Internet for a specific port.

This method is restricted to security researchers and companies with a Shodan Data license. To apply for access to this method as a researcher, please email [email protected] with information about your project. Access is restricted to prevent abuse.

Example

rest_api.crawl_for(port: 80, protocol: "http")


113
114
115
116
117
# File 'lib/shodanz/apis/rest.rb', line 113

def crawl_for(**params)
  params[:query] = ""
  params = turn_into_query(params)
  post('shodan/scan/internet', params)
end

#get(path, **params) ⇒ Object

Perform a direct GET HTTP request to the REST API.



182
183
184
185
186
187
188
189
190
# File 'lib/shodanz/apis/rest.rb', line 182

def get(path, **params)
  resp = Unirest.get "#{URL}#{path}?key=#{@key}", parameters: params
  if resp.code != 200
    binding.pry
    raise resp.body['error'] if resp.body.key?('error')
    raise resp
  end
  resp.body
end

#honeypot_score(ip) ⇒ Object

Calculates a honeypot probability score ranging from 0 (not a honeypot) to 1.0 (is a honeypot).



172
173
174
# File 'lib/shodanz/apis/rest.rb', line 172

def honeypot_score(ip)
  get("labs/honeyscore/#{ip}")
end

#host(ip, **params) ⇒ Hash

Returns all services that have been found on the given host IP.

Examples

# Typical usage.
rest_api.host("8.8.8.8")

# All historical banners should be returned.
rest_api.host("8.8.8.8", history: true) 

# Only return the list of ports and the general host information, no banners.
rest_api.host("8.8.8.8", minify: true)

Parameters:

  • ip (String)
  • params (Hash)

    a customizable set of options

Options Hash (**params):

  • (Hash)

Returns:

  • (Hash)


40
41
42
# File 'lib/shodanz/apis/rest.rb', line 40

def host(ip, **params)
  get("shodan/host/#{ip}", params)
end

#host_count(query = "", facets: {}, **params) ⇒ Object

This method behaves identical to “/shodan/host/search” with the only difference that this method does not return any host results, it only returns the total number of results that matched the query and any facet information that was requested. As a result this method does not consume query credits.

Examples

rest_api.host_count("apache")
rest_api.host_count("apache", country: "US")
rest_api.host_count("apache", country: "US", state: "MI")
rest_api.host_count("apache", country: "US", state: "MI", city: "Detroit")


54
55
56
57
58
59
# File 'lib/shodanz/apis/rest.rb', line 54

def host_count(query = "", facets: {}, **params)
  params[:query] = query
  params = turn_into_query(params)
  facets = turn_into_facets(facets)
  get("shodan/host/count", params.merge(facets))
end

#host_search(query = "", facets: {}, page: 1, minify: true, **params) ⇒ Object

Search Shodan using the same query syntax as the website and use facets to get summary information for different properties.

Example

rest_api.host_search("apache", country: "US", facets: { city: "Detroit" }, page: 1, minify: false)


65
66
67
68
69
70
71
72
# File 'lib/shodanz/apis/rest.rb', line 65

def host_search(query = "", facets: {}, page: 1, minify: true, **params)
  params[:query] = query
  params = turn_into_query(params)
  facets = turn_into_facets(facets)
  params[:page] = page
  params[:minify] = minify
  get("shodan/host/search", params.merge(facets))
end

#host_search_tokens(query = "", **params) ⇒ Object

This method lets you determine which filters are being used by the query string and what parameters were provided to the filters.



76
77
78
79
80
# File 'lib/shodanz/apis/rest.rb', line 76

def host_search_tokens(query = "", **params)
  params[:query] = query
  params = turn_into_query(params)
  get("shodan/host/search/tokens", params)
end

#http_headersObject

Shows the HTTP headers that your client sends when connecting to a webserver.



161
162
163
# File 'lib/shodanz/apis/rest.rb', line 161

def http_headers
  get('tools/httpheaders')
end

#infoObject

Returns information about the API plan belonging to the given API key.



177
178
179
# File 'lib/shodanz/apis/rest.rb', line 177

def info
  get('api-info')
end

#key?Boolean

Check if there’s an API key.

Returns:

  • (Boolean)


23
24
25
# File 'lib/shodanz/apis/rest.rb', line 23

def key?
  return true if @key; false
end

#my_ipObject

Get your current IP address as seen from the Internet.



166
167
168
# File 'lib/shodanz/apis/rest.rb', line 166

def my_ip
  get('tools/myip')
end

Use this method to obtain a list of popular tags for the saved search queries in Shodan.



137
138
139
140
141
# File 'lib/shodanz/apis/rest.rb', line 137

def popular_query_tags(size = 10)
  params = {}
  params[:size] = size
  get('shodan/query/tags', params)
end

#portsObject

This method returns a list of port numbers that the crawlers are looking for.



83
84
85
# File 'lib/shodanz/apis/rest.rb', line 83

def ports
  get("shodan/ports")
end

#post(path, **params) ⇒ Object

Perform a direct POST HTTP request to the REST API.



193
194
195
196
197
198
199
200
# File 'lib/shodanz/apis/rest.rb', line 193

def post(path, **params)
  resp = Unirest.post "#{URL}#{path}?key=#{@key}", parameters: params
  if resp.code != 200
    raise resp.body['error'] if resp.body.key?('error')
    raise resp
  end
  resp.body
end

#profileObject

Returns information about the Shodan account linked to this API key.



144
145
146
# File 'lib/shodanz/apis/rest.rb', line 144

def profile
  get('account/profile')
end

#protocolsObject

List all protocols that can be used when performing on-demand Internet scans via Shodan.



88
89
90
# File 'lib/shodanz/apis/rest.rb', line 88

def protocols 
  get("shodan/protocols")
end

#resolve(*hostnames) ⇒ Object

Look up the IP address for the provided list of hostnames.



149
150
151
# File 'lib/shodanz/apis/rest.rb', line 149

def resolve(*hostnames)
  get('dns/resolve', hostnames: hostnames.join(","))
end

#reverse_lookup(*ips) ⇒ Object

Look up the hostnames that have been defined for the given list of IP addresses.



155
156
157
# File 'lib/shodanz/apis/rest.rb', line 155

def reverse_lookup(*ips)
  get('dns/reverse', ips: ips.join(","))
end

#scan(*ips) ⇒ Object

Use this method to request Shodan to crawl a network.

This method uses API scan credits: 1 IP consumes 1 scan credit. You must have a paid API plan (either one-time payment or subscription) in order to use this method.

IP, IPs or netblocks (in CIDR notation) that should get crawled.



99
100
101
102
# File 'lib/shodanz/apis/rest.rb', line 99

def scan(*ips)
  raise "Not enough scan credits!" unless self.info["scan_credits"] >= 1
  post("shodan/scan", ips: ips.join(","))
end

#scan_status(id) ⇒ Object

Check the progress of a previously submitted scan request.



120
121
122
# File 'lib/shodanz/apis/rest.rb', line 120

def scan_status(id)
  get("shodan/scan/#{id}")
end

#search_for_community_query(query, **params) ⇒ Object

Use this method to search the directory of search queries that users have saved in Shodan.



130
131
132
133
134
# File 'lib/shodanz/apis/rest.rb', line 130

def search_for_community_query(query, **params)
  params[:query] = query
  params = turn_into_query(params)
  get('shodan/query/search', params) 
end