mihari 5.4.9 → 5.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/docs/analyzers/binaryedge.md +2 -2
  3. data/docs/analyzers/censys.md +3 -3
  4. data/docs/analyzers/circl.md +3 -3
  5. data/docs/analyzers/crtsh.md +2 -2
  6. data/docs/analyzers/dnstwister.md +1 -1
  7. data/docs/analyzers/feed.md +7 -7
  8. data/docs/analyzers/greynoise.md +2 -2
  9. data/docs/analyzers/hunterhow.md +4 -4
  10. data/docs/analyzers/index.md +13 -8
  11. data/docs/analyzers/onyphe.md +2 -2
  12. data/docs/analyzers/otx.md +2 -2
  13. data/docs/analyzers/passivetotal.md +7 -3
  14. data/docs/analyzers/pulsedive.md +2 -2
  15. data/docs/analyzers/securitytrails.md +6 -2
  16. data/docs/analyzers/shodan.md +2 -2
  17. data/docs/analyzers/urlscan.md +2 -2
  18. data/docs/analyzers/virustotal.md +6 -2
  19. data/docs/analyzers/virustotal_intelligence.md +6 -2
  20. data/docs/analyzers/zoomeye.md +3 -3
  21. data/docs/emitters/hive.md +4 -4
  22. data/docs/emitters/index.md +29 -0
  23. data/docs/emitters/misp.md +2 -2
  24. data/docs/emitters/slack.md +2 -7
  25. data/docs/emitters/webhook.md +4 -4
  26. data/docs/enrichers/index.md +29 -0
  27. data/docs/enrichers/ipinfo.md +7 -0
  28. data/docs/index.md +0 -2
  29. data/docs/installation.md +1 -1
  30. data/docs/rule.md +12 -15
  31. data/docs/usage.md +5 -2
  32. data/frontend/package-lock.json +294 -2772
  33. data/frontend/package.json +10 -10
  34. data/frontend/src/components/ErrorMessage.vue +0 -1
  35. data/frontend/src/components/alert/Alerts.vue +0 -1
  36. data/frontend/src/components/alert/AlertsWithPagination.vue +0 -1
  37. data/frontend/src/components/alert/AlertsWrapper.vue +0 -6
  38. data/frontend/src/components/alert/Form.vue +1 -3
  39. data/frontend/src/components/artifact/Artifact.vue +0 -17
  40. data/frontend/src/components/artifact/ArtifactWrapper.vue +0 -2
  41. data/frontend/src/components/artifact/WhoisRecord.vue +0 -3
  42. data/frontend/src/components/config/ConfigsWrapper.vue +0 -2
  43. data/frontend/src/components/rule/EditRule.vue +0 -3
  44. data/frontend/src/components/rule/EditRuleWrapper.vue +0 -2
  45. data/frontend/src/components/rule/Form.vue +1 -3
  46. data/frontend/src/components/rule/NewRule.vue +0 -3
  47. data/frontend/src/components/rule/Rule.vue +1 -7
  48. data/frontend/src/components/rule/RuleWrapper.vue +0 -2
  49. data/frontend/src/components/rule/RulesWrapper.vue +0 -6
  50. data/frontend/src/swagger.yaml +254 -254
  51. data/lib/mihari/analyzers/base.rb +7 -37
  52. data/lib/mihari/analyzers/binaryedge.rb +5 -1
  53. data/lib/mihari/analyzers/censys.rb +6 -1
  54. data/lib/mihari/analyzers/greynoise.rb +5 -1
  55. data/lib/mihari/analyzers/hunterhow.rb +5 -1
  56. data/lib/mihari/analyzers/onyphe.rb +5 -1
  57. data/lib/mihari/analyzers/passivetotal.rb +9 -0
  58. data/lib/mihari/analyzers/pulsedive.rb +1 -1
  59. data/lib/mihari/analyzers/rule.rb +55 -54
  60. data/lib/mihari/analyzers/securitytrails.rb +9 -0
  61. data/lib/mihari/analyzers/shodan.rb +5 -1
  62. data/lib/mihari/analyzers/urlscan.rb +5 -1
  63. data/lib/mihari/analyzers/virustotal.rb +11 -2
  64. data/lib/mihari/analyzers/virustotal_intelligence.rb +21 -1
  65. data/lib/mihari/analyzers/zoomeye.rb +7 -3
  66. data/lib/mihari/base.rb +69 -0
  67. data/lib/mihari/cli/main.rb +36 -0
  68. data/lib/mihari/clients/base.rb +7 -7
  69. data/lib/mihari/clients/binaryedge.rb +10 -4
  70. data/lib/mihari/clients/censys.rb +11 -4
  71. data/lib/mihari/clients/greynoise.rb +10 -4
  72. data/lib/mihari/clients/hunterhow.rb +10 -4
  73. data/lib/mihari/clients/misp.rb +3 -2
  74. data/lib/mihari/clients/onyphe.rb +10 -4
  75. data/lib/mihari/clients/shodan.rb +10 -4
  76. data/lib/mihari/clients/the_hive.rb +3 -2
  77. data/lib/mihari/clients/urlscan.rb +9 -3
  78. data/lib/mihari/clients/virustotal.rb +10 -4
  79. data/lib/mihari/clients/zoomeye.rb +11 -5
  80. data/lib/mihari/commands/alert.rb +6 -33
  81. data/lib/mihari/commands/rule.rb +7 -12
  82. data/lib/mihari/commands/search.rb +10 -38
  83. data/lib/mihari/config.rb +8 -0
  84. data/lib/mihari/constants.rb +3 -3
  85. data/lib/mihari/emitters/base.rb +22 -15
  86. data/lib/mihari/emitters/database.rb +1 -1
  87. data/lib/mihari/emitters/misp.rb +7 -6
  88. data/lib/mihari/emitters/slack.rb +24 -6
  89. data/lib/mihari/emitters/the_hive.rb +8 -7
  90. data/lib/mihari/emitters/webhook.rb +31 -29
  91. data/lib/mihari/enrichers/base.rb +25 -19
  92. data/lib/mihari/enrichers/google_public_dns.rb +38 -38
  93. data/lib/mihari/enrichers/ipinfo.rb +32 -34
  94. data/lib/mihari/enrichers/shodan.rb +18 -26
  95. data/lib/mihari/enrichers/whois.rb +121 -111
  96. data/lib/mihari/mixins/retriable.rb +4 -2
  97. data/lib/mihari/models/artifact.rb +37 -23
  98. data/lib/mihari/models/autonomous_system.rb +3 -2
  99. data/lib/mihari/models/cpe.rb +3 -2
  100. data/lib/mihari/models/dns.rb +3 -2
  101. data/lib/mihari/models/geolocation.rb +3 -2
  102. data/lib/mihari/models/port.rb +3 -2
  103. data/lib/mihari/models/reverse_dns.rb +3 -2
  104. data/lib/mihari/models/whois.rb +4 -3
  105. data/lib/mihari/schemas/analyzer.rb +24 -23
  106. data/lib/mihari/schemas/emitter.rb +32 -25
  107. data/lib/mihari/schemas/enricher.rb +21 -2
  108. data/lib/mihari/schemas/options.rb +27 -0
  109. data/lib/mihari/schemas/rule.rb +8 -4
  110. data/lib/mihari/services/alert_runner.rb +1 -1
  111. data/lib/mihari/services/rule_runner.rb +1 -11
  112. data/lib/mihari/types.rb +1 -14
  113. data/lib/mihari/version.rb +1 -1
  114. data/lib/mihari/web/endpoints/ip_addresses.rb +1 -1
  115. data/lib/mihari/web/public/assets/{index-33165282.css → index-56fc2187.css} +1 -1
  116. data/lib/mihari/web/public/assets/index-9cc489e6.js +1749 -0
  117. data/lib/mihari/web/public/index.html +2 -2
  118. data/lib/mihari/web/public/redoc-static.html +400 -400
  119. data/lib/mihari.rb +67 -37
  120. data/mihari.gemspec +3 -2
  121. data/mkdocs.yml +8 -6
  122. data/requirements.txt +1 -1
  123. metadata +24 -8
  124. data/lib/mihari/web/public/assets/index-a92abd57.js +0 -1740
@@ -19,7 +19,7 @@
19
19
  "@fortawesome/vue-fontawesome": "^3.0.3",
20
20
  "@vueuse/core": "^10.5.0",
21
21
  "@vueuse/router": "^10.5.0",
22
- "ace-builds": "^1.29.0",
22
+ "ace-builds": "^1.30.0",
23
23
  "axios": "^1.5.1",
24
24
  "bulma": "^0.9.4",
25
25
  "bulma-helpers": "^0.4.3",
@@ -30,27 +30,27 @@
30
30
  "ts-dedent": "^2.2.0",
31
31
  "url-parse": "^1.5.10",
32
32
  "uuidv4": "^6.2.13",
33
- "vue": "^3.3.4",
33
+ "vue": "^3.3.6",
34
34
  "vue-concurrency": "4.0.1",
35
35
  "vue-json-pretty": "^2.2.4",
36
36
  "vue-router": "^4.2.5",
37
37
  "vue3-ace-editor": "^2.2.3"
38
38
  },
39
39
  "devDependencies": {
40
- "@redocly/cli": "1.2.0",
40
+ "@redocly/cli": "1.3.0",
41
41
  "@rushstack/eslint-patch": "^1.5.1",
42
42
  "@tsconfig/node20": "^20.1.2",
43
- "@types/jsdom": "^21.1.3",
44
- "@types/node": "^20.8.5",
45
- "@types/url-parse": "^1.4.9",
46
- "@typescript-eslint/eslint-plugin": "^6.7.5",
47
- "@typescript-eslint/parser": "^6.7.5",
43
+ "@types/jsdom": "^21.1.4",
44
+ "@types/node": "^20.8.7",
45
+ "@types/url-parse": "^1.4.10",
46
+ "@typescript-eslint/eslint-plugin": "^6.8.0",
47
+ "@typescript-eslint/parser": "^6.8.0",
48
48
  "@vitejs/plugin-vue": "^4.4.0",
49
49
  "@vue/eslint-config-prettier": "^8.0.0",
50
50
  "@vue/eslint-config-typescript": "^12.0.0",
51
51
  "@vue/test-utils": "2.4.1",
52
52
  "@vue/tsconfig": "^0.4.0",
53
- "eslint": "^8.51.0",
53
+ "eslint": "^8.52.0",
54
54
  "eslint-config-prettier": "^9.0.0",
55
55
  "eslint-plugin-prettier": "^5.0.1",
56
56
  "eslint-plugin-simple-import-sort": "^10.0.0",
@@ -60,7 +60,7 @@
60
60
  "npm-run-all": "^4.1.5",
61
61
  "prettier": "^3.0.3",
62
62
  "typescript": "~5.2.2",
63
- "vite": "^4.4.11",
63
+ "vite": "^4.5.0",
64
64
  "vitest": "^0.34.6",
65
65
  "vue-tsc": "^1.8.19"
66
66
  }
@@ -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"