mihari 0.13.2 → 0.14.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 +17 -0
- data/lib/mihari.rb +5 -0
- data/lib/mihari/analyzers/passive_dns.rb +62 -0
- data/lib/mihari/analyzers/passive_ssl.rb +60 -0
- data/lib/mihari/analyzers/reverse_whois.rb +60 -0
- data/lib/mihari/analyzers/sha256.rb +60 -0
- data/lib/mihari/cli.rb +40 -0
- data/lib/mihari/type_checker.rb +15 -0
- data/lib/mihari/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 429387bdb6483e260f1631661721fce1a5abc284711a2c763b50452140388a0c
|
4
|
+
data.tar.gz: 7ba6ad5c62da25d668cf975a4ffecb3e70a01c7c5c6961e646412b0227886fc0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c64e408f6e8d11c27285f1bceccd504cbffa360978864cf5c4a45b7841a1718166158b6818af2d2a3f83087af21cda7c1808e948335270ac742a0c0094c467c4
|
7
|
+
data.tar.gz: c36b4d97ae530b19c5c9f06b22438032eeca23aeea941a39a12b56a0236565de1a09c7f977b8d04b7f2a5c62fbcfe4e2abf06f553d497d05660982879fa9edba
|
data/README.md
CHANGED
@@ -77,9 +77,13 @@ Commands:
|
|
77
77
|
mihari help [COMMAND] # Describe available commands or one specific command
|
78
78
|
mihari import_from_json # Give a JSON input via STDIN
|
79
79
|
mihari onyphe [QUERY] # Onyphe datascan search by a query
|
80
|
+
mihari passive_dns [IP|Domain] # Cross search with passive DNS services by an ip / domain
|
81
|
+
mihari passive_ssl [SHA1] # Cross search with passive SSL services by an SHA1 certificate fingerprint
|
80
82
|
mihari passivetotal [IP|DOMAIN|EMAIL|SHA1] # PassiveTotal lookup by an ip / domain / email / SHA1 certificate fingerprint
|
83
|
+
mihari reverse_whois [email] # Cross search with reverse whois services by an email
|
81
84
|
mihari securitytrails [IP|DOMAIN|EMAIL] # SecurityTrails lookup by an ip, domain or email
|
82
85
|
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
|
83
87
|
mihari shodan [QUERY] # Shodan host search by a query
|
84
88
|
mihari status # Show the current configuration status
|
85
89
|
mihari urlscan [QUERY] # urlscan search by a given query
|
@@ -88,6 +92,19 @@ Commands:
|
|
88
92
|
|
89
93
|
```
|
90
94
|
|
95
|
+
### Cross searches
|
96
|
+
|
97
|
+
mihari has cross search features. A cross search is a search across a number of services.
|
98
|
+
|
99
|
+
You can get aggregated results by using the following commands.
|
100
|
+
|
101
|
+
| Command | Desc. |
|
102
|
+
|---------------|----------------------------------------------------------------------------------------|
|
103
|
+
| passive_dns | Passive DNS lookup with CIRCL passive DNS, PassiveTotal, SecurityTrails and VirusTotal |
|
104
|
+
| passive_ssl | Passive SSL lookup with CIRCL passive SSL and PassiveTotal |
|
105
|
+
| reverse_whois | Revese Whois lookup with PassiveTotal and SecurityTrails |
|
106
|
+
| sha256 | SHA256 hash search with BinaryEdge and Censys |
|
107
|
+
|
91
108
|
### Example usages
|
92
109
|
|
93
110
|
```bash
|
data/lib/mihari.rb
CHANGED
@@ -51,6 +51,11 @@ require "mihari/analyzers/urlscan"
|
|
51
51
|
require "mihari/analyzers/virustotal"
|
52
52
|
require "mihari/analyzers/zoomeye"
|
53
53
|
|
54
|
+
require "mihari/analyzers/passive_dns"
|
55
|
+
require "mihari/analyzers/passive_ssl"
|
56
|
+
require "mihari/analyzers/reverse_whois"
|
57
|
+
require "mihari/analyzers/sha256"
|
58
|
+
|
54
59
|
require "mihari/notifiers/base"
|
55
60
|
require "mihari/notifiers/slack"
|
56
61
|
require "mihari/notifiers/exception_notifier"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "parallel"
|
4
|
+
|
5
|
+
module Mihari
|
6
|
+
module Analyzers
|
7
|
+
class PassiveDNS < Base
|
8
|
+
attr_reader :query
|
9
|
+
attr_reader :type
|
10
|
+
|
11
|
+
attr_reader :title
|
12
|
+
attr_reader :description
|
13
|
+
attr_reader :tags
|
14
|
+
|
15
|
+
ANALYZERS = [
|
16
|
+
Mihari::Analyzers::CIRCL,
|
17
|
+
Mihari::Analyzers::PassiveTotal,
|
18
|
+
Mihari::Analyzers::SecurityTrails,
|
19
|
+
Mihari::Analyzers::VirusTotal,
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
def initialize(query, title: nil, description: nil, tags: [])
|
23
|
+
super()
|
24
|
+
|
25
|
+
@query = query
|
26
|
+
@type = TypeChecker.type(query)
|
27
|
+
|
28
|
+
@title = title || "PassiveDNS cross search"
|
29
|
+
@description = description || "query = #{query}"
|
30
|
+
@tags = tags
|
31
|
+
end
|
32
|
+
|
33
|
+
def artifacts
|
34
|
+
Parallel.map(analyzers) do |analyzer|
|
35
|
+
run_analyzer analyzer
|
36
|
+
end.flatten
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def valid_type?
|
42
|
+
%w(ip domain).include? type
|
43
|
+
end
|
44
|
+
|
45
|
+
def analyzers
|
46
|
+
raise InvalidInputError, "#{query}(type: #{type || 'unknown'}) is not supported." unless valid_type?
|
47
|
+
|
48
|
+
ANALYZERS.map do |klass|
|
49
|
+
klass.new(query)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def run_analyzer(analyzer)
|
54
|
+
analyzer.artifacts
|
55
|
+
rescue ArgumentError, InvalidInputError => _e
|
56
|
+
nil
|
57
|
+
rescue ::PassiveCIRCL::Error, ::PassiveTotal::Error, ::SecurityTrails::Error, ::VirusTotal::Error => _e
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "parallel"
|
4
|
+
|
5
|
+
module Mihari
|
6
|
+
module Analyzers
|
7
|
+
class PassiveSSL < Base
|
8
|
+
attr_reader :query
|
9
|
+
attr_reader :type
|
10
|
+
|
11
|
+
attr_reader :title
|
12
|
+
attr_reader :description
|
13
|
+
attr_reader :tags
|
14
|
+
|
15
|
+
ANALYZERS = [
|
16
|
+
Mihari::Analyzers::CIRCL,
|
17
|
+
Mihari::Analyzers::PassiveTotal,
|
18
|
+
].freeze
|
19
|
+
|
20
|
+
def initialize(query, title: nil, description: nil, tags: [])
|
21
|
+
super()
|
22
|
+
|
23
|
+
@query = query
|
24
|
+
@type = TypeChecker.detailed_type(query)
|
25
|
+
|
26
|
+
@title = title || "PassiveSSL cross search"
|
27
|
+
@description = description || "query = #{query}"
|
28
|
+
@tags = tags
|
29
|
+
end
|
30
|
+
|
31
|
+
def artifacts
|
32
|
+
Parallel.map(analyzers) do |analyzer|
|
33
|
+
run_analyzer analyzer
|
34
|
+
end.flatten
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def valid_type?
|
40
|
+
%w(sha1).include? type
|
41
|
+
end
|
42
|
+
|
43
|
+
def analyzers
|
44
|
+
raise InvalidInputError, "#{query}(type: #{type || 'unknown'}) is not supported." unless valid_type?
|
45
|
+
|
46
|
+
ANALYZERS.map do |klass|
|
47
|
+
klass.new(query)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_analyzer(analyzer)
|
52
|
+
analyzer.artifacts
|
53
|
+
rescue ArgumentError, InvalidInputError => _e
|
54
|
+
nil
|
55
|
+
rescue ::PassiveCIRCL::Error, ::PassiveTotal::Error => _e
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "parallel"
|
4
|
+
|
5
|
+
module Mihari
|
6
|
+
module Analyzers
|
7
|
+
class ReveseWhois < Base
|
8
|
+
attr_reader :query
|
9
|
+
attr_reader :type
|
10
|
+
|
11
|
+
attr_reader :title
|
12
|
+
attr_reader :description
|
13
|
+
attr_reader :tags
|
14
|
+
|
15
|
+
ANALYZERS = [
|
16
|
+
Mihari::Analyzers::PassiveTotal,
|
17
|
+
Mihari::Analyzers::SecurityTrails,
|
18
|
+
].freeze
|
19
|
+
|
20
|
+
def initialize(query, title: nil, description: nil, tags: [])
|
21
|
+
super()
|
22
|
+
|
23
|
+
@query = query
|
24
|
+
@type = TypeChecker.type(query)
|
25
|
+
|
26
|
+
@title = title || "ReveseWhois cross search"
|
27
|
+
@description = description || "query = #{query}"
|
28
|
+
@tags = tags
|
29
|
+
end
|
30
|
+
|
31
|
+
def artifacts
|
32
|
+
Parallel.map(analyzers) do |analyzer|
|
33
|
+
run_analyzer analyzer
|
34
|
+
end.flatten
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def valid_type?
|
40
|
+
%w(mail).include? type
|
41
|
+
end
|
42
|
+
|
43
|
+
def analyzers
|
44
|
+
raise InvalidInputError, "#{query}(type: #{type || 'unknown'}) is not supported." unless valid_type?
|
45
|
+
|
46
|
+
ANALYZERS.map do |klass|
|
47
|
+
klass.new(query)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_analyzer(analyzer)
|
52
|
+
analyzer.artifacts
|
53
|
+
rescue ArgumentError, InvalidInputError => _e
|
54
|
+
nil
|
55
|
+
rescue ::PassiveTotal::Error, ::SecurityTrails::Error => _e
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "parallel"
|
4
|
+
|
5
|
+
module Mihari
|
6
|
+
module Analyzers
|
7
|
+
class SHA256 < Base
|
8
|
+
attr_reader :query
|
9
|
+
attr_reader :type
|
10
|
+
|
11
|
+
attr_reader :title
|
12
|
+
attr_reader :description
|
13
|
+
attr_reader :tags
|
14
|
+
|
15
|
+
ANALYZERS = [
|
16
|
+
Mihari::Analyzers::BinaryEdge,
|
17
|
+
Mihari::Analyzers::Censys,
|
18
|
+
].freeze
|
19
|
+
|
20
|
+
def initialize(query, title: nil, description: nil, tags: [])
|
21
|
+
super()
|
22
|
+
|
23
|
+
@query = query
|
24
|
+
@type = TypeChecker.detailed_type(query)
|
25
|
+
|
26
|
+
@title = title || "SHA256 hash cross search"
|
27
|
+
@description = description || "query = #{query}"
|
28
|
+
@tags = tags
|
29
|
+
end
|
30
|
+
|
31
|
+
def artifacts
|
32
|
+
Parallel.map(analyzers) do |analyzer|
|
33
|
+
run_analyzer analyzer
|
34
|
+
end.flatten
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def valid_type?
|
40
|
+
%w(sha256).include? type
|
41
|
+
end
|
42
|
+
|
43
|
+
def analyzers
|
44
|
+
raise InvalidInputError, "#{query}(type: #{type || 'unknown'}) is not supported." unless valid_type?
|
45
|
+
|
46
|
+
ANALYZERS.map do |klass|
|
47
|
+
klass.new(query)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_analyzer(analyzer)
|
52
|
+
analyzer.artifacts
|
53
|
+
rescue ArgumentError, InvalidInputError => _e
|
54
|
+
nil
|
55
|
+
rescue ::BinaryEdge::Error, ::Censys::ResponseError => _e
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/mihari/cli.rb
CHANGED
@@ -141,6 +141,46 @@ module Mihari
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
+
desc "passive_dns [IP|Domain]", "Cross search with passive DNS services by an ip / domain"
|
145
|
+
method_option :title, type: :string, desc: "title"
|
146
|
+
method_option :description, type: :string, desc: "description"
|
147
|
+
method_option :tags, type: :array, desc: "tags"
|
148
|
+
def passive_dns(query)
|
149
|
+
with_error_handling do
|
150
|
+
run_analyzer Analyzers::PassiveDNS, query: query, options: options
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
desc "passive_ssl [SHA1]", "Cross search with passive SSL services by an SHA1 certificate fingerprint"
|
155
|
+
method_option :title, type: :string, desc: "title"
|
156
|
+
method_option :description, type: :string, desc: "description"
|
157
|
+
method_option :tags, type: :array, desc: "tags"
|
158
|
+
def passive_ssl(query)
|
159
|
+
with_error_handling do
|
160
|
+
run_analyzer Analyzers::PassiveSSL, query: query, options: options
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
desc "reverse_whois [email]", "Cross search with reverse whois services by an email"
|
165
|
+
method_option :title, type: :string, desc: "title"
|
166
|
+
method_option :description, type: :string, desc: "description"
|
167
|
+
method_option :tags, type: :array, desc: "tags"
|
168
|
+
def reverse_whois(query)
|
169
|
+
with_error_handling do
|
170
|
+
run_analyzer Analyzers::ReveseWhois, query: query, options: options
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
desc "sha256 [SHA256]", "Cross search with search engines by an SHA256 hash"
|
175
|
+
method_option :title, type: :string, desc: "title"
|
176
|
+
method_option :description, type: :string, desc: "description"
|
177
|
+
method_option :tags, type: :array, desc: "tags"
|
178
|
+
def sha256(query)
|
179
|
+
with_error_handling do
|
180
|
+
run_analyzer Analyzers::SHA256, query: query, options: options
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
144
184
|
desc "import_from_json", "Give a JSON input via STDIN"
|
145
185
|
def import_from_json(input = nil)
|
146
186
|
with_error_handling do
|
data/lib/mihari/type_checker.rb
CHANGED
@@ -56,11 +56,26 @@ module Mihari
|
|
56
56
|
return "mail" if mail?
|
57
57
|
end
|
58
58
|
|
59
|
+
# @return [String, nil]
|
60
|
+
def detailed_type
|
61
|
+
return "md5" if md5?
|
62
|
+
return "sha1" if sha1?
|
63
|
+
return "sha256" if sha256?
|
64
|
+
return "sha512" if sha512?
|
65
|
+
|
66
|
+
type
|
67
|
+
end
|
68
|
+
|
59
69
|
# @return [String, nil]
|
60
70
|
def self.type(data)
|
61
71
|
new(data).type
|
62
72
|
end
|
63
73
|
|
74
|
+
# @return [String, nil]
|
75
|
+
def self.detailed_type(data)
|
76
|
+
new(data).detailed_type
|
77
|
+
end
|
78
|
+
|
64
79
|
private
|
65
80
|
|
66
81
|
# @return [true, false]
|
data/lib/mihari/version.rb
CHANGED
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.14.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-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -474,9 +474,13 @@ files:
|
|
474
474
|
- lib/mihari/analyzers/crtsh.rb
|
475
475
|
- lib/mihari/analyzers/dnpedia.rb
|
476
476
|
- lib/mihari/analyzers/onyphe.rb
|
477
|
+
- lib/mihari/analyzers/passive_dns.rb
|
478
|
+
- lib/mihari/analyzers/passive_ssl.rb
|
477
479
|
- lib/mihari/analyzers/passivetotal.rb
|
480
|
+
- lib/mihari/analyzers/reverse_whois.rb
|
478
481
|
- lib/mihari/analyzers/securitytrails.rb
|
479
482
|
- lib/mihari/analyzers/securitytrails_domain_feed.rb
|
483
|
+
- lib/mihari/analyzers/sha256.rb
|
480
484
|
- lib/mihari/analyzers/shodan.rb
|
481
485
|
- lib/mihari/analyzers/urlscan.rb
|
482
486
|
- lib/mihari/analyzers/virustotal.rb
|