shodan 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/shodan/api.rb +204 -203
  2. data/lib/shodan/version.rb +3 -3
  3. metadata +6 -6
@@ -1,203 +1,204 @@
1
- require 'rubygems'
2
- require 'cgi'
3
- require 'json'
4
- require 'net/http'
5
-
6
- module Shodan
7
-
8
- # The WebAPI class interfaces with the shodanhq.com/api
9
- # It currently supports 2 methods:
10
- # 1. search (query)
11
- # 2. host (ip)
12
- #
13
- # Author:: achillean (mailto:jmath at surtri.com)
14
- #
15
- # :title:Shodan::WebAPI
16
- class WebAPI
17
- attr_accessor :api_key
18
- attr_accessor :base_url
19
- attr_accessor :dataloss
20
- attr_accessor :exploitdb
21
- attr_accessor :msf
22
-
23
- def initialize(api_key)
24
- @api_key = api_key
25
- @base_url = "http://www.shodanhq.com/api/"
26
- @dataloss = DatalossDB.new(self)
27
- @exploitdb = ExploitDB.new(self)
28
- @msf = Msf.new(self)
29
- end
30
-
31
- # Internal method that sends out the HTTP request.
32
- # Expects a webservice function (ex. 'search') name and a hash of arguments.
33
- def request(func, args)
34
- # Convert the argument hash into a string
35
- args_string = args.map{|k, v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v)}"}.join("&")
36
-
37
- # Craft the final request URL
38
- url = "#{@base_url}#{func}?key=#{@api_key}&#{args_string}"
39
-
40
- # Send the request
41
- response = Net::HTTP.get_response(URI.parse(url))
42
-
43
- # Convert the JSON data into a native Ruby hash
44
- data = JSON.parse(response.body)
45
-
46
- # Raise an error if something went wrong
47
- if data.has_key? 'error'
48
- raise data['error']
49
- end
50
-
51
- return data
52
- end
53
-
54
- # Get all available information on an IP.
55
- #
56
- # Arguments:
57
- # ip - host IP (string)
58
- #
59
- # Returns a hash containing the host information
60
- def host(ip)
61
- return request('host', {:ip => ip})
62
- end
63
-
64
- # Perform a search on Shodan.
65
- #
66
- # Arguments:
67
- # query - search query; same format as the website (string)
68
- #
69
- # Returns a hash containing the search results
70
- def search(query)
71
- return request('search', {:q => query})
72
- end
73
- end
74
-
75
- # The DatalossDB class shouldn't be used independently,
76
- # as it depends on the WebAPI class.
77
- #
78
- # Author:: achillean (mailto:jmath at surtri.com)
79
- #
80
- # :title:Shodan::DatalossDB
81
- class DatalossDB
82
- attr_accessor :api
83
-
84
- def initialize(api)
85
- @api = api
86
- end
87
-
88
- # Search the Dataloss DB archive.
89
- #
90
- # Arguments:
91
- # name -- Name of the affected company/ organisation
92
- #
93
- # arrest -- whether the incident resulted in an arrest
94
- # breaches -- the type of breach that occurred (Hack, MissingLaptop etc.)
95
- # country -- country where the incident took place
96
- # ext -- whether an external, third party was affected
97
- # ext_names -- the name of the third party company that was affected
98
- # lawsuit -- whether the incident resulted in a lawsuit
99
- # records -- the number of records that were lost/ stolen
100
- # recovered -- whether the affected items were recovered
101
- # sub_types -- the sub-categorization of the affected company/ organization
102
- # source -- whether the incident occurred from inside or outside the organization
103
- # stocks -- stock symbol of the affected company
104
- # types -- the basic type of organization (government, business, educational)
105
- # uid -- unique ID for the incident
106
- def search(params={})
107
- return @api.request('datalossdb/search', params)
108
- end
109
-
110
- end
111
-
112
- # The ExploitDB class shouldn't be used independently,
113
- # as it depends on the WebAPI class.
114
- #
115
- # Author:: achillean (mailto:jmath at surtri.com)
116
- #
117
- # :title:Shodan::ExploitDB
118
- class ExploitDB
119
- attr_accessor :api
120
-
121
- def initialize(api)
122
- @api = api
123
- end
124
-
125
- # Download the exploit code from the ExploitDB archive.
126
- #
127
- # Arguments:
128
- # id -- ID of the ExploitDB entry
129
- #
130
- # Returns:
131
- # A hash with the following fields:
132
- # filename -- Name of the file
133
- # content-type -- Mimetype
134
- # data -- Contents of the file
135
- def download(id)
136
- return @api.request('exploitdb/download', {:id => "#{id}"})
137
- end
138
-
139
- # Search the ExploitDB archive.
140
- #
141
- # Arguments:
142
- # query -- Search terms
143
- #
144
- # Optional arguments:
145
- # author -- Name of the exploit submitter
146
- # platform -- Target platform (e.g. windows, linux, hardware etc.)
147
- # port -- Service port number
148
- # type -- Any, dos, local, papers, remote, shellcode and webapps
149
- #
150
- # Returns:
151
- # A dictionary with 2 main items: matches (list) and total (int).
152
- # Each item in 'matches' is a dictionary with the following elements:
153
- #
154
- # id
155
- # author
156
- # date
157
- # description
158
- # platform
159
- # port
160
- # type
161
- def search(query, params={})
162
- params[:q] = query
163
- return @api.request('exploitdb/search', params)
164
- end
165
-
166
- end
167
-
168
- # The Msf class shouldn't be used independently,
169
- # as it depends on the WebAPI class.
170
- #
171
- # Author:: achillean (mailto:jmath at surtri.com)
172
- #
173
- # :title:Shodan::Msf
174
- class Msf
175
- attr_accessor :api
176
-
177
- def initialize(api)
178
- @api = api
179
- end
180
-
181
- # Download a metasploit module given the fullname (id) of it.
182
- #
183
- # Arguments:
184
- # id -- fullname of the module (ex. auxiliary/admin/backupexec/dump)
185
- #
186
- # Returns:
187
- # A dictionary with the following fields:
188
- # # filename -- Name of the file
189
- # content-type -- Mimetype
190
- # data -- File content
191
- def download(id)
192
- return @api.request('msf/download', {:id => "#{id}"})
193
- end
194
-
195
- # Search for a metasploit module
196
- def search(query, params={})
197
- params[:q] = query
198
- return @api.request('msf/search', params)
199
- end
200
-
201
- end
202
-
203
- end
1
+ require 'rubygems'
2
+ require 'cgi'
3
+ require 'json'
4
+ require 'net/http'
5
+
6
+ module Shodan
7
+
8
+ # The WebAPI class interfaces with the shodanhq.com/api
9
+ # It currently supports 2 methods:
10
+ # 1. search (query)
11
+ # 2. host (ip)
12
+ #
13
+ # Author:: achillean (mailto:jmath at surtri.com)
14
+ #
15
+ # :title:Shodan::WebAPI
16
+ class WebAPI
17
+ attr_accessor :api_key
18
+ attr_accessor :base_url
19
+ attr_accessor :dataloss
20
+ attr_accessor :exploitdb
21
+ attr_accessor :msf
22
+
23
+ def initialize(api_key)
24
+ @api_key = api_key
25
+ @base_url = "http://www.shodanhq.com/api/"
26
+ @dataloss = DatalossDB.new(self)
27
+ @exploitdb = ExploitDB.new(self)
28
+ @msf = Msf.new(self)
29
+ end
30
+
31
+ # Internal method that sends out the HTTP request.
32
+ # Expects a webservice function (ex. 'search') name and a hash of arguments.
33
+ def request(func, args)
34
+ # Convert the argument hash into a string
35
+ args_string = args.map{|k, v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"}.join("&")
36
+
37
+ # Craft the final request URL
38
+ url = "#{@base_url}#{func}?key=#{@api_key}&#{args_string}"
39
+
40
+ # Send the request
41
+ response = Net::HTTP.get_response(URI.parse(url))
42
+
43
+ # Convert the JSON data into a native Ruby hash
44
+ data = JSON.parse(response.body)
45
+
46
+ # Raise an error if something went wrong
47
+ if data.has_key? 'error'
48
+ raise data['error']
49
+ end
50
+
51
+ return data
52
+ end
53
+
54
+ # Get all available information on an IP.
55
+ #
56
+ # Arguments:
57
+ # ip - host IP (string)
58
+ #
59
+ # Returns a hash containing the host information
60
+ def host(ip)
61
+ return request('host', {:ip => ip})
62
+ end
63
+
64
+ # Perform a search on Shodan.
65
+ #
66
+ # Arguments:
67
+ # query - search query; same format as the website (string)
68
+ #
69
+ # Returns a hash containing the search results
70
+ def search(query, params={})
71
+ params[:q] = query
72
+ return request('search', params)
73
+ end
74
+ end
75
+
76
+ # The DatalossDB class shouldn't be used independently,
77
+ # as it depends on the WebAPI class.
78
+ #
79
+ # Author:: achillean (mailto:jmath at surtri.com)
80
+ #
81
+ # :title:Shodan::DatalossDB
82
+ class DatalossDB
83
+ attr_accessor :api
84
+
85
+ def initialize(api)
86
+ @api = api
87
+ end
88
+
89
+ # Search the Dataloss DB archive.
90
+ #
91
+ # Arguments:
92
+ # name -- Name of the affected company/ organisation
93
+ #
94
+ # arrest -- whether the incident resulted in an arrest
95
+ # breaches -- the type of breach that occurred (Hack, MissingLaptop etc.)
96
+ # country -- country where the incident took place
97
+ # ext -- whether an external, third party was affected
98
+ # ext_names -- the name of the third party company that was affected
99
+ # lawsuit -- whether the incident resulted in a lawsuit
100
+ # records -- the number of records that were lost/ stolen
101
+ # recovered -- whether the affected items were recovered
102
+ # sub_types -- the sub-categorization of the affected company/ organization
103
+ # source -- whether the incident occurred from inside or outside the organization
104
+ # stocks -- stock symbol of the affected company
105
+ # types -- the basic type of organization (government, business, educational)
106
+ # uid -- unique ID for the incident
107
+ def search(params={})
108
+ return @api.request('datalossdb/search', params)
109
+ end
110
+
111
+ end
112
+
113
+ # The ExploitDB class shouldn't be used independently,
114
+ # as it depends on the WebAPI class.
115
+ #
116
+ # Author:: achillean (mailto:jmath at surtri.com)
117
+ #
118
+ # :title:Shodan::ExploitDB
119
+ class ExploitDB
120
+ attr_accessor :api
121
+
122
+ def initialize(api)
123
+ @api = api
124
+ end
125
+
126
+ # Download the exploit code from the ExploitDB archive.
127
+ #
128
+ # Arguments:
129
+ # id -- ID of the ExploitDB entry
130
+ #
131
+ # Returns:
132
+ # A hash with the following fields:
133
+ # filename -- Name of the file
134
+ # content-type -- Mimetype
135
+ # data -- Contents of the file
136
+ def download(id)
137
+ return @api.request('exploitdb/download', {:id => "#{id}"})
138
+ end
139
+
140
+ # Search the ExploitDB archive.
141
+ #
142
+ # Arguments:
143
+ # query -- Search terms
144
+ #
145
+ # Optional arguments:
146
+ # author -- Name of the exploit submitter
147
+ # platform -- Target platform (e.g. windows, linux, hardware etc.)
148
+ # port -- Service port number
149
+ # type -- Any, dos, local, papers, remote, shellcode and webapps
150
+ #
151
+ # Returns:
152
+ # A dictionary with 2 main items: matches (list) and total (int).
153
+ # Each item in 'matches' is a dictionary with the following elements:
154
+ #
155
+ # id
156
+ # author
157
+ # date
158
+ # description
159
+ # platform
160
+ # port
161
+ # type
162
+ def search(query, params={})
163
+ params[:q] = query
164
+ return @api.request('exploitdb/search', params)
165
+ end
166
+
167
+ end
168
+
169
+ # The Msf class shouldn't be used independently,
170
+ # as it depends on the WebAPI class.
171
+ #
172
+ # Author:: achillean (mailto:jmath at surtri.com)
173
+ #
174
+ # :title:Shodan::Msf
175
+ class Msf
176
+ attr_accessor :api
177
+
178
+ def initialize(api)
179
+ @api = api
180
+ end
181
+
182
+ # Download a metasploit module given the fullname (id) of it.
183
+ #
184
+ # Arguments:
185
+ # id -- fullname of the module (ex. auxiliary/admin/backupexec/dump)
186
+ #
187
+ # Returns:
188
+ # A dictionary with the following fields:
189
+ # # filename -- Name of the file
190
+ # content-type -- Mimetype
191
+ # data -- File content
192
+ def download(id)
193
+ return @api.request('msf/download', {:id => "#{id}"})
194
+ end
195
+
196
+ # Search for a metasploit module
197
+ def search(query, params={})
198
+ params[:q] = query
199
+ return @api.request('msf/search', params)
200
+ end
201
+
202
+ end
203
+
204
+ end
@@ -1,3 +1,3 @@
1
- module Shodan
2
- Version = VERSION = '0.5.0'
3
- end
1
+ module Shodan
2
+ Version = VERSION = '0.6.0'
3
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shodan
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 5
8
+ - 6
9
9
  - 0
10
- version: 0.5.0
10
+ version: 0.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Matherly
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-12 00:00:00 -07:00
18
+ date: 2012-08-23 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -24,7 +24,7 @@ dependencies:
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ">="
28
28
  - !ruby/object:Gem::Version
29
29
  hash: 11
30
30
  segments:
@@ -47,9 +47,9 @@ files:
47
47
  - README.md
48
48
  - LICENSE
49
49
  - HISTORY.md
50
- - lib/shodan.rb
51
50
  - lib/shodan/version.rb
52
51
  - lib/shodan/api.rb
52
+ - lib/shodan.rb
53
53
  has_rdoc: true
54
54
  homepage: http://github.com/achillean/shodan-ruby
55
55
  licenses: []