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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/docs/analyzers/passivetotal.md +4 -0
  3. data/docs/analyzers/securitytrails.md +4 -0
  4. data/docs/analyzers/virustotal.md +4 -0
  5. data/docs/analyzers/virustotal_intelligence.md +4 -0
  6. data/docs/emitters/hive.md +1 -1
  7. data/docs/emitters/slack.md +0 -5
  8. data/docs/rule.md +1 -4
  9. data/docs/usage.md +5 -2
  10. data/frontend/src/components/ErrorMessage.vue +0 -1
  11. data/frontend/src/components/alert/Alerts.vue +0 -1
  12. data/frontend/src/components/alert/AlertsWithPagination.vue +0 -1
  13. data/frontend/src/components/alert/AlertsWrapper.vue +0 -6
  14. data/frontend/src/components/alert/Form.vue +1 -3
  15. data/frontend/src/components/artifact/Artifact.vue +0 -17
  16. data/frontend/src/components/artifact/ArtifactWrapper.vue +0 -2
  17. data/frontend/src/components/artifact/WhoisRecord.vue +0 -3
  18. data/frontend/src/components/config/ConfigsWrapper.vue +0 -2
  19. data/frontend/src/components/rule/EditRule.vue +0 -3
  20. data/frontend/src/components/rule/EditRuleWrapper.vue +0 -2
  21. data/frontend/src/components/rule/Form.vue +1 -3
  22. data/frontend/src/components/rule/NewRule.vue +0 -3
  23. data/frontend/src/components/rule/Rule.vue +1 -7
  24. data/frontend/src/components/rule/RuleWrapper.vue +0 -2
  25. data/frontend/src/components/rule/RulesWrapper.vue +0 -6
  26. data/frontend/src/swagger.yaml +254 -254
  27. data/lib/mihari/analyzers/base.rb +4 -41
  28. data/lib/mihari/analyzers/passivetotal.rb +9 -0
  29. data/lib/mihari/analyzers/pulsedive.rb +1 -1
  30. data/lib/mihari/analyzers/rule.rb +24 -59
  31. data/lib/mihari/analyzers/securitytrails.rb +9 -0
  32. data/lib/mihari/analyzers/virustotal.rb +11 -2
  33. data/lib/mihari/analyzers/virustotal_intelligence.rb +16 -0
  34. data/lib/mihari/analyzers/zoomeye.rb +2 -2
  35. data/lib/mihari/base.rb +69 -0
  36. data/lib/mihari/cli/main.rb +36 -0
  37. data/lib/mihari/commands/alert.rb +6 -33
  38. data/lib/mihari/commands/rule.rb +7 -12
  39. data/lib/mihari/commands/search.rb +10 -38
  40. data/lib/mihari/constants.rb +3 -3
  41. data/lib/mihari/emitters/base.rb +3 -33
  42. data/lib/mihari/emitters/database.rb +1 -1
  43. data/lib/mihari/enrichers/base.rb +2 -33
  44. data/lib/mihari/enrichers/google_public_dns.rb +9 -0
  45. data/lib/mihari/schemas/analyzer.rb +24 -24
  46. data/lib/mihari/schemas/emitter.rb +6 -13
  47. data/lib/mihari/schemas/enricher.rb +4 -11
  48. data/lib/mihari/schemas/options.rb +27 -0
  49. data/lib/mihari/schemas/rule.rb +2 -2
  50. data/lib/mihari/services/alert_runner.rb +1 -1
  51. data/lib/mihari/services/rule_runner.rb +1 -11
  52. data/lib/mihari/types.rb +1 -14
  53. data/lib/mihari/version.rb +1 -1
  54. data/lib/mihari/web/public/assets/{index-33165282.css → index-56fc2187.css} +1 -1
  55. data/lib/mihari/web/public/assets/{index-b5d817a3.js → index-9cc489e6.js} +2 -2
  56. data/lib/mihari/web/public/index.html +2 -2
  57. data/lib/mihari.rb +67 -37
  58. data/mihari.gemspec +1 -0
  59. metadata +20 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a0bb32d105b9879fbf87b5bcd5d49a4930cc9e054c42f992bd5c58d883ea8b0
4
- data.tar.gz: 0c547d79f1a1950008f4797a743bf84b7bc1b766d693eb9c2e9b93d150ee4cb9
3
+ metadata.gz: 9131a7f69be7cde564ec00479ae3fa3723a3e80d28690c3e989119de3feab5f5
4
+ data.tar.gz: b115531cc635b7767e6bcf75c8ca0376e4ade45772e98aa9fc07df3b2dcc2e96
5
5
  SHA512:
6
- metadata.gz: f9d5217d01e12da402ad9edde9dbeb35c14f6b18061807c48e9e0f6b84419b009b0bbdd4848d3df7302ba4c414c0fe004d7e0ee86a3e9fa29dcaea7bb79b6a8e
7
- data.tar.gz: aa353778dc0f9eb1d525c828e7e662531ba1318f8c380a93cd1f0bd7eca8da33dba7915de297695223cf53a7c3de35419f152ae6d1c199382e6aa7e870a629f2
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.
@@ -28,6 +28,10 @@ api_key: ...
28
28
 
29
29
  ## Components
30
30
 
31
+ ### Analyzer
32
+
33
+ `analyzer` (`string`) should be either of `securitytrails` and `st`.
34
+
31
35
  ### Query
32
36
 
33
37
  `query` (`string`) is a passive DNS search/reverse whois query. Domain, IP address or mail.
@@ -30,6 +30,10 @@ api_key: ...
30
30
 
31
31
  ## Components
32
32
 
33
+ ### Analyzer
34
+
35
+ `analyzer` (`string`) should be either of `virustoal` and `vt`.
36
+
33
37
  ### Query
34
38
 
35
39
  `query` (`string`) is a passive DNS search query. Domain or IP address.
@@ -20,6 +20,10 @@ api_key: ...
20
20
 
21
21
  ## Components
22
22
 
23
+ ### Analyzer
24
+
25
+ `analyzer` (`string`) should be either of `virustotal_intelligence` and ``.
26
+
23
27
  ### Query
24
28
 
25
29
  `query` (`string`) is a search query.
@@ -5,7 +5,7 @@
5
5
  This emitter creates an alert on TheHive. TheHive v4 & v5 are supported.
6
6
 
7
7
  ```yaml
8
- emitter: the_hive
8
+ emitter: thehive
9
9
  url: ...
10
10
  api_key: ...
11
11
  api_version: ...
@@ -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: the_hive
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 (6254bb74-5e5d-42ad-bc1e-231da0293b0f). Are you sure you want to overwrite the rule? (y/n)
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>
@@ -6,7 +6,6 @@
6
6
  @refresh-page="refreshPage"
7
7
  @update-tag="updateTag"
8
8
  ></Alert>
9
-
10
9
  <Pagination
11
10
  :total="alerts.total"
12
11
  :currentPage="alerts.currentPage"
@@ -1,6 +1,5 @@
1
1
  <template>
2
2
  <Loading v-if="getAlertsTask.isRunning"></Loading>
3
-
4
3
  <Alerts
5
4
  :alerts="getAlertsTask.last.value"
6
5
  v-if="getAlertsTask.last?.value"
@@ -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>
@@ -1,8 +1,6 @@
1
1
  <template>
2
2
  <Loading v-if="getArtifactTask.isRunning"></Loading>
3
-
4
3
  <ErrorMessage v-if="getArtifactTask.isError" :error="getArtifactTask.last?.error"></ErrorMessage>
5
-
6
4
  <ArtifactComponent
7
5
  :artifact="getArtifactTask.last.value"
8
6
  @refresh="refresh"
@@ -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>
@@ -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
  <EditRule :rule="getRuleTask.last.value" v-if="getRuleTask.last?.value"></EditRule>
7
5
  </template>
8
6
 
@@ -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"