5 using System.Collections.Generic;
10 using System.Threading.Tasks;
19 private readonly
string apikey;
20 private const string BasePath =
"https://api.shodan.io";
27 if(
string.IsNullOrWhiteSpace(apikey))
29 throw new ArgumentNullException(nameof(apikey));
37 RequestHandler = requestHandler;
47 if(
string.IsNullOrWhiteSpace(hostnames))
49 throw new ArgumentNullException(hostnames);
51 var url =
new Uri($
"{BasePath}/dns/resolve?hostnames={hostnames}&key={this.apikey}");
52 return RequestHandler.MakeRequestAsync<Dictionary<string, string>>(url);
66 public Task<SearchHostResults>
SearchHosts(Action<QueryGenerator> query, Action<FacetGenerator> facet = null,
int page = 1,
bool minify =
true)
70 throw new ArgumentNullException(nameof(query));
73 query.Invoke(queryGenerator);
74 var queryResult = queryGenerator.Generate();
75 var url =
new UriBuilder($
"{BasePath}/shodan/host/search")
77 Query = $
"key={apikey}&query={queryResult}&minify={minify.ToString()}" 82 facet.Invoke(facetGenerator);
83 url.Query = $
"{url.Query}&facets={facetGenerator.GenerateFacets()}";
87 url.Query = $
"{url.Query}&page={page}";
98 public Task<SearchHostResults>
SearchHostsCount(Action<QueryGenerator> query, Action<FacetGenerator> facet = null)
102 throw new ArgumentNullException(nameof(query));
105 query.Invoke(queryGenObj);
107 var url =
new UriBuilder($
"{BasePath}/shodan/host/count")
109 Query = $
"key={apikey}&query={queryGenObj.Generate()}" 114 facet.Invoke(facetGenObj);
116 url.Query = $
"{url.Query}&facets={facetGenObj.GenerateFacets()}";
122 public Task<SearchTokens>
SearchTokens(Action<QueryGenerator> query)
126 throw new ArgumentNullException(nameof(query));
129 query.Invoke(queryObj);
130 var url =
new Uri($
"{BasePath}/shodan/host/search/tokens?key={apikey}&query={queryObj.Generate()}");
131 return RequestHandler.MakeRequestAsync<
SearchTokens>(url);
141 if(
string.IsNullOrWhiteSpace(ip))
143 throw new ArgumentNullException(nameof(ip));
145 var url =
new Uri($
"{BasePath}/labs/honeyscore/{ip}?key={apikey}");
146 var result = await RequestHandler.MakeRequestAsync<
string>(url);
148 if(!
double.TryParse(result, out resultParsed))
150 throw new ShodanException($
"honeypot score returned with {result} failed to parse to double");
161 var url =
new Uri($
"{BasePath}/api-info?key={apikey}");
162 return RequestHandler.MakeRequestAsync<
ApiStatus>(url);
172 public Task<Host>
GetHostAsync(
string Ip,
bool history =
false,
bool minify =
false)
174 if(
string.IsNullOrWhiteSpace(Ip))
176 throw new ArgumentNullException(nameof(Ip));
178 var builder =
new UriBuilder($
"{BasePath}/shodan/host/{Ip}")
180 Query = $
"key={this.apikey}&history={history.ToString()}&minify={minify.ToString()}" 183 return RequestHandler.MakeRequestAsync<
Host>(builder.Uri);
192 var url =
new Uri($
"{BasePath}/tools/myip?key={this.apikey}");
193 return RequestHandler.MakeRequestAsync<
string>(url);
202 var builder =
new Uri($
"{BasePath}/shodan/ports?key={this.apikey}");
203 return RequestHandler.MakeRequestAsync<List<int>>(builder);
212 var url =
new Uri($
"{BasePath}/account/profile?key={apikey}");
213 return RequestHandler.MakeRequestAsync<
Profile>(url);
222 var url =
new Uri($
"{BasePath}/shodan/protocols?key={this.apikey}");
223 return RequestHandler.MakeRequestAsync<Dictionary<string, string>>(url);
235 var url =
new UriBuilder($
"{BasePath}/shodan/query")
237 Query = $
"key={apikey}" 241 var sortName = Enum.GetName(typeof(
SortOptions), sort.Value);
242 url.Query = $
"{url.Query}&sort={sortName}";
246 var orderName = Enum.GetName(typeof(
OrderOption), order.Value);
247 url.Query = $
"{url.Query}&order={orderName}";
249 return RequestHandler.MakeRequestAsync<
SearchQueries>(url.Uri);
260 if(
string.IsNullOrWhiteSpace(query))
262 throw new ArgumentNullException(query);
264 var url =
new UriBuilder($
"{BasePath}/shodan/query/search")
266 Query = $
"key={apikey}&query={query}" 270 url.Query = $
"{url.Query}&page={page}";
272 return RequestHandler.MakeRequestAsync<
SearchQueries>(url.Uri);
282 if(
string.IsNullOrWhiteSpace(
id))
284 throw new ArgumentNullException(nameof(
id));
286 var url =
new Uri($
"{BasePath}/shodan/scan/{id}");
287 return RequestHandler.MakeRequestAsync<
ScanStatus>(url);
296 var url =
new Uri($
"{BasePath}/shodan/services?key={this.apikey}");
297 return RequestHandler.MakeRequestAsync<Dictionary<string, string>>(url);
307 var url =
new UriBuilder($
"{BasePath}/shodan/query/tags")
309 Query = $
"key={apikey}&size={size}" 311 return RequestHandler.MakeRequestAsync<
TagResult>(url.Uri);
323 var url =
new Uri($
"{BasePath}/shodan/scan/internet?key={this.apikey}");
324 using(var data =
new FormUrlEncodedContent(
new List<KeyValuePair<string, string>>() {
325 new KeyValuePair<string, string>(
"port", port.ToString()),
326 new KeyValuePair<string, string>(
"protocol", protocol)
329 return RequestHandler.MakeRequestAsync<
ScanPortResult>(url, data, RequestType.POST);
341 if(
string.IsNullOrWhiteSpace(ips))
343 throw new ArgumentNullException(nameof(ips));
345 if(!ips.Split(
',').Any())
347 throw new ArgumentOutOfRangeException($
"{ips} must have one valid record");
349 var url =
new Uri($
"{BasePath}/shodan/scan?key={this.apikey}");
350 using(var data =
new FormUrlEncodedContent(
new KeyValuePair<string, string>[] {
new KeyValuePair<string, string>(
"ips", ips) }))
352 return RequestHandler.MakeRequestAsync<
ScanResult>(url, data, RequestType.POST);
363 if(
string.IsNullOrWhiteSpace(ips))
365 throw new ArgumentNullException(ips);
367 var url =
new Uri($
"{BasePath}/dns/reverse?ips={ips}&key={this.apikey}");
368 return RequestHandler.MakeRequestAsync<Dictionary<string, List<string>>>(url);
371 #region IDisposable Support 373 private bool disposedValue =
false;
375 protected virtual void Dispose(
bool disposing)
381 RequestHandler.Dispose();
384 disposedValue =
true;
389 public void Dispose()
397 #endregion IDisposable Support Main mechanism to talk to the shodan api. This is what you should use to interact with the api ...
Task< Host > GetHostAsync(string Ip, bool history=false, bool minify=false)
Returns all services that have been found on the given host IP.
Task< ScanPortResult > RequestInternetPortScanAsync(int port, string protocol)
Use this method to request Shodan to crawl the Internet for a specific port. This method is restricte...
Result of ShodanClient.GetQueriesAsync(int?, SortOptions?, OrderOption?) and ShodanClient.SearchQueriesAsync(string, int?)
Task< Dictionary< string, string > > GetServicesAsync()
This method returns an object containing all the services that the Shodan crawlers look at...
result of ShodanClient.GetTagsAsync(int)
Task< SearchHostResults > SearchHosts(Action< QueryGenerator > query, Action< FacetGenerator > facet=null, int page=1, bool minify=true)
Search Shodan using the same query syntax as the website and use facets to get summary information fo...
Task< Dictionary< string, string > > GetProtocolsAsync()
This method returns an object containing all the protocols that can be used when launching an Interne...
Task< string > GetMyIpAsync()
Get your current IP address as seen from the Internet.
Task< Dictionary< string, List< string > > > ReverseLookupAsync(string ips)
Look up the hostnames that have been defined for the given list of IP addresses
OrderOption
Represents an order of either ascending or descending
Represents data about your profile
sane wrapper of http, and simple abstraction layer for unit testing
Task< ScanResult > RequstScanAsync(string ips)
Use this method to request Shodan to crawl a network Requirements: This method uses API scan credits:...
sane wrapper of http, and simple abstraction layer for unit testing
Returns information about the API plan belonging to the given API key.
Represents return data for querying hosts
result of ShodanClient.RequestInternetPortScanAsync(int, string)
Task< ScanStatus > GetScanStatusAsync(string id)
Check the progress of a previously submitted scan request
Task< SearchQueries > GetQueriesAsync(int?page=null, SortOptions?sort=null, OrderOption?order=null)
Use this method to obtain a list of search queries that users have saved in Shodan.
Task< SearchQueries > SearchQueriesAsync(string query, int?page=null)
Use this method to search the directory of search queries that users have saved in Shodan...
Task< ApiStatus > GetApiStatusAsync()
Returns information about the API plan belonging to the given API key.
SortOptions
Represents an option to sort
Result of ShodanClient.GetScanStatusAsync(string)
result of ShodanClient.RequstScanAsync(string)
async Task< double > Experimental_GetHoneyPotScoreAsync(string ip)
Calculates a honeypot probability score ranging from 0 (not a honeypot) to 1.0 (is a honeypot)...
Task< List< int > > GetPortsAsync()
This method returns a list of port numbers that the crawlers are looking for.
Task< TagResult > GetTagsAsync(int size=10)
Use this method to obtain a list of popular tags for the saved search queries in Shodan.
Task< Dictionary< string, string > > DnsLookupAsync(string hostnames)
Look up the IP address for the provided list of hostnames.
result of ShodanClient.SearchHosts(SearchQuery, FacetQuery, int, bool) and ShodanClient.SearchHostsCount(SearchQuery, FacetQuery)
Task< SearchHostResults > SearchHostsCount(Action< QueryGenerator > query, Action< FacetGenerator > facet=null)
This method behaves identical to SearchHosts(SearchQuery, FacetQuery, int, bool)" with the only diffe...
Task< Profile > GetProfileAsync()
Returns information about the Shodan account linked to this API key.