mihari 5.5.0 → 5.6.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/docs/analyzers/passivetotal.md +4 -0
- data/docs/analyzers/securitytrails.md +4 -0
- data/docs/analyzers/virustotal.md +4 -0
- data/docs/analyzers/virustotal_intelligence.md +4 -0
- data/docs/emitters/hive.md +1 -1
- data/docs/emitters/slack.md +0 -5
- data/docs/rule.md +1 -4
- data/docs/usage.md +5 -2
- data/frontend/src/components/ErrorMessage.vue +0 -1
- data/frontend/src/components/alert/Alerts.vue +0 -1
- data/frontend/src/components/alert/AlertsWithPagination.vue +0 -1
- data/frontend/src/components/alert/AlertsWrapper.vue +0 -6
- data/frontend/src/components/alert/Form.vue +1 -3
- data/frontend/src/components/artifact/Artifact.vue +0 -17
- data/frontend/src/components/artifact/ArtifactWrapper.vue +0 -2
- data/frontend/src/components/artifact/WhoisRecord.vue +0 -3
- data/frontend/src/components/config/ConfigsWrapper.vue +0 -2
- data/frontend/src/components/rule/EditRule.vue +0 -3
- data/frontend/src/components/rule/EditRuleWrapper.vue +0 -2
- data/frontend/src/components/rule/Form.vue +1 -3
- data/frontend/src/components/rule/NewRule.vue +0 -3
- data/frontend/src/components/rule/Rule.vue +1 -7
- data/frontend/src/components/rule/RuleWrapper.vue +0 -2
- data/frontend/src/components/rule/RulesWrapper.vue +0 -6
- data/frontend/src/swagger.yaml +254 -254
- data/lib/mihari/analyzers/base.rb +4 -41
- data/lib/mihari/analyzers/passivetotal.rb +9 -0
- data/lib/mihari/analyzers/pulsedive.rb +1 -1
- data/lib/mihari/analyzers/rule.rb +24 -59
- data/lib/mihari/analyzers/securitytrails.rb +9 -0
- data/lib/mihari/analyzers/virustotal.rb +11 -2
- data/lib/mihari/analyzers/virustotal_intelligence.rb +16 -0
- data/lib/mihari/analyzers/zoomeye.rb +2 -2
- data/lib/mihari/base.rb +69 -0
- data/lib/mihari/cli/main.rb +36 -0
- data/lib/mihari/commands/alert.rb +6 -33
- data/lib/mihari/commands/rule.rb +7 -12
- data/lib/mihari/commands/search.rb +10 -38
- data/lib/mihari/constants.rb +3 -3
- data/lib/mihari/emitters/base.rb +3 -33
- data/lib/mihari/emitters/database.rb +1 -1
- data/lib/mihari/enrichers/base.rb +2 -33
- data/lib/mihari/enrichers/google_public_dns.rb +9 -0
- data/lib/mihari/schemas/analyzer.rb +24 -24
- data/lib/mihari/schemas/emitter.rb +6 -13
- data/lib/mihari/schemas/enricher.rb +4 -11
- data/lib/mihari/schemas/options.rb +27 -0
- data/lib/mihari/schemas/rule.rb +2 -2
- data/lib/mihari/services/alert_runner.rb +1 -1
- data/lib/mihari/services/rule_runner.rb +1 -11
- data/lib/mihari/types.rb +1 -14
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/public/assets/{index-33165282.css → index-56fc2187.css} +1 -1
- data/lib/mihari/web/public/assets/{index-b5d817a3.js → index-9cc489e6.js} +2 -2
- data/lib/mihari/web/public/index.html +2 -2
- data/lib/mihari.rb +67 -37
- data/mihari.gemspec +1 -0
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9131a7f69be7cde564ec00479ae3fa3723a3e80d28690c3e989119de3feab5f5
|
4
|
+
data.tar.gz: b115531cc635b7767e6bcf75c8ca0376e4ade45772e98aa9fc07df3b2dcc2e96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a893bb138e769bf082bbea057229726f9b2e353fa539c9a1fb64aabcc8a622ed22315a0aa42e5dc873f6a13e3ec145776afe75203db93b7a3d2352d46b026b9
|
7
|
+
data.tar.gz: cd11791f340b58ffc39a03fba8ee2aad1da58fcf47fd8a00281fe8984d0149fa1e448aff4b55860b47e5fb424d994a40ab00f7691b416f315b3fbfdcd5737509
|
@@ -31,6 +31,10 @@ api_key: ...
|
|
31
31
|
|
32
32
|
## Components
|
33
33
|
|
34
|
+
### Analyzer
|
35
|
+
|
36
|
+
`analyzer` (`string`) should be either of `passivetotal` and `pt`.
|
37
|
+
|
34
38
|
### Query
|
35
39
|
|
36
40
|
`query` (`string`) is a passive DNS/SSL or reverse whois search query. Domain, IP address, mail or SHA1 certificate fingerprint.
|
data/docs/emitters/hive.md
CHANGED
data/docs/emitters/slack.md
CHANGED
@@ -10,11 +10,6 @@ webhook_url: ...
|
|
10
10
|
channel: ...
|
11
11
|
```
|
12
12
|
|
13
|
-
| Name | Type | Required? | Default | Desc. |
|
14
|
-
| ----------- | ------ | --------- | ------------------------------- | ----------------- |
|
15
|
-
| webhook_url | String | No | ENV[SLACK_WEBHOOK_URL] | Slack webhook URL |
|
16
|
-
| channel | String | No | ENV[SLACK_CHANNEL] / `#general` | Slack channel |
|
17
|
-
|
18
13
|
## Components
|
19
14
|
|
20
15
|
### Webhook URL
|
data/docs/rule.md
CHANGED
@@ -54,7 +54,7 @@ emitters:
|
|
54
54
|
- emitter: database
|
55
55
|
- emitter: misp
|
56
56
|
- emitter: slack
|
57
|
-
- emitter:
|
57
|
+
- emitter: thehive
|
58
58
|
data_types:
|
59
59
|
- hash
|
60
60
|
- ip
|
@@ -124,9 +124,6 @@ See [Emitters](./emitters/index.md) to know details of each emitter.
|
|
124
124
|
Defaults to:
|
125
125
|
|
126
126
|
- `database`
|
127
|
-
- `misp`
|
128
|
-
- `slack`
|
129
|
-
- `the_hive`
|
130
127
|
|
131
128
|
### Data Types
|
132
129
|
|
data/docs/usage.md
CHANGED
@@ -8,8 +8,11 @@ Commands:
|
|
8
8
|
mihari db # Sub commands for DB
|
9
9
|
mihari help [COMMAND] # Describe available commands or one specific command
|
10
10
|
mihari rule # Sub commands for rule
|
11
|
-
mihari search [PATH_OR_ID] # Search by a rule
|
11
|
+
mihari search [PATH_OR_ID] # Search by a rule (Outputs null if there is no new finding)
|
12
12
|
mihari web # Launch the web app
|
13
|
+
|
14
|
+
Options:
|
15
|
+
-d, [--debug], [--no-debug] # Sets up debug mode
|
13
16
|
```
|
14
17
|
|
15
18
|
## `mihari db`
|
@@ -43,7 +46,7 @@ Mihari asks whether really you want to update a rule if there is a diff by defau
|
|
43
46
|
|
44
47
|
```bash
|
45
48
|
$ mihari search /path/to/rule.yml
|
46
|
-
There is a diff in the rule
|
49
|
+
There is a diff in the rule. Are you sure you want to overwrite the rule? (y/n)
|
47
50
|
```
|
48
51
|
|
49
52
|
It can be suppressed by providing `-f`.
|
@@ -3,7 +3,6 @@
|
|
3
3
|
<p v-if="error.response.data?.message">{{ error.response.data.message }}</p>
|
4
4
|
<p v-else>{{ error }}</p>
|
5
5
|
</div>
|
6
|
-
|
7
6
|
<article class="message" v-if="error.response.data?.details">
|
8
7
|
<div class="message-body">
|
9
8
|
<VueJsonPretty :data="error.response.data.details"></VueJsonPretty>
|
@@ -7,9 +7,7 @@
|
|
7
7
|
:page="page"
|
8
8
|
:tag="tag"
|
9
9
|
></FormComponent>
|
10
|
-
|
11
10
|
<hr />
|
12
|
-
|
13
11
|
<div class="columns">
|
14
12
|
<div class="column">
|
15
13
|
<div class="field is-grouped is-grouped-centered">
|
@@ -25,14 +23,10 @@
|
|
25
23
|
</div>
|
26
24
|
</div>
|
27
25
|
</div>
|
28
|
-
|
29
26
|
<div v-if="getAlertsTask.performCount > 0">
|
30
27
|
<hr />
|
31
|
-
|
32
28
|
<Loading v-if="getAlertsTask.isRunning"></Loading>
|
33
|
-
|
34
29
|
<ErrorMessage v-if="getAlertsTask.isError" :error="getAlertsTask.last?.error"></ErrorMessage>
|
35
|
-
|
36
30
|
<AlertsComponent
|
37
31
|
:alerts="getAlertsTask.last.value"
|
38
32
|
v-if="getAlertsTask.last?.value"
|
@@ -36,7 +36,6 @@
|
|
36
36
|
</div>
|
37
37
|
</div>
|
38
38
|
</div>
|
39
|
-
|
40
39
|
<div class="columns">
|
41
40
|
<div class="column">
|
42
41
|
<div class="field is-horizontal">
|
@@ -61,7 +60,6 @@
|
|
61
60
|
</div>
|
62
61
|
<div class="column"></div>
|
63
62
|
</div>
|
64
|
-
|
65
63
|
<div class="columns">
|
66
64
|
<div class="column">
|
67
65
|
<div class="field is-horizontal">
|
@@ -95,7 +93,7 @@
|
|
95
93
|
</template>
|
96
94
|
|
97
95
|
<script lang="ts">
|
98
|
-
import { defineComponent, type PropType, ref, toRef,watch } from "vue"
|
96
|
+
import { defineComponent, type PropType, ref, toRef, watch } from "vue"
|
99
97
|
import { useRoute } from "vue-router"
|
100
98
|
|
101
99
|
import type { AlertSearchParams } from "@/types"
|
@@ -4,9 +4,7 @@
|
|
4
4
|
<Loading></Loading>
|
5
5
|
<hr />
|
6
6
|
</div>
|
7
|
-
|
8
7
|
<h2 class="is-size-2 mb-4">Artifact</h2>
|
9
|
-
|
10
8
|
<div class="columns">
|
11
9
|
<div
|
12
10
|
class="column is-half"
|
@@ -21,7 +19,6 @@
|
|
21
19
|
</h4>
|
22
20
|
<iframe class="mb-4" :src="googleMapSrc" width="100%" height="240px"></iframe>
|
23
21
|
</div>
|
24
|
-
|
25
22
|
<div v-if="urlscanLiveshotSrc">
|
26
23
|
<h4 class="is-size-4 mb-2">
|
27
24
|
Live screenshot
|
@@ -30,11 +27,9 @@
|
|
30
27
|
<img :src="urlscanLiveshotSrc" class="liveshot" alt="liveshot" />
|
31
28
|
</div>
|
32
29
|
</div>
|
33
|
-
|
34
30
|
<div class="column">
|
35
31
|
<div class="block">
|
36
32
|
<h4 class="is-size-4 mb-2">Information</h4>
|
37
|
-
|
38
33
|
<table class="table is-fullwidth is-completely-borderless">
|
39
34
|
<tr>
|
40
35
|
<th>ID</th>
|
@@ -47,7 +42,6 @@
|
|
47
42
|
<font-awesome-icon icon="lightbulb"></font-awesome-icon>
|
48
43
|
</span>
|
49
44
|
</button>
|
50
|
-
|
51
45
|
<button
|
52
46
|
class="button is-info is-light is-small"
|
53
47
|
@click="flipShowMetadata"
|
@@ -58,7 +52,6 @@
|
|
58
52
|
<font-awesome-icon icon="info-circle"></font-awesome-icon>
|
59
53
|
</span>
|
60
54
|
</button>
|
61
|
-
|
62
55
|
<button class="button is-light is-small" @click="deleteArtifact">
|
63
56
|
<span>Delete</span>
|
64
57
|
<span class="icon is-small">
|
@@ -86,7 +79,6 @@
|
|
86
79
|
</tr>
|
87
80
|
</table>
|
88
81
|
</div>
|
89
|
-
|
90
82
|
<div v-if="artifact.metadata && showMetadata">
|
91
83
|
<div class="modal is-active">
|
92
84
|
<div class="modal-background" @click="flipShowMetadata"></div>
|
@@ -103,45 +95,36 @@
|
|
103
95
|
</div>
|
104
96
|
</div>
|
105
97
|
</div>
|
106
|
-
|
107
98
|
<div class="block" v-if="artifact.autonomousSystem">
|
108
99
|
<h4 class="is-size-4 mb-2">AS</h4>
|
109
100
|
<AS :autonomousSystem="artifact.autonomousSystem"></AS>
|
110
101
|
</div>
|
111
|
-
|
112
102
|
<div class="block" v-if="artifact.reverseDnsNames">
|
113
103
|
<h4 class="is-size-4 mb-2">Reverse DNS</h4>
|
114
104
|
<ReverseDnsNames :reverseDnsNames="artifact.reverseDnsNames"></ReverseDnsNames>
|
115
105
|
</div>
|
116
|
-
|
117
106
|
<div class="block" v-if="artifact.dnsRecords">
|
118
107
|
<h4 class="is-size-4 mb-2">DNS records</h4>
|
119
108
|
<DnsRecords :dnsRecords="artifact.dnsRecords"></DnsRecords>
|
120
109
|
</div>
|
121
|
-
|
122
110
|
<div class="block" v-if="artifact.cpes">
|
123
111
|
<h4 class="is-size-4 mb-2">CPEs</h4>
|
124
112
|
<CPEs :cpes="artifact.cpes"></CPEs>
|
125
113
|
</div>
|
126
|
-
|
127
114
|
<div class="block" v-if="artifact.ports">
|
128
115
|
<h4 class="is-size-4 mb-2">Ports</h4>
|
129
116
|
<Ports :ports="artifact.ports"></Ports>
|
130
117
|
</div>
|
131
|
-
|
132
118
|
<div class="block" v-if="artifact.whoisRecord">
|
133
119
|
<h4 class="is-size-4 mb-2">Whois record</h4>
|
134
120
|
<WhoisRecord :whoisRecord="artifact.whoisRecord"></WhoisRecord>
|
135
121
|
</div>
|
136
|
-
|
137
122
|
<div class="block">
|
138
123
|
<h4 class="is-size-4 mb-2">Links</h4>
|
139
124
|
<Links :data="artifact.data" :type="artifact.dataType"></Links>
|
140
125
|
</div>
|
141
126
|
</div>
|
142
|
-
|
143
127
|
<hr />
|
144
|
-
|
145
128
|
<div class="column">
|
146
129
|
<h2 class="is-size-2 mb-4">Related alerts</h2>
|
147
130
|
<Alerts :artifact="artifact.data"></Alerts>
|
@@ -6,21 +6,18 @@
|
|
6
6
|
<span class="tag is-light">{{ whoisRecord.registrar?.name || "N/A" }}</span>
|
7
7
|
</div>
|
8
8
|
</div>
|
9
|
-
|
10
9
|
<div class="control">
|
11
10
|
<div class="tags has-addons are-medium">
|
12
11
|
<span class="tag is-dark">Created on</span>
|
13
12
|
<span class="tag is-light">{{ whoisRecord.createdOn || "N/A" }}</span>
|
14
13
|
</div>
|
15
14
|
</div>
|
16
|
-
|
17
15
|
<div class="control">
|
18
16
|
<div class="tags has-addons are-medium">
|
19
17
|
<span class="tag is-dark">Updated on</span>
|
20
18
|
<span class="tag is-light">{{ whoisRecord.updatedOn || "N/A" }}</span>
|
21
19
|
</div>
|
22
20
|
</div>
|
23
|
-
|
24
21
|
<div class="control">
|
25
22
|
<div class="tags has-addons are-medium">
|
26
23
|
<span class="tag is-dark">Exipres on</span>
|
@@ -1,8 +1,6 @@
|
|
1
1
|
<template>
|
2
2
|
<Loading v-if="getConfigsTask.isRunning"></Loading>
|
3
|
-
|
4
3
|
<ErrorMessage v-if="getConfigsTask.isError" :error="getConfigsTask.last?.error"></ErrorMessage>
|
5
|
-
|
6
4
|
<Configs :configs="getConfigsTask.last.value" v-if="getConfigsTask.last?.value"></Configs>
|
7
5
|
</template>
|
8
6
|
|
@@ -1,9 +1,7 @@
|
|
1
1
|
<template>
|
2
2
|
<div class="column">
|
3
3
|
<h2 class="is-size-2 mb-4">Edit rule: {{ rule.id }}</h2>
|
4
|
-
|
5
4
|
<InputForm v-model:yaml="yaml" @update-yaml="updateYAML"></InputForm>
|
6
|
-
|
7
5
|
<div class="field is-grouped is-grouped-centered">
|
8
6
|
<p class="control">
|
9
7
|
<a class="button is-primary" @click="edit">
|
@@ -14,7 +12,6 @@
|
|
14
12
|
</a>
|
15
13
|
</p>
|
16
14
|
</div>
|
17
|
-
|
18
15
|
<div v-if="updateRuleTask.last?.error">
|
19
16
|
<hr />
|
20
17
|
<ErrorMessage :error="updateRuleTask.last?.error"></ErrorMessage>
|
@@ -29,7 +29,6 @@
|
|
29
29
|
</div>
|
30
30
|
</div>
|
31
31
|
</div>
|
32
|
-
|
33
32
|
<div class="columns">
|
34
33
|
<div class="column">
|
35
34
|
<div class="field is-horizontal">
|
@@ -54,7 +53,6 @@
|
|
54
53
|
</div>
|
55
54
|
<div class="column"></div>
|
56
55
|
</div>
|
57
|
-
|
58
56
|
<div class="columns">
|
59
57
|
<div class="column">
|
60
58
|
<div class="field is-horizontal">
|
@@ -88,7 +86,7 @@
|
|
88
86
|
</template>
|
89
87
|
|
90
88
|
<script lang="ts">
|
91
|
-
import { defineComponent, type PropType, ref, toRef,watch } from "vue"
|
89
|
+
import { defineComponent, type PropType, ref, toRef, watch } from "vue"
|
92
90
|
import { useRoute } from "vue-router"
|
93
91
|
|
94
92
|
import type { RuleSearchParams } from "@/types"
|
@@ -1,9 +1,7 @@
|
|
1
1
|
<template>
|
2
2
|
<div class="column">
|
3
3
|
<h2 class="is-size-2 mb-4">New rule</h2>
|
4
|
-
|
5
4
|
<InputForm v-model:yaml="yaml" @update-yaml="updateYAML"></InputForm>
|
6
|
-
|
7
5
|
<div class="field is-grouped is-grouped-centered">
|
8
6
|
<p class="control">
|
9
7
|
<a class="button is-primary" @click="create">
|
@@ -14,7 +12,6 @@
|
|
14
12
|
</a>
|
15
13
|
</p>
|
16
14
|
</div>
|
17
|
-
|
18
15
|
<div v-if="createRuleTask.last?.error">
|
19
16
|
<hr />
|
20
17
|
<ErrorMessage :error="createRuleTask.last?.error"></ErrorMessage>
|
@@ -4,15 +4,12 @@
|
|
4
4
|
<Loading></Loading>
|
5
5
|
<hr />
|
6
6
|
</div>
|
7
|
-
|
8
7
|
<div v-if="runRuleTask.last?.error">
|
9
8
|
<ErrorMessage :error="runRuleTask.last.error"></ErrorMessage>
|
10
9
|
<hr />
|
11
10
|
</div>
|
12
|
-
|
13
11
|
<h2 class="is-size-2 mb-4">Rule</h2>
|
14
|
-
|
15
|
-
<p class="is-clearfix">
|
12
|
+
<p class="block is-clearfix">
|
16
13
|
<span class="buttons is-pulled-right">
|
17
14
|
<button class="button is-primary is-light is-small" @click="runRule">
|
18
15
|
<span>Run</span>
|
@@ -37,12 +34,9 @@
|
|
37
34
|
</button>
|
38
35
|
</span>
|
39
36
|
</p>
|
40
|
-
|
41
37
|
<YAML :yaml="rule.yaml"></YAML>
|
42
38
|
</div>
|
43
|
-
|
44
39
|
<hr />
|
45
|
-
|
46
40
|
<div class="column">
|
47
41
|
<h2 class="is-size-2 mb-4">Related alerts</h2>
|
48
42
|
|
@@ -1,8 +1,6 @@
|
|
1
1
|
<template>
|
2
2
|
<Loading v-if="getRuleTask.isRunning"></Loading>
|
3
|
-
|
4
3
|
<ErrorMessage v-if="getRuleTask.isError" :error="getRuleTask.last?.error"></ErrorMessage>
|
5
|
-
|
6
4
|
<Rule :rule="getRuleTask.last.value" @refresh="refresh" v-if="getRuleTask.last?.value"></Rule>
|
7
5
|
</template>
|
8
6
|
|
@@ -6,9 +6,7 @@
|
|
6
6
|
:page="page"
|
7
7
|
:tag="tag"
|
8
8
|
></FormComponent>
|
9
|
-
|
10
9
|
<hr />
|
11
|
-
|
12
10
|
<div class="column">
|
13
11
|
<div class="field is-grouped is-grouped-centered">
|
14
12
|
<p class="control">
|
@@ -22,14 +20,10 @@
|
|
22
20
|
</div>
|
23
21
|
</div>
|
24
22
|
</div>
|
25
|
-
|
26
23
|
<div v-if="getRulesTask.performCount > 0">
|
27
24
|
<hr />
|
28
|
-
|
29
25
|
<Loading v-if="getRulesTask.isRunning"></Loading>
|
30
|
-
|
31
26
|
<ErrorMessage v-if="getRulesTask.isError" :error="getRulesTask.last?.error"></ErrorMessage>
|
32
|
-
|
33
27
|
<Rules
|
34
28
|
:rules="getRulesTask.last.value"
|
35
29
|
v-if="getRulesTask.last?.value"
|