passivetotalx 0.1.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.
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PassiveTotal
4
+ module Client
5
+ class Artifact < Base
6
+ #
7
+ # Create artifacts in bulk.
8
+ # http://api.passivetotal.org/api/docs/#api-Artifact-PutV2ArtifactBulk
9
+ #
10
+ # @param [Array<Hash>] artifacts a list of dictionaries that match the /v2/artifact interface (has query, type, tags, and project fields per dictionary)
11
+ #
12
+ # @return [Hash]
13
+ #
14
+ def bulk_create(artifacts)
15
+ params = {
16
+ artifacts: artifacts,
17
+ }.compact
18
+
19
+ _put("/artifact/bulk", params) { |json| json }
20
+ end
21
+
22
+ #
23
+ # Delete artifacts in bulk.
24
+ # http://api.passivetotal.org/api/docs/#api-Artifact-DeleteV2ArtifactBulk
25
+ #
26
+ # @param [Array<String>] artifacts the artifact ids to delete
27
+ #
28
+ # @return [Hash]
29
+ #
30
+ def bulk_delete(artifacts)
31
+ params = {
32
+ artifacts: artifacts,
33
+ }.compact
34
+
35
+ _delete("/artifact/bulk", params) { |json| json }
36
+ end
37
+
38
+ #
39
+ # Perform artifact updates in bulk.
40
+ # http://api.passivetotal.org/api/docs/#api-Artifact-PostV2ArtifactBulk
41
+ #
42
+ # @param [Array<Hash>] artifacts a list of dictionaries which match the fields for the /v2/artifact (artifact, monitor, tags)
43
+ #
44
+ # @return [Hash]
45
+ #
46
+ def bulk_update(artifacts)
47
+ params = {
48
+ artifacts: artifacts,
49
+ }.compact
50
+
51
+ _post("/artifact/bulk", params) { |json| json }
52
+ end
53
+
54
+ #
55
+ # Create an artifact.
56
+ # http://api.passivetotal.org/api/docs/#api-Artifact-PutV2Artifact
57
+ #
58
+ # @param [String] project the project id the artifact will live on
59
+ # @param [String] query the actual artifact query (passivetotal.org, 8.8.8.8, etc).
60
+ # @param [String, nil] type the type of the artifact (domain, ip, etc), or inferred by query string if domain or ip (optional).
61
+ # @param [String, nil] tags the tags the new artifact will have
62
+ #
63
+ # @return [Hash]
64
+ #
65
+ def create(project:, query:, type: nil, tags: nil)
66
+ params = {
67
+ project: project,
68
+ query: query,
69
+ type: type,
70
+ tags: tags,
71
+ }.compact
72
+
73
+ _put("/artifact", params) { |json| json }
74
+ end
75
+
76
+ #
77
+ # Delete an artifact with a UUID.
78
+ # http://api.passivetotal.org/api/docs/#api-Artifact-DeleteV2Artifact
79
+ #
80
+ # @param [String] artifact the artifact id
81
+ #
82
+ # @return [Hash]
83
+ #
84
+ def delete(artifact)
85
+ params = {
86
+ artifact: artifact,
87
+ }.compact
88
+
89
+ _delete("/artifact", params) { |json| json }
90
+ end
91
+
92
+ #
93
+ # Read existing artifacts. If no filters are passed, this returns all your personal artifacts created by you or your organization.
94
+ # http://api.passivetotal.org/api/docs/#api-Artifact-GetV2Artifact
95
+ #
96
+ # @param [String] artifact the artifact id
97
+ # @param [String] project filter by project id
98
+ # @param [String] owner filter by owner (an email or organization id)
99
+ # @param [String] creator filter by creator
100
+ # @param [String] organization filter by organization
101
+ # @param [String] query filter by query (passivetotal.org, etc)
102
+ # @param [String] type filter by artifact type (domain, ip, etc)
103
+ #
104
+ # @return [Hash]
105
+ #
106
+ def find(artifact: nil, project: nil, owner: nil, creator: nil, organization: nil, query: nil, type: nil)
107
+ params = {
108
+ artifact: artifact,
109
+ project: project,
110
+ owner: owner,
111
+ creator: creator,
112
+ organization: organization,
113
+ query: query,
114
+ type: type,
115
+ }.compact
116
+
117
+ _get("/artifact", params) { |json| json }
118
+ end
119
+
120
+ #
121
+ # Update artifact, or toggle monitoring status. If you want to change the query or artifact type, simply delete it and create a new one. Use /v2/artifact/tag to add or delete tags without setting everything at once.
122
+ # http://api.passivetotal.org/api/docs/#api-Artifact-PostV2Artifact
123
+ #
124
+ # @param [String] artifact the artifact id to update
125
+ # @param [String, nil] monitor whether to monitor the artifact
126
+ # @param [Array<String>, nil] tags sets the artifact's tags to this list
127
+ #
128
+ # @return [Hash]
129
+ #
130
+ def update(artifact, monitor: nil, tags: nil)
131
+ params = {
132
+ artifact: artifact,
133
+ monitor: monitor,
134
+ tags: tags,
135
+ }.compact
136
+
137
+ _post("/artifact", params) { |json| json }
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PassiveTotal
4
+ module Client
5
+ class Base
6
+ HOST = "api.passivetotal.org"
7
+ VERSION = "v2"
8
+ BASE_URL = "https://#{HOST}/#{VERSION}"
9
+
10
+ def initialize(username:, api_key:)
11
+ @username = username
12
+ @api_key = api_key
13
+ end
14
+
15
+ private
16
+
17
+ def url_for(path)
18
+ URI(BASE_URL + path)
19
+ end
20
+
21
+ def https_options
22
+ if proxy = ENV["HTTPS_PROXY"] || ENV["https_proxy"]
23
+ uri = URI(proxy)
24
+ {
25
+ proxy_address: uri.hostname,
26
+ proxy_port: uri.port,
27
+ proxy_from_env: false,
28
+ use_ssl: true
29
+ }
30
+ else
31
+ { use_ssl: true }
32
+ end
33
+ end
34
+
35
+ def make_request(req)
36
+ Net::HTTP.start(HOST, 443, https_options) do |http|
37
+ response = http.request(req)
38
+
39
+ code = response.code.to_i
40
+ body = response.body
41
+ json = JSON.parse(body)
42
+
43
+ case code
44
+ when 200
45
+ yield json
46
+ else
47
+ error = json.dig("error") || body
48
+ raise Error, "Unsupported response code returned: #{code} - #{error}"
49
+ end
50
+ end
51
+ end
52
+
53
+ def build_request(type: "GET", path:, params: {})
54
+ uri = url_for(path)
55
+ uri.query = URI.encode_www_form(params) if type == "GET"
56
+
57
+ request = case type
58
+ when "GET"
59
+ Net::HTTP::Get.new(uri)
60
+ when "POST"
61
+ Net::HTTP::Post.new(uri)
62
+ when "PUT"
63
+ Net::HTTP::Put.new(path)
64
+ when "DELETE"
65
+ Net::HTTP::Delete.new(path)
66
+ else
67
+ raise ArgumentError, "#{type} HTTP method is not supported"
68
+ end
69
+
70
+ request.body = JSON.generate(params) unless type == "GET"
71
+ request.basic_auth @username, @api_key
72
+
73
+ request
74
+ end
75
+
76
+ def _get(path, params = {}, &block)
77
+ request = build_request(type: "GET", path: path, params: params)
78
+ make_request(request, &block)
79
+ end
80
+
81
+ def _post(path, params = {}, &block)
82
+ request = build_request(type: "POST", path: path, params: params)
83
+ make_request(request, &block)
84
+ end
85
+
86
+ def _put(path, params = {}, &block)
87
+ request = build_request(type: "PUT", path: path, params: params)
88
+ make_request(request, &block)
89
+ end
90
+
91
+ def _delete(path, params = {}, &block)
92
+ request = build_request(type: "DELETE", path: path, params: params)
93
+ make_request(request, &block)
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PassiveTotal
4
+ module Client
5
+ class DNS < Base
6
+ #
7
+ # Retrieves the passive DNS results from active account sources.
8
+ # http://api.passivetotal.org/api/docs/#api-Passive_DNS-GetV2DnsPassive
9
+ #
10
+ # @param [String] query the domain or IP being queried
11
+ # @param [String] start the start datetime
12
+ # @param [String] end the end datetime
13
+ # @param [String] timeout timeout to use for external resources
14
+ #
15
+ # @return [Hash]
16
+ #
17
+ def passive(query, start_at: nil, end_at: nil, timeout: 7)
18
+ params = {
19
+ query: query,
20
+ start: start_at,
21
+ end: end_at,
22
+ timeout: timeout,
23
+ }.compact
24
+
25
+ _get("/dns/passive", params) { |json| json }
26
+ end
27
+
28
+ #
29
+ # Retrieves the unique passive DNS results from active account sources.
30
+ # http://api.passivetotal.org/api/docs/#api-Passive_DNS-GetV2DnsPassiveUnique
31
+ #
32
+ # @param [String] query the domain or IP being queried
33
+ #
34
+ # @return [Hash]
35
+ #
36
+ def passive_unique(query)
37
+ params = {
38
+ query: query,
39
+ }.compact
40
+
41
+ _get("/dns/passive/unique", params) { |json| json }
42
+ end
43
+
44
+ #
45
+ # Searches the Passive DNS data for a keyword query.
46
+ # http://api.passivetotal.org/api/docs/#api-Passive_DNS-GetV2DnsSearchKeyword
47
+ #
48
+ # @param [String] query query
49
+ #
50
+ # @return [Hash]
51
+ #
52
+ def search(query)
53
+ params = {
54
+ query: query
55
+ }.compact
56
+
57
+ _get("/dns/search/keyword", params) { |json| json }
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PassiveTotal
4
+ module Client
5
+ class Enrichment < Base
6
+ #
7
+ # Get enrichment data for a query
8
+ # http://api.passivetotal.org/api/docs/#api-Enrichment-GetV2Enrichment
9
+ #
10
+ # @param [String] query the domain or IP being queried
11
+ #
12
+ # @return [Hash]
13
+ #
14
+ def get(query)
15
+ params = {
16
+ query: query,
17
+ }.compact
18
+
19
+ _get("/enrichment", params) { |json| json }
20
+ end
21
+
22
+ #
23
+ # Get malware data for a query
24
+ # http://api.passivetotal.org/api/docs/#api-Enrichment-GetV2EnrichmentMalware
25
+ #
26
+ # @param [String] query the domain or IP being queried
27
+ #
28
+ # @return [Hash]
29
+ #
30
+ def malware(query)
31
+ params = {
32
+ query: query,
33
+ }.compact
34
+
35
+ _get("/enrichment/malware", params) { |json| json }
36
+ end
37
+
38
+ #
39
+ # Get osint data for a query
40
+ # http://api.passivetotal.org/api/docs/#api-Enrichment-GetV2EnrichmentOsint
41
+ #
42
+ # @param [String] query the domain or IP being queried
43
+ #
44
+ # @return [Hash]
45
+ #
46
+ def osint(query)
47
+ params = {
48
+ query: query,
49
+ }.compact
50
+
51
+ _get("/enrichment/osint", params) { |json| json }
52
+ end
53
+
54
+ #
55
+ # Get subdomains data for a query
56
+ # http://api.passivetotal.org/api/docs/#api-Enrichment-GetV2EnrichmentSubdomains
57
+ #
58
+ # @param [String] query the domain being queried
59
+ #
60
+ # @return [Hash]
61
+ #
62
+ def subdomains(query)
63
+ params = {
64
+ query: query,
65
+ }.compact
66
+
67
+ _get("/enrichment/subdomains", params) { |json| json }
68
+ end
69
+
70
+ #
71
+ # Get bulk enrichment data for many queries
72
+ # http://api.passivetotal.org/api/docs/#api-Bulk_Enrichment-GetV2EnrichmentBulk
73
+ #
74
+ # @param [Array<String>] query the domains and IPs being queried
75
+ #
76
+ # @return [Hash]
77
+ #
78
+ def bulk_data(*query)
79
+ params = {
80
+ query: query,
81
+ }.compact
82
+
83
+ _get("/enrichment/bulk", params) { |json| json }
84
+ end
85
+
86
+ #
87
+ # Get bulk malware data for many queries
88
+ # http://api.passivetotal.org/api/docs/#api-Bulk_Enrichment-GetV2EnrichmentBulkMalware
89
+ #
90
+ # @param [Array<String>] query the domains and IPs being queried
91
+ #
92
+ # @return [Hash]
93
+ #
94
+ def bulk_malware(*query)
95
+ params = {
96
+ query: query,
97
+ }.compact
98
+
99
+ _get("/enrichment/bulk/malware", params) { |json| json }
100
+ end
101
+
102
+ #
103
+ # Get bulk osint data for many queries
104
+ # http://api.passivetotal.org/api/docs/#api-Bulk_Enrichment-GetV2EnrichmentBulkOsint
105
+ #
106
+ # @param [Array<String>] query the domains and IPs being queried
107
+ #
108
+ # @return [Hash]
109
+ #
110
+ def bulk_osint(*query)
111
+ params = {
112
+ query: query,
113
+ }.compact
114
+
115
+ _get("/enrichment/bulk/osint", params) { |json| json }
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PassiveTotal
4
+ module Client
5
+ class Host < Base
6
+ #
7
+ # Retrieves the host attribute components of a query.
8
+ # http://api.passivetotal.org/api/docs/#api-Host_Attributes-GetV2HostAttributesComponents
9
+ #
10
+ # @param [String] query
11
+ # @param [String, nil] start_at
12
+ # @param [String, nil] end_at
13
+ #
14
+ # @return [Hash]
15
+ #
16
+ def components(query, start_at: nil, end_at: nil)
17
+ params = {
18
+ query: query,
19
+ start: start_at,
20
+ end: end_at,
21
+ }.compact
22
+
23
+ _get("/host-attributes/components", params) { |json| json }
24
+ end
25
+
26
+ #
27
+ # Retrieves the host attribute pairs related to the query.
28
+ # https://api.passivetotal.org/api/docs/#api-Host_Attributes-GetV2HostAttributesComponents
29
+ #
30
+ # @param [String] query
31
+ # @param [String] direction
32
+ # @param [String] start_at
33
+ # @param [String] end_at
34
+ #
35
+ # @return [Hash]
36
+ #
37
+ def pairs(query, direction: "children", start_at: nil, end_at: nil)
38
+ params = {
39
+ query: query,
40
+ direction: direction,
41
+ start: start_at,
42
+ end: end_at,
43
+ }.compact
44
+
45
+ _get("/host-attributes/pairs", params) { |json| json }
46
+ end
47
+
48
+ #
49
+ # Retrieves the host attribute trackers
50
+ # https://api.passivetotal.org/api/docs/#api-Host_Attributes-GetV2HostAttributesTrackers
51
+ #
52
+ # @param [String] query
53
+ # @param [String, nil] start_at
54
+ # @param [String, nil] end_at
55
+ #
56
+ # @return [Hash]
57
+ #
58
+ def trackers(query, start_at: nil, end_at: nil)
59
+ params = {
60
+ query: query,
61
+ start: start_at,
62
+ end: end_at,
63
+ }.compact
64
+
65
+ _get("/host-attributes/trackers", params) { |json| json }
66
+ end
67
+ end
68
+ end
69
+ end