mihari 5.4.3 → 5.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -25
- data/docs/alternatives.md +5 -0
- data/docs/analyzers/binaryedge.md +21 -0
- data/docs/analyzers/censys.md +23 -0
- data/docs/analyzers/circl.md +29 -0
- data/docs/analyzers/crtsh.md +25 -0
- data/docs/analyzers/dnstwister.md +23 -0
- data/docs/analyzers/feed.md +49 -0
- data/docs/analyzers/greynoise.md +21 -0
- data/docs/analyzers/hunterhow.md +25 -0
- data/docs/analyzers/index.md +79 -0
- data/docs/analyzers/onyphe.md +21 -0
- data/docs/analyzers/otx.md +23 -0
- data/docs/analyzers/passivetotal.md +36 -0
- data/docs/analyzers/pulsedive.md +23 -0
- data/docs/analyzers/securitytrails.md +32 -0
- data/docs/analyzers/shodan.md +21 -0
- data/docs/analyzers/urlscan.md +23 -0
- data/docs/analyzers/virustotal.md +34 -0
- data/docs/analyzers/virustotal_intelligence.md +22 -0
- data/docs/analyzers/zoomeye.md +25 -0
- data/docs/configuration.md +35 -0
- data/docs/emitters/database.md +22 -0
- data/docs/emitters/hive.md +18 -0
- data/docs/emitters/index.md +7 -0
- data/docs/emitters/misp.md +16 -0
- data/docs/emitters/slack.md +16 -0
- data/docs/emitters/webhook.md +63 -0
- data/docs/enrichers/google_public_dns.md +19 -0
- data/docs/enrichers/index.md +6 -0
- data/docs/enrichers/ipinfo.md +19 -0
- data/docs/enrichers/shodan.md +22 -0
- data/docs/enrichers/whois.md +17 -0
- data/docs/github_actions.md +43 -0
- data/docs/index.md +13 -0
- data/docs/installation.md +31 -0
- data/docs/requirements.md +20 -0
- data/docs/rule.md +165 -0
- data/docs/tags.md +3 -0
- data/docs/usage.md +100 -0
- data/frontend/package-lock.json +2414 -1516
- data/frontend/package.json +22 -22
- data/lib/mihari/analyzers/base.rb +25 -10
- data/lib/mihari/analyzers/binaryedge.rb +1 -7
- data/lib/mihari/analyzers/circl.rb +1 -1
- data/lib/mihari/analyzers/dnstwister.rb +1 -1
- data/lib/mihari/analyzers/otx.rb +1 -1
- data/lib/mihari/analyzers/passivetotal.rb +1 -1
- data/lib/mihari/analyzers/pulsedive.rb +1 -1
- data/lib/mihari/analyzers/rule.rb +18 -13
- data/lib/mihari/analyzers/securitytrails.rb +1 -1
- data/lib/mihari/analyzers/urlscan.rb +1 -1
- data/lib/mihari/analyzers/virustotal.rb +1 -1
- data/lib/mihari/analyzers/zoomeye.rb +1 -1
- data/lib/mihari/clients/binaryedge.rb +4 -7
- data/lib/mihari/clients/crtsh.rb +1 -3
- data/lib/mihari/clients/publsedive.rb +1 -1
- data/lib/mihari/clients/shodan.rb +2 -2
- data/lib/mihari/commands/alert.rb +42 -13
- data/lib/mihari/commands/rule.rb +11 -7
- data/lib/mihari/commands/search.rb +54 -22
- data/lib/mihari/config.rb +5 -0
- data/lib/mihari/emitters/base.rb +9 -3
- data/lib/mihari/emitters/slack.rb +1 -1
- data/lib/mihari/enrichers/base.rb +13 -0
- data/lib/mihari/enrichers/google_public_dns.rb +16 -1
- data/lib/mihari/enrichers/ipinfo.rb +9 -13
- data/lib/mihari/enrichers/shodan.rb +1 -2
- data/lib/mihari/enrichers/whois.rb +2 -2
- data/lib/mihari/errors.rb +16 -10
- data/lib/mihari/feed/parser.rb +2 -2
- data/lib/mihari/models/artifact.rb +1 -1
- data/lib/mihari/models/autonomous_system.rb +11 -5
- data/lib/mihari/models/cpe.rb +10 -4
- data/lib/mihari/models/dns.rb +11 -16
- data/lib/mihari/models/geolocation.rb +11 -5
- data/lib/mihari/models/port.rb +10 -4
- data/lib/mihari/models/reverse_dns.rb +10 -4
- data/lib/mihari/models/whois.rb +4 -1
- data/lib/mihari/schemas/analyzer.rb +1 -0
- data/lib/mihari/services/alert_builder.rb +43 -0
- data/lib/mihari/services/alert_proxy.rb +7 -25
- data/lib/mihari/services/alert_runner.rb +9 -0
- data/lib/mihari/services/rule_builder.rb +47 -0
- data/lib/mihari/services/rule_proxy.rb +5 -61
- data/lib/mihari/services/rule_runner.rb +9 -4
- data/lib/mihari/structs/binaryedge.rb +89 -0
- data/lib/mihari/structs/shodan.rb +2 -1
- data/lib/mihari/structs/urlscan.rb +1 -3
- data/lib/mihari/structs/virustotal_intelligence.rb +1 -3
- data/lib/mihari/type_checker.rb +1 -1
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/endpoints/alerts.rb +33 -15
- data/lib/mihari/web/endpoints/artifacts.rb +53 -25
- data/lib/mihari/web/endpoints/configs.rb +2 -2
- data/lib/mihari/web/endpoints/ip_addresses.rb +3 -5
- data/lib/mihari/web/endpoints/rules.rb +97 -71
- data/lib/mihari/web/endpoints/tags.rb +15 -5
- data/lib/mihari/web/public/assets/index-0a5a47bf.js +1740 -0
- data/lib/mihari/web/public/index.html +1 -1
- data/lib/mihari/web/public/redoc-static.html +419 -382
- data/lib/mihari.rb +4 -0
- data/mihari.gemspec +6 -5
- data/mkdocs.yml +35 -0
- data/requirements.txt +2 -0
- metadata +70 -12
- data/lib/mihari/web/public/assets/index-4d7eda9f.js +0 -1738
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c21e0cc46aa56c0b38742049ff9fb25d8375b8c555d26dc9c5893205f80947b0
|
4
|
+
data.tar.gz: 452122ef77d5e839a105b01c8ac703924c8488945f8a6d26dffb328efe758418
|
5
5
|
SHA512:
|
6
|
-
metadata.gz: '
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0488ab7be1fd505ffb6c1bf174bf4eb51a2809b39d014206a9078c2b25b635d1b1cecf71db54870cbe41f363f3016be0116193963a83f8038d8f87fd990075ad'
|
7
|
+
data.tar.gz: 392f31818f021e205a70e315e430dec4864edf7a37245651a2e516be4f41afb2c9572d73a0275574cb4917036398686f2da917d5c5386084a7527f0c2a68abb3
|
data/README.md
CHANGED
@@ -13,25 +13,9 @@
|
|
13
13
|
|
14
14
|
---
|
15
15
|
|
16
|
-
|
16
|
+
A query aggregator for OSINT based threat hunting.
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
![img](https://github.com/ninoseki/mihari/raw/master/images/overview.jpg)
|
21
|
-
|
22
|
-
- Mihari makes a query against Shodan, Censys, VirusTotal, SecurityTrails, etc. and extracts artifacts (IP addresses, domains, URLs or hashes).
|
23
|
-
- Mihari checks whether the database (SQLite3, PostgreSQL or MySQL) contains the artifacts or not.
|
24
|
-
- If it doesn't contain the artifacts:
|
25
|
-
- Mihari saves artifacts in the database.
|
26
|
-
- Mihari creates an alert on TheHive.
|
27
|
-
- Mihari sends a notification to Slack.
|
28
|
-
- Mihari creates an event on MISP.
|
29
|
-
|
30
|
-
Also, you can check the alerts on a built-in web app.
|
31
|
-
|
32
|
-
![img](https://github.com/ninoseki/mihari/raw/master/images/web_alerts.png)
|
33
|
-
|
34
|
-
## Supported services
|
18
|
+
Mihari can aggregate multiple searches across multiple services in a single rule & persist findings in a database.
|
35
19
|
|
36
20
|
Mihari supports the following services by default.
|
37
21
|
|
@@ -52,13 +36,7 @@ Mihari supports the following services by default.
|
|
52
36
|
- [VirusTotal](http://virustotal.com) & [VirusTotal Intelligence](https://www.virustotal.com/gui/intelligence-overview)
|
53
37
|
- [ZoomEye](https://zoomeye.org)
|
54
38
|
|
55
|
-
|
56
|
-
|
57
|
-
- [Mihari Knowledge Base](https://www.notion.so/Mihari-Knowledge-Base-266994ff61204428ba6cfcebe40b0bd1)
|
58
|
-
|
59
|
-
## Presentations
|
60
|
-
|
61
|
-
- [Adversary Infrastructure Tracking with Mihari](https://ninoseki.github.io/presentations/Adversary%20Infrastructure%20Tracking%20with%20Mihari.pdf)
|
39
|
+
See [documentation](https://ninoseki.github.io/mihari/) for more details.
|
62
40
|
|
63
41
|
## License
|
64
42
|
|
@@ -0,0 +1,5 @@
|
|
1
|
+
# Alternatives
|
2
|
+
|
3
|
+
- [InQuest/ThreatIngestor](https://github.com/InQuest/ThreatIngestor) - Extract and aggregate threat intelligence.
|
4
|
+
- [thalesgroup-cert/Watcher](https://github.com/thalesgroup-cert/Watcher) - Watcher - Open Source Cybersecurity Threat Hunting Platform. Developed with Django & React JS.
|
5
|
+
- [projectdiscovery/uncover](https://github.com/projectdiscovery/uncover) - Quickly discover exposed hosts on the internet using multiple search engines.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
---
|
5
|
+
|
6
|
+
# BinaryEdge
|
7
|
+
|
8
|
+
- [https://www.binaryedge.io/](https://www.binaryedge.io/)
|
9
|
+
|
10
|
+
This analyzer uses [BinaryEdge API V2](https://docs.binaryedge.io/api-v2/) and [/v2/query/search](https://docs.binaryedge.io/api-v2/#v2querysearch) API endpoint to search.
|
11
|
+
|
12
|
+
```yaml
|
13
|
+
analyzer: binaryedge
|
14
|
+
query: ...
|
15
|
+
api_key: ...
|
16
|
+
```
|
17
|
+
|
18
|
+
| Name | Type | Required? | Default | Desc. |
|
19
|
+
| ------- | ------ | --------- | ------------------------- | ------------ |
|
20
|
+
| query | String | Yes | | Search query |
|
21
|
+
| api_key | String | No | ENV[”BINARYEDGE_API_KEY"] | API key |
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
---
|
5
|
+
|
6
|
+
# Censys
|
7
|
+
|
8
|
+
- [https://censys.io/](https://censys.io/)
|
9
|
+
|
10
|
+
The analyzer uses [Censys Search 2.0 REST API](https://search.censys.io/api) to search.
|
11
|
+
|
12
|
+
```yaml
|
13
|
+
analyzer: censys
|
14
|
+
query: ...
|
15
|
+
id: ...
|
16
|
+
secret: ...
|
17
|
+
```
|
18
|
+
|
19
|
+
| Name | Type | Required? | Default | Desc. |
|
20
|
+
| ------ | ------ | --------- | -------------------- | ------------- |
|
21
|
+
| query | String | Yes | | Search query |
|
22
|
+
| id | String | No | ENV[”CENSYS_ID”] | Censys ID |
|
23
|
+
| secret | String | No | ENV[”CENSYS_SECRET”] | Censys secret |
|
@@ -0,0 +1,29 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
- Passive DNS
|
5
|
+
- Passive SSL
|
6
|
+
---
|
7
|
+
|
8
|
+
# CIRCL Passive DNS/SSL
|
9
|
+
|
10
|
+
- [https://www.circl.lu/services/passive-dns/](https://www.circl.lu/services/passive-dns/)
|
11
|
+
- [https://www.circl.lu/services/passive-ssl/](https://www.circl.lu/services/passive-ssl/)
|
12
|
+
|
13
|
+
This analyzer uses CIRCL passive DNS API or passive SSL API:
|
14
|
+
|
15
|
+
- Use passive DNS API if a query(input) is a domain
|
16
|
+
- Use passive SSL API if a query(input) is a SHA1 certificate fingerprint
|
17
|
+
|
18
|
+
```yaml
|
19
|
+
analyzer: circl
|
20
|
+
query: ...
|
21
|
+
password: ...
|
22
|
+
username: ...
|
23
|
+
```
|
24
|
+
|
25
|
+
| Name | Type | Required? | Default | Desc. |
|
26
|
+
| -------- | ------ | --------- | ----------------------------- | -------------------------------------- |
|
27
|
+
| query | String | Yes | | Domain or SHA1 certificate fingerprint |
|
28
|
+
| username | String | No | ENV[”CIRCL_PASSIVE_USERNAME”] | Username |
|
29
|
+
| password | String | Noe | ENV[”CIRCL_PASSIVE_PASSWORD”] | Password |
|
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- Domain
|
4
|
+
---
|
5
|
+
|
6
|
+
# crt.sh
|
7
|
+
|
8
|
+
- [https://crt.sh/](https://crt.sh/)
|
9
|
+
|
10
|
+
This analyzer uses [crt.sh](http://crt.sh)'s (unofficial?) REST API.
|
11
|
+
|
12
|
+
```yaml
|
13
|
+
analyzer: crtsh
|
14
|
+
query: ...
|
15
|
+
exclude_expired: ...
|
16
|
+
```
|
17
|
+
|
18
|
+
| Name | Type | Default | Desc. |
|
19
|
+
| --------------- | ------------------ | ------- | ----------------------------------------- |
|
20
|
+
| query | String | | Search query |
|
21
|
+
| exclude_expired | Boolean (optional) | True | Whether to exclude expired domains or not |
|
22
|
+
|
23
|
+
!!! tip
|
24
|
+
|
25
|
+
if `exclude_expired` is set as `true`, expired domains are excluded from search results.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- Domain
|
4
|
+
---
|
5
|
+
|
6
|
+
# dnstwister
|
7
|
+
|
8
|
+
- [https://dnstwister.report/](https://dnstwister.report/)
|
9
|
+
|
10
|
+
This analyzer uses [dnstwister API](https://dnstwister.report/api/) to search.
|
11
|
+
|
12
|
+
```yaml
|
13
|
+
analyzer: dnstwister
|
14
|
+
query: ...
|
15
|
+
```
|
16
|
+
|
17
|
+
| Name | Type | Required? | Default | Desc. |
|
18
|
+
| ----- | ------ | --------- | ------- | ------ |
|
19
|
+
| query | String | Yes | | Domain |
|
20
|
+
|
21
|
+
!!! tip
|
22
|
+
|
23
|
+
There is no need to input a domain in hexadecimal format. This analyzer automatically converts a domain (in string format) into a hexadecimal value.
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Feed
|
2
|
+
|
3
|
+
This analyzer can ingest a feed (JSON or CSV) by specifying conditions.
|
4
|
+
|
5
|
+
Note that you should write a selector to get proper IoCs from a feed. A selector is based on [jr](https://github.com/yuya-takeyama/jr).
|
6
|
+
|
7
|
+
```yaml
|
8
|
+
analyzer: feed
|
9
|
+
query: ...
|
10
|
+
http_request_method: ...
|
11
|
+
http_request_payload: ...
|
12
|
+
http_request_payload_type: ...
|
13
|
+
http_request_headers: ...
|
14
|
+
selector: ...
|
15
|
+
```
|
16
|
+
|
17
|
+
| Name | Type | Required? | Default | Desc. |
|
18
|
+
| ------------------------- | ------ | --------- | ------- | ------------------------------------ |
|
19
|
+
| query | String | Yes | | URL |
|
20
|
+
| http_request_method | String | No | GET | HTTP request method (GET or POST) |
|
21
|
+
| http_request_headers | Hash | No | | HTTP request headers |
|
22
|
+
| http_request_payload | Hash | No | | HTTP request payload |
|
23
|
+
| http_request_payload_type | String | No | | Content-type of HTTP request payload |
|
24
|
+
| selector | String | Yes | | `jr` selector |
|
25
|
+
|
26
|
+
## Examples
|
27
|
+
|
28
|
+
**ThreatFox**
|
29
|
+
|
30
|
+
```yaml
|
31
|
+
analyzer: feed
|
32
|
+
query: "https://threatfox-api.abuse.ch/api/v1/"
|
33
|
+
http_request_method: "POST"
|
34
|
+
http_request_payload:
|
35
|
+
query: "get_iocs"
|
36
|
+
days: 1
|
37
|
+
http_request_payload_type: "application/json"
|
38
|
+
http_request_headers:
|
39
|
+
"api-key": "YOUR_API_KEY"
|
40
|
+
selector: "map(&:data).unwrap.map(&:ioc).map { |v| v.start_with?('http://', 'https://') ? v : v.split(':').first }"
|
41
|
+
```
|
42
|
+
|
43
|
+
**URLhaus**
|
44
|
+
|
45
|
+
```yaml
|
46
|
+
analyzer: feed
|
47
|
+
query: "https://urlhaus.abuse.ch/feeds/country/JP/"
|
48
|
+
selector: "map { |v| v[1] }"
|
49
|
+
```
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
---
|
5
|
+
|
6
|
+
# GreyNoise
|
7
|
+
|
8
|
+
- [https://www.greynoise.io/](https://www.greynoise.io/)
|
9
|
+
|
10
|
+
This analyzer uses GreyNoise API and `[https://api.greynoise.io/v2/experimental/gnql](https://api.greynoise.io/v2/experimental/gnql)` API endpoint to search.
|
11
|
+
|
12
|
+
```yaml
|
13
|
+
analyzer: greynoise
|
14
|
+
query: ...
|
15
|
+
api_key: ...
|
16
|
+
```
|
17
|
+
|
18
|
+
| Name | Type | Required? | Default | Desc. |
|
19
|
+
| ------- | ------ | --------- | ------------------------ | ------------ |
|
20
|
+
| query | String | Yes | | Search query |
|
21
|
+
| api_key | String | No | ENV[”GREYNOISE_API_KEY"] | API key |
|
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
---
|
5
|
+
|
6
|
+
# Hunter How
|
7
|
+
|
8
|
+
- [https://hunter.how/](https://hunter.how/)
|
9
|
+
|
10
|
+
This analyzer uses `https://api.hunter.how/search` API endpoint to search.
|
11
|
+
|
12
|
+
```yaml
|
13
|
+
analyzer: hunterhow
|
14
|
+
query: ...
|
15
|
+
api_key: ...
|
16
|
+
start_time: ...
|
17
|
+
end_time: ...
|
18
|
+
```
|
19
|
+
|
20
|
+
| Name | Type | Required? | Default | Desc. |
|
21
|
+
| ---------- | ------ | --------- | ------------------------ | ------------ |
|
22
|
+
| query | String | Yes | | Search query |
|
23
|
+
| start_time | Date | Yes | | |
|
24
|
+
| end_time | Date | Yes | | |
|
25
|
+
| api_key | String | No | ENV[”HUNTERHOW_API_KEY"] | API key |
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Analyzers
|
2
|
+
|
3
|
+
- [BinaryEdge](binaryedge.md)
|
4
|
+
- [Censys](censys.md)
|
5
|
+
- [Circle Passive DNS/SSL](circl.md)
|
6
|
+
- [crt.sh](crtsh.md)
|
7
|
+
- [dnstwister](dnstwister.md)
|
8
|
+
- [Feed](feed.md)
|
9
|
+
- [GreyNoise](greynoise.md)
|
10
|
+
- [HunterHow](hunterhow.md)
|
11
|
+
- [Onyphe](onyphe.md)
|
12
|
+
- [OTX](otx.md)
|
13
|
+
- [PassiveTotal](passivetotal.md)
|
14
|
+
- [PulseDive](pulsedive.md)
|
15
|
+
- [SecurityTrails](securitytrails.md)
|
16
|
+
- [Shodan](shodan.md)
|
17
|
+
- [urlscan.io](urlscan.md)
|
18
|
+
- [VirusTotal](virustotal.md)
|
19
|
+
- [VirusTotal Intelligence](virustotal_intelligence.md)
|
20
|
+
|
21
|
+
## Options
|
22
|
+
|
23
|
+
All the analyzers can have optional `options`.
|
24
|
+
|
25
|
+
```yaml
|
26
|
+
analyzer: ...
|
27
|
+
query: ...
|
28
|
+
options:
|
29
|
+
interval: ...
|
30
|
+
pagination_limit: ...
|
31
|
+
retry_times: ...
|
32
|
+
retry_interval: ...
|
33
|
+
ignore_error: ...
|
34
|
+
```
|
35
|
+
|
36
|
+
### Interval
|
37
|
+
|
38
|
+
`interval` is an interval in seconds between pagination. (If an analyzer does pagination). Optional.
|
39
|
+
|
40
|
+
### Pagination Limit
|
41
|
+
|
42
|
+
`pagination_limit` is an limit for pagination. Defaults to 100.
|
43
|
+
|
44
|
+
In the worst case, if something wrong with Mihari or a service, Mihari can drain API quota by doing pagination forever.
|
45
|
+
`pagination_limit` is a safety valve for that. A number of pagination is limited as `pagination_limit` times.
|
46
|
+
|
47
|
+
### Retry Times
|
48
|
+
|
49
|
+
`retry_times` is a number of times of retry when something goes wrong. Defaults to 3.
|
50
|
+
|
51
|
+
### Retry Interval
|
52
|
+
|
53
|
+
`retry_interval` is an interval in seconds between retries. Defaults to 5.
|
54
|
+
|
55
|
+
### Ignore Error
|
56
|
+
|
57
|
+
`ignore_error` controls whether to ignore an error or not. Defaults to `false`.
|
58
|
+
|
59
|
+
Mihari uses fail-fast approach. For example, if Shodan returns an error, the Censys query next is not triggered because Mihari raises an error before it.
|
60
|
+
|
61
|
+
```yaml
|
62
|
+
queries:
|
63
|
+
- analyzer: shodan
|
64
|
+
query: ip:1.1.1.1
|
65
|
+
- analyzer: censys
|
66
|
+
query: ip:8.8.8.8
|
67
|
+
```
|
68
|
+
|
69
|
+
You can set `ignore_error` option to make it fault tolerance.
|
70
|
+
|
71
|
+
```yaml
|
72
|
+
queries:
|
73
|
+
- analyzer: shodan
|
74
|
+
query: ip:1.1.1.1
|
75
|
+
options:
|
76
|
+
ignore_error: true
|
77
|
+
- analyzer: censys
|
78
|
+
query: ip:8.8.8.8
|
79
|
+
```
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
---
|
5
|
+
|
6
|
+
# ONYPHE
|
7
|
+
|
8
|
+
- [https://www.onyphe.io/](https://www.onyphe.io/)
|
9
|
+
|
10
|
+
This analyzer uses ONYPHE API v2 (`/api/v2/simple/datascan`) to search.
|
11
|
+
|
12
|
+
```yaml
|
13
|
+
analyzer: onyphe
|
14
|
+
query: ...
|
15
|
+
api_key: ...
|
16
|
+
```
|
17
|
+
|
18
|
+
| Name | Type | Required? | Default | Desc. |
|
19
|
+
| ------- | ------ | --------- | --------------------- | ------------ |
|
20
|
+
| query | String | Yes | | Search query |
|
21
|
+
| api_key | String | No | ENV[”ONYPHE_API_KEY”] | API key |
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
- Domain
|
5
|
+
- Passive DNS
|
6
|
+
---
|
7
|
+
|
8
|
+
# OTX
|
9
|
+
|
10
|
+
- [https://otx.alienvault.com/](https://otx.alienvault.com/dashboard/new)
|
11
|
+
|
12
|
+
This analyzer uses [OTX API v1](https://otx.alienvault.com/api) (`/api/v1/indicators/`) API endpoints to search.
|
13
|
+
|
14
|
+
```yaml
|
15
|
+
analyzer: otx
|
16
|
+
query: ...
|
17
|
+
api_key: ...
|
18
|
+
```
|
19
|
+
|
20
|
+
| Name | Type | Required? | Default | Desc. |
|
21
|
+
| ------- | ------ | --------- | ------------------ | -------------------- |
|
22
|
+
| query | String | Yes | | Domain or IP address |
|
23
|
+
| api_key | String | No | ENV[”OTX_API_KEY”] | API key |
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
- Domain
|
5
|
+
- Passive DNS
|
6
|
+
- Passive SSL
|
7
|
+
- Reverse Whois
|
8
|
+
---
|
9
|
+
|
10
|
+
# PassiveTotal
|
11
|
+
|
12
|
+
- [https://community.riskiq.com/](https://community.riskiq.com/home)
|
13
|
+
|
14
|
+
This analyzer uses [PassvieTotal API](https://api.passivetotal.org/index.html).
|
15
|
+
|
16
|
+
An API endpoint to use is changed based on a type of a query.
|
17
|
+
|
18
|
+
| Query | API endpoint | Artifact |
|
19
|
+
| --------------------------------------- | ----------------------------- | ---------- |
|
20
|
+
| IP address | `/v2/dns/passive` | Domain |
|
21
|
+
| Domain | `/v2/dns/passive` | IP address |
|
22
|
+
| Mail | `/v2/whois/search` | Domain |
|
23
|
+
| Hash (SSL certificate SHA1 fingerprint) | `/v2/ssl-certificate/history` | IP address |
|
24
|
+
|
25
|
+
```yaml
|
26
|
+
analyzer: passivetotal
|
27
|
+
query: ...
|
28
|
+
username: ...
|
29
|
+
api_key: ...
|
30
|
+
```
|
31
|
+
|
32
|
+
| Name | Type | Required? | Default | Desc. |
|
33
|
+
| -------- | ------ | --------- | ---------------------------- | ---------------------------------------------------------------- |
|
34
|
+
| query | String | Yes | | Domain, IP address, mail address or SHA1 certificate fingerprint |
|
35
|
+
| username | String | No | ENV[”PASSIVETOTAL_USERNAME"] | Username |
|
36
|
+
| api_key | String | No | ENV[”PASSIVETOTAL_API_KEY"] | API key |
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
- Domain
|
5
|
+
- Passive DNS
|
6
|
+
---
|
7
|
+
|
8
|
+
# Pulsedive
|
9
|
+
|
10
|
+
- [https://pulsedive.com/](https://pulsedive.com/)
|
11
|
+
|
12
|
+
This analyzer uses [Pulsedive API](https://pulsedive.com/api/) (`/api/info.php`) to search.
|
13
|
+
|
14
|
+
```yaml
|
15
|
+
analyzer: pulsedive
|
16
|
+
query: ...
|
17
|
+
api_key: ...
|
18
|
+
```
|
19
|
+
|
20
|
+
| Name | Type | Required? | Default | Desc. |
|
21
|
+
| ------- | ------ | --------- | ------------------------ | -------------------- |
|
22
|
+
| query | String | Yes | | Domain or IP address |
|
23
|
+
| api_key | String | No | ENV[”PULSEDIVE_API_KEY"] | API key |
|
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
- Domain
|
5
|
+
- Passive DNS
|
6
|
+
- Reverse Whois
|
7
|
+
---
|
8
|
+
|
9
|
+
# SecurityTrails
|
10
|
+
|
11
|
+
- [https://securitytrails.com/](https://securitytrails.com/)
|
12
|
+
|
13
|
+
This analyzer uses [SecurityTrails API](https://docs.securitytrails.com/docs).
|
14
|
+
|
15
|
+
An API endpoint to use is changed based on a type of a query.
|
16
|
+
|
17
|
+
| Query type | API endpoint | Artifact |
|
18
|
+
| ---------- | ------------------ | ---------- |
|
19
|
+
| IP address | `/v1/domains/list` | Domain |
|
20
|
+
| Domain | `/v1/history/` | IP address |
|
21
|
+
| Mail | `/v1/domains/list` | Domain |
|
22
|
+
|
23
|
+
```yaml
|
24
|
+
analyzer: securitytrails
|
25
|
+
query: ...
|
26
|
+
api_key: ...
|
27
|
+
```
|
28
|
+
|
29
|
+
| Name | Type | Required? | Default | Desc. |
|
30
|
+
| ------- | ------ | --------- | ----------------------------- | ---------------------------------- |
|
31
|
+
| query | String | Yes | | Domain, IP address or mail address |
|
32
|
+
| api_key | String | No | ENV[”SECURITYTRAILS_API_KEY"] | API key |
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
---
|
5
|
+
|
6
|
+
# Shodan
|
7
|
+
|
8
|
+
- [https://shodan.io/](https://shodan.io/)
|
9
|
+
|
10
|
+
This analyzer uses [Shodan REST AP](https://developer.shodan.io/api) (`/shodan/host/search`) API to search.
|
11
|
+
|
12
|
+
```yaml
|
13
|
+
analyzer: shodan
|
14
|
+
query: ...
|
15
|
+
api_key: ...
|
16
|
+
```
|
17
|
+
|
18
|
+
| Name | Type | Required? | Default | Desc. |
|
19
|
+
| ------- | ------ | --------- | --------------------- | ------------ |
|
20
|
+
| query | String | Yes | | Search query |
|
21
|
+
| api_key | String | No | ENV[”SHODAN_API_KEY"] | API key |
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
- Domain
|
5
|
+
- URL
|
6
|
+
---
|
7
|
+
|
8
|
+
# urlscan.io
|
9
|
+
|
10
|
+
- [https://urlscan.io/](https://urlscan.io/)
|
11
|
+
|
12
|
+
This analyzer uses [urlscan.io](http://urlscan.io) API (`/api/v1/search`) to search.
|
13
|
+
|
14
|
+
```yaml
|
15
|
+
analyzer: urlscan
|
16
|
+
query: ...
|
17
|
+
api_key: ...
|
18
|
+
```
|
19
|
+
|
20
|
+
| Name | Type | Required? | Default | Desc. |
|
21
|
+
| ------- | ------ | --------- | ---------------------- | ------------ |
|
22
|
+
| query | String | Yes | | Search query |
|
23
|
+
| api_key | String | No | ENV[”URLSCAN_API_KEY"] | API key |
|
@@ -0,0 +1,34 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
- Domain
|
5
|
+
- Passive DNS
|
6
|
+
---
|
7
|
+
|
8
|
+
# VirusTotal
|
9
|
+
|
10
|
+
- [https://www.virustotal.com](https://www.virustotal.com/gui/home/search)
|
11
|
+
|
12
|
+
The analyzer uses VirusTotal API v3.
|
13
|
+
|
14
|
+
An API endpoint to use is changed based on a type of a query.
|
15
|
+
|
16
|
+
::: top
|
17
|
+
|
18
|
+
Note that this analyzer only checks passive DNS data of a given query (domain or IP address).
|
19
|
+
|
20
|
+
| Query | API endpoint | Artifact |
|
21
|
+
| ---------- | ----------------------- | ---------- |
|
22
|
+
| IP address | `/api/v3/ip_addresses/` | Domain |
|
23
|
+
| Domain | `/api/v3/domains/` | IP address |
|
24
|
+
|
25
|
+
```yaml
|
26
|
+
analyzer: virustotal
|
27
|
+
query: ...
|
28
|
+
api_key: ...
|
29
|
+
```
|
30
|
+
|
31
|
+
| Name | Type | Required? | Default | Desc. |
|
32
|
+
| ------- | ------ | --------- | ------------------------- | -------------------- |
|
33
|
+
| query | String | Yes | | Domain or IP address |
|
34
|
+
| api_key | String | No | ENV[”VIRUSTOTAL_API_KEY"] | API key |
|
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
tags:
|
3
|
+
- IP address
|
4
|
+
- Domain
|
5
|
+
- URL
|
6
|
+
- Hash
|
7
|
+
---
|
8
|
+
|
9
|
+
# VirusTotal Intelligence
|
10
|
+
|
11
|
+
- [https://www.virustotal.com](https://www.virustotal.com/gui/home/search)
|
12
|
+
|
13
|
+
```yaml
|
14
|
+
analyzer: virustotal_intelligence
|
15
|
+
query: ...
|
16
|
+
api_key: ...
|
17
|
+
```
|
18
|
+
|
19
|
+
| Name | Type | Required? | Default | Desc. |
|
20
|
+
| ------- | ------ | --------- | ------------------------- | ------------ |
|
21
|
+
| query | String | Yes | | Search query |
|
22
|
+
| api_key | String | No | ENV[”VIRUSTOTAL_API_KEY"] | API key |
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# ZoomEye
|
2
|
+
|
3
|
+
- [https://zoomeye.org/](https://zoomeye.org/)
|
4
|
+
|
5
|
+
The analyzer uses ZoomEye API v3.
|
6
|
+
|
7
|
+
An API endpoint to use is changed based on a `type` option.
|
8
|
+
|
9
|
+
| Type | API endpoint | Artifact type |
|
10
|
+
| ---- | -------------- | ------------- |
|
11
|
+
| web | `/web/search` | IP address |
|
12
|
+
| host | `/host/search` | IP address |
|
13
|
+
|
14
|
+
```yaml
|
15
|
+
analyzer: zoomeye
|
16
|
+
query: ...
|
17
|
+
type: ...
|
18
|
+
api_key: ...
|
19
|
+
```
|
20
|
+
|
21
|
+
| Name | Type | Required? | Default | Desc. |
|
22
|
+
| ------- | ------------------------ | --------- | ---------------------- | ------------ |
|
23
|
+
| query | String | Yes | | Search query |
|
24
|
+
| type | String (`web` or `host`) | Yes | | Query type |
|
25
|
+
| api_key | String | No | ENV[”ZOOMEYE_API_KEY"] | API key |
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Configuration
|
2
|
+
|
3
|
+
Configuration can be done via environment variables.
|
4
|
+
|
5
|
+
| Environmental Variable | Description | Default |
|
6
|
+
| ---------------------- | ------------------------------- | -------------------- |
|
7
|
+
| DATABASE_URL | Database URL | sqlite3:///mihari.db |
|
8
|
+
| BINARYEDGE_API_KEY | BinaryEdge API key | |
|
9
|
+
| CENSYS_ID | Censys API ID | |
|
10
|
+
| CENSYS_SECRET | Censys secret | |
|
11
|
+
| CIRCL_PASSIVE_PASSWORD | CIRCL passive DNS/SSL password | |
|
12
|
+
| CIRCL_PASSIVE_USERNAME | CIRCL passive DNS/SSL username, | |
|
13
|
+
| IPINFO_API_KEY | IPInfo API key (token) | |
|
14
|
+
| MISP_URL | MISP URL | |
|
15
|
+
| MISP_API_KEY | MISP API key | |
|
16
|
+
| ONYPHE_API_KEY | Onyphe API key | |
|
17
|
+
| OTX_API_KEY | OTX API key | |
|
18
|
+
| PASSIVETOTAL_API_KEY | PassiveTotal API key | |
|
19
|
+
| PASSIVETOTAL_USERNAME | PassiveTotal username | |
|
20
|
+
| PULSEDIVE_API_KEY | Pulsedive API key | |
|
21
|
+
| SECURITYTRAILS_API_KEY | SecurityTrails API key | |
|
22
|
+
| SHODAN_API_KEY | Shodan API key | |
|
23
|
+
| SLACK_CHANNEL | Slack channel name | #general |
|
24
|
+
| SLACK_WEBHOOK_URL | Slack Webhook URL | |
|
25
|
+
| THEHIVE_URL | TheHive URL, | |
|
26
|
+
| THEHIVE_API_KEY | TheHive API key, | |
|
27
|
+
| URLSCAN_API_KEY | urlscan.io API key, | |
|
28
|
+
| VIRUSTOTAL_API_KEY | VirusTotal API key | |
|
29
|
+
| ZOOMEYE_API_KEY | ZoomEye API key | |
|
30
|
+
| SENTRY_DSN | Sentry DSN | |
|
31
|
+
| RETRY_INTERVAL | Retry interval | 5 |
|
32
|
+
| RETRY_TIMES | Retry times | 3 |
|
33
|
+
| PAGINATION_LIMIT | Pagination limit | 100 |
|
34
|
+
|
35
|
+
Or you can set values through `.env` file. Values in `.env` file will be automatically loaded.
|