mihari 5.3.1 → 5.3.2
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/frontend/package-lock.json +538 -581
- data/frontend/package.json +21 -21
- data/frontend/src/ace-config.ts +6 -0
- data/frontend/src/components/alert/Form.vue +2 -2
- data/frontend/src/components/rule/EditRule.vue +3 -2
- data/frontend/src/components/rule/Form.vue +2 -2
- data/frontend/src/components/rule/InputForm.vue +18 -59
- data/frontend/src/components/rule/YAML.vue +21 -28
- data/frontend/src/views/Artifact.vue +3 -8
- data/frontend/src/views/EditRule.vue +2 -7
- data/frontend/src/views/Rule.vue +3 -8
- data/lib/mihari/analyzers/base.rb +6 -0
- data/lib/mihari/analyzers/binaryedge.rb +1 -1
- data/lib/mihari/analyzers/censys.rb +1 -1
- data/lib/mihari/analyzers/onyphe.rb +1 -1
- data/lib/mihari/analyzers/rule.rb +4 -7
- data/lib/mihari/analyzers/shodan.rb +1 -1
- data/lib/mihari/analyzers/urlscan.rb +1 -1
- data/lib/mihari/analyzers/virustotal_intelligence.rb +1 -1
- data/lib/mihari/analyzers/zoomeye.rb +2 -2
- data/lib/mihari/commands/rule.rb +3 -3
- data/lib/mihari/commands/search.rb +3 -3
- data/lib/mihari/constants.rb +3 -0
- data/lib/mihari/emitters/base.rb +2 -2
- data/lib/mihari/emitters/misp.rb +3 -3
- data/lib/mihari/emitters/slack.rb +1 -1
- data/lib/mihari/emitters/the_hive.rb +1 -1
- data/lib/mihari/emitters/webhook.rb +1 -1
- data/lib/mihari/mixins/configurable.rb +5 -0
- data/lib/mihari/mixins/falsepositive.rb +1 -1
- data/lib/mihari/mixins/retriable.rb +0 -2
- data/lib/mihari/{structs → services}/rule.rb +16 -16
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/endpoints/rules.rb +9 -8
- data/lib/mihari/web/public/assets/index-116033d0.js +1737 -0
- data/lib/mihari/web/public/assets/index-33165282.css +1 -0
- data/lib/mihari/web/public/assets/mode-yaml-a21faa53.js +8 -0
- data/lib/mihari/web/public/index.html +2 -2
- data/lib/mihari.rb +3 -2
- data/mihari.gemspec +5 -4
- metadata +62 -18
- data/lib/mihari/web/public/assets/index-b17c40c6.css +0 -1
- data/lib/mihari/web/public/assets/index-f740e4f9.js +0 -799
data/frontend/package.json
CHANGED
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@fortawesome/fontawesome-svg-core": "^6.4.
|
|
18
|
-
"@fortawesome/free-solid-svg-icons": "^6.4.
|
|
17
|
+
"@fortawesome/fontawesome-svg-core": "^6.4.2",
|
|
18
|
+
"@fortawesome/free-solid-svg-icons": "^6.4.2",
|
|
19
19
|
"@fortawesome/vue-fontawesome": "^3.0.3",
|
|
20
|
-
"@vueuse/core": "^10.
|
|
21
|
-
"@vueuse/router": "^10.
|
|
20
|
+
"@vueuse/core": "^10.3.0",
|
|
21
|
+
"@vueuse/router": "^10.3.0",
|
|
22
|
+
"ace-builds": "^1.23.4",
|
|
22
23
|
"axios": "^1.4.0",
|
|
23
24
|
"bulma": "^0.9.4",
|
|
24
25
|
"bulma-helpers": "^0.4.3",
|
|
@@ -32,36 +33,35 @@
|
|
|
32
33
|
"vue": "^3.3.4",
|
|
33
34
|
"vue-concurrency": "4.0.1",
|
|
34
35
|
"vue-json-pretty": "^2.2.4",
|
|
35
|
-
"vue-
|
|
36
|
-
"
|
|
36
|
+
"vue-router": "^4.2.4",
|
|
37
|
+
"vue3-ace-editor": "^2.2.3"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
|
-
"@redocly/cli": "
|
|
40
|
+
"@redocly/cli": "1.0.0",
|
|
40
41
|
"@rushstack/eslint-patch": "^1.3.2",
|
|
41
|
-
"@tsconfig/node20": "^1.
|
|
42
|
+
"@tsconfig/node20": "^20.1.1",
|
|
42
43
|
"@types/jsdom": "^21.1.1",
|
|
43
|
-
"@types/node": "^20.4.
|
|
44
|
-
"@types/prismjs": "^1.26.0",
|
|
44
|
+
"@types/node": "^20.4.8",
|
|
45
45
|
"@types/url-parse": "^1.4.8",
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
47
|
-
"@typescript-eslint/parser": "^6.
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
|
47
|
+
"@typescript-eslint/parser": "^6.2.1",
|
|
48
48
|
"@vitejs/plugin-vue": "^4.2.3",
|
|
49
|
-
"@vue/eslint-config-prettier": "^
|
|
49
|
+
"@vue/eslint-config-prettier": "^8.0.0",
|
|
50
50
|
"@vue/eslint-config-typescript": "^11.0.3",
|
|
51
|
-
"@vue/test-utils": "2.4.
|
|
51
|
+
"@vue/test-utils": "2.4.1",
|
|
52
52
|
"@vue/tsconfig": "^0.4.0",
|
|
53
|
-
"eslint": "^8.
|
|
54
|
-
"eslint-config-prettier": "^
|
|
53
|
+
"eslint": "^8.46.0",
|
|
54
|
+
"eslint-config-prettier": "^9.0.0",
|
|
55
55
|
"eslint-plugin-prettier": "^5.0.0",
|
|
56
56
|
"eslint-plugin-simple-import-sort": "^10.0.0",
|
|
57
|
-
"eslint-plugin-vue": "^9.
|
|
57
|
+
"eslint-plugin-vue": "^9.16.1",
|
|
58
58
|
"husky": "^8.0.3",
|
|
59
59
|
"jsdom": "^22.1.0",
|
|
60
60
|
"npm-run-all": "^4.1.5",
|
|
61
|
-
"prettier": "^3.0.
|
|
61
|
+
"prettier": "^3.0.1",
|
|
62
62
|
"typescript": "~5.1.6",
|
|
63
|
-
"vite": "^4.4.
|
|
64
|
-
"vitest": "^0.
|
|
65
|
-
"vue-tsc": "^1.8.
|
|
63
|
+
"vite": "^4.4.9",
|
|
64
|
+
"vitest": "^0.34.1",
|
|
65
|
+
"vue-tsc": "^1.8.8"
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import ace from "ace-builds"
|
|
2
|
+
import modeYamlUrl from "ace-builds/src-min-noconflict/mode-yaml?url"
|
|
3
|
+
import themeMonokaiUrl from "ace-builds/src-min-noconflict/theme-monokai?url"
|
|
4
|
+
|
|
5
|
+
ace.config.setModuleUrl("ace/mode/yaml", modeYamlUrl)
|
|
6
|
+
ace.config.setModuleUrl("ace/theme/monokai", themeMonokaiUrl)
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
</template>
|
|
96
96
|
|
|
97
97
|
<script lang="ts">
|
|
98
|
-
import { defineComponent, type PropType, ref, watch } from "vue"
|
|
98
|
+
import { defineComponent, type PropType, ref, toRef,watch } from "vue"
|
|
99
99
|
import { useRoute } from "vue-router"
|
|
100
100
|
|
|
101
101
|
import type { AlertSearchParams } from "@/types"
|
|
@@ -126,7 +126,7 @@ export default defineComponent({
|
|
|
126
126
|
|
|
127
127
|
const artifact = ref<string | undefined>(undefined)
|
|
128
128
|
const fromAt = ref<string | undefined>(undefined)
|
|
129
|
-
const tagInput =
|
|
129
|
+
const tagInput = toRef(props, "tag")
|
|
130
130
|
const ruleId = ref<string | undefined>(undefined)
|
|
131
131
|
const toAt = ref<string | undefined>(undefined)
|
|
132
132
|
const asn = ref<number | undefined>(undefined)
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
</template>
|
|
24
24
|
|
|
25
25
|
<script lang="ts">
|
|
26
|
-
import { defineComponent, type PropType,
|
|
26
|
+
import { defineComponent, type PropType, toRef } from "vue"
|
|
27
27
|
import { useRouter } from "vue-router"
|
|
28
28
|
|
|
29
29
|
import { generateUpdateRuleTask } from "@/api-helper"
|
|
@@ -46,7 +46,8 @@ export default defineComponent({
|
|
|
46
46
|
setup(props) {
|
|
47
47
|
const router = useRouter()
|
|
48
48
|
|
|
49
|
-
const
|
|
49
|
+
const rule = toRef(props, "rule")
|
|
50
|
+
const yaml = toRef(rule.value, "yaml")
|
|
50
51
|
|
|
51
52
|
const updateRuleTask = generateUpdateRuleTask()
|
|
52
53
|
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
</template>
|
|
89
89
|
|
|
90
90
|
<script lang="ts">
|
|
91
|
-
import { defineComponent, type PropType, ref, watch } from "vue"
|
|
91
|
+
import { defineComponent, type PropType, ref, toRef,watch } from "vue"
|
|
92
92
|
import { useRoute } from "vue-router"
|
|
93
93
|
|
|
94
94
|
import type { RuleSearchParams } from "@/types"
|
|
@@ -115,7 +115,7 @@ export default defineComponent({
|
|
|
115
115
|
|
|
116
116
|
const description = ref<string | undefined>(undefined)
|
|
117
117
|
const fromAt = ref<string | undefined>(undefined)
|
|
118
|
-
const tagInput =
|
|
118
|
+
const tagInput = toRef(props, "tag")
|
|
119
119
|
const title = ref<string | undefined>(undefined)
|
|
120
120
|
const toAt = ref<string | undefined>(undefined)
|
|
121
121
|
|
|
@@ -1,31 +1,29 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="block
|
|
3
|
-
<
|
|
4
|
-
class="
|
|
5
|
-
v-model="yamlInput"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
<div class="block">
|
|
3
|
+
<VAceEditor
|
|
4
|
+
class="vue-ace-editor"
|
|
5
|
+
v-model:value="yamlInput"
|
|
6
|
+
lang="yaml"
|
|
7
|
+
theme="monokai"
|
|
8
|
+
:options="{
|
|
9
|
+
fontSize: 16,
|
|
10
|
+
minLines: 6,
|
|
11
|
+
maxLines: 10000
|
|
12
|
+
}"
|
|
13
|
+
></VAceEditor>
|
|
9
14
|
</div>
|
|
10
15
|
</template>
|
|
11
16
|
|
|
12
17
|
<script lang="ts">
|
|
13
|
-
|
|
14
|
-
import "vue-prism-editor/dist/prismeditor.min.css"
|
|
18
|
+
import "@/ace-config"
|
|
15
19
|
|
|
16
|
-
import { defineComponent,
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
import Prism from "prismjs"
|
|
20
|
-
|
|
21
|
-
import "prismjs/components/prism-yaml"
|
|
22
|
-
import "prismjs/plugins/custom-class/prism-custom-class"
|
|
23
|
-
import "prismjs/themes/prism-twilight.css"
|
|
20
|
+
import { defineComponent, toRef, watchEffect } from "vue"
|
|
21
|
+
import { VAceEditor } from "vue3-ace-editor"
|
|
24
22
|
|
|
25
23
|
export default defineComponent({
|
|
26
24
|
name: "RuleInputForm",
|
|
27
25
|
components: {
|
|
28
|
-
|
|
26
|
+
VAceEditor
|
|
29
27
|
},
|
|
30
28
|
props: {
|
|
31
29
|
yaml: {
|
|
@@ -35,52 +33,13 @@ export default defineComponent({
|
|
|
35
33
|
},
|
|
36
34
|
emits: ["update-yaml"],
|
|
37
35
|
setup(props, context) {
|
|
38
|
-
const yamlInput =
|
|
39
|
-
const wrapper = ref<HTMLElement | undefined>(undefined)
|
|
40
|
-
|
|
41
|
-
Prism.plugins.customClass.map({
|
|
42
|
-
number: "prism-number",
|
|
43
|
-
tag: "prism-tag"
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
const highlighter = (code: string) => {
|
|
47
|
-
return Prism.highlight(code, Prism.languages.yaml, "yaml")
|
|
48
|
-
}
|
|
36
|
+
const yamlInput = toRef(props, "yaml")
|
|
49
37
|
|
|
50
38
|
watchEffect(() => {
|
|
51
39
|
context.emit("update-yaml", yamlInput.value)
|
|
52
|
-
|
|
53
|
-
// TODO: a dirty hack to change the default text color
|
|
54
|
-
if (wrapper.value) {
|
|
55
|
-
const strings = wrapper.value.querySelectorAll(":not(span.token)")
|
|
56
|
-
strings.forEach((string) => {
|
|
57
|
-
;(string as HTMLElement).style.color = "white"
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
40
|
})
|
|
61
41
|
|
|
62
|
-
return { yamlInput
|
|
42
|
+
return { yamlInput }
|
|
63
43
|
}
|
|
64
44
|
})
|
|
65
45
|
</script>
|
|
66
|
-
|
|
67
|
-
<style scoped>
|
|
68
|
-
.my-editor {
|
|
69
|
-
background: hsl(0, 0%, 8%);
|
|
70
|
-
font-family:
|
|
71
|
-
Fira code,
|
|
72
|
-
Fira Mono,
|
|
73
|
-
Consolas,
|
|
74
|
-
Menlo,
|
|
75
|
-
Courier,
|
|
76
|
-
monospace;
|
|
77
|
-
font-size: 1em;
|
|
78
|
-
line-height: 1.5;
|
|
79
|
-
padding: 5px;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.my-editor-wrapper {
|
|
83
|
-
background: hsl(0, 0%, 8%);
|
|
84
|
-
padding: 10px;
|
|
85
|
-
}
|
|
86
|
-
</style>
|
|
@@ -1,44 +1,37 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<div class="block">
|
|
3
|
+
<VAceEditor
|
|
4
|
+
class="vue-ace-editor"
|
|
5
|
+
:value="yaml"
|
|
6
|
+
lang="yaml"
|
|
7
|
+
theme="monokai"
|
|
8
|
+
:options="{
|
|
9
|
+
readOnly: true,
|
|
10
|
+
fontSize: 16,
|
|
11
|
+
maxLines: 10000,
|
|
12
|
+
minLines: 6
|
|
13
|
+
}"
|
|
14
|
+
></VAceEditor>
|
|
15
|
+
</div>
|
|
3
16
|
</template>
|
|
4
17
|
|
|
5
18
|
<script lang="ts">
|
|
6
|
-
|
|
7
|
-
import { defineComponent, onMounted, ref } from "vue"
|
|
19
|
+
import "@/ace-config"
|
|
8
20
|
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
import "prismjs/components/prism-yaml"
|
|
12
|
-
import "prismjs/plugins/custom-class/prism-custom-class"
|
|
13
|
-
import "prismjs/plugins/line-numbers/prism-line-numbers.css"
|
|
14
|
-
import "prismjs/plugins/line-numbers/prism-line-numbers"
|
|
15
|
-
import "prismjs/themes/prism-twilight.css"
|
|
21
|
+
import { defineComponent } from "vue"
|
|
22
|
+
import { VAceEditor } from "vue3-ace-editor"
|
|
16
23
|
|
|
17
24
|
export default defineComponent({
|
|
18
25
|
name: "YAML",
|
|
26
|
+
components: {
|
|
27
|
+
VAceEditor
|
|
28
|
+
},
|
|
19
29
|
props: {
|
|
20
30
|
yaml: {
|
|
21
31
|
type: String,
|
|
22
32
|
required: true
|
|
23
33
|
}
|
|
24
34
|
},
|
|
25
|
-
setup() {
|
|
26
|
-
const pre = ref<HTMLElement | undefined>(undefined)
|
|
27
|
-
|
|
28
|
-
Prism.plugins.customClass.map({
|
|
29
|
-
number: "prism-number",
|
|
30
|
-
tag: "prism-tag"
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
onMounted(() => {
|
|
34
|
-
if (pre.value) {
|
|
35
|
-
pre.value.querySelectorAll("code").forEach((elem) => {
|
|
36
|
-
Prism.highlightElement(elem)
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
return { pre }
|
|
42
|
-
}
|
|
35
|
+
setup() {}
|
|
43
36
|
})
|
|
44
37
|
</script>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Artifact :id="
|
|
2
|
+
<Artifact :id="id"></Artifact>
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
5
|
<script lang="ts">
|
|
6
6
|
import { useTitle } from "@vueuse/core"
|
|
7
|
-
import { defineComponent, onMounted,
|
|
7
|
+
import { defineComponent, onMounted, watch } from "vue"
|
|
8
8
|
|
|
9
9
|
import Artifact from "@/components/artifact/ArtifactWrapper.vue"
|
|
10
10
|
|
|
@@ -20,10 +20,8 @@ export default defineComponent({
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
setup(props) {
|
|
23
|
-
const artifactId = ref<string>(props.id)
|
|
24
|
-
|
|
25
23
|
const updateTitle = () => {
|
|
26
|
-
useTitle(`Artifact:${
|
|
24
|
+
useTitle(`Artifact:${props.id} - Mihari`)
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
onMounted(() => {
|
|
@@ -33,12 +31,9 @@ export default defineComponent({
|
|
|
33
31
|
watch(
|
|
34
32
|
() => props.id,
|
|
35
33
|
() => {
|
|
36
|
-
artifactId.value = props.id
|
|
37
34
|
updateTitle()
|
|
38
35
|
}
|
|
39
36
|
)
|
|
40
|
-
|
|
41
|
-
return { artifactId }
|
|
42
37
|
}
|
|
43
38
|
})
|
|
44
39
|
</script>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<script lang="ts">
|
|
6
6
|
import { useTitle } from "@vueuse/core"
|
|
7
|
-
import { defineComponent, onMounted,
|
|
7
|
+
import { defineComponent, onMounted, watch } from "vue"
|
|
8
8
|
|
|
9
9
|
import EditRule from "@/components/rule/EditRuleWrapper.vue"
|
|
10
10
|
|
|
@@ -20,10 +20,8 @@ export default defineComponent({
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
setup(props) {
|
|
23
|
-
const ruleId = ref<string>(props.id)
|
|
24
|
-
|
|
25
23
|
const updateTitle = () => {
|
|
26
|
-
useTitle(`Edit rule:${
|
|
24
|
+
useTitle(`Edit rule:${props.id} - Mihari`)
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
onMounted(() => {
|
|
@@ -33,12 +31,9 @@ export default defineComponent({
|
|
|
33
31
|
watch(
|
|
34
32
|
() => props.id,
|
|
35
33
|
() => {
|
|
36
|
-
ruleId.value = props.id
|
|
37
34
|
updateTitle()
|
|
38
35
|
}
|
|
39
36
|
)
|
|
40
|
-
|
|
41
|
-
return { ruleId }
|
|
42
37
|
}
|
|
43
38
|
})
|
|
44
39
|
</script>
|
data/frontend/src/views/Rule.vue
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Rule :id="
|
|
2
|
+
<Rule :id="id"></Rule>
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
5
|
<script lang="ts">
|
|
6
6
|
import { useTitle } from "@vueuse/core"
|
|
7
|
-
import { defineComponent, onMounted,
|
|
7
|
+
import { defineComponent, onMounted, watch } from "vue"
|
|
8
8
|
|
|
9
9
|
import Rule from "@/components/rule/RuleWrapper.vue"
|
|
10
10
|
|
|
@@ -20,10 +20,8 @@ export default defineComponent({
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
setup(props) {
|
|
23
|
-
const ruleId = ref<string>(props.id)
|
|
24
|
-
|
|
25
23
|
const updateTitle = () => {
|
|
26
|
-
useTitle(`Rule:${
|
|
24
|
+
useTitle(`Rule:${props.id} - Mihari`)
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
onMounted(() => {
|
|
@@ -33,12 +31,9 @@ export default defineComponent({
|
|
|
33
31
|
watch(
|
|
34
32
|
() => props.id,
|
|
35
33
|
() => {
|
|
36
|
-
ruleId.value = props.id
|
|
37
34
|
updateTitle()
|
|
38
35
|
}
|
|
39
36
|
)
|
|
40
|
-
|
|
41
|
-
return { ruleId }
|
|
42
37
|
}
|
|
43
38
|
})
|
|
44
39
|
</script>
|
|
@@ -37,14 +37,14 @@ module Mihari
|
|
|
37
37
|
class Rule
|
|
38
38
|
include Mixins::FalsePositive
|
|
39
39
|
|
|
40
|
-
# @return [Mihari::
|
|
40
|
+
# @return [Mihari::Services::Rule]
|
|
41
41
|
attr_reader :rule
|
|
42
42
|
|
|
43
43
|
# @return [Time]
|
|
44
44
|
attr_reader :base_time
|
|
45
45
|
|
|
46
46
|
#
|
|
47
|
-
# @param [Mihari::
|
|
47
|
+
# @param [Mihari::Services::Rule] rule
|
|
48
48
|
#
|
|
49
49
|
def initialize(rule)
|
|
50
50
|
@rule = rule
|
|
@@ -146,11 +146,8 @@ module Mihari
|
|
|
146
146
|
def falsepositive?(value)
|
|
147
147
|
return true if rule.falsepositives.include?(value)
|
|
148
148
|
|
|
149
|
-
rule.falsepositives.select
|
|
150
|
-
|
|
151
|
-
end.any? do |falseposistive|
|
|
152
|
-
falseposistive.match?(value)
|
|
153
|
-
end
|
|
149
|
+
regexps = rule.falsepositives.select { |fp| fp.is_a?(Regexp) }
|
|
150
|
+
regexps.any? { |fp| fp.match?(value) }
|
|
154
151
|
end
|
|
155
152
|
|
|
156
153
|
#
|
|
@@ -60,7 +60,7 @@ module Mihari
|
|
|
60
60
|
break if res.total <= page * PAGE_SIZE
|
|
61
61
|
|
|
62
62
|
# sleep #{interval} seconds to avoid the rate limitation (if it is set)
|
|
63
|
-
|
|
63
|
+
sleep_interval
|
|
64
64
|
rescue JSON::ParserError
|
|
65
65
|
# ignore JSON::ParserError
|
|
66
66
|
# ref. https://github.com/ninoseki/mihari/issues/197
|
|
@@ -104,7 +104,7 @@ module Mihari
|
|
|
104
104
|
break if total <= page * PAGE_SIZE
|
|
105
105
|
|
|
106
106
|
# sleep #{interval} seconds to avoid the rate limitation (if it is set)
|
|
107
|
-
|
|
107
|
+
sleep_interval
|
|
108
108
|
end
|
|
109
109
|
convert_responses responses.compact
|
|
110
110
|
end
|
|
@@ -137,7 +137,7 @@ module Mihari
|
|
|
137
137
|
break if total <= page * PAGE_SIZE
|
|
138
138
|
|
|
139
139
|
# sleep #{interval} seconds to avoid the rate limitation (if it is set)
|
|
140
|
-
|
|
140
|
+
sleep_interval
|
|
141
141
|
end
|
|
142
142
|
convert_responses responses.compact
|
|
143
143
|
end
|
data/lib/mihari/commands/rule.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Mihari
|
|
|
15
15
|
# @param [String] path
|
|
16
16
|
#
|
|
17
17
|
def validate(path)
|
|
18
|
-
rule =
|
|
18
|
+
rule = Services::Rule.from_path_or_id(path)
|
|
19
19
|
|
|
20
20
|
begin
|
|
21
21
|
rule.validate!
|
|
@@ -44,10 +44,10 @@ module Mihari
|
|
|
44
44
|
|
|
45
45
|
no_commands do
|
|
46
46
|
#
|
|
47
|
-
# @return [Mihari::
|
|
47
|
+
# @return [Mihari::Services::Rule]
|
|
48
48
|
#
|
|
49
49
|
def rule_template
|
|
50
|
-
|
|
50
|
+
Services::Rule.from_path File.expand_path("../templates/rule.yml.erb", __dir__)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
#
|
|
@@ -33,12 +33,12 @@ module Mihari
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def update_or_create
|
|
36
|
-
rule.
|
|
36
|
+
rule.to_model.save
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def run
|
|
40
40
|
begin
|
|
41
|
-
analyzer = rule.
|
|
41
|
+
analyzer = rule.to_analyzer
|
|
42
42
|
rescue ConfigurationError => e
|
|
43
43
|
# if there is a configuration error, output that error without the stack trace
|
|
44
44
|
Mihari.logger.error e.to_s
|
|
@@ -69,7 +69,7 @@ module Mihari
|
|
|
69
69
|
#
|
|
70
70
|
def search(path_or_id)
|
|
71
71
|
Mihari::Database.with_db_connection do
|
|
72
|
-
rule =
|
|
72
|
+
rule = Services::Rule.from_path_or_id path_or_id
|
|
73
73
|
|
|
74
74
|
begin
|
|
75
75
|
rule.validate!
|
data/lib/mihari/constants.rb
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Mihari
|
|
4
|
+
# @return [Array<String>]
|
|
4
5
|
DEFAULT_DATA_TYPES = %w[hash ip domain url mail].freeze
|
|
5
6
|
|
|
7
|
+
# @return [Array<Hash>]
|
|
6
8
|
DEFAULT_EMITTERS = %w[database misp slack the_hive].map { |name| { emitter: name } }.freeze
|
|
7
9
|
|
|
10
|
+
# @return [Array<Hash>]
|
|
8
11
|
DEFAULT_ENRICHERS = %w[whois ipinfo shodan google_public_dns].map { |name| { enricher: name } }.freeze
|
|
9
12
|
|
|
10
13
|
DEFAULT_RETRY_TIMES = 3
|
data/lib/mihari/emitters/base.rb
CHANGED
|
@@ -9,12 +9,12 @@ module Mihari
|
|
|
9
9
|
# @return [Array<Mihari::Artifact>]
|
|
10
10
|
attr_reader :artifacts
|
|
11
11
|
|
|
12
|
-
# @return [Mihari::
|
|
12
|
+
# @return [Mihari::Services::Rule]
|
|
13
13
|
attr_reader :rule
|
|
14
14
|
|
|
15
15
|
#
|
|
16
16
|
# @param [Array<Mihari::Artifact>] artifacts
|
|
17
|
-
# @param [Mihari::
|
|
17
|
+
# @param [Mihari::Services::Rule] rule
|
|
18
18
|
# @param [Hash] **_options
|
|
19
19
|
#
|
|
20
20
|
def initialize(artifacts:, rule:, **_options)
|
data/lib/mihari/emitters/misp.rb
CHANGED
|
@@ -12,12 +12,12 @@ module Mihari
|
|
|
12
12
|
# @return [Array<Mihari::Artifact>]
|
|
13
13
|
attr_reader :artifacts
|
|
14
14
|
|
|
15
|
-
# @return [Mihari::
|
|
15
|
+
# @return [Mihari::Services::Rule]
|
|
16
16
|
attr_reader :rule
|
|
17
17
|
|
|
18
18
|
#
|
|
19
19
|
# @param [Array<Mihari::Artifact>] artifacts
|
|
20
|
-
# @param [Mihari::
|
|
20
|
+
# @param [Mihari::Services::Rule] rule
|
|
21
21
|
# @param [Hash] **options
|
|
22
22
|
#
|
|
23
23
|
def initialize(artifacts:, rule:, **options)
|
|
@@ -47,7 +47,7 @@ module Mihari
|
|
|
47
47
|
# Create a MISP event
|
|
48
48
|
#
|
|
49
49
|
# @param [Arra<Mihari::Artifact>] artifacts
|
|
50
|
-
# @param [Mihari::
|
|
50
|
+
# @param [Mihari::Services::Rule] rule
|
|
51
51
|
#
|
|
52
52
|
# @return [::MISP::Event]
|
|
53
53
|
#
|