mihari 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
![img](
|
20
|
+
![img](https://github.com/ninoseki/mihari/blob/master/screenshots/eyecatch.png)
|
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
|