otx_ruby 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 80186fd6a333eac1ece08c746755f08f06691f2e
4
+ data.tar.gz: e86becc8bf3d42b0c93bfc851e4bf3b20779e1c5
5
+ SHA512:
6
+ metadata.gz: 1b951af4d57f56a601617376cae407fdcffbaa0afea9f1169abbd137cd7cd02e119cc4bc9fa96c777eaa01db2a927a2da41c3dd0fa34e76373c833630ad4fe37
7
+ data.tar.gz: 5deec8205b91c0f72ff275b6c4742ff96ceb55d25e09133a27a80db7efe00752c34b8982296f010ae05738a927c0d6896cdb5be2ee5f8c1fc0a00f868baa891a
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in otx_ruby.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # Open Threat Exchange (OTX) Ruby Wrapper
2
+
3
+ Open Threat Exchange is an open community that allows participants to learn about the latest threats, research indicators of compromise observed in their environments, share threats they have identified, and automatically update their security infrastructure with the latest indicators to defend their environment.
4
+
5
+ This gem provides a wrapper for Ruby applications to pull pulses from OTX and be consumed by the ruby application.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'otx_ruby'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install otx_ruby
22
+
23
+ ## Usage
24
+
25
+ ```ruby
26
+ require `otx_ruby`
27
+
28
+ api_key = '4xxx........'
29
+ otx = OTX::Subscribed.new(apikey)
30
+
31
+ # Get all subscribed pulses
32
+ pulses = otx.get_all
33
+
34
+ # Read contents of a single pulse
35
+ pulse_id = '56xxxx..........'
36
+ pulses = OTX::Pulses.new(apikey)
37
+
38
+ pulse = pulses.get_pulse(pulse_id)
39
+ ```
40
+
41
+ ## API Key
42
+
43
+ Library requires your API key this can be found in your settings page https://otx.alienvault.com/settings
44
+
45
+ ## API Timestamp
46
+
47
+ The API uses ISO Format timestamps, however there is a quirk, the API seems to use Python style timestamps as a result it is important to ensure that the sent time stamp uses the UTC format when sent
48
+
49
+ ```
50
+ "2010-10-25T23:48:46Z"
51
+ ```
52
+
53
+ ## Development
54
+
55
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
56
+
57
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
58
+
59
+ ## Contributing
60
+
61
+ Bug reports and pull requests are welcome on GitHub at https://github.com/mort666/otx_ruby.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "otx_ruby"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/circle.yml ADDED
@@ -0,0 +1,9 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.1.5
4
+ database:
5
+ override:
6
+ - echo 'no database'
7
+ dependencies:
8
+ pre:
9
+ - gem install bundler
@@ -0,0 +1,75 @@
1
+ module OTX
2
+ #
3
+ # Base Class for API access, provides initial wrapper around Faraday performs
4
+ # base request
5
+ #
6
+ class Base
7
+ #
8
+ # Initialise object
9
+ #
10
+ # @param key [String] API Key for AlienVault OTX API
11
+ # @param server [String] Base URL for API, defaults to 'https://otx.alienvault.com'
12
+ #
13
+ def initialize(key, server="https://otx.alienvault.com")
14
+ @key = key
15
+ @server = server
16
+
17
+ @conn = Faraday.new(:url => @server) do |faraday|
18
+ faraday.request :url_encoded # form-encode POST params
19
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
20
+ end
21
+ end
22
+
23
+ #
24
+ # Get the provided URL
25
+ #
26
+ # @param url [String] URL to make API request to
27
+ # @param params [Hash] Additional parameters to be added to the requests
28
+ #
29
+ def get(url, params={})
30
+ response = @conn.get do |req|
31
+ req.url url
32
+ req.headers['X-OTX-API-KEY'] = @key
33
+ req.params = params
34
+ end
35
+
36
+ # Parse and return JSON object as hash to caller
37
+ return Oj.load(response.body)
38
+ end
39
+ end
40
+ end
41
+
42
+
43
+ module OTX
44
+ #
45
+ # Base Data Types for Returned Data from API
46
+ #
47
+ # Implements two default handlers for created and modified timestamps as DataTime
48
+ # objects
49
+ #
50
+ module Type
51
+ #
52
+ # Base Class for types
53
+ #
54
+ # @attr [DateTime] created Date and Time stamp for the creation of the records
55
+ # @attr [DateTime] modified Date and Time stamp for the last modification of the records
56
+ #
57
+ class Base
58
+ attr_writer :modified, :created
59
+
60
+ def created
61
+ return @created.nil? ? nil : DateTime.parse(@created)
62
+ end
63
+
64
+ def modified
65
+ return @modified.nil? ? nil : DateTime.parse(@modified)
66
+ end
67
+
68
+ def initialize(attributes={})
69
+ attributes.each do |key, value|
70
+ send("#{key}=", value)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,64 @@
1
+ module OTX
2
+ #
3
+ # Besides receiving the pulse information, it is possible to return details of
4
+ # events that have occured in the OTX system and affect your account. This class
5
+ # provides a wrapper around this functionality.
6
+ #
7
+ class Events < OTX::Base
8
+ #
9
+ # Get all events from the API, get all events in chunks defined by limit
10
+ #
11
+ # @param limit [Integer] Size of chunk of data to be Returned (default = 20)
12
+ # @return [Array] Array of OTX::Event records
13
+ #
14
+ def get_all(limit=20)
15
+ uri = '/api/v1/pulses/events'
16
+ params = {limit: limit}
17
+ events = []
18
+ begin
19
+ json_data = get(uri, params)
20
+ page = json_data['next']
21
+
22
+ params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
23
+
24
+ events += json_data['results']
25
+ end while !page.nil?
26
+
27
+ results = []
28
+ events.each do |event|
29
+ results << OTX::Event.new(event)
30
+ end
31
+
32
+ return results
33
+ end
34
+
35
+ #
36
+ # Get all events from the API, get all events in chunks defined by limit and since
37
+ # timestamp
38
+ #
39
+ # @param timestamp [Time] Timestamp of point in time to get records since in ISO Format
40
+ # @param limit [Integer] Size of chunk of data to be Returned (default = 20)
41
+ # @return [Array] Array of OTX::Event records
42
+ #
43
+ def get_since(timestamp, limit=20)
44
+ uri = '/api/v1/pulses/events'
45
+ params = {limit: limit, since: timestamp}
46
+ events = []
47
+ begin
48
+ json_data = get(uri, params)
49
+ page = json_data['next']
50
+
51
+ params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
52
+
53
+ events += json_data['results']
54
+ end while !page.nil?
55
+
56
+ results = []
57
+ events.each do |event|
58
+ results << OTX::Event.new(event)
59
+ end
60
+
61
+ return results
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,22 @@
1
+ module OTX
2
+ #
3
+ # Retrieve and parse into the appropriate object a pulse from the OTX System
4
+ #
5
+ class Pulses < OTX::Base
6
+ #
7
+ # Download an individually identified pulse and parse the output
8
+ #
9
+ # @param id [String] The id value for the pulse to Download
10
+ # @return [OTX::Pulse] Parsed Pulse
11
+ #
12
+ def get_pulse(id)
13
+ uri = "/api/v1/pulses/#{id}"
14
+
15
+ json_data = get(uri)
16
+
17
+ pulse = OTX::Pulse.new(json_data)
18
+
19
+ return pulse
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,64 @@
1
+ module OTX
2
+ #
3
+ # Within the OTX system you are able to subscribe to pulses from other users,
4
+ # this class allows the retreival of the currently subscribed pulse feeds and the
5
+ # associated pulses
6
+ #
7
+ class Subscribed < OTX::Base
8
+ #
9
+ # Get all subscribed pulses from the API, get all events in chunks defined by limit
10
+ #
11
+ # @param limit [Integer] Size of chunk of data to be Returned (default = 20)
12
+ # @return [Array] Array of OTX::Pulse records
13
+ #
14
+ def get_all(limit=20)
15
+ uri = '/api/v1/pulses/subscribed'
16
+ params = {limit: limit}
17
+ pulses = []
18
+ begin
19
+ json_data = get(uri, params)
20
+ page = json_data['next']
21
+
22
+ params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
23
+
24
+ pulses += json_data['results']
25
+ end while !page.nil?
26
+
27
+ results = []
28
+ pulses.each do |pulse|
29
+ results << OTX::Pulse.new(pulse)
30
+ end
31
+
32
+ return results
33
+ end
34
+
35
+ #
36
+ # Get all subscribed pulses from the API, get all events in chunks defined by limit and since
37
+ # timestamp
38
+ #
39
+ # @param timestamp [Time] Timestamp of point in time to get records since in ISO Format
40
+ # @param limit [Integer] Size of chunk of data to be Returned (default = 20)
41
+ # @return [Array] Array of OTX::Pulse records
42
+ #
43
+ def get_since(timestamp, limit=20)
44
+ uri = '/api/v1/pulses/subscribed'
45
+ params = {limit: limit, modified_since: timestamp}
46
+ pulses = []
47
+ begin
48
+ json_data = get(uri, params)
49
+ page = json_data['next']
50
+
51
+ params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
52
+
53
+ pulses += json_data['results']
54
+ end while !page.nil?
55
+
56
+ results = []
57
+ pulses.each do |pulse|
58
+ results << OTX::Pulse.new(pulse)
59
+ end
60
+
61
+ return results
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,14 @@
1
+ module OTX
2
+ #
3
+ # Account Events Object Type
4
+ #
5
+ # @author Stephen Kapp
6
+ # @attr [String] id ID value for record
7
+ # @attr [String] action Action peformed, currently supports (subscribe, unsubscribe, delete)
8
+ # @attr [String] object_type Currently supports events for pulse and user objects
9
+ # @attr [String] object_id ID value for the object the event is created for
10
+ #
11
+ class Event < OTX::Type::Base
12
+ attr_accessor :id, :action, :object_type, :object_id
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ module OTX
2
+ #
3
+ # Pulse Indicator of Compromise (IoC) records
4
+ #
5
+ # @attr [String] _id IoC record ID value
6
+ # @attr [String] indicator Value of the indicator type
7
+ # @attr [String] type Type of IoC
8
+ # @attr [String] description Description associated with the IoC
9
+ #
10
+ # Indicator of Compromise types:
11
+ # IPv4 - An IPv4 address indicating the online location of a server or other computer.
12
+ # IPv6 - An IPv6 address indicating the online location of a server or other computer.
13
+ # domain - A domain name for a website or server. Domains encompass a series of hostnames.
14
+ # hostname - The hostname for a server located within a domain.
15
+ # email - An email associated with suspicious activity.
16
+ # URL - Uniform Resource Location (URL) summarizing the online location of a file or resource.
17
+ # URI - Uniform Resource Indicator (URI) describing the explicit path to a file hosted online.
18
+ # FileHash-MD5 - A MD5-format hash that summarizes the architecture and content of a file.
19
+ # FileHash-SHA1 - A SHA-format hash that summarizes the architecture and content of a file.
20
+ # FileHash-SHA256 - A SHA-256-format hash that summarizes the architecture and content of a file.
21
+ # FileHash-PEHASH - A PEPHASH-format hash that summarizes the architecture and content of a file.
22
+ # FileHash-IMPHASH - An IMPHASH-format hash that summarizes the architecture and content of a file.
23
+ # CIDR - Classless Inter-Domain Routing (CIDR) address, which describes both a server's IP address and the network architecture (routing path) surrounding that server.
24
+ # FilePath - A unique location in a file system.
25
+ # Mutex - The name of a mutex resource describing the execution architecture of a file.
26
+ # CVE - Common Vulnerability and Exposure (CVE) entry describing a software vulnerability that can be exploited to engage in malicious activity.
27
+ #
28
+ class Indicators < OTX::Type::Base
29
+ attr_accessor :_id, :indicator, :type, :description
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ module OTX
2
+ #
3
+ # AlienVault OTX Pulse Record
4
+ #
5
+ # @author Stephen Kapp
6
+ # @attr [String] id OTX ID value for the pulse Record
7
+ # @attr [String] name Pulse Name
8
+ # @attr [String] description Description of the pulse
9
+ # @attr [String] author_name Name of the pulse author_name
10
+ # @attr [Array<String>] tags Array of 'tags' to describe the pulse
11
+ # @attr [Array<String>] referenes Array of references attached to the pulse
12
+ # @attr [String] revision Revision number of the OTX Pulse Record
13
+ # @attr [Array<OTX::Indicators>] indicators Array of the IoC attached to the OTX pulse
14
+ #
15
+ class Pulse < OTX::Type::Base
16
+ attr_accessor :id, :name, :description, :author_name,
17
+ :tags, :references, :revision, :indicators
18
+
19
+ def initialize(attributes={})
20
+ attributes.each do |key, value|
21
+ if key != 'indicators'
22
+ send("#{key}=", value)
23
+ else
24
+ @indicators = []
25
+ value.each do |indicator|
26
+ @indicators << OTX::Indicators.new(indicator)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,4 @@
1
+ module OTX
2
+ # Library Version Number
3
+ VERSION = "0.5.0"
4
+ end
data/lib/otx_ruby.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'faraday'
2
+ require 'oj'
3
+
4
+ require "otx_ruby/version"
5
+ require "otx_ruby/base.rb"
6
+ require "otx_ruby/subscribed.rb"
7
+ require "otx_ruby/events.rb"
8
+ require "otx_ruby/pulses.rb"
9
+ require "otx_ruby/types/pulse.rb"
10
+ require "otx_ruby/types/indicators.rb"
11
+
12
+ #
13
+ # Base AlienVault OTX Module
14
+ #
15
+ module OTX
16
+
17
+ end
data/otx_ruby.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'otx_ruby/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "otx_ruby"
8
+ spec.version = OTX::VERSION
9
+ spec.authors = ["Stephen Kapp"]
10
+ spec.email = ["mort666@virus.org"]
11
+ spec.summary = %q{AlienVault OTX Ruby Gem}
12
+ spec.description = %q{AlienVault Open Threat Exchange Threat Intel feed API Wrapper}
13
+ spec.homepage = "http://github.com/mort666/otx_ruby"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "faraday"
21
+ spec.add_dependency "oj"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "minitest"
26
+ spec.add_development_dependency "vcr"
27
+ spec.add_development_dependency "webmock"
28
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: otx_ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Stephen Kapp
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-01-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: vcr
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: AlienVault Open Threat Exchange Threat Intel feed API Wrapper
112
+ email:
113
+ - mort666@virus.org
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - Gemfile
120
+ - README.md
121
+ - Rakefile
122
+ - bin/console
123
+ - bin/setup
124
+ - circle.yml
125
+ - lib/otx_ruby.rb
126
+ - lib/otx_ruby/base.rb
127
+ - lib/otx_ruby/events.rb
128
+ - lib/otx_ruby/pulses.rb
129
+ - lib/otx_ruby/subscribed.rb
130
+ - lib/otx_ruby/types/event.rb
131
+ - lib/otx_ruby/types/indicators.rb
132
+ - lib/otx_ruby/types/pulse.rb
133
+ - lib/otx_ruby/version.rb
134
+ - otx_ruby.gemspec
135
+ homepage: http://github.com/mort666/otx_ruby
136
+ licenses: []
137
+ metadata: {}
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project:
154
+ rubygems_version: 2.4.3
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: AlienVault OTX Ruby Gem
158
+ test_files: []
159
+ has_rdoc: