passivetotalx 0.1.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
+ SHA256:
3
+ metadata.gz: 489c68db79e0c9e37b37f5ca916e2358c1f04d2639dd4e8d888d6ea02ae97a1e
4
+ data.tar.gz: e063f27ce5d7a5cac82751ff0450e2f2cc1ce93c362cba864b0496937c5e750e
5
+ SHA512:
6
+ metadata.gz: 1062e63210b36d9ba6d982063c90ae2bcce52a36639002d3f308e041440ebbf608d733f38f7e722305f179cce2032ecd895ca33cc1cf3a04075bdbc32c063018
7
+ data.tar.gz: 43301ec9cf335e863f4f2b4ad3decfab5e28c900d69cadf54dfdd937e804b5884f46a09ebb7e157a5e0962afc29c5355f46f305e6197e35bfa8dc57a7ed25bc3
data/.gitignore ADDED
@@ -0,0 +1,52 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ Gemfile.lock
46
+ .ruby-version
47
+ .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
51
+
52
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6
7
+ before_install: gem install bundler -v 2.0.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in passivetotal.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Manabu Niseki
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # passivetotalx
2
+
3
+ [![Build Status](https://travis-ci.com/ninoseki/passivetotal.svg?branch=master)](https://travis-ci.com/ninoseki/passivetotal)
4
+ [![Coverage Status](https://coveralls.io/repos/github/ninoseki/passivetotal/badge.svg?branch=master)](https://coveralls.io/github/ninoseki/passivetotal?branch=master)
5
+ [![CodeFactor](https://www.codefactor.io/repository/github/ninoseki/passivetotal/badge)](https://www.codefactor.io/repository/github/ninoseki/passivetotal)
6
+
7
+ Yet another [PassiveTotal](https://community.riskiq.com/) API wrapper for Ruby.
8
+
9
+ ## Why I created this
10
+
11
+ There is an official PassiveTotal API wrapper for Ruby.
12
+
13
+ - [chrislee35/passivetotal](https://github.com/chrislee35/passivetotal)
14
+
15
+ But I don't like that in several reasons.
16
+
17
+ - A lack of proxy support.
18
+ - Not well structured (IMHO).
19
+ - Not tested with Ruby >= 2.6.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ gem install passivetotalx
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```ruby
30
+ require "passivetotal"
31
+
32
+ # when given nothing, it tries to load your usernamem & API key via ENV["PASSIVETOTAL_USERNAME"] and ENV["PASSIVETOTAL_API_KEY"]
33
+ api = PassiveTotal::API.new
34
+ # or you can set them manually
35
+ api = PassiveTotal::API.new(username: "USERNAME", api_key: "API_KEY")
36
+
37
+ query = "passivetotal.org"
38
+
39
+ api.dns.passive(query)
40
+ api.dns.passive_unique(query)
41
+ api.dns.search(query)
42
+ ```
43
+
44
+ ## License
45
+
46
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "passivetotal"
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(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "passivetotal/version"
4
+
5
+ require "passivetotal/clients/base"
6
+
7
+ require "passivetotal/clients/account"
8
+ require "passivetotal/clients/action"
9
+ require "passivetotal/clients/artifact"
10
+ require "passivetotal/clients/base"
11
+ require "passivetotal/clients/dns"
12
+ require "passivetotal/clients/enrichment"
13
+ require "passivetotal/clients/host"
14
+ require "passivetotal/clients/monitor"
15
+ require "passivetotal/clients/project"
16
+ require "passivetotal/clients/ssl"
17
+ require "passivetotal/clients/tag"
18
+ require "passivetotal/clients/tracker"
19
+ require "passivetotal/clients/whois"
20
+ require "passivetotal/clients/host"
21
+
22
+ require "passivetotal/api"
23
+
24
+ module PassiveTotal
25
+ class Error < StandardError; end
26
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PassiveTotal
4
+ class API
5
+ attr_reader :username
6
+ attr_reader :api_key
7
+
8
+ def initialize(username: ENV["PASSIVETOTAL_USERNAME"], api_key: ENV["PASSIVETOTAL_API_KEY"])
9
+ @username = username
10
+ raise ArgumentError, "No usernamme has been found or provided!" unless @username
11
+
12
+ @api_key = api_key
13
+ raise ArgumentError, "No api key has been found or provided!" unless @api_key
14
+ end
15
+
16
+ def account
17
+ @account ||= Client::Account.new(username: username, api_key: api_key)
18
+ end
19
+
20
+ def action
21
+ @action ||= Client::Action.new(username: username, api_key: api_key)
22
+ end
23
+
24
+ def artifact
25
+ @artifact ||= Client::Artifact.new(username: username, api_key: api_key)
26
+ end
27
+
28
+ def base
29
+ @base ||= Client::Base.new(username: username, api_key: api_key)
30
+ end
31
+
32
+ def dns
33
+ @dns ||= Client::DNS.new(username: username, api_key: api_key)
34
+ end
35
+
36
+ def enrichment
37
+ @enrichment ||= Client::Enrichment.new(username: username, api_key: api_key)
38
+ end
39
+
40
+ def host
41
+ @host ||= Client::Host.new(username: username, api_key: api_key)
42
+ end
43
+
44
+ def monitor
45
+ @monitor ||= Client::Monitor.new(username: username, api_key: api_key)
46
+ end
47
+
48
+ def project
49
+ @project ||= Client::Project.new(username: username, api_key: api_key)
50
+ end
51
+
52
+ def ssl
53
+ @ssl ||= Client::SSL.new(username: username, api_key: api_key)
54
+ end
55
+
56
+ def tag
57
+ @tag ||= Client::Tag.new(username: username, api_key: api_key)
58
+ end
59
+
60
+ def tracker
61
+ @tracker ||= Client::Tracker.new(username: username, api_key: api_key)
62
+ end
63
+
64
+ def whois
65
+ @whois ||= Client::WHOIS.new(username: username, api_key: api_key)
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PassiveTotal
4
+ module Client
5
+ class Account < Base
6
+ #
7
+ # Read current account metadata and settings.
8
+ # http://api.passivetotal.org/api/docs/#api-Account-GetV2Account
9
+ #
10
+ #
11
+ # @return [Hash]
12
+ #
13
+ def get
14
+ _get("/account") { |json| json }
15
+ end
16
+
17
+ #
18
+ # Read API usage history of the account.
19
+ # http://api.passivetotal.org/api/docs/#api-Account-GetV2AccountHistory
20
+ #
21
+ # @param [String, nil] source history type (api/ui), defaults to both
22
+ #
23
+ # @return [Hash]
24
+ #
25
+ def history(source = nil)
26
+ params = {
27
+ source: source
28
+ }.compact
29
+
30
+ _get("/account/history", params) { |json| json }
31
+ end
32
+
33
+ #
34
+ # Get active monitors
35
+ # http://api.passivetotal.org/api/docs/#api-Account-GetV2AccountMonitors
36
+ #
37
+ #
38
+ # @return [Hash]
39
+ #
40
+ def monitors
41
+ _get("/account/monitors") { |json| json }
42
+ end
43
+
44
+ #
45
+ # Read current organization metadata
46
+ # http://api.passivetotal.org/api/docs/#api-Account-GetV2AccountOrganization
47
+ #
48
+ #
49
+ # @return [Hash]
50
+ #
51
+ def organization
52
+ _get("/account/organization") { |json| json }
53
+ end
54
+
55
+ #
56
+ # Read current account and organization quotas.
57
+ # http://api.passivetotal.org/api/docs/#api-Account-GetV2AccountQuotas
58
+ #
59
+ #
60
+ # @return [Hash]
61
+ #
62
+ def quotas
63
+ _get("/account/quotas") { |json| json }
64
+ end
65
+
66
+ #
67
+ # Check sources being used for queries.
68
+ # http://api.passivetotal.org/api/docs/#api-Account-GetV2AccountSources
69
+ #
70
+ # @param [String, nil] source the source to filter on
71
+ #
72
+ # @return [Hash]
73
+ #
74
+ def sources(source: nil)
75
+ params = {
76
+ source: source
77
+ }.compact
78
+
79
+ _get("/account/sources", params) { |json| json }
80
+ end
81
+
82
+ #
83
+ # Read team activity.
84
+ # http://api.passivetotal.org/api/docs/#api-Account-GetV2AccountOrganizationTeamstream
85
+ #
86
+ # @param [String, nil] source filter to this source
87
+ # @param [String, nil] dt filter to this datetime
88
+ # @param [String, nil] type filter by type field
89
+ # @param [String, nil] focus filter by focus (domain, ip, etc)
90
+ #
91
+ # @return [Hash]
92
+ #
93
+ def teamstream(source: nil, dt: nil, type: nil, focus: nil)
94
+ params = {
95
+ source: source,
96
+ dt: dt,
97
+ type: type,
98
+ focus: focus,
99
+ }.compact
100
+
101
+ _get("/account/organization/teamstream", params) { |json| json }
102
+ end
103
+
104
+ #
105
+ # Retrieve items with the specified classification.
106
+ # http://api.passivetotal.org/api/docs/#api-Account-GetV2AccountClassifications
107
+ #
108
+ # @param [String] classification classification for which to retrieve items for
109
+ #
110
+ # @return [Hash]
111
+ #
112
+ def classifications(classification)
113
+ params = {
114
+ classification: classification
115
+ }.compact
116
+
117
+ _get("/account/classifications", params) { |json| json }
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,279 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PassiveTotal
4
+ module Client
5
+ class Action < Base
6
+ #
7
+ # Adds tags to a given artifact.
8
+ # http://api.passivetotal.org/api/docs/#api-Actions-PostV2ActionsTags
9
+ #
10
+ # @param [String] query artifact for which to add tags
11
+ # @param [Array<String>] tags tags to add to artifact
12
+ #
13
+ # @return [Hash]
14
+ #
15
+ def add_tags(query:, tags:)
16
+ params = {
17
+ query: query,
18
+ tags: tags,
19
+ }.compact
20
+
21
+ _post("/actions/tags", params) { |json| json }
22
+ end
23
+
24
+ #
25
+ # Removes tags from an artifact.
26
+ # http://api.passivetotal.org/api/docs/#api-Actions-DeleteV2ActionsTags
27
+ #
28
+ # @param [String] query artifact from which to remove tags
29
+ # @param [Array<String>] tags tags to remove from artifact
30
+ #
31
+ # @return [Hash]
32
+ #
33
+ def delete_tags(query:, tags:)
34
+ params = {
35
+ query: query,
36
+ tags: tags,
37
+ }.compact
38
+
39
+ _delete("/actions/tags", params) { |json| json }
40
+ end
41
+
42
+ #
43
+ # Retrieve classification statuses for given domains.
44
+ # http://api.passivetotal.org/api/docs/#api-Actions-GetV2ActionsBulkClassification
45
+ #
46
+ # @param [Array<String>] query domains for which to retrieve classification statuses
47
+ #
48
+ # @return [Hash]
49
+ #
50
+ def bulk_classification(*query)
51
+ params = {
52
+ query: query,
53
+ }.compact
54
+
55
+ _get("/actions/bulk/classification", params) { |json| json }
56
+ end
57
+
58
+ #
59
+ # Retrieve classification status for a given domain.
60
+ # http://api.passivetotal.org/api/docs/#api-Actions-GetV2ActionsClassification
61
+ #
62
+ # @param [String] query domain for which to retrieve classification status
63
+ #
64
+ # @return [Hash]
65
+ #
66
+ def classification(query)
67
+ params = {
68
+ query: query,
69
+ }.compact
70
+
71
+ _get("/actions/classification", params) { |json| json }
72
+ end
73
+
74
+ #
75
+ # Indicates whether or not a given domain has ever been compromised.
76
+ # http://api.passivetotal.org/api/docs/#api-Actions-GetV2ActionsEverCompromised
77
+ #
78
+ # @param [String] query domain to check for compromised status
79
+ #
80
+ # @return [Hash]
81
+ #
82
+ def ever_compromised(query)
83
+ params = {
84
+ query: query,
85
+ }.compact
86
+
87
+ _get("/actions/ever-compromised", params) { |json| json }
88
+ end
89
+
90
+ #
91
+ # Indicates whether or not a domain's DNS records are updated via dynamic DNS.
92
+ # http://api.passivetotal.org/api/docs/#api-Actions-GetV2ActionsDynamicDns
93
+ #
94
+ # @param [String] query domain for which to retrieve dynamic DNS status
95
+ #
96
+ # @return [Hash]
97
+ #
98
+ def dynamic_dns(query)
99
+ params = {
100
+ query: query,
101
+ }.compact
102
+
103
+ _get("/actions/dynamic-dns", params) { |json| json }
104
+ end
105
+
106
+ #
107
+ # Indicates whether or not a domain is monitored.
108
+ # http://api.passivetotal.org/api/docs/#api-Actions-GetV2ActionsMonitor
109
+ #
110
+ # @param [String] query domain for which to check for monitoring
111
+ #
112
+ # @return [Hash]
113
+ #
114
+ def monitor(query)
115
+ params = {
116
+ query: query,
117
+ }.compact
118
+
119
+ _get("/actions/monitor", params) { |json| json }
120
+ end
121
+
122
+ #
123
+ # Indicates whether or not an IP address is a sinkhole.
124
+ # http://api.passivetotal.org/api/docs/#api-Actions-GetV2ActionsSinkhole
125
+ #
126
+ # @param [String] query IP address to check for sinkhole status
127
+ #
128
+ # @return [Hash]
129
+ #
130
+ def sinkhole(query)
131
+ params = {
132
+ query: query,
133
+ }.compact
134
+
135
+ _get("/actions/sinkhole", params) { |json| json }
136
+ end
137
+
138
+ #
139
+ # Retrieves tags for a given artifact.
140
+ # http://api.passivetotal.org/api/docs/#api-Actions-GetV2ActionsTags
141
+ #
142
+ # @param [String] query artifact for which to retrieve tags
143
+ #
144
+ # @return [Hash]
145
+ #
146
+ def tags(query)
147
+ params = {
148
+ query: query,
149
+ }.compact
150
+
151
+ _get("/actions/tags", params) { |json| json }
152
+ end
153
+
154
+ #
155
+ # Retrieve artifacts for a given tag.
156
+ # http://api.passivetotal.org/api/docs/#api-Actions-GetV2ActionsTagsSearch
157
+ #
158
+ # @param [String] query tag for which to retrieve artifacts
159
+ #
160
+ # @return [Hash]
161
+ #
162
+ def search_by_tags(query)
163
+ params = {
164
+ query: query,
165
+ }.compact
166
+
167
+ _get("/actions/tags/search", params) { |json| json }
168
+ end
169
+
170
+ #
171
+ # Set classification statuses for given domains.
172
+ # http://api.passivetotal.org/api/docs/#api-Actions-PostV2ActionsBulkClassification
173
+ #
174
+ # @param [Arra<String>] queries domain for which to set classification status
175
+ # @param [String] classification classification status to set for domain
176
+ #
177
+ # @return [Hash]
178
+ #
179
+ def set_bulk_classification(queries:, classification:)
180
+ params = {
181
+ queries: queries,
182
+ classification: classification,
183
+ }.compact
184
+
185
+ _post("/actions/bulk/classification", params) { |json| json }
186
+ end
187
+
188
+ #
189
+ # Sets the classification status for a given domain.
190
+ # https://api.passivetotal.org/api/docs/#api-Actions-PostV2ActionsClassification
191
+ #
192
+ # @param [String] query domain for which to set classification status
193
+ # @param [String] classification classification status to set for domain
194
+ #
195
+ # @return [Hash]
196
+ #
197
+ def set_classification(query:, classification:)
198
+ params = {
199
+ query: query,
200
+ classification: classification,
201
+ }.compact
202
+
203
+ _post("/actions/classification", params) { |json| json }
204
+ end
205
+
206
+ #
207
+ # Sets status for a domain to indicate if it has ever been compromised.
208
+ # http://api.passivetotal.org/api/docs/#api-Actions-PostV2ActionsEverCompromised
209
+ #
210
+ # @param [String] query domain for which to set compromised status
211
+ # @param [Boolean] status if the domain has ever been compromised
212
+ #
213
+ # @return [Hash]
214
+ #
215
+ def set_ever_compromised(query:, status:)
216
+ params = {
217
+ query: query,
218
+ status: status,
219
+ }.compact
220
+
221
+ _post("/actions/ever-compromised", params) { |json| json }
222
+ end
223
+
224
+ #
225
+ # Sets a domain's status to indicate whether or not its DNS records are updated via dynamic DNS.
226
+ # http://api.passivetotal.org/api/docs/#api-Actions-PostV2ActionsDynamicDns
227
+ #
228
+ # @param [String] query domain for which to set dynamic DNS status
229
+ # @param [Boolean] status if the domain's DNS records are updated via dynamic DNS
230
+ #
231
+ # @return [Hash]
232
+ #
233
+ def set_dynamic_dns(query:, status:)
234
+ params = {
235
+ query: query,
236
+ status: status,
237
+ }.compact
238
+
239
+ _post("/actions/dynamic-dns", params) { |json| json }
240
+ end
241
+
242
+ #
243
+ # Sets status for an IP address to indicate whether or not it is a sinkhole.
244
+ # http://api.passivetotal.org/api/docs/#api-Actions-PostV2ActionsSinkhole
245
+ #
246
+ # @param [String] query IP address for which to set sinkhole status
247
+ # @param [Boolean] status if the IP address is a sinkhole
248
+ #
249
+ # @return [Hash]
250
+ #
251
+ def set_sinkhole(query:, status:)
252
+ params = {
253
+ query: query,
254
+ status: status,
255
+ }.compact
256
+
257
+ _post("/actions/sinkhole", params) { |json| json }
258
+ end
259
+
260
+ #
261
+ # Sets the tags for a given artifact.
262
+ # http://api.passivetotal.org/api/docs/#api-Actions-PutV2ActionsTags
263
+ #
264
+ # @param [String] query artifact for which to set tags
265
+ # @param [Array<String>] tags tags to set for artifact
266
+ #
267
+ # @return [Hash]
268
+ #
269
+ def set_tags(query:, tags:)
270
+ params = {
271
+ query: query,
272
+ tags: tags,
273
+ }.compact
274
+
275
+ _put("/actions/tags", params) { |json| json }
276
+ end
277
+ end
278
+ end
279
+ end