mihari 5.2.0 → 5.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/lib/mihari/analyzers/base.rb +20 -115
- data/lib/mihari/analyzers/censys.rb +20 -2
- data/lib/mihari/analyzers/onyphe.rb +1 -1
- data/lib/mihari/analyzers/rule.rb +116 -60
- data/lib/mihari/analyzers/shodan.rb +1 -1
- data/lib/mihari/analyzers/urlscan.rb +6 -9
- data/lib/mihari/analyzers/virustotal_intelligence.rb +1 -5
- data/lib/mihari/cli/main.rb +2 -2
- data/lib/mihari/commands/search.rb +69 -0
- data/lib/mihari/commands/web.rb +9 -2
- data/lib/mihari/mixins/error_notification.rb +0 -2
- data/lib/mihari/models/artifact.rb +1 -1
- data/lib/mihari/schemas/rule.rb +2 -17
- data/lib/mihari/structs/censys.rb +167 -11
- data/lib/mihari/structs/config.rb +28 -0
- data/lib/mihari/structs/google_public_dns.rb +39 -1
- data/lib/mihari/structs/greynoise.rb +93 -6
- data/lib/mihari/structs/ipinfo.rb +40 -0
- data/lib/mihari/structs/onyphe.rb +88 -6
- data/lib/mihari/structs/rule.rb +4 -2
- data/lib/mihari/structs/shodan.rb +138 -4
- data/lib/mihari/structs/urlscan.rb +98 -1
- data/lib/mihari/structs/virustotal_intelligence.rb +96 -1
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/app.rb +2 -2
- data/lib/mihari/web/public/assets/index-cbe1734c.js +50 -0
- data/lib/mihari/web/public/assets/index-eed1bcd8.css +5 -0
- data/lib/mihari/web/public/index.html +2 -2
- data/lib/mihari.rb +1 -0
- data/mihari.gemspec +13 -12
- metadata +41 -42
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -43
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -15
- data/.github/workflows/test.yml +0 -90
- data/config/pre_commit.yml +0 -3
- data/docker/Dockerfile +0 -14
- data/examples/ipinfo_hosted_domains.rb +0 -45
- data/images/Tines-Full_Logo-Tines_Black.png +0 -0
- data/images/alert.png +0 -0
- data/images/logo.png +0 -0
- data/images/misp.png +0 -0
- data/images/overview.jpg +0 -0
- data/images/slack.png +0 -0
- data/images/tines.png +0 -0
- data/images/web_alerts.png +0 -0
- data/images/web_config.png +0 -0
- data/lib/mihari/commands/searcher.rb +0 -61
- data/lib/mihari/web/public/assets/index-9948ee35.js +0 -50
- data/lib/mihari/web/public/assets/index-d88cc3f1.css +0 -5
data/lib/mihari/schemas/rule.rb
CHANGED
@@ -25,30 +25,15 @@ module Mihari
|
|
25
25
|
AnalyzerWithoutAPIKey | AnalyzerWithAPIKey | Censys | CIRCL | PassiveTotal | ZoomEye | Urlscan | Crtsh | Feed
|
26
26
|
end
|
27
27
|
|
28
|
-
optional(:emitters).value(:array).each { Database | MISP | TheHive | Slack | Webhook }
|
28
|
+
optional(:emitters).value(:array).each { Database | MISP | TheHive | Slack | Webhook }.default(DEFAULT_EMITTERS)
|
29
29
|
|
30
|
-
optional(:enrichers).value(:array).each(Enricher)
|
30
|
+
optional(:enrichers).value(:array).each(Enricher).default(DEFAULT_ENRICHERS)
|
31
31
|
|
32
32
|
optional(:data_types).value(array[Types::DataTypes]).default(DEFAULT_DATA_TYPES)
|
33
33
|
optional(:falsepositives).value(array[:string]).default([])
|
34
34
|
|
35
35
|
optional(:artifact_lifetime).value(:integer)
|
36
36
|
optional(:artifact_ttl).value(:integer)
|
37
|
-
|
38
|
-
before(:key_coercer) do |result|
|
39
|
-
# it looks like that dry-schema v1.9.1 has an issue with setting an array of schemas as a default value
|
40
|
-
# e.g. optional(:emitters).value(:array).each { Emitter | HTTP }.default(DEFAULT_EMITTERS) does not work well
|
41
|
-
# so let's do a dirty hack...
|
42
|
-
h = result.to_h
|
43
|
-
|
44
|
-
emitters = h[:emitters]
|
45
|
-
h[:emitters] = emitters || DEFAULT_EMITTERS
|
46
|
-
|
47
|
-
enrichers = h[:enrichers]
|
48
|
-
h[:enrichers] = enrichers || DEFAULT_ENRICHERS
|
49
|
-
|
50
|
-
h
|
51
|
-
end
|
52
37
|
end
|
53
38
|
|
54
39
|
class RuleContract < Dry::Validation::Contract
|
@@ -8,6 +8,13 @@ module Mihari
|
|
8
8
|
|
9
9
|
attribute :asn, Types::Int
|
10
10
|
|
11
|
+
#
|
12
|
+
# @return [Integer]
|
13
|
+
#
|
14
|
+
def asn
|
15
|
+
attributes[:asn]
|
16
|
+
end
|
17
|
+
|
11
18
|
#
|
12
19
|
# @return [Mihari::AutonomousSystem]
|
13
20
|
#
|
@@ -15,6 +22,11 @@ module Mihari
|
|
15
22
|
Mihari::AutonomousSystem.new(asn: normalize_asn(asn))
|
16
23
|
end
|
17
24
|
|
25
|
+
#
|
26
|
+
# @param [Hash] d
|
27
|
+
#
|
28
|
+
# @return [AutonomousSystem]
|
29
|
+
#
|
18
30
|
def self.from_dynamic!(d)
|
19
31
|
d = Types::Hash[d]
|
20
32
|
new(
|
@@ -27,6 +39,20 @@ module Mihari
|
|
27
39
|
attribute :country, Types::String.optional
|
28
40
|
attribute :country_code, Types::String.optional
|
29
41
|
|
42
|
+
#
|
43
|
+
# @return [String, nil]
|
44
|
+
#
|
45
|
+
def country
|
46
|
+
attributes[:country]
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# @return [String, nil]
|
51
|
+
#
|
52
|
+
def country_code
|
53
|
+
attributes[:country_code]
|
54
|
+
end
|
55
|
+
|
30
56
|
#
|
31
57
|
# @return [Mihari::Geolocation] <description>
|
32
58
|
#
|
@@ -41,6 +67,11 @@ module Mihari
|
|
41
67
|
)
|
42
68
|
end
|
43
69
|
|
70
|
+
#
|
71
|
+
# @param [Hash] d
|
72
|
+
#
|
73
|
+
# @return [Location]
|
74
|
+
#
|
44
75
|
def self.from_dynamic!(d)
|
45
76
|
d = Types::Hash[d]
|
46
77
|
new(
|
@@ -53,6 +84,13 @@ module Mihari
|
|
53
84
|
class Service < Dry::Struct
|
54
85
|
attribute :port, Types::Integer
|
55
86
|
|
87
|
+
#
|
88
|
+
# @return [Integer]
|
89
|
+
#
|
90
|
+
def port
|
91
|
+
attributes[:port]
|
92
|
+
end
|
93
|
+
|
56
94
|
#
|
57
95
|
# @return [Mihari::Port]
|
58
96
|
#
|
@@ -60,6 +98,11 @@ module Mihari
|
|
60
98
|
Port.new(port: port)
|
61
99
|
end
|
62
100
|
|
101
|
+
#
|
102
|
+
# @param [Hash] d
|
103
|
+
#
|
104
|
+
# @return [Service]
|
105
|
+
#
|
63
106
|
def self.from_dynamic!(d)
|
64
107
|
d = Types::Hash[d]
|
65
108
|
new(
|
@@ -75,6 +118,41 @@ module Mihari
|
|
75
118
|
attribute :metadata, Types::Hash
|
76
119
|
attribute :services, Types.Array(Service)
|
77
120
|
|
121
|
+
#
|
122
|
+
# @return [String]
|
123
|
+
#
|
124
|
+
def ip
|
125
|
+
attributes[:ip]
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# @return [Location]
|
130
|
+
#
|
131
|
+
def location
|
132
|
+
attributes[:location]
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# @return [AutonomousSystem]
|
137
|
+
#
|
138
|
+
def autonomous_system
|
139
|
+
attributes[:autonomous_system]
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# @return [Hash]
|
144
|
+
#
|
145
|
+
def metadata
|
146
|
+
attributes[:metadata]
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# @return [Array<Service>]
|
151
|
+
#
|
152
|
+
def services
|
153
|
+
attributes[:services]
|
154
|
+
end
|
155
|
+
|
78
156
|
#
|
79
157
|
# @return [Array<Mihari::Port>]
|
80
158
|
#
|
@@ -82,15 +160,12 @@ module Mihari
|
|
82
160
|
services.map(&:to_port)
|
83
161
|
end
|
84
162
|
|
85
|
-
#
|
86
|
-
# @param [String] source
|
87
163
|
#
|
88
164
|
# @return [Mihari::Artifact]
|
89
165
|
#
|
90
|
-
def to_artifact
|
166
|
+
def to_artifact
|
91
167
|
Artifact.new(
|
92
168
|
data: ip,
|
93
|
-
source: source,
|
94
169
|
metadata: metadata,
|
95
170
|
autonomous_system: autonomous_system.to_as,
|
96
171
|
geolocation: location.to_geolocation,
|
@@ -98,6 +173,11 @@ module Mihari
|
|
98
173
|
)
|
99
174
|
end
|
100
175
|
|
176
|
+
#
|
177
|
+
# @param [Hash] d
|
178
|
+
#
|
179
|
+
# @return [Hit]
|
180
|
+
#
|
101
181
|
def self.from_dynamic!(d)
|
102
182
|
d = Types::Hash[d]
|
103
183
|
new(
|
@@ -111,14 +191,33 @@ module Mihari
|
|
111
191
|
end
|
112
192
|
|
113
193
|
class Links < Dry::Struct
|
114
|
-
attribute :next, Types::String
|
115
|
-
attribute :prev, Types::String
|
194
|
+
attribute :next, Types::String.optional
|
195
|
+
attribute :prev, Types::String.optional
|
196
|
+
|
197
|
+
#
|
198
|
+
# @return [String, nil]
|
199
|
+
#
|
200
|
+
def next
|
201
|
+
attributes[:next]
|
202
|
+
end
|
116
203
|
|
204
|
+
#
|
205
|
+
# @return [String, nil]
|
206
|
+
#
|
207
|
+
def prev
|
208
|
+
attributes[:prev]
|
209
|
+
end
|
210
|
+
|
211
|
+
#
|
212
|
+
# @param [Hash] d
|
213
|
+
#
|
214
|
+
# @return [Links]
|
215
|
+
#
|
117
216
|
def self.from_dynamic!(d)
|
118
217
|
d = Types::Hash[d]
|
119
218
|
new(
|
120
|
-
next: d
|
121
|
-
prev: d
|
219
|
+
next: d["next"],
|
220
|
+
prev: d["prev"]
|
122
221
|
)
|
123
222
|
end
|
124
223
|
end
|
@@ -130,14 +229,45 @@ module Mihari
|
|
130
229
|
attribute :links, Links
|
131
230
|
|
132
231
|
#
|
133
|
-
# @
|
232
|
+
# @return [String]
|
233
|
+
#
|
234
|
+
def query
|
235
|
+
attributes[:query]
|
236
|
+
end
|
237
|
+
|
238
|
+
#
|
239
|
+
# @return [Integer]
|
240
|
+
#
|
241
|
+
def total
|
242
|
+
attributes[:total]
|
243
|
+
end
|
244
|
+
|
245
|
+
#
|
246
|
+
# @return [Array<Hit>]
|
247
|
+
#
|
248
|
+
def hits
|
249
|
+
attributes[:hits]
|
250
|
+
end
|
251
|
+
|
252
|
+
#
|
253
|
+
# @return [Links]
|
254
|
+
#
|
255
|
+
def links
|
256
|
+
attributes[:links]
|
257
|
+
end
|
258
|
+
|
134
259
|
#
|
135
260
|
# @return [Array<Mihari::Artifact>]
|
136
261
|
#
|
137
|
-
def to_artifacts
|
138
|
-
hits.map { |hit| hit.to_artifact
|
262
|
+
def to_artifacts
|
263
|
+
hits.map { |hit| hit.to_artifact }
|
139
264
|
end
|
140
265
|
|
266
|
+
#
|
267
|
+
# @param [Hash] d
|
268
|
+
#
|
269
|
+
# @return [Result]
|
270
|
+
#
|
141
271
|
def self.from_dynamic!(d)
|
142
272
|
d = Types::Hash[d]
|
143
273
|
new(
|
@@ -154,6 +284,32 @@ module Mihari
|
|
154
284
|
attribute :status, Types::String
|
155
285
|
attribute :result, Result
|
156
286
|
|
287
|
+
#
|
288
|
+
# @return [Integer]
|
289
|
+
#
|
290
|
+
def code
|
291
|
+
attributes[:code]
|
292
|
+
end
|
293
|
+
|
294
|
+
#
|
295
|
+
# @return [String]
|
296
|
+
#
|
297
|
+
def status
|
298
|
+
attributes[:status]
|
299
|
+
end
|
300
|
+
|
301
|
+
#
|
302
|
+
# @return [Result]
|
303
|
+
#
|
304
|
+
def result
|
305
|
+
attributes[:result]
|
306
|
+
end
|
307
|
+
|
308
|
+
#
|
309
|
+
# @param [Hash] d
|
310
|
+
#
|
311
|
+
# @return [Response]
|
312
|
+
#
|
157
313
|
def self.from_dynamic!(d)
|
158
314
|
d = Types::Hash[d]
|
159
315
|
new(
|
@@ -8,6 +8,34 @@ module Mihari
|
|
8
8
|
attribute :is_configured, Types::Bool
|
9
9
|
attribute :values, Types.Array(Types::Hash).optional
|
10
10
|
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
def name
|
15
|
+
attributes[:name]
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
#
|
21
|
+
def type
|
22
|
+
attributes[:type]
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# @return [Boolean]
|
27
|
+
#
|
28
|
+
def is_configured
|
29
|
+
attributes[:is_configured]
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# @return [Array<Hash>]
|
34
|
+
#
|
35
|
+
def values
|
36
|
+
attributes[:values]
|
37
|
+
end
|
38
|
+
|
11
39
|
#
|
12
40
|
# @param [Class<Mihari::Analyzers::Base>, Class<Mihari::Emitters::Base>] klass
|
13
41
|
#
|
@@ -9,13 +9,39 @@ module Mihari
|
|
9
9
|
5 => "CNAME",
|
10
10
|
16 => "TXT",
|
11
11
|
28 => "AAAA"
|
12
|
-
}
|
12
|
+
}.freeze
|
13
13
|
|
14
14
|
class Answer < Dry::Struct
|
15
15
|
attribute :name, Types::String
|
16
16
|
attribute :data, Types::String
|
17
17
|
attribute :resource_type, Types::String
|
18
18
|
|
19
|
+
#
|
20
|
+
# @return [String]
|
21
|
+
#
|
22
|
+
def name
|
23
|
+
attributes[:name]
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
#
|
29
|
+
def data
|
30
|
+
attributes[:data]
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
#
|
36
|
+
def resource_type
|
37
|
+
attributes[:resource_type]
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# @param [Hash] d
|
42
|
+
#
|
43
|
+
# @return [Answer]
|
44
|
+
#
|
19
45
|
def self.from_dynamic!(d)
|
20
46
|
d = Types::Hash[d]
|
21
47
|
resource_type = INT_TYPE_TO_TYPE[d.fetch("type")]
|
@@ -30,6 +56,18 @@ module Mihari
|
|
30
56
|
class Response < Dry::Struct
|
31
57
|
attribute :answers, Types.Array(Answer)
|
32
58
|
|
59
|
+
#
|
60
|
+
# @return [Array<Answer>]
|
61
|
+
#
|
62
|
+
def answers
|
63
|
+
attributes[:answers]
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# @param [Hash] d
|
68
|
+
#
|
69
|
+
# @return [Response]
|
70
|
+
#
|
33
71
|
def self.from_dynamic!(d)
|
34
72
|
d = Types::Hash[d]
|
35
73
|
new(
|
@@ -10,6 +10,27 @@ module Mihari
|
|
10
10
|
attribute :country_code, Types::String
|
11
11
|
attribute :asn, Types::String
|
12
12
|
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
def country
|
17
|
+
attributes[:country]
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
def country_code
|
24
|
+
attributes[:country_code]
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
#
|
30
|
+
def asn
|
31
|
+
attributes[:asn]
|
32
|
+
end
|
33
|
+
|
13
34
|
#
|
14
35
|
# @return [Mihari::AutonomousSystem]
|
15
36
|
#
|
@@ -27,6 +48,11 @@ module Mihari
|
|
27
48
|
)
|
28
49
|
end
|
29
50
|
|
51
|
+
#
|
52
|
+
# @param [Hash] d
|
53
|
+
#
|
54
|
+
# @return [Metadata]
|
55
|
+
#
|
30
56
|
def self.from_dynamic!(d)
|
31
57
|
d = Types::Hash[d]
|
32
58
|
new(
|
@@ -43,20 +69,43 @@ module Mihari
|
|
43
69
|
attribute :metadata_, Types::Hash
|
44
70
|
|
45
71
|
#
|
46
|
-
# @
|
72
|
+
# @return [String]
|
73
|
+
#
|
74
|
+
def ip
|
75
|
+
attributes[:ip]
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# @return [Metadata]
|
80
|
+
#
|
81
|
+
def metadata
|
82
|
+
attributes[:metadata]
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# @return [Hash]
|
87
|
+
#
|
88
|
+
def metadata_
|
89
|
+
attributes[:metadata_]
|
90
|
+
end
|
91
|
+
|
47
92
|
#
|
48
93
|
# @return [Mihari::Artifact]
|
49
94
|
#
|
50
|
-
def to_artifact
|
95
|
+
def to_artifact
|
51
96
|
Mihari::Artifact.new(
|
52
97
|
data: ip,
|
53
|
-
source: source,
|
54
98
|
metadata: metadata_,
|
55
99
|
autonomous_system: metadata.to_as,
|
56
100
|
geolocation: metadata.to_geolocation
|
57
101
|
)
|
58
102
|
end
|
59
103
|
|
104
|
+
#
|
105
|
+
# @param [Hash] d
|
106
|
+
#
|
107
|
+
# @return [Datum]
|
108
|
+
#
|
60
109
|
def self.from_dynamic!(d)
|
61
110
|
d = Types::Hash[d]
|
62
111
|
new(
|
@@ -75,14 +124,52 @@ module Mihari
|
|
75
124
|
attribute :query, Types::String
|
76
125
|
|
77
126
|
#
|
78
|
-
# @
|
127
|
+
# @return [Boolean]
|
128
|
+
#
|
129
|
+
def complete
|
130
|
+
attributes[:complete]
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# @return [Integer]
|
135
|
+
#
|
136
|
+
def count
|
137
|
+
attributes[:count]
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
# @return [Array<Datum>]
|
142
|
+
#
|
143
|
+
def data
|
144
|
+
attributes[:data]
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# @return [String]
|
149
|
+
#
|
150
|
+
def message
|
151
|
+
attributes[:message]
|
152
|
+
end
|
153
|
+
|
154
|
+
#
|
155
|
+
# @return [String]
|
156
|
+
#
|
157
|
+
def query
|
158
|
+
attributes[:query]
|
159
|
+
end
|
160
|
+
|
79
161
|
#
|
80
162
|
# @return [Array<Mihari::Artifact>]
|
81
163
|
#
|
82
|
-
def to_artifacts
|
83
|
-
data.map { |datum| datum.to_artifact
|
164
|
+
def to_artifacts
|
165
|
+
data.map { |datum| datum.to_artifact }
|
84
166
|
end
|
85
167
|
|
168
|
+
#
|
169
|
+
# @param [Hash] d
|
170
|
+
#
|
171
|
+
# @return [Response]
|
172
|
+
#
|
86
173
|
def self.from_dynamic!(d)
|
87
174
|
d = Types::Hash[d]
|
88
175
|
new(
|
@@ -10,9 +10,49 @@ module Mihari
|
|
10
10
|
attribute :country_code, Types::String.optional
|
11
11
|
attribute :asn, Types::Integer.optional
|
12
12
|
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
def ip
|
17
|
+
attributes[:ip]
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# @return [String, nil]
|
22
|
+
#
|
23
|
+
def hostname
|
24
|
+
attributes[:hostname]
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# @return [String, nil]
|
29
|
+
#
|
30
|
+
def loc
|
31
|
+
attributes[:loc]
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# @return [String, nil]
|
36
|
+
#
|
37
|
+
def country_code
|
38
|
+
attributes[:country_code]
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# @return [Integer, nil]
|
43
|
+
#
|
44
|
+
def asn
|
45
|
+
attributes[:asn]
|
46
|
+
end
|
47
|
+
|
13
48
|
class << self
|
14
49
|
include Mixins::AutonomousSystem
|
15
50
|
|
51
|
+
#
|
52
|
+
# @param [Hash] d
|
53
|
+
#
|
54
|
+
# @return [Response]
|
55
|
+
#
|
16
56
|
def from_dynamic!(d)
|
17
57
|
d = d.deep_stringify_keys
|
18
58
|
d = Types::Hash[d]
|
@@ -12,14 +12,39 @@ module Mihari
|
|
12
12
|
attribute :metadata, Types::Hash
|
13
13
|
|
14
14
|
#
|
15
|
-
# @
|
15
|
+
# @return [String]
|
16
|
+
#
|
17
|
+
def asn
|
18
|
+
attributes[:asn]
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# @return [String, nil]
|
23
|
+
#
|
24
|
+
def country_code
|
25
|
+
attributes[:country_code]
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
#
|
31
|
+
def ip
|
32
|
+
attributes[:ip]
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# @return [Hash]
|
37
|
+
#
|
38
|
+
def metadata
|
39
|
+
attributes[:metadata]
|
40
|
+
end
|
41
|
+
|
16
42
|
#
|
17
43
|
# @return [Mihari::Artifact]
|
18
44
|
#
|
19
|
-
def to_artifact
|
45
|
+
def to_artifact
|
20
46
|
Mihari::Artifact.new(
|
21
47
|
data: ip,
|
22
|
-
source: source,
|
23
48
|
metadata: metadata,
|
24
49
|
autonomous_system: to_as,
|
25
50
|
geolocation: to_geolocation
|
@@ -45,6 +70,11 @@ module Mihari
|
|
45
70
|
Mihari::AutonomousSystem.new(asn: normalize_asn(asn))
|
46
71
|
end
|
47
72
|
|
73
|
+
#
|
74
|
+
# @param [Hash] d
|
75
|
+
#
|
76
|
+
# @return [Result]
|
77
|
+
#
|
48
78
|
def self.from_dynamic!(d)
|
49
79
|
d = Types::Hash[d]
|
50
80
|
new(
|
@@ -67,14 +97,66 @@ module Mihari
|
|
67
97
|
attribute :total, Types::Int
|
68
98
|
|
69
99
|
#
|
70
|
-
# @
|
100
|
+
# @return [Integer]
|
101
|
+
#
|
102
|
+
def count
|
103
|
+
attributes[:count]
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# @return [Integer]
|
108
|
+
#
|
109
|
+
def error
|
110
|
+
attributes[:error]
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# @return [Integer]
|
115
|
+
#
|
116
|
+
def max_page
|
117
|
+
attributes[:max_page]
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# @return [Integer]
|
122
|
+
#
|
123
|
+
def page
|
124
|
+
attributes[:page]
|
125
|
+
end
|
126
|
+
|
127
|
+
#
|
128
|
+
# @return [Array<Result>]
|
129
|
+
#
|
130
|
+
def results
|
131
|
+
attributes[:results]
|
132
|
+
end
|
133
|
+
|
134
|
+
#
|
135
|
+
# @return [String]
|
136
|
+
#
|
137
|
+
def status
|
138
|
+
attributes[:status]
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# @return [Integer]
|
143
|
+
#
|
144
|
+
def total
|
145
|
+
attributes[:total]
|
146
|
+
end
|
147
|
+
|
71
148
|
#
|
72
149
|
# @return [Array<Mihari::Artifact>]
|
73
150
|
#
|
74
|
-
def to_artifacts
|
75
|
-
results.map
|
151
|
+
def to_artifacts
|
152
|
+
results.map(&:to_artifact)
|
76
153
|
end
|
77
154
|
|
155
|
+
#
|
156
|
+
# @param [Hash] d
|
157
|
+
#
|
158
|
+
# @return [Response]
|
159
|
+
#
|
78
160
|
def self.from_dynamic!(d)
|
79
161
|
d = Types::Hash[d]
|
80
162
|
new(
|