-
Notifications
You must be signed in to change notification settings - Fork 174
Expand file tree
/
Copy pathcommon.go
More file actions
82 lines (70 loc) · 2.36 KB
/
common.go
File metadata and controls
82 lines (70 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package mitre
import (
"embed"
"encoding/json"
"github.com/pkg/errors"
"github.com/stackrox/rox/generated/storage"
)
const (
mitreBundleFile = "files/mitre.json"
)
var (
//go:embed files/mitre.json
mitreFS embed.FS
)
// GetMitreBundle returns MITRE ATT&CK bundle.
func GetMitreBundle() (*storage.MitreAttackBundle, error) {
bytes, err := mitreFS.ReadFile(mitreBundleFile)
if err != nil {
return nil, errors.Wrapf(err, "could not load MITRE ATT&CK data from %q", mitreBundleFile)
}
var bundle storage.MitreAttackBundle
if err := json.Unmarshal(bytes, &bundle); err != nil {
return nil, errors.Wrapf(err, "parsing MITRE ATT&CK data loaded from %q", mitreBundleFile)
}
return &bundle, nil
}
// FlattenMitreMatrices flattens multiple matrices such as container, network, etc. into one enterprise matrix.
// For example,
//
// matrix1: tactic1: technique1, technique2
// matrix2: tactic1: technique2; tactic2: technique3
// result:
// tactic1: technique1, technique2; tactic2: technique3
func FlattenMitreMatrices(matrices ...*storage.MitreAttackMatrix) []*storage.MitreAttackVector {
tactics := make(map[string]*storage.MitreTactic)
techniques := make(map[string]*storage.MitreTechnique)
tacticsTechniques := make(map[string]map[string]struct{})
for _, matrix := range matrices {
for _, vector := range matrix.GetVectors() {
tacticID := vector.GetTactic().GetId()
if tactics[tacticID] == nil {
tactics[tacticID] = vector.GetTactic()
}
if tacticsTechniques[tacticID] == nil {
tacticsTechniques[tacticID] = make(map[string]struct{})
}
for _, technique := range vector.GetTechniques() {
if techniques[technique.GetId()] == nil {
techniques[technique.GetId()] = technique
}
if _, ok := tacticsTechniques[tacticID][technique.GetId()]; ok {
techniques[technique.GetId()] = technique
}
tacticsTechniques[tacticID][technique.GetId()] = struct{}{}
}
}
}
vectors := make([]*storage.MitreAttackVector, 0, len(tactics))
for tacticID, techniqueIDs := range tacticsTechniques {
techniquesForTactics := make([]*storage.MitreTechnique, 0, len(techniqueIDs))
for techniqueID := range techniqueIDs {
techniquesForTactics = append(techniquesForTactics, techniques[techniqueID])
}
vectors = append(vectors, &storage.MitreAttackVector{
Tactic: tactics[tacticID],
Techniques: techniquesForTactics,
})
}
return vectors
}