mihari 0.8.2 → 0.9.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 +89 -3
- data/docker/Dockerfile +11 -0
- data/lib/mihari.rb +1 -0
- data/lib/mihari/analyzers/base.rb +11 -1
- data/lib/mihari/emitters/misp.rb +84 -0
- data/lib/mihari/version.rb +1 -1
- data/mihari.gemspec +2 -0
- data/screenshots/misp.png +0 -0
- metadata +33 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1801d9d520fb6de9a4a27d17145b775b074f87e7e1ff88fcb7c50d5630d19e4
|
4
|
+
data.tar.gz: 886708647767e1d5d5a7aaaf7bfd9aca8d25bc714f7f2faf72e0c2c2c4b3073f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 727703b118506f0b310ed1422a757f669748057bd6b4bdb091c638d716209c5ff220088c1396c91924ca275c6fb959e2014f80cb5b9ecbdf72eee23025cf2a7d
|
7
|
+
data.tar.gz: 150c88bac7b129001b109b1966dc527eda5a7e734438507028e5e2a79f74d1884d6cf98d63a4142a8c45f37f501093a7214187aac88265d9a15a9e6f3d24d03e
|
data/README.md
CHANGED
@@ -9,14 +9,18 @@ mihari(`見張り`) is a sidekick tool for [TheHive](https://github.com/TheHive-
|
|
9
9
|
|
10
10
|
## How it works
|
11
11
|
|
12
|
-
- mihari
|
12
|
+
- mihari makes a query against Shodan, Censys, VirusTotal, SecurityTrails, etc. and extracts artifacts from the query results.
|
13
|
+
- mihari checks whether a TheHive instance contains the artifacts or not.
|
13
14
|
- If it doesn't contain the artifacts:
|
14
15
|
- mihari creates an alert with the artifacts on the TheHive instance.
|
15
16
|
- mihari sends a notification to Slack. (Optional)
|
17
|
+
- mihari creates an event on MISP. (Optional)
|
16
18
|
|
17
19
|

|
18
20
|
|
19
|
-
Check this blog post for more detail: [Continuous C2 hunting with Censys, Shodan, Onyphe and TheHive](https://hackmd.io/s/SkUaSrqoE)
|
21
|
+
Check this blog post for more detail: [Continuous C2 hunting with Censys, Shodan, Onyphe and TheHive](https://hackmd.io/s/SkUaSrqoE).
|
22
|
+
|
23
|
+
You can use mihari without TheHive. But note that mihari depends on TheHive to manage artifacts. It means mihari might make duplications when without TheHive.
|
20
24
|
|
21
25
|
### Screenshots
|
22
26
|
|
@@ -28,12 +32,22 @@ Check this blog post for more detail: [Continuous C2 hunting with Censys, Shodan
|
|
28
32
|
|
29
33
|

|
30
34
|
|
35
|
+
- MISP event example
|
36
|
+
|
37
|
+

|
38
|
+
|
31
39
|
## Installation
|
32
40
|
|
33
41
|
```bash
|
34
42
|
gem install mihari
|
35
43
|
```
|
36
44
|
|
45
|
+
Or you can use this tool with Docker.
|
46
|
+
|
47
|
+
```bash
|
48
|
+
docker pull ninoseki/mihari
|
49
|
+
```
|
50
|
+
|
37
51
|
## Basic usage
|
38
52
|
|
39
53
|
mihari supports Censys, Shodan, Onyphe, urlscan, SecurityTrails, crt.sh and VirusTotal by default.
|
@@ -56,6 +70,52 @@ Commands:
|
|
56
70
|
|
57
71
|
```
|
58
72
|
|
73
|
+
### Example usages
|
74
|
+
|
75
|
+
```bash
|
76
|
+
# Censys lookup for PANDA C2
|
77
|
+
$ mihari censys '("PANDA" AND "SMAdmin" AND "layui")' --title "PANDA C2"
|
78
|
+
{
|
79
|
+
"title": "PANDA C2",
|
80
|
+
"description": "query = (\"PANDA\" AND \"SMAdmin\" AND \"layui\")",
|
81
|
+
"artifacts": [
|
82
|
+
"154.223.165.223",
|
83
|
+
"154.194.2.31",
|
84
|
+
"45.114.127.119",
|
85
|
+
"..."
|
86
|
+
],
|
87
|
+
"tags": []
|
88
|
+
}
|
89
|
+
|
90
|
+
# VirusTotal passive DNS lookup for a FAKESPY host
|
91
|
+
$ mihari virustotal "jppost-hi.top" --title "FAKESPY host passive DNS results"
|
92
|
+
{
|
93
|
+
"title": "FAKESPY host passive DNS results",
|
94
|
+
"description": "indicator = jppost-hi.top",
|
95
|
+
"artifacts": [
|
96
|
+
"185.22.152.28",
|
97
|
+
"192.236.200.44",
|
98
|
+
"193.148.69.12",
|
99
|
+
"..."
|
100
|
+
],
|
101
|
+
"tags": []
|
102
|
+
}
|
103
|
+
|
104
|
+
# SecurityTrails domain feed lookup for finding (possibly) Apple phishing websites
|
105
|
+
mihari securitytrails_domain_feed "apple-" --type new
|
106
|
+
{
|
107
|
+
"title": "SecurityTrails domain feed lookup",
|
108
|
+
"description": "Regexp = /apple-/",
|
109
|
+
"artifacts": [
|
110
|
+
"apple-sign.online",
|
111
|
+
"apple-log-in.com",
|
112
|
+
"apple-locator-id.info",
|
113
|
+
"..."
|
114
|
+
],
|
115
|
+
"tags": []
|
116
|
+
}
|
117
|
+
```
|
118
|
+
|
59
119
|
### Import from JSON
|
60
120
|
|
61
121
|
```bash
|
@@ -88,6 +148,8 @@ All configuration is done via ENV variables.
|
|
88
148
|
|------------------------|------------------------|--------------------------------|
|
89
149
|
| THEHIVE_API_ENDPOINT | TheHive URL | Required |
|
90
150
|
| THEHIVE_API_KEY | TheHive API key | Required |
|
151
|
+
| MISP_API_ENDPOINT | MISP URL | Optional |
|
152
|
+
| MISP_API_KEY | MISP API key | Optional |
|
91
153
|
| SLACK_WEBHOOK_URL | Slack Webhook URL | Optional |
|
92
154
|
| SLACK_CHANNEL | Slack channel name | Optional (default: `#general`) |
|
93
155
|
| CENSYS_ID | Censys API ID | Optional |
|
@@ -97,7 +159,7 @@ All configuration is done via ENV variables.
|
|
97
159
|
| SHODAN_API_KEY | Shodan API key | Optional |
|
98
160
|
| VIRUSTOTAL_API_KEY | VirusTotal API key | Optional |
|
99
161
|
|
100
|
-
## How to create a custom
|
162
|
+
## How to create a custom script
|
101
163
|
|
102
164
|
Create a class which extends `Mihari::Analyzers::Base` and implements the following methods.
|
103
165
|
|
@@ -143,6 +205,30 @@ See `/examples` for more.
|
|
143
205
|
|
144
206
|
mihari caches execution results in `/tmp/mihari` and the default cache duration is 7 days. If you want to clear the cache, please clear `/tmp/mihari`.
|
145
207
|
|
208
|
+
## Using it with Docker
|
209
|
+
|
210
|
+
```bash
|
211
|
+
$ docker run --rm ninoseki/mihari
|
212
|
+
Commands:
|
213
|
+
mihari alerts # Show the alerts on TheHive
|
214
|
+
mihari censys [QUERY] # Censys IPv4 lookup by a given...
|
215
|
+
mihari crtsh [QUERY] # crt.sh lookup by a given query
|
216
|
+
mihari help [COMMAND] # Describe available commands o...
|
217
|
+
mihari import_from_json # Give a JSON input via STDIN
|
218
|
+
mihari onyphe [QUERY] # Onyphe datascan lookup by a g...
|
219
|
+
mihari securitytrails [IP|DOMAIN] # SecurityTrails resolutions lo...
|
220
|
+
mihari securitytrails_domain_feed [REGEXP] # SecurityTrails new domain fee...
|
221
|
+
mihari shodan [QUERY] # Shodan host lookup by a given...
|
222
|
+
mihari status # Show the current configuratio...
|
223
|
+
mihari urlscan [QUERY] # urlscan lookup by a given query
|
224
|
+
mihari virustotal [IP|DOMAIN] # VirusTotal resolutions lookup...
|
225
|
+
|
226
|
+
# Note that you should pass configurations via environment variables
|
227
|
+
$ docker run --rm ninoseki/mihari -e THEHIVE_API_ENDPOINT="http://THEHIVE_URL" -e THEHIVE_API_KEY="API KEY" mihari
|
228
|
+
# or
|
229
|
+
$ docker run --rm ninoseki/mihari --env-file ~/.mihari.env mihari
|
230
|
+
```
|
231
|
+
|
146
232
|
## License
|
147
233
|
|
148
234
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/docker/Dockerfile
ADDED
data/lib/mihari.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "parallel"
|
4
|
+
|
3
5
|
module Mihari
|
4
6
|
module Analyzers
|
5
7
|
class Base
|
@@ -29,7 +31,9 @@ module Mihari
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def run
|
32
|
-
|
34
|
+
set_unique_artifacts
|
35
|
+
|
36
|
+
Parallel.each(Mihari.emitters) do |emitter_class|
|
33
37
|
emitter = emitter_class.new
|
34
38
|
next unless emitter.valid?
|
35
39
|
|
@@ -64,6 +68,12 @@ module Mihari
|
|
64
68
|
|
65
69
|
@unique_artifacts ||= @the_hive.artifact.find_non_existing_artifacts(uncached_artifacts)
|
66
70
|
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def set_unique_artifacts
|
75
|
+
unique_artifacts
|
76
|
+
end
|
67
77
|
end
|
68
78
|
end
|
69
79
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "misp"
|
4
|
+
require "net/ping"
|
5
|
+
|
6
|
+
module Mihari
|
7
|
+
module Emitters
|
8
|
+
class MISP < Base
|
9
|
+
# @return [true, false]
|
10
|
+
def valid?
|
11
|
+
api_endpoint? && api_key? && ping?
|
12
|
+
end
|
13
|
+
|
14
|
+
def emit(title:, description:, artifacts:, tags: [])
|
15
|
+
event = ::MISP::Event.new(info: title)
|
16
|
+
|
17
|
+
artifacts.each do |artifact|
|
18
|
+
event.attributes << build_attribute(artifact)
|
19
|
+
end
|
20
|
+
|
21
|
+
tags.each do |tag|
|
22
|
+
event.add_tag name: tag
|
23
|
+
end
|
24
|
+
|
25
|
+
event.create
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def build_attribute(artifact)
|
31
|
+
::MISP::Attribute.new(value: artifact.data, type: to_misp_type(type: artifact.data_type, value: artifact.data))
|
32
|
+
end
|
33
|
+
|
34
|
+
def hash_type(value)
|
35
|
+
case value.length
|
36
|
+
when 32
|
37
|
+
"md5"
|
38
|
+
when 40
|
39
|
+
"sha1"
|
40
|
+
when 64
|
41
|
+
"sha256"
|
42
|
+
when 128
|
43
|
+
"sha512"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_misp_type(type:, value:)
|
48
|
+
type = type.to_sym
|
49
|
+
table = {
|
50
|
+
ip: "ip-dst",
|
51
|
+
mail: "email-dst",
|
52
|
+
url: "url",
|
53
|
+
domain: "domain",
|
54
|
+
}
|
55
|
+
return table[type] if table.key?(type)
|
56
|
+
|
57
|
+
hash_type value
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_attribute(artifact)
|
61
|
+
artifact.data_type
|
62
|
+
end
|
63
|
+
|
64
|
+
def api_endpoint?
|
65
|
+
api_endpoint = ::MISP.configuration.api_endpoint
|
66
|
+
!api_endpoint.nil? && !api_endpoint.empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
def api_key?
|
70
|
+
api_key = ::MISP.configuration.api_key
|
71
|
+
!api_key.nil? && !api_key.empty?
|
72
|
+
end
|
73
|
+
|
74
|
+
def ping?
|
75
|
+
base_url = ::MISP.configuration.api_endpoint
|
76
|
+
base_url = base_url.end_with?("/") ? base_url[0..-2] : base_url
|
77
|
+
url = "#{base_url}/users/login"
|
78
|
+
|
79
|
+
http = Net::Ping::HTTP.new(url)
|
80
|
+
http.ping?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/mihari/version.rb
CHANGED
data/mihari.gemspec
CHANGED
@@ -40,8 +40,10 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.add_dependency "hachi", "~> 0.2"
|
41
41
|
spec.add_dependency "lightly", "~> 0.3"
|
42
42
|
spec.add_dependency "mem", "~> 0.1"
|
43
|
+
spec.add_dependency "misp", "~> 0.1"
|
43
44
|
spec.add_dependency "net-ping", "~> 2.0"
|
44
45
|
spec.add_dependency "onyphe", "~> 0.2"
|
46
|
+
spec.add_dependency "parallel", "~> 1.17"
|
45
47
|
spec.add_dependency "public_suffix", "~> 4.0"
|
46
48
|
spec.add_dependency "securitytrails", "~> 0.2"
|
47
49
|
spec.add_dependency "shodanx", "~> 0.2"
|
Binary file
|
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.9.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-09-
|
11
|
+
date: 2019-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -220,6 +220,20 @@ dependencies:
|
|
220
220
|
- - "~>"
|
221
221
|
- !ruby/object:Gem::Version
|
222
222
|
version: '0.1'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: misp
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - "~>"
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0.1'
|
230
|
+
type: :runtime
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - "~>"
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0.1'
|
223
237
|
- !ruby/object:Gem::Dependency
|
224
238
|
name: net-ping
|
225
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -248,6 +262,20 @@ dependencies:
|
|
248
262
|
- - "~>"
|
249
263
|
- !ruby/object:Gem::Version
|
250
264
|
version: '0.2'
|
265
|
+
- !ruby/object:Gem::Dependency
|
266
|
+
name: parallel
|
267
|
+
requirement: !ruby/object:Gem::Requirement
|
268
|
+
requirements:
|
269
|
+
- - "~>"
|
270
|
+
- !ruby/object:Gem::Version
|
271
|
+
version: '1.17'
|
272
|
+
type: :runtime
|
273
|
+
prerelease: false
|
274
|
+
version_requirements: !ruby/object:Gem::Requirement
|
275
|
+
requirements:
|
276
|
+
- - "~>"
|
277
|
+
- !ruby/object:Gem::Version
|
278
|
+
version: '1.17'
|
251
279
|
- !ruby/object:Gem::Dependency
|
252
280
|
name: public_suffix
|
253
281
|
requirement: !ruby/object:Gem::Requirement
|
@@ -363,6 +391,7 @@ files:
|
|
363
391
|
- Rakefile
|
364
392
|
- bin/console
|
365
393
|
- bin/setup
|
394
|
+
- docker/Dockerfile
|
366
395
|
- examples/ipinfo_hosted_domains.rb
|
367
396
|
- examples/vt_passive_dns.rb
|
368
397
|
- exe/mihari
|
@@ -382,6 +411,7 @@ files:
|
|
382
411
|
- lib/mihari/cache.rb
|
383
412
|
- lib/mihari/cli.rb
|
384
413
|
- lib/mihari/emitters/base.rb
|
414
|
+
- lib/mihari/emitters/misp.rb
|
385
415
|
- lib/mihari/emitters/slack.rb
|
386
416
|
- lib/mihari/emitters/stdout.rb
|
387
417
|
- lib/mihari/emitters/the_hive.rb
|
@@ -399,6 +429,7 @@ files:
|
|
399
429
|
- mihari.gemspec
|
400
430
|
- screenshots/alert.png
|
401
431
|
- screenshots/eyecatch.png
|
432
|
+
- screenshots/misp.png
|
402
433
|
- screenshots/slack.png
|
403
434
|
homepage: https://github.com/ninoseki/mihari
|
404
435
|
licenses:
|