mihari 0.14.0 → 0.15.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/README.md +16 -12
- data/lib/mihari.rb +3 -1
- data/lib/mihari/analyzers/{sha256.rb → free_text.rb} +3 -11
- data/lib/mihari/analyzers/http_hash.rb +92 -0
- data/lib/mihari/analyzers/ssh_fingerprint.rb +62 -0
- data/lib/mihari/cli.rb +26 -3
- data/lib/mihari/version.rb +1 -1
- data/mihari.gemspec +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 720fd6a91aeb9dad3ad3ad37129b6f810da8dd66f6e007638471c52c7050313b
|
4
|
+
data.tar.gz: 276123ca8645e124110c5f7cf9012481846344188ac0173792f9f2d16c5ea351
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4cdeaf7a7040a72ab30795c0ac2d446c13c1ceee3352384382c4faa912b6f8293db9ee3d69a08b72c84b206fc8a99e98df9253cc050196ea48d188497e3df9c
|
7
|
+
data.tar.gz: da6e803d6c250be258cb0cb542cbb2255f413c6199a43dfd728f4f347129087b27857d36b8039d23ad475603c73dbe1e2b36ccd4f110eb02d44f0a7f02bc1f7a
|
data/README.md
CHANGED
@@ -17,7 +17,7 @@ mihari(`見張り`) is a sidekick tool for [TheHive](https://github.com/TheHive-
|
|
17
17
|
- mihari sends a notification to Slack. (Optional)
|
18
18
|
- mihari creates an event on MISP. (Optional)
|
19
19
|
|
20
|
-

|
21
21
|
|
22
22
|
Check this blog post for more details: [Continuous C2 hunting with Censys, Shodan, Onyphe and TheHive](https://hackmd.io/s/SkUaSrqoE).
|
23
23
|
|
@@ -74,7 +74,9 @@ Commands:
|
|
74
74
|
mihari circl [DOMAIN|SHA1] # CIRCL passive DNS/SSL lookup by a domain / SHA1 certificate fingerprint
|
75
75
|
mihari crtsh [QUERY] # crt.sh search by a query
|
76
76
|
mihari dnpedia [QUERY] # DNPedia domain search by a query
|
77
|
+
mihari free_text [TEXT] # Cross search with search engines by a free text
|
77
78
|
mihari help [COMMAND] # Describe available commands or one specific command
|
79
|
+
mihari http_hash # Cross search with search engines by a hash of an HTTP response (SHA256, MD5 and MurmurHash3)
|
78
80
|
mihari import_from_json # Give a JSON input via STDIN
|
79
81
|
mihari onyphe [QUERY] # Onyphe datascan search by a query
|
80
82
|
mihari passive_dns [IP|Domain] # Cross search with passive DNS services by an ip / domain
|
@@ -83,8 +85,8 @@ Commands:
|
|
83
85
|
mihari reverse_whois [email] # Cross search with reverse whois services by an email
|
84
86
|
mihari securitytrails [IP|DOMAIN|EMAIL] # SecurityTrails lookup by an ip, domain or email
|
85
87
|
mihari securitytrails_domain_feed [REGEXP] # SecurityTrails new domain feed search by a regexp
|
86
|
-
mihari sha256 [SHA256] # Cross search with search engines by an SHA256 hash
|
87
88
|
mihari shodan [QUERY] # Shodan host search by a query
|
89
|
+
mihari ssh_fingerprint [FINGERPRINT] # Cross search with search engines by an SSH fingerprint
|
88
90
|
mihari status # Show the current configuration status
|
89
91
|
mihari urlscan [QUERY] # urlscan search by a given query
|
90
92
|
mihari virustotal [IP|DOMAIN] # VirusTotal resolutions lookup by an ip or domain
|
@@ -98,12 +100,14 @@ mihari has cross search features. A cross search is a search across a number of
|
|
98
100
|
|
99
101
|
You can get aggregated results by using the following commands.
|
100
102
|
|
101
|
-
| Command
|
102
|
-
|
103
|
-
| passive_dns
|
104
|
-
| passive_ssl
|
105
|
-
| reverse_whois
|
106
|
-
|
|
103
|
+
| Command | Desc. |
|
104
|
+
| --------------- | ------------------------------------------------------------------------------------------------------- |
|
105
|
+
| passive_dns | Passive DNS lookup with CIRCL passive DNS, PassiveTotal, SecurityTrails and VirusTotal |
|
106
|
+
| passive_ssl | Passive SSL lookup with CIRCL passive SSL and PassiveTotal |
|
107
|
+
| reverse_whois | Revese Whois lookup with PassiveTotal and SecurityTrails |
|
108
|
+
| http_hash | HTTP response hash lookup with BinaryEdge(SHA256), Censys(SHA256), Onyphpe(MD5) and Shodan(MurmurHash3) |
|
109
|
+
| free_text | Free text lookup with BinaryEdge and Censys |
|
110
|
+
| ssh_fingerprint | SSH fingerprint lookup with BinaryEdge and Shodan |
|
107
111
|
|
108
112
|
### Example usages
|
109
113
|
|
@@ -140,7 +144,7 @@ $ mihari virustotal "jppost-hi.top" --title "FAKESPY host passive DNS results"
|
|
140
144
|
$ mihari virustotal "jppost-hi[.]top" --title "FAKESPY host passive DNS results"
|
141
145
|
|
142
146
|
# SecurityTrails domain feed lookup for finding (possibly) Apple phishing websites
|
143
|
-
mihari securitytrails_domain_feed "apple-" --type new
|
147
|
+
$ mihari securitytrails_domain_feed "apple-" --type new
|
144
148
|
{
|
145
149
|
"title": "SecurityTrails domain feed lookup",
|
146
150
|
"description": "Regexp = /apple-/",
|
@@ -172,7 +176,7 @@ The input is a JSON data should have `title`, `description` and `artifacts` key.
|
|
172
176
|
```
|
173
177
|
|
174
178
|
| Key | Desc. | Required or optional |
|
175
|
-
|
179
|
+
| ----------- | -------------------------------------------------------------------------- | -------------------- |
|
176
180
|
| title | A title of an alert | Required |
|
177
181
|
| description | A description of an alert | Required |
|
178
182
|
| artifacts | An array of artifacts (supported data types: ip, domain, url, email, hash) | Required |
|
@@ -183,7 +187,7 @@ The input is a JSON data should have `title`, `description` and `artifacts` key.
|
|
183
187
|
All configuration is done via ENV variables.
|
184
188
|
|
185
189
|
| Key | Desc. | Required or optional |
|
186
|
-
|
190
|
+
| ---------------------- | ------------------------------ | ------------------------------ |
|
187
191
|
| THEHIVE_API_ENDPOINT | TheHive URL | Required |
|
188
192
|
| THEHIVE_API_KEY | TheHive API key | Required |
|
189
193
|
| MISP_API_ENDPOINT | MISP URL | Optional |
|
@@ -215,7 +219,7 @@ mihari status
|
|
215
219
|
Create a class which extends `Mihari::Analyzers::Base` and implements the following methods.
|
216
220
|
|
217
221
|
| Name | Desc. | @return | Required or optional |
|
218
|
-
|
222
|
+
| -------------- | -------------------------------------------------------------------------- | ------------- | -------------------- |
|
219
223
|
| `#title` | A title of an alert | String | Required |
|
220
224
|
| `#description` | A description of an alert | String | Required |
|
221
225
|
| `#artifacts` | An array of artifacts (supported data types: ip, domain, url, email, hash) | Array<String> | Required |
|
data/lib/mihari.rb
CHANGED
@@ -51,10 +51,12 @@ require "mihari/analyzers/urlscan"
|
|
51
51
|
require "mihari/analyzers/virustotal"
|
52
52
|
require "mihari/analyzers/zoomeye"
|
53
53
|
|
54
|
+
require "mihari/analyzers/free_text"
|
55
|
+
require "mihari/analyzers/http_hash"
|
54
56
|
require "mihari/analyzers/passive_dns"
|
55
57
|
require "mihari/analyzers/passive_ssl"
|
56
58
|
require "mihari/analyzers/reverse_whois"
|
57
|
-
require "mihari/analyzers/
|
59
|
+
require "mihari/analyzers/ssh_fingerprint"
|
58
60
|
|
59
61
|
require "mihari/notifiers/base"
|
60
62
|
require "mihari/notifiers/slack"
|
@@ -4,9 +4,8 @@ require "parallel"
|
|
4
4
|
|
5
5
|
module Mihari
|
6
6
|
module Analyzers
|
7
|
-
class
|
7
|
+
class FreeText < Base
|
8
8
|
attr_reader :query
|
9
|
-
attr_reader :type
|
10
9
|
|
11
10
|
attr_reader :title
|
12
11
|
attr_reader :description
|
@@ -21,9 +20,8 @@ module Mihari
|
|
21
20
|
super()
|
22
21
|
|
23
22
|
@query = query
|
24
|
-
@type = TypeChecker.detailed_type(query)
|
25
23
|
|
26
|
-
@title = title || "
|
24
|
+
@title = title || "Free text cross search"
|
27
25
|
@description = description || "query = #{query}"
|
28
26
|
@tags = tags
|
29
27
|
end
|
@@ -36,13 +34,7 @@ module Mihari
|
|
36
34
|
|
37
35
|
private
|
38
36
|
|
39
|
-
def valid_type?
|
40
|
-
%w(sha256).include? type
|
41
|
-
end
|
42
|
-
|
43
37
|
def analyzers
|
44
|
-
raise InvalidInputError, "#{query}(type: #{type || 'unknown'}) is not supported." unless valid_type?
|
45
|
-
|
46
38
|
ANALYZERS.map do |klass|
|
47
39
|
klass.new(query)
|
48
40
|
end
|
@@ -52,7 +44,7 @@ module Mihari
|
|
52
44
|
analyzer.artifacts
|
53
45
|
rescue ArgumentError, InvalidInputError => _e
|
54
46
|
nil
|
55
|
-
rescue ::BinaryEdge::Error, ::Censys::
|
47
|
+
rescue ::BinaryEdge::Error, ::Censys::Error => _e
|
56
48
|
nil
|
57
49
|
end
|
58
50
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "parallel"
|
4
|
+
|
5
|
+
module Mihari
|
6
|
+
module Analyzers
|
7
|
+
class HTTPHash < Base
|
8
|
+
attr_reader :md5
|
9
|
+
attr_reader :sha256
|
10
|
+
attr_reader :mmh3
|
11
|
+
|
12
|
+
attr_reader :title
|
13
|
+
attr_reader :description
|
14
|
+
attr_reader :tags
|
15
|
+
|
16
|
+
def initialize(_query, md5: nil, sha256: nil, mmh3: nil, title: nil, description: nil, tags: [])
|
17
|
+
super()
|
18
|
+
|
19
|
+
@md5 = md5
|
20
|
+
@sha256 = sha256
|
21
|
+
@mmh3 = mmh3
|
22
|
+
|
23
|
+
@title = title || "HTTP hash cross search"
|
24
|
+
@description = description || "query = #{query}"
|
25
|
+
@tags = tags
|
26
|
+
end
|
27
|
+
|
28
|
+
def artifacts
|
29
|
+
Parallel.map(analyzers) do |analyzer|
|
30
|
+
run_analyzer analyzer
|
31
|
+
end.flatten
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def valid_query?
|
37
|
+
[md5, sha256, mmh3].compact.any?
|
38
|
+
end
|
39
|
+
|
40
|
+
def query
|
41
|
+
[
|
42
|
+
md5 ? "md5:#{md5}" : nil,
|
43
|
+
sha256 ? "sha256:#{sha256}" : nil,
|
44
|
+
mmh3 ? "mmh3:#{mmh3}" : nil,
|
45
|
+
].compact.join(",")
|
46
|
+
end
|
47
|
+
|
48
|
+
def binary_edge
|
49
|
+
return nil unless sha256
|
50
|
+
|
51
|
+
BinaryEdge.new sha256
|
52
|
+
end
|
53
|
+
|
54
|
+
def censys
|
55
|
+
return nil unless sha256
|
56
|
+
|
57
|
+
Censys.new sha256
|
58
|
+
end
|
59
|
+
|
60
|
+
def onyphe
|
61
|
+
return nil unless md5
|
62
|
+
|
63
|
+
Onyphe.new "app.http.bodymd5:#{md5}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def shodan
|
67
|
+
return nil unless mmh3
|
68
|
+
|
69
|
+
Shodan.new "http.html_hash:#{mmh3}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def analyzers
|
73
|
+
raise InvalidInputError, "No hashes are given." unless valid_query?
|
74
|
+
|
75
|
+
[
|
76
|
+
binary_edge,
|
77
|
+
censys,
|
78
|
+
onyphe,
|
79
|
+
shodan,
|
80
|
+
].compact
|
81
|
+
end
|
82
|
+
|
83
|
+
def run_analyzer(analyzer)
|
84
|
+
analyzer.artifacts
|
85
|
+
rescue ArgumentError, InvalidInputError => _e
|
86
|
+
nil
|
87
|
+
rescue ::BinaryEdge::Error, ::Censys::ResponseError, ::Onyphe::Error, ::Shodan::Error => _e
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "parallel"
|
4
|
+
|
5
|
+
module Mihari
|
6
|
+
module Analyzers
|
7
|
+
class SSHFingerprint < Base
|
8
|
+
attr_reader :fingerprint
|
9
|
+
|
10
|
+
attr_reader :title
|
11
|
+
attr_reader :description
|
12
|
+
attr_reader :tags
|
13
|
+
|
14
|
+
def initialize(fingerprint, title: nil, description: nil, tags: [])
|
15
|
+
super()
|
16
|
+
|
17
|
+
@fingerprint = fingerprint
|
18
|
+
|
19
|
+
@title = title || "SSH fingerprint cross search"
|
20
|
+
@description = description || "fingerprint = #{fingerprint}"
|
21
|
+
@tags = tags
|
22
|
+
end
|
23
|
+
|
24
|
+
def artifacts
|
25
|
+
Parallel.map(analyzers) do |analyzer|
|
26
|
+
run_analyzer analyzer
|
27
|
+
end.flatten
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def valid_fingerprint?
|
33
|
+
/^([0-9a-f]{2}:){15}[0-9a-f]{2}$/.match? fingerprint
|
34
|
+
end
|
35
|
+
|
36
|
+
def binary_edge
|
37
|
+
BinaryEdge.new "ssh.fingerprint:\"#{fingerprint}\""
|
38
|
+
end
|
39
|
+
|
40
|
+
def shodan
|
41
|
+
Shodan.new fingerprint
|
42
|
+
end
|
43
|
+
|
44
|
+
def analyzers
|
45
|
+
raise InvalidInputError, "Invalid fingerprint is given." unless valid_fingerprint?
|
46
|
+
|
47
|
+
[
|
48
|
+
binary_edge,
|
49
|
+
shodan,
|
50
|
+
].compact
|
51
|
+
end
|
52
|
+
|
53
|
+
def run_analyzer(analyzer)
|
54
|
+
analyzer.artifacts
|
55
|
+
rescue ArgumentError, InvalidInputError => _e
|
56
|
+
nil
|
57
|
+
rescue ::BinaryEdge::Error, ::Shodan::Error => _e
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/mihari/cli.rb
CHANGED
@@ -171,13 +171,36 @@ module Mihari
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
-
desc "
|
174
|
+
desc "http_hash", "Cross search with search engines by a hash of an HTTP response (SHA256, MD5 and MurmurHash3)"
|
175
175
|
method_option :title, type: :string, desc: "title"
|
176
176
|
method_option :description, type: :string, desc: "description"
|
177
177
|
method_option :tags, type: :array, desc: "tags"
|
178
|
-
|
178
|
+
method_option :md5, type: :string, desc: "MD5 hash"
|
179
|
+
method_option :sha256, type: :string, desc: "SHA256 hash"
|
180
|
+
method_option :mmh3, type: :numeric, desc: "MurmurHash3 hash"
|
181
|
+
def http_hash
|
179
182
|
with_error_handling do
|
180
|
-
run_analyzer Analyzers::
|
183
|
+
run_analyzer Analyzers::HTTPHash, query: nil, options: options
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
desc "free_text [TEXT]", "Cross search with search engines by a free text"
|
188
|
+
method_option :title, type: :string, desc: "title"
|
189
|
+
method_option :description, type: :string, desc: "description"
|
190
|
+
method_option :tags, type: :array, desc: "tags"
|
191
|
+
def free_text(text)
|
192
|
+
with_error_handling do
|
193
|
+
run_analyzer Analyzers::FreeText, query: text, options: options
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
desc "ssh_fingerprint [FINGERPRINT]", "Cross search with search engines by an SSH fingerprint"
|
198
|
+
method_option :title, type: :string, desc: "title"
|
199
|
+
method_option :description, type: :string, desc: "description"
|
200
|
+
method_option :tags, type: :array, desc: "tags"
|
201
|
+
def ssh_fingerprint(fingerprint)
|
202
|
+
with_error_handling do
|
203
|
+
run_analyzer Analyzers::SSHFingerprint, query: fingerprint, options: options
|
181
204
|
end
|
182
205
|
end
|
183
206
|
|
data/lib/mihari/version.rb
CHANGED
data/mihari.gemspec
CHANGED
@@ -45,7 +45,7 @@ Gem::Specification.new do |spec|
|
|
45
45
|
spec.add_dependency "misp", "~> 0.1"
|
46
46
|
spec.add_dependency "net-ping", "~> 2.0"
|
47
47
|
spec.add_dependency "onyphe", "~> 1.0"
|
48
|
-
spec.add_dependency "parallel", "~> 1.
|
48
|
+
spec.add_dependency "parallel", "~> 1.19"
|
49
49
|
spec.add_dependency "passive_circl", "~> 0.1"
|
50
50
|
spec.add_dependency "passivetotalx", "~> 0.1"
|
51
51
|
spec.add_dependency "public_suffix", "~> 4.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mihari
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manabu Niseki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -296,14 +296,14 @@ dependencies:
|
|
296
296
|
requirements:
|
297
297
|
- - "~>"
|
298
298
|
- !ruby/object:Gem::Version
|
299
|
-
version: '1.
|
299
|
+
version: '1.19'
|
300
300
|
type: :runtime
|
301
301
|
prerelease: false
|
302
302
|
version_requirements: !ruby/object:Gem::Requirement
|
303
303
|
requirements:
|
304
304
|
- - "~>"
|
305
305
|
- !ruby/object:Gem::Version
|
306
|
-
version: '1.
|
306
|
+
version: '1.19'
|
307
307
|
- !ruby/object:Gem::Dependency
|
308
308
|
name: passive_circl
|
309
309
|
requirement: !ruby/object:Gem::Requirement
|
@@ -473,6 +473,8 @@ files:
|
|
473
473
|
- lib/mihari/analyzers/circl.rb
|
474
474
|
- lib/mihari/analyzers/crtsh.rb
|
475
475
|
- lib/mihari/analyzers/dnpedia.rb
|
476
|
+
- lib/mihari/analyzers/free_text.rb
|
477
|
+
- lib/mihari/analyzers/http_hash.rb
|
476
478
|
- lib/mihari/analyzers/onyphe.rb
|
477
479
|
- lib/mihari/analyzers/passive_dns.rb
|
478
480
|
- lib/mihari/analyzers/passive_ssl.rb
|
@@ -480,8 +482,8 @@ files:
|
|
480
482
|
- lib/mihari/analyzers/reverse_whois.rb
|
481
483
|
- lib/mihari/analyzers/securitytrails.rb
|
482
484
|
- lib/mihari/analyzers/securitytrails_domain_feed.rb
|
483
|
-
- lib/mihari/analyzers/sha256.rb
|
484
485
|
- lib/mihari/analyzers/shodan.rb
|
486
|
+
- lib/mihari/analyzers/ssh_fingerprint.rb
|
485
487
|
- lib/mihari/analyzers/urlscan.rb
|
486
488
|
- lib/mihari/analyzers/virustotal.rb
|
487
489
|
- lib/mihari/analyzers/zoomeye.rb
|