otx_ruby 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/circle.yml +1 -1
- data/lib/otx_ruby/activity.rb +90 -0
- data/lib/otx_ruby/base.rb +42 -2
- data/lib/otx_ruby/correlation_rule.rb +13 -0
- data/lib/otx_ruby/cve.rb +22 -0
- data/lib/otx_ruby/domain.rb +90 -0
- data/lib/otx_ruby/events.rb +28 -4
- data/lib/otx_ruby/export.rb +103 -0
- data/lib/otx_ruby/file.rb +23 -0
- data/lib/otx_ruby/hostname.rb +95 -0
- data/lib/otx_ruby/ip.rb +105 -0
- data/lib/otx_ruby/nids.rb +13 -0
- data/lib/otx_ruby/pulses.rb +150 -0
- data/lib/otx_ruby/subscribed.rb +19 -4
- data/lib/otx_ruby/types/author.rb +8 -0
- data/lib/otx_ruby/types/base_indicator.rb +8 -0
- data/lib/otx_ruby/types/correlation_rule.rb +21 -0
- data/lib/otx_ruby/types/cve.rb +36 -0
- data/lib/otx_ruby/types/file_analysis.rb +6 -0
- data/lib/otx_ruby/types/indicator_type.rb +6 -0
- data/lib/otx_ruby/types/indicator_type_counts.rb +8 -0
- data/lib/otx_ruby/types/ip/dns.rb +8 -0
- data/lib/otx_ruby/types/ip/general.rb +24 -0
- data/lib/otx_ruby/types/ip/geo.rb +8 -0
- data/lib/otx_ruby/types/ip/http_scan.rb +8 -0
- data/lib/otx_ruby/types/ip/malware.rb +21 -0
- data/lib/otx_ruby/types/{ip_reputation.rb → ip/reputation.rb} +0 -0
- data/lib/otx_ruby/types/ip/url.rb +8 -0
- data/lib/otx_ruby/types/ip/whois.rb +8 -0
- data/lib/otx_ruby/types/observation.rb +8 -0
- data/lib/otx_ruby/types/pulse.rb +14 -3
- data/lib/otx_ruby/types/pulse_info.rb +24 -0
- data/lib/otx_ruby/types/reference.rb +8 -0
- data/lib/otx_ruby/types/user.rb +21 -0
- data/lib/otx_ruby/url.rb +35 -0
- data/lib/otx_ruby/users.rb +97 -0
- data/lib/otx_ruby/version.rb +1 -1
- data/lib/otx_ruby.rb +32 -1
- metadata +33 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7934c02ca3191b73093883c9e5c1ca6daa18d175
|
4
|
+
data.tar.gz: 3a0320e544d2d7f0864c64fc18c89c2d38bbc603
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a89b9e968eb3ea1b53296e3d749b6da872dc389d699bfaa0927acc2636be5509c0fd2abc917b97c5e6aec7f9642ec70b8321c69ffe5748c0d19032e61ff9f7a
|
7
|
+
data.tar.gz: 674f4eefb4f5fc1a48bc05954e17f272f1b31cbc830e1d20abd8ff61bfec447a0757875ab4fe179bfbcd19265d59a9c47f3fcabcbe593609a2c8db51a71dbbaa
|
data/circle.yml
CHANGED
@@ -0,0 +1,90 @@
|
|
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
|
5
|
+
# the associated pulses, as well as pulses from followed Users
|
6
|
+
#
|
7
|
+
class Activity < OTX::Base
|
8
|
+
#
|
9
|
+
# Get pulse activity from the API
|
10
|
+
#
|
11
|
+
# @param limit [Integer] Number of records returned
|
12
|
+
# @param page [Integer] page of records returned
|
13
|
+
# @param params [Hash] Addtional parameters eg `modified_since: DateTime`
|
14
|
+
#
|
15
|
+
def get_activity(limit = 10, page = 1, params = {})
|
16
|
+
uri = '/api/v1/pulses/activity'
|
17
|
+
params['limit'] = limit
|
18
|
+
params['page'] = page
|
19
|
+
|
20
|
+
json_data = get(uri, params)
|
21
|
+
|
22
|
+
pulses = json_data['results']
|
23
|
+
|
24
|
+
results = []
|
25
|
+
pulses.each do |pulse|
|
26
|
+
results << OTX::Pulse.new(pulse)
|
27
|
+
end
|
28
|
+
|
29
|
+
return results
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Get all pulses activity from the API, get all events in chunks defined by
|
34
|
+
# limit
|
35
|
+
#
|
36
|
+
# @param limit [Integer] Size of chunk of data to be Returned (default = 20)
|
37
|
+
# @return [Array<OTX::Pulse>] Parsed Pulses
|
38
|
+
#
|
39
|
+
def get_all(limit = 20)
|
40
|
+
uri = '/api/v1/pulses/activity'
|
41
|
+
params = {limit: limit}
|
42
|
+
pulses = []
|
43
|
+
begin
|
44
|
+
json_data = get(uri, params)
|
45
|
+
page = json_data['next']
|
46
|
+
|
47
|
+
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
48
|
+
|
49
|
+
pulses += json_data['results']
|
50
|
+
end while page && !json_data['results'].empty?
|
51
|
+
|
52
|
+
results = []
|
53
|
+
pulses.each do |pulse|
|
54
|
+
results << OTX::Pulse.new(pulse)
|
55
|
+
end
|
56
|
+
|
57
|
+
return results
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Get all pulses activity from the API, get all events in chunks defined by
|
62
|
+
# limit and since timestamp
|
63
|
+
#
|
64
|
+
# @param timestamp [Time] Timestamp of point in time to get records since in
|
65
|
+
# ISO Format
|
66
|
+
# @param limit [Integer] Size of chunk of data to be Returned (default = 20)
|
67
|
+
# @return [Array<OTX::Pulse>] Parsed Pulses
|
68
|
+
#
|
69
|
+
def get_since(timestamp, limit = 20)
|
70
|
+
uri = '/api/v1/pulses/activity'
|
71
|
+
params = {limit: limit, modified_since: timestamp}
|
72
|
+
pulses = []
|
73
|
+
begin
|
74
|
+
json_data = get(uri, params)
|
75
|
+
page = json_data['next']
|
76
|
+
|
77
|
+
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
78
|
+
|
79
|
+
pulses += json_data['results']
|
80
|
+
end while page && !json_data['results'].empty?
|
81
|
+
|
82
|
+
results = []
|
83
|
+
pulses.each do |pulse|
|
84
|
+
results << OTX::Pulse.new(pulse)
|
85
|
+
end
|
86
|
+
|
87
|
+
return results
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/otx_ruby/base.rb
CHANGED
@@ -21,7 +21,7 @@ module OTX
|
|
21
21
|
end
|
22
22
|
|
23
23
|
#
|
24
|
-
#
|
24
|
+
# GET the provided URL
|
25
25
|
#
|
26
26
|
# @param url [String] URL to make API request to
|
27
27
|
# @param params [Hash] Additional parameters to be added to the requests
|
@@ -36,6 +36,40 @@ module OTX
|
|
36
36
|
# Parse and return JSON object as hash to caller
|
37
37
|
return Oj.load(response.body)
|
38
38
|
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# POST to the provided URL
|
42
|
+
#
|
43
|
+
# @param url [String] URL to make API request to
|
44
|
+
# @param params [Hash] Additional parameters to be added to the requests
|
45
|
+
#
|
46
|
+
def post(url, params={})
|
47
|
+
response = @conn.post do |req|
|
48
|
+
req.url url
|
49
|
+
req.headers['X-OTX-API-KEY'] = @key
|
50
|
+
req.params = params
|
51
|
+
end
|
52
|
+
|
53
|
+
# Parse and return JSON object as hash to caller
|
54
|
+
return Oj.load(response.body)
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# PATCH to the provided URL
|
59
|
+
#
|
60
|
+
# @param url [String] URL to make API request to
|
61
|
+
# @param params [Hash] Additional parameters to be added to the requests
|
62
|
+
#
|
63
|
+
def patch(url, params={})
|
64
|
+
response = @conn.patch do |req|
|
65
|
+
req.url url
|
66
|
+
req.headers['X-OTX-API-KEY'] = @key
|
67
|
+
req.params = params
|
68
|
+
end
|
69
|
+
|
70
|
+
# Parse and return JSON object as hash to caller
|
71
|
+
return Oj.load(response.body)
|
72
|
+
end
|
39
73
|
end
|
40
74
|
end
|
41
75
|
|
@@ -68,7 +102,13 @@ module OTX
|
|
68
102
|
|
69
103
|
def initialize(attributes={})
|
70
104
|
attributes.each do |key, value|
|
71
|
-
|
105
|
+
_key = key.gsub('-', '_')
|
106
|
+
|
107
|
+
unless self.respond_to?(_key.downcase)
|
108
|
+
self.class.send(:attr_accessor, _key.downcase)
|
109
|
+
end
|
110
|
+
|
111
|
+
send("#{_key.downcase}=", value)
|
72
112
|
end
|
73
113
|
end
|
74
114
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module OTX
|
2
|
+
class CorrelationRule < OTX::Base
|
3
|
+
def get_general(correlation_rule)
|
4
|
+
uri = "/api/v1/indicators/correlation-rule/#{correlation_rule}/general"
|
5
|
+
|
6
|
+
json_data = get(uri)
|
7
|
+
|
8
|
+
general = OTX::Indicator::CorrelationRule.new(json_data)
|
9
|
+
|
10
|
+
return general
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/otx_ruby/cve.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module OTX
|
2
|
+
#
|
3
|
+
# Retrieve and parse into the appropriate object the reputation for an IP Address from the OTX System
|
4
|
+
#
|
5
|
+
class CVE < OTX::Base
|
6
|
+
#
|
7
|
+
# Download an individually identified IP Address Reputation and parse the output
|
8
|
+
#
|
9
|
+
# @param cve [String] The CVE ID to check
|
10
|
+
# @return [OTX::Pulse] Parsed CVE Indicator
|
11
|
+
#
|
12
|
+
def get_general(cve)
|
13
|
+
uri = "api/v1/indicators/cve/#{cve}/general"
|
14
|
+
|
15
|
+
json_data = get(uri)
|
16
|
+
|
17
|
+
general = OTX::Indicator::CVE::General.new(json_data)
|
18
|
+
|
19
|
+
return general
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module OTX
|
2
|
+
class Domain < OTX::Base
|
3
|
+
def get_general(domain)
|
4
|
+
uri = "/api/v1/indicators/domain/#{domain}/general"
|
5
|
+
|
6
|
+
json_data = get(uri)
|
7
|
+
|
8
|
+
general = OTX::Indicator::IP::General.new(json_data)
|
9
|
+
|
10
|
+
return general
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_geo(domain)
|
14
|
+
uri = "/api/v1/indicators/domain/#{domain}/geo"
|
15
|
+
|
16
|
+
json_data = get(uri)
|
17
|
+
|
18
|
+
geo = OTX::Indicator::IP::Geo.new(json_data)
|
19
|
+
|
20
|
+
return geo
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_malware(domain)
|
24
|
+
uri = "/api/v1/indicators/domain/#{domain}/malware"
|
25
|
+
malwares = []
|
26
|
+
params = {}
|
27
|
+
|
28
|
+
begin
|
29
|
+
json_data = get(uri, params)
|
30
|
+
page = json_data['next']
|
31
|
+
|
32
|
+
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
33
|
+
|
34
|
+
malwares += json_data['data']
|
35
|
+
end while page && !json_data['data'].empty?
|
36
|
+
|
37
|
+
results = []
|
38
|
+
malwares.each do |malware|
|
39
|
+
results << OTX::Indicator::IP::Malware.new(malware)
|
40
|
+
end
|
41
|
+
|
42
|
+
return results
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_url_list(domain)
|
46
|
+
uri = "/api/v1/indicators/domain/#{domain}/url_list"
|
47
|
+
|
48
|
+
page = 0
|
49
|
+
url_list = []
|
50
|
+
begin
|
51
|
+
page += 1
|
52
|
+
params = {limit: 20, page: page}
|
53
|
+
json_data = get(uri, params)
|
54
|
+
has_next = json_data['has_next']
|
55
|
+
|
56
|
+
url_list += json_data['url_list']
|
57
|
+
end while has_next
|
58
|
+
|
59
|
+
results = []
|
60
|
+
url_list.each do |url|
|
61
|
+
results << OTX::Indicator::IP::URL.new(url)
|
62
|
+
end
|
63
|
+
|
64
|
+
return results
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_passive_dns(domain)
|
68
|
+
uri = "/api/v1/indicators/domain/#{domain}/passive_dns"
|
69
|
+
|
70
|
+
json_data = get(uri)
|
71
|
+
|
72
|
+
results = []
|
73
|
+
json_data['passive_dns'].each do |dns|
|
74
|
+
results << OTX::Indicator::IP::DNS.new(dns)
|
75
|
+
end
|
76
|
+
|
77
|
+
return results
|
78
|
+
end
|
79
|
+
|
80
|
+
def whois(domain)
|
81
|
+
uri = "/api/v1/indicators/domain/#{domain}/whois"
|
82
|
+
|
83
|
+
json_data = get(uri)
|
84
|
+
|
85
|
+
whois = OTX::Indicator::IP::Whois.new(json_data)
|
86
|
+
|
87
|
+
return whois
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/otx_ruby/events.rb
CHANGED
@@ -5,13 +5,37 @@ module OTX
|
|
5
5
|
# provides a wrapper around this functionality.
|
6
6
|
#
|
7
7
|
class Events < OTX::Base
|
8
|
+
#
|
9
|
+
# Get subscribed events from the API
|
10
|
+
#
|
11
|
+
# @param limit [Integer] Number of records returned
|
12
|
+
# @param page [Integer] page of records returned
|
13
|
+
# @param params [Hash] Addtional parameters eg `modified_since: DateTime`
|
14
|
+
#
|
15
|
+
def get_events(limit = 10, page = 1, params = {})
|
16
|
+
uri = '/api/v1/pulses/events'
|
17
|
+
params['limit'] = limit
|
18
|
+
params['page'] = page
|
19
|
+
|
20
|
+
json_data = get(uri, params)
|
21
|
+
|
22
|
+
events = json_data['results']
|
23
|
+
|
24
|
+
results = []
|
25
|
+
events.each do |event|
|
26
|
+
results << OTX::Event.new(event)
|
27
|
+
end
|
28
|
+
|
29
|
+
return results
|
30
|
+
end
|
31
|
+
|
8
32
|
#
|
9
33
|
# Get all events from the API, get all events in chunks defined by limit
|
10
34
|
#
|
11
35
|
# @param limit [Integer] Size of chunk of data to be Returned (default = 20)
|
12
36
|
# @return [Array] Array of OTX::Event records
|
13
37
|
#
|
14
|
-
def get_all(limit=20)
|
38
|
+
def get_all(limit = 20)
|
15
39
|
uri = '/api/v1/pulses/events'
|
16
40
|
params = {limit: limit}
|
17
41
|
events = []
|
@@ -22,7 +46,7 @@ module OTX
|
|
22
46
|
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
23
47
|
|
24
48
|
events += json_data['results']
|
25
|
-
end while !
|
49
|
+
end while page && !json_data['results'].empty?
|
26
50
|
|
27
51
|
results = []
|
28
52
|
events.each do |event|
|
@@ -40,7 +64,7 @@ module OTX
|
|
40
64
|
# @param limit [Integer] Size of chunk of data to be Returned (default = 20)
|
41
65
|
# @return [Array] Array of OTX::Event records
|
42
66
|
#
|
43
|
-
def get_since(timestamp, limit=20)
|
67
|
+
def get_since(timestamp, limit = 20)
|
44
68
|
uri = '/api/v1/pulses/events'
|
45
69
|
params = {limit: limit, since: timestamp}
|
46
70
|
events = []
|
@@ -51,7 +75,7 @@ module OTX
|
|
51
75
|
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
52
76
|
|
53
77
|
events += json_data['results']
|
54
|
-
end while !
|
78
|
+
end while page && !json_data['results'].empty?
|
55
79
|
|
56
80
|
results = []
|
57
81
|
events.each do |event|
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module OTX
|
2
|
+
class Export < OTX::Base
|
3
|
+
def get_export(limit = 10, page = 1, params = {})
|
4
|
+
uri = '/api/v1/indicators/export'
|
5
|
+
|
6
|
+
params['limit'] = limit
|
7
|
+
params['page'] = page
|
8
|
+
indicators = []
|
9
|
+
|
10
|
+
json_data = get(uri, params)
|
11
|
+
|
12
|
+
json_data['results'].each do |indicator|
|
13
|
+
indicators << OTX::Indicators.new(indicator)
|
14
|
+
end
|
15
|
+
|
16
|
+
return indicators
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_all(limit = 20)
|
20
|
+
uri = '/api/v1/indicators/export'
|
21
|
+
params = { limit: limit }
|
22
|
+
indicators = []
|
23
|
+
begin
|
24
|
+
json_data = get(uri, params)
|
25
|
+
page = json_data['next']
|
26
|
+
|
27
|
+
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
28
|
+
|
29
|
+
indicators += json_data['results']
|
30
|
+
end while page && !json_data['results'].empty?
|
31
|
+
|
32
|
+
results = []
|
33
|
+
indicators.each do |indicator|
|
34
|
+
results << OTX::Indicators.new(indicator)
|
35
|
+
end
|
36
|
+
|
37
|
+
return results
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_since(timestamp, limit = 20)
|
41
|
+
uri = '/api/v1/indicators/export'
|
42
|
+
params = { limit: limit, modified_since: timestamp }
|
43
|
+
indicators = []
|
44
|
+
begin
|
45
|
+
json_data = get(uri, params)
|
46
|
+
page = json_data['next']
|
47
|
+
|
48
|
+
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
49
|
+
|
50
|
+
indicators += json_data['results']
|
51
|
+
end while page && !json_data['results'].empty?
|
52
|
+
|
53
|
+
results = []
|
54
|
+
indicators.each do |indicator|
|
55
|
+
results << OTX::Indicators.new(indicator)
|
56
|
+
end
|
57
|
+
|
58
|
+
return results
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_only(list_of_types, limit = 20)
|
62
|
+
uri = '/api/v1/indicators/export'
|
63
|
+
params = { limit: limit, types: list_of_types }
|
64
|
+
indicators = []
|
65
|
+
begin
|
66
|
+
json_data = get(uri, params)
|
67
|
+
page = json_data['next']
|
68
|
+
|
69
|
+
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
70
|
+
|
71
|
+
indicators += json_data['results']
|
72
|
+
end while page && !json_data['results'].empty?
|
73
|
+
|
74
|
+
results = []
|
75
|
+
indicators.each do |indicator|
|
76
|
+
results << OTX::Indicator.new(indicator)
|
77
|
+
end
|
78
|
+
|
79
|
+
return results
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_only_since(list_of_types, timestamp, limit = 20)
|
83
|
+
uri = '/api/v1/indicators/export'
|
84
|
+
params = { limit: limit, types: list_of_types, modified_since: timestamp }
|
85
|
+
indicators = []
|
86
|
+
begin
|
87
|
+
json_data = get(uri, params)
|
88
|
+
page = json_data['next']
|
89
|
+
|
90
|
+
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
91
|
+
|
92
|
+
indicators += json_data['results']
|
93
|
+
end while page && !json_data['results'].empty?
|
94
|
+
|
95
|
+
results = []
|
96
|
+
indicators.each do |indicator|
|
97
|
+
results << OTX::Indicator.new(indicator)
|
98
|
+
end
|
99
|
+
|
100
|
+
return results
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module OTX
|
2
|
+
class File < OTX::Base
|
3
|
+
def get_general(file_hash)
|
4
|
+
uri = "/api/v1/indicators/file/#{file_hash}/general"
|
5
|
+
|
6
|
+
json_data = get(uri)
|
7
|
+
|
8
|
+
general = OTX::Indicator::IP::General.new(json_data)
|
9
|
+
|
10
|
+
return general
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_analysis(file_hash)
|
14
|
+
uri = "/api/v1/indicators/file/#{file_hash}/analysis"
|
15
|
+
|
16
|
+
json_data = get(uri)
|
17
|
+
|
18
|
+
analysis = OTX::Indicator::FileAnalysis.new(json_data)
|
19
|
+
|
20
|
+
return analysis
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module OTX
|
2
|
+
class Hostname < OTX::Base
|
3
|
+
def get_general(hostname)
|
4
|
+
uri = "/api/v1/indicators/hostname/#{hostname}/general"
|
5
|
+
|
6
|
+
json_data = get(uri)
|
7
|
+
|
8
|
+
general = OTX::Indicator::IP::General.new(json_data)
|
9
|
+
|
10
|
+
return general
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_geo(hostname)
|
14
|
+
uri = "/api/v1/indicators/hostname/#{hostname}/geo"
|
15
|
+
|
16
|
+
json_data = get(uri)
|
17
|
+
|
18
|
+
geo = OTX::Indicator::IP::Geo.new(json_data)
|
19
|
+
|
20
|
+
return geo
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_malware(hostname)
|
24
|
+
uri = "/api/v1/indicators/hostname/#{hostname}/malware"
|
25
|
+
malwares = []
|
26
|
+
params = {}
|
27
|
+
|
28
|
+
begin
|
29
|
+
json_data = get(uri, params)
|
30
|
+
page = json_data['next']
|
31
|
+
|
32
|
+
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
33
|
+
|
34
|
+
malwares += json_data['data']
|
35
|
+
end while page && !json_data['data'].empty?
|
36
|
+
|
37
|
+
results = []
|
38
|
+
malwares.each do |malware|
|
39
|
+
results << OTX::Indicator::IP::Malware.new(malware)
|
40
|
+
end
|
41
|
+
|
42
|
+
return results
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_url_list(hostname)
|
46
|
+
uri = "/api/v1/indicators/hostname/#{hostname}/url_list"
|
47
|
+
|
48
|
+
page = 0
|
49
|
+
url_list = []
|
50
|
+
begin
|
51
|
+
page += 1
|
52
|
+
params = {limit: 20, page: page}
|
53
|
+
json_data = get(uri, params)
|
54
|
+
has_next = json_data['has_next']
|
55
|
+
|
56
|
+
url_list += json_data['url_list']
|
57
|
+
end while has_next
|
58
|
+
|
59
|
+
results = []
|
60
|
+
url_list.each do |url|
|
61
|
+
results << OTX::Indicator::IP::URL.new(url)
|
62
|
+
end
|
63
|
+
|
64
|
+
return results
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_passive_dns(hostname)
|
68
|
+
uri = "/api/v1/indicators/hostname/#{hostname}/passive_dns"
|
69
|
+
|
70
|
+
json_data = get(uri)
|
71
|
+
|
72
|
+
results = []
|
73
|
+
json_data['passive_dns'].each do |dns|
|
74
|
+
results << OTX::Indicator::IP::DNS.new(dns)
|
75
|
+
end
|
76
|
+
|
77
|
+
return results
|
78
|
+
end
|
79
|
+
|
80
|
+
def get_http_scans(hostname)
|
81
|
+
uri = "/api/v1/indicators/hostname/#{hostname}/http_scans"
|
82
|
+
|
83
|
+
json_data = get(uri)
|
84
|
+
|
85
|
+
results = []
|
86
|
+
unless json_data['data'].nil?
|
87
|
+
json_data['data'].each do |http_scan|
|
88
|
+
results << OTX::Indicator::IP::HTTPScan.new(http_scan)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
return results
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/otx_ruby/ip.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
module OTX
|
2
|
+
class IP < OTX::Base
|
3
|
+
def get_general(ip, type = :ipv4)
|
4
|
+
uri = "/api/v1/indicators/#{type == :ipv6 ? 'IPv6' : 'IPv4'}/#{ip}/general"
|
5
|
+
|
6
|
+
json_data = get(uri)
|
7
|
+
|
8
|
+
general = OTX::Indicator::IP::General.new(json_data)
|
9
|
+
|
10
|
+
return general
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_reputation(ip, type = :ipv4)
|
14
|
+
uri = "/api/v1/indicators/#{type == :ipv6 ? 'IPv6' : 'IPv4'}/#{ip}/reputation"
|
15
|
+
|
16
|
+
json_data = get(uri)
|
17
|
+
|
18
|
+
if json_data['reputation']
|
19
|
+
reputation = OTX::Indicator::IP::Reputation.new(json_data["reputation"])
|
20
|
+
end
|
21
|
+
|
22
|
+
return reputation
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_geo(ip, type = :ipv4)
|
26
|
+
uri = "/api/v1/indicators/#{type == :ipv6 ? 'IPv6' : 'IPv4'}/#{ip}/geo"
|
27
|
+
|
28
|
+
json_data = get(uri)
|
29
|
+
|
30
|
+
geo = OTX::Indicator::IP::Geo.new(json_data)
|
31
|
+
|
32
|
+
return geo
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_malware(ip, type = :ipv4)
|
36
|
+
uri = "/api/v1/indicators/#{type == :ipv6 ? 'IPv6' : 'IPv4'}/#{ip}/malware"
|
37
|
+
malwares = []
|
38
|
+
params = {}
|
39
|
+
|
40
|
+
begin
|
41
|
+
json_data = get(uri, params)
|
42
|
+
page = json_data['next']
|
43
|
+
|
44
|
+
params = URI::decode_www_form(URI(page).query).to_h unless page.nil?
|
45
|
+
|
46
|
+
malwares += json_data['data']
|
47
|
+
end while page && !json_data['data'].empty?
|
48
|
+
|
49
|
+
results = []
|
50
|
+
malwares.each do |malware|
|
51
|
+
results << OTX::Indicator::IP::Malware.new(malware)
|
52
|
+
end
|
53
|
+
|
54
|
+
return results
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_url_list(ip, type = :ipv4)
|
58
|
+
uri = "/api/v1/indicators/#{type == :ipv6 ? 'IPv6' : 'IPv4'}/#{ip}/url_list"
|
59
|
+
|
60
|
+
page = 0
|
61
|
+
url_list = []
|
62
|
+
begin
|
63
|
+
page += 1
|
64
|
+
params = {limit: 20, page: page}
|
65
|
+
json_data = get(uri, params)
|
66
|
+
has_next = json_data['has_next']
|
67
|
+
|
68
|
+
url_list += json_data['url_list']
|
69
|
+
end while has_next
|
70
|
+
|
71
|
+
results = []
|
72
|
+
url_list.each do |url|
|
73
|
+
results << OTX::Indicator::IP::URL.new(url)
|
74
|
+
end
|
75
|
+
|
76
|
+
return results
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_passive_dns(ip, type = :ipv4)
|
80
|
+
uri = "/api/v1/indicators/#{type == :ipv6 ? 'IPv6' : 'IPv4'}/#{ip}/passive_dns"
|
81
|
+
|
82
|
+
json_data = get(uri)
|
83
|
+
|
84
|
+
results = []
|
85
|
+
json_data['passive_dns'].each do |dns|
|
86
|
+
results << OTX::Indicator::IP::DNS.new(dns)
|
87
|
+
end
|
88
|
+
|
89
|
+
return results
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_http_scans(ip, type = :ipv4)
|
93
|
+
uri = "/api/v1/indicators/#{type == :ipv6 ? 'IPv6' : 'IPv4'}/#{ip}/http_scans"
|
94
|
+
|
95
|
+
json_data = get(uri)
|
96
|
+
|
97
|
+
results = []
|
98
|
+
json_data['data'].each do |http_scan|
|
99
|
+
results << OTX::Indicator::IP::HTTPScan.new(http_scan)
|
100
|
+
end
|
101
|
+
|
102
|
+
return results
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|