mihari 5.5.0 → 5.6.0

Sign up to get free protection for your applications and to get access to all the features.
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"