backscatterio 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5508c62631c77d734b28d680bbb89c49a56eda99
4
- data.tar.gz: ce8ae7f744ba3b595c591a7fc3bc8ebcd283c9f0
3
+ metadata.gz: fe9d8b796f4fd06e225d8819340b518b86356c39
4
+ data.tar.gz: 6a463a6f64fc97f3cefea14525da0531f017caf1
5
5
  SHA512:
6
- metadata.gz: f78082fa1777ec84a86bf497876bc2d79c633682129588ae287bff6c3e1634ffb012bfe0a77e1718d6ae10524954c21c598717f9871f27c104d5f6945f4cca69
7
- data.tar.gz: c2f87dc57d467364a7192f6af912da489ab5cc6e63d42f2e01383b8491d050b0d4d3522e15407e8add4db4ec68d831cefa451b42d295e1dbb3bb0d0f88ee3834
6
+ metadata.gz: e6bb446c2769eff38953008851c26e6adfad0707c54c1cb56718704311861775d973cee02af9d404bf28069b9de459868801ebd7ae7267cda88206afea4342b0
7
+ data.tar.gz: f633883a98397bc5cf335f8a51d7b0262bdf77a03a833ec88aef27d8ccff1865f3afa0f71e4b1522a1227499be3456a5b7cb5af34a7bbf3434d81cbe71985dba
Binary file
@@ -40,6 +40,6 @@ Gem::Specification.new do |s|
40
40
 
41
41
  s.files = `find *`.split("\n").uniq.sort.select { |f| !f.empty? }
42
42
  s.test_files = `find spec/*`.split("\n")
43
- s.executables = []
43
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
44
44
  s.require_paths = ["lib"]
45
45
  end
@@ -0,0 +1,253 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'backscatterio'
4
+ require 'getoptlong'
5
+ require 'json'
6
+ require 'ipaddr'
7
+ require 'fileutils'
8
+
9
+ module BackscatterIO
10
+ class CLInterface
11
+ def self.detect_query(query)
12
+ begin
13
+ if query.index('/') and IPAddr.new(query[0, query.index('/')])
14
+ return 'network'
15
+ elsif IPAddr.new query
16
+ return 'ip'
17
+ end
18
+ rescue
19
+ if query =~ /^[A-Z]{2}$/i
20
+ return 'country'
21
+ elsif query =~ /^AS\d+$/i
22
+ return 'asn'
23
+ elsif query =~ /^(TCP|UDP)\d+$/i or [21, 22, 23, 25, 53, 80, 81, 113, 139, 443, 445, 1433, 5222, 5900, 8080].index(query.to_i)
24
+ return 'port'
25
+ else
26
+ return 'asn'
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.parse_command_line(args)
32
+ origARGV = ARGV.dup
33
+ ARGV.replace(args)
34
+ opts = GetoptLong.new(
35
+ [ '--api-key', '-k', GetoptLong::REQUIRED_ARGUMENT ],
36
+ [ '--query', '-q', GetoptLong::REQUIRED_ARGUMENT ],
37
+ [ '--type', '-t', GetoptLong::REQUIRED_ARGUMENT ],
38
+ [ '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
39
+ [ '--scope', '-z', GetoptLong::REQUIRED_ARGUMENT ],
40
+ [ '--count', '-c', GetoptLong::REQUIRED_ARGUMENT ],
41
+ [ '--config', '-a', GetoptLong::REQUIRED_ARGUMENT ],
42
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
43
+ [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ]
44
+ )
45
+
46
+ options = {
47
+ :command => 'trends',
48
+ :api_key => nil,
49
+ :query => nil,
50
+ :type => nil,
51
+ :format => 'json',
52
+ :scope => '7d',
53
+ :count => nil,
54
+ :help => false,
55
+ :verbose => false,
56
+ :version => 'v0',
57
+ :config_file => "#{ENV['HOME']}/.config/backscatter/config.json"
58
+ }
59
+
60
+ opts.each do |opt, arg|
61
+ case opt
62
+ when '--api-key'
63
+ options[:api_key] = arg
64
+ when '--query'
65
+ options[:query] = arg
66
+ when '--type'
67
+ options[:type] = arg
68
+ when '--format'
69
+ options[:format] = arg
70
+ when '--scope'
71
+ options[:scope] = arg
72
+ when '--count'
73
+ options[:count] = arg
74
+ when '--config'
75
+ options[:config_file] = arg
76
+ when '--help'
77
+ options[:help] = true
78
+ when '--verbose'
79
+ options[:verbose] = true
80
+ else
81
+ raise "Unknown option #{opt}"
82
+ end
83
+ end
84
+
85
+ if options[:config_file]
86
+ if File.exist?(options[:config_file])
87
+ data = JSON.parse(open(options[:config_file]).read)
88
+ options[:api_key] = data["api_key"]
89
+ options[:version] = data["version"]
90
+ end
91
+ end
92
+
93
+ [options, args]
94
+ end
95
+
96
+ def self.error(message)
97
+ puts message
98
+ exit
99
+ end
100
+
101
+
102
+ def self.run(args)
103
+ options, items = parse_command_line(args)
104
+ if items[0]
105
+ options[:command] = items[0]
106
+ end
107
+
108
+ if not options[:api_key]
109
+ error("An API key is required to use the Backscatter.io service. Please specify one via -k or in a configuration file #{ENV['HOME']}/.config/backscatter/config.json")
110
+ end
111
+
112
+ if options[:help]
113
+ usage
114
+ exit
115
+ end
116
+
117
+ BackscatterIO.configure do |config|
118
+ # Configure API key authorization: ApiKeyAuth
119
+ config.api_key['X-API-KEY'] = options[:api_key]
120
+ end
121
+
122
+ client = BackscatterIO::Api.new
123
+
124
+ case options[:command]
125
+ when 'observations'
126
+ if not options[:query]
127
+ error("-q <query_item> is a required parameter to the observations command")
128
+ end
129
+ options[:type] ||= detect_query(options[:query])
130
+ if not options[:type]
131
+ error "Could not determine the format of the query, please use the -t flag to specify the type"
132
+ end
133
+ results = client.observations(options[:type], options[:query], { "scope" => options[:scope] })
134
+ when 'trends'
135
+ options[:type] ||= 'ip'
136
+ results = client.trends(options[:type], { "scope" => options[:scope], "count" => options[:count] })
137
+ when 'enrich'
138
+ if not options[:query]
139
+ error "-q <query_item> is a required parameter to the enrich command"
140
+ end
141
+ options[:type] ||= detect_query(options[:query])
142
+ if not options[:type]
143
+ error "Could not determine the format of the query, please use the -t flag to specify the type"
144
+ end
145
+ case options[:type]
146
+ when 'ip'
147
+ results = client.enrich_ip(options[:query])
148
+ when 'network'
149
+ results = client.enrich_network(options[:query])
150
+ when 'asn'
151
+ results = client.enrich_asn(options[:query])
152
+ else
153
+ error "Enrichment is not available for #{options[:type]}"
154
+ end
155
+ when 'setup'
156
+ dirname = File.dirname(options[:config_file])
157
+ if not File.exist?(dirname)
158
+ FileUtils.mkdir_p(dirname)
159
+ end
160
+ fh = open(options[:config_file], 'w')
161
+ fh.write(JSON.pretty_generate({"version" => options[:version], "api_key" => options[:api_key]}))
162
+ fh.close
163
+ results = { "message" => "Configuration saved" }
164
+ else
165
+ error "Unknown command #{options[:command]}"
166
+ end
167
+
168
+ if options[:format] == 'json'
169
+ return results.to_hash.to_json
170
+ else
171
+ return tabulate(results)
172
+ end
173
+ end
174
+
175
+ def self.tabulate(results)
176
+ if not results.success
177
+ return "Unsuccessful"
178
+ end
179
+
180
+ table = ""
181
+
182
+ if results.query == nil or results.query.type == "top_x_query"
183
+ maxlen = 0
184
+ results.results.each do |k,v|
185
+ if k.length > maxlen
186
+ maxlen = k.length
187
+ end
188
+ end
189
+ maxlen += 1
190
+ results.results.keys.sort {|a,b| results.results[b] <=> results.results[a]}.each do |k|
191
+ table += "#{k.to_s.ljust(maxlen)}: #{results.results[k]}\n"
192
+ end
193
+ else
194
+ headers = {}
195
+ headers = {'observed' => 9, 'src_ip' => 7, 'protocol' => 9,
196
+ 'fragment_flags' => 15, 'id' => 3, 'dst_port' => 9, 'length' => 7, 'ttl' => 4, 'tos' => 4,
197
+ 'precedence' => 11, 'window' => 7}
198
+ results.results.observations.each do |item|
199
+ headers.each_key do |h|
200
+ vl = item.__send__(h).length + 1
201
+ if vl > headers[h]
202
+ headers[h] = vl
203
+ end
204
+ end
205
+ end
206
+ headers.each_key do |h|
207
+ table += "#{h.ljust(headers[h])}"
208
+ end
209
+ table += "\n"
210
+ results.results.observations.each do |item|
211
+ headers.each_key do |h|
212
+ table += "#{item.__send__(h).ljust(headers[h])}"
213
+ end
214
+ table += "\n"
215
+ end
216
+ end
217
+ table
218
+ end
219
+
220
+ def self.usage
221
+ usage = <<EOD
222
+ Usage: #{ARGV[0]} [setup|observations|trends|enrich] [options]
223
+ setup: Configure this client with your API key in order to run commands without issue. Find your API key at https://backscatter.io/account.
224
+ -k Specify an API key to save to your configuration file [required]
225
+
226
+ observations: queries observations matching your query. https://backscatter.io/developers#observations
227
+ -k Specify an API key to use for the API [required if not specified in the configuration]
228
+ -q Specify an IP, netblock, ASN, country, or port [required]
229
+ -t The type of the query you wish to make: ip, netblock, ASN, country, or port [autodetects]
230
+ -f Output format of the results. table or json, defaults to json
231
+ --scope Days to search back through (integer)
232
+
233
+ trends: queries trends (top N) of items of a given type seen withing the scope
234
+ -k Specify an API key to use for the API [required if not specified in the configuration]
235
+ -t Trend type: ip, network, asn, port, or country, defaults to ip
236
+ -f Output format of the results. table or json, defaults to json
237
+ --scope Days to search back through (integer)
238
+
239
+ enrich: adds enriching information to the queried item
240
+ -k Specify an API key to use for the API [required if not specified in the configuration]
241
+ -q Specify an IP, netblock, ASN, country, or port [required]
242
+ -t The type of the query you wish to make: ip, netblock, ASN, country, or port [autodetects]
243
+ -f Output format of the results. table or json, defaults to json
244
+ EOD
245
+ puts usage
246
+ end
247
+ end
248
+ # Alias for the CLInterface class
249
+ CLI = BackscatterIO::CLInterface
250
+ end
251
+
252
+ results = BackscatterIO::CLI.run(ARGV)
253
+ puts results
@@ -11,5 +11,5 @@ Swagger Codegen version: 2.4.0
11
11
  =end
12
12
 
13
13
  module BackscatterIO
14
- VERSION = '1.0.0'
14
+ VERSION = '1.0.1'
15
15
  end
@@ -0,0 +1,387 @@
1
+ ---
2
+ swagger: "2.0"
3
+ info:
4
+ description: |
5
+ [This is the Backscatter.io API.](https://backscatter.io/developers)
6
+ version: 1.0.0
7
+ title: Backscatter.io
8
+ termsOfService: https://backscatter.io/tos
9
+ contact:
10
+ email: info@backscatter.io
11
+ license:
12
+ name: Apache 2.0
13
+ url: http://www.apache.org/licenses/LICENSE-2.0.html
14
+ host: api.backscatter.io
15
+ basePath: /v0
16
+ schemes:
17
+ - https
18
+ security:
19
+ - ApiKeyAuth: []
20
+ paths:
21
+ /hello:
22
+ get:
23
+ summary: authenticate to the service
24
+ operationId: hello
25
+ consumes:
26
+ - application/json
27
+ produces:
28
+ - application/json
29
+ parameters: []
30
+ responses:
31
+ 200:
32
+ description: authenticated
33
+ schema:
34
+ $ref: '#/definitions/Hello'
35
+ 405:
36
+ description: Invalid input
37
+ /observations/{queryType}:
38
+ get:
39
+ summary: fetches observations for a given querytype
40
+ operationId: observations
41
+ consumes:
42
+ - application/json
43
+ produces:
44
+ - application/json
45
+ parameters:
46
+ - name: queryType
47
+ in: path
48
+ description: query type ip, network, asn, port, country
49
+ required: true
50
+ type: string
51
+ - name: query
52
+ in: query
53
+ description: ip address, cidr block, asn, port, or country
54
+ required: true
55
+ type: string
56
+ - name: scope
57
+ in: query
58
+ description: timeframe to search over, e.g., 1d, 7d
59
+ required: false
60
+ type: string
61
+ responses:
62
+ 200:
63
+ description: observations
64
+ schema:
65
+ $ref: '#/definitions/Observations'
66
+ 405:
67
+ description: Invalid input
68
+ /trends/popular/{trendType}:
69
+ get:
70
+ summary: Top N items
71
+ description: A listing of the top N items observered over the query scope
72
+ operationId: trends
73
+ produces:
74
+ - application/json
75
+ parameters:
76
+ - name: trendType
77
+ in: path
78
+ description: which item type you want to perform a trend over
79
+ required: true
80
+ type: string
81
+ enum:
82
+ - ip
83
+ - network
84
+ - asn
85
+ - port
86
+ - country
87
+ - name: scope
88
+ in: query
89
+ description: timeframe to search over, e.g., 1d, 7d
90
+ required: false
91
+ type: string
92
+ responses:
93
+ 200:
94
+ description: observations
95
+ schema:
96
+ $ref: '#/definitions/Trends'
97
+ 405:
98
+ description: Invalid input
99
+ /enrichment/ip:
100
+ get:
101
+ summary: enriches ip
102
+ description: returns enrichment data for an ip
103
+ operationId: enrich_ip
104
+ produces:
105
+ - application/json
106
+ parameters:
107
+ - name: query
108
+ in: query
109
+ required: true
110
+ type: string
111
+ responses:
112
+ 200:
113
+ description: ip_enrichment
114
+ schema:
115
+ $ref: '#/definitions/IPEnrichment'
116
+ 405:
117
+ description: Invalid input
118
+ /enrichment/network:
119
+ get:
120
+ summary: enriches network
121
+ description: returns enrichment data for a network
122
+ operationId: enrich_network
123
+ produces:
124
+ - application/json
125
+ parameters:
126
+ - name: query
127
+ in: query
128
+ required: true
129
+ type: string
130
+ responses:
131
+ 200:
132
+ description: network_enrichment
133
+ schema:
134
+ $ref: '#/definitions/NetworkEnrichment'
135
+ 405:
136
+ description: Invalid input
137
+ /enrichment/asn:
138
+ get:
139
+ summary: enriches asn
140
+ description: returns enrichment data for an ASN
141
+ operationId: enrich_asn
142
+ produces:
143
+ - application/json
144
+ parameters:
145
+ - name: query
146
+ in: query
147
+ required: true
148
+ type: string
149
+ responses:
150
+ 200:
151
+ description: asn_enrichment
152
+ schema:
153
+ $ref: '#/definitions/ASNEnrichment'
154
+ 405:
155
+ description: Invalid input
156
+ securityDefinitions:
157
+ ApiKeyAuth:
158
+ type: apiKey
159
+ name: X-API-KEY
160
+ in: header
161
+ definitions:
162
+ Hello:
163
+ type: object
164
+ properties:
165
+ message:
166
+ type: string
167
+ success:
168
+ type: boolean
169
+ Observations:
170
+ type: object
171
+ properties:
172
+ query:
173
+ $ref: '#/definitions/Query'
174
+ results:
175
+ $ref: '#/definitions/Results'
176
+ success:
177
+ type: boolean
178
+ Query:
179
+ type: object
180
+ properties:
181
+ after_time:
182
+ type: string
183
+ focus:
184
+ type: string
185
+ scope:
186
+ type: string
187
+ type:
188
+ type: string
189
+ enum:
190
+ - ip_query
191
+ - network_query
192
+ - asn_query
193
+ - port_query
194
+ - country_query
195
+ - top_x_query
196
+ Results:
197
+ type: object
198
+ properties:
199
+ observations:
200
+ type: array
201
+ items:
202
+ $ref: '#/definitions/Observation'
203
+ summary:
204
+ $ref: '#/definitions/Summary'
205
+ unique:
206
+ $ref: '#/definitions/Unique'
207
+ Observation:
208
+ type: object
209
+ properties:
210
+ dst_port:
211
+ type: string
212
+ fragment_flags:
213
+ type: string
214
+ id:
215
+ type: string
216
+ length:
217
+ type: string
218
+ observed:
219
+ type: string
220
+ precedence:
221
+ type: string
222
+ protocol:
223
+ type: string
224
+ res:
225
+ type: string
226
+ src_ip:
227
+ type: string
228
+ src_port:
229
+ type: string
230
+ tcp_flags:
231
+ type: string
232
+ tos:
233
+ type: string
234
+ ttl:
235
+ type: string
236
+ window:
237
+ type: string
238
+ Summary:
239
+ type: object
240
+ properties:
241
+ autonomous_system_count:
242
+ type: integer
243
+ format: int32
244
+ has_observations:
245
+ type: boolean
246
+ ip_address_count:
247
+ type: array
248
+ items:
249
+ type: string
250
+ network_count:
251
+ type: integer
252
+ format: int32
253
+ observations:
254
+ type: boolean
255
+ observations_count:
256
+ type: integer
257
+ format: int32
258
+ port_count:
259
+ type: integer
260
+ format: int32
261
+ protocol_count:
262
+ type: integer
263
+ format: int32
264
+ Unique:
265
+ type: object
266
+ properties:
267
+ autonomous_systems:
268
+ type: array
269
+ items:
270
+ type: string
271
+ countries:
272
+ type: array
273
+ items:
274
+ type: string
275
+ ip_addresses:
276
+ type: array
277
+ items:
278
+ type: string
279
+ networks:
280
+ type: array
281
+ items:
282
+ type: string
283
+ ports:
284
+ type: array
285
+ items:
286
+ type: string
287
+ protocols:
288
+ type: array
289
+ items:
290
+ type: string
291
+ Trends:
292
+ type: object
293
+ properties:
294
+ query:
295
+ $ref: '#/definitions/Query'
296
+ results:
297
+ type: object
298
+ properties: {}
299
+ success:
300
+ type: boolean
301
+ IPEnrichment:
302
+ type: object
303
+ properties:
304
+ results:
305
+ $ref: '#/definitions/IPEnrichment_results'
306
+ success:
307
+ type: boolean
308
+ NetworkEnrichment:
309
+ type: object
310
+ properties:
311
+ results:
312
+ $ref: '#/definitions/NetworkEnrichment_results'
313
+ success:
314
+ type: boolean
315
+ ASNEnrichment:
316
+ type: object
317
+ properties:
318
+ results:
319
+ $ref: '#/definitions/ASNEnrichment_results'
320
+ success:
321
+ type: boolean
322
+ IPEnrichment_results:
323
+ properties:
324
+ as_name:
325
+ type: string
326
+ as_num:
327
+ type: integer
328
+ format: int32
329
+ city:
330
+ type: string
331
+ country_iso:
332
+ type: string
333
+ country_name:
334
+ type: string
335
+ ip:
336
+ type: string
337
+ ip_hex:
338
+ type: string
339
+ ip_version:
340
+ type: integer
341
+ format: int8
342
+ latitude:
343
+ type: number
344
+ longitude:
345
+ type: number
346
+ network:
347
+ type: string
348
+ network_broadcast:
349
+ type: string
350
+ network_hostmask:
351
+ type: string
352
+ network_netmask:
353
+ type: string
354
+ network_size:
355
+ type: integer
356
+ format: int32
357
+ postal_code:
358
+ type: string
359
+ region_iso:
360
+ type: string
361
+ region_name:
362
+ type: string
363
+ NetworkEnrichment_results:
364
+ properties:
365
+ cidr:
366
+ type: string
367
+ network_addresses:
368
+ type: array
369
+ items:
370
+ type: string
371
+ network_size:
372
+ type: integer
373
+ format: int32
374
+ ASNEnrichment_results:
375
+ properties:
376
+ as_num:
377
+ type: integer
378
+ format: int32
379
+ as_name:
380
+ type: string
381
+ prefix_count:
382
+ type: integer
383
+ format: int32
384
+ prefixes:
385
+ type: array
386
+ items:
387
+ type: string
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backscatterio
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - rubygems@chrislee.dhs.org
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-31 00:00:00.000000000 Z
11
+ date: 2019-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -193,7 +193,8 @@ dependencies:
193
193
  description: "[This is the Backscatter.io API.](https://backscatter.io/developers) "
194
194
  email:
195
195
  - rubygems@chrislee.dhs.org
196
- executables: []
196
+ executables:
197
+ - backscatterio-rb
197
198
  extensions: []
198
199
  extra_rdoc_files: []
199
200
  files:
@@ -201,7 +202,9 @@ files:
201
202
  - LICENSE
202
203
  - README.md
203
204
  - Rakefile
205
+ - backscatterio-1.0.0.gem
204
206
  - backscatterio.gemspec
207
+ - bin/backscatterio-rb
205
208
  - docs/ASNEnrichment.md
206
209
  - docs/ASNEnrichmentResults.md
207
210
  - docs/Api.md
@@ -256,6 +259,7 @@ files:
256
259
  - spec/models/trends_spec.rb
257
260
  - spec/models/unique_spec.rb
258
261
  - spec/spec_helper.rb
262
+ - swagger.yaml
259
263
  homepage: https://github.com/backscatterio/ruby
260
264
  licenses:
261
265
  - Unlicense