Skip to content

Commit 0ff73ad

Browse files
committed
chore: fix go mod
1 parent 2aa954b commit 0ff73ad

File tree

5 files changed

+132
-144
lines changed

5 files changed

+132
-144
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ falcon:
4949
min_cve_base_score: 0
5050
# the CVEs you want to ignore
5151
skip_cves: ["CVE-2019-15315"]
52+
# the minimum exprtAI severity you want to filter for
53+
min_exprtai_severity: medium
5254

5355
# vmware workspace one
5456
ws1:

config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type Config struct {
3030
SkipSeverities []string `yaml:"skip_severities" env:"FALCON_SKIP_SEVERITIES"`
3131
MinCVEBaseScore int `yaml:"min_cve_base_score" env:"FALCON_MIN_CVE_BASE_SCORE"`
3232
SkipCVEs []string `yaml:"skip_cves" env:"FALCON_SKIP_CVES"`
33+
MinExprtAISeverity string `yaml:"min_exprtai_severity" env:"FALCON_MIN_EXPRTAI_SEVERITYs"`
3334
} `yaml:"falcon"`
3435

3536
WS1 struct {

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/hazcod/crowdstrike-spotlight-slacker
33
go 1.16
44

55
require (
6-
github.com/crowdstrike/gofalcon v0.2.12
6+
github.com/crowdstrike/gofalcon v0.2.14-0.20211026142948-62733f384b4d
77
github.com/kelseyhightower/envconfig v1.4.0
88
github.com/pkg/errors v0.9.1
99
github.com/sirupsen/logrus v1.8.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
5656
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
5757
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
5858
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
59-
github.com/crowdstrike/gofalcon v0.2.12 h1:Y2CFPTz8LLb0ky1eWc6orBzL1pY+a39m9V8R6vziiME=
60-
github.com/crowdstrike/gofalcon v0.2.12/go.mod h1:cnJxuFcSaHBJJRTASY+BRhsUXaJku2JOURUjihHxwLo=
59+
github.com/crowdstrike/gofalcon v0.2.14-0.20211026142948-62733f384b4d h1:7xkFSX7JX4v2LqGqzuTyrwoWCco2OrdMrcifVHmfRyM=
60+
github.com/crowdstrike/gofalcon v0.2.14-0.20211026142948-62733f384b4d/go.mod h1:cnJxuFcSaHBJJRTASY+BRhsUXaJku2JOURUjihHxwLo=
6161
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6262
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
6363
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

pkg/falcon/extractor.go

Lines changed: 126 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ type UserDeviceFinding struct {
4040
Mitigations []string
4141
}
4242

43-
func getUniqueDeviceID(hostInfo models.DomainAPIVulnerabilityHostInfoV2) (string, error) {
43+
func getUniqueDeviceID(hostInfo models.DomainAPIVulnerabilityHostFacetV2) (string, error) {
4444
b, err := json.Marshal(&hostInfo)
4545
if err != nil {
4646
return "", err
@@ -118,11 +118,21 @@ func appendUnique(main, adder []string) []string {
118118
return main
119119
}
120120

121-
func remove(a []string, i int) []string {
122-
a[i] = a[len(a)-1] // Copy last element to index i.
123-
a[len(a)-1] = "" // Erase last element (write zero value).
124-
a = a[:len(a)-1] // Truncate slice.
125-
return a
121+
func getSeverityScore(severity string) (int, error) {
122+
switch strings.TrimSpace(strings.ToLower(severity)) {
123+
case "":
124+
return 0, nil
125+
case "low":
126+
return 0, nil
127+
case "medium":
128+
return 1, nil
129+
case "high":
130+
return 2, nil
131+
case "critical":
132+
return 3, nil
133+
}
134+
135+
return -1, errors.New("unknown severity: " + severity)
126136
}
127137

128138
func GetMessages(config *config.Config, ctx context.Context) (results map[string]FalconResult, err error) {
@@ -140,11 +150,12 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
140150
return nil, errors.Wrap(err, "could not initialize Falcon client")
141151
}
142152

143-
queryResult, err := client.SpotlightVulnerabilities.QueryVulnerabilities(
144-
&spotlight_vulnerabilities.QueryVulnerabilitiesParams{
153+
queryResult, err := client.SpotlightVulnerabilities.CombinedQueryVulnerabilities(
154+
&spotlight_vulnerabilities.CombinedQueryVulnerabilitiesParams{
145155
Context: ctx,
146156
Filter: "status:'open'",
147157
Limit: &falconAPIMaxRecords,
158+
Facet: []string{"host_info", "cve", "remediation"},
148159
},
149160
)
150161
if err != nil {
@@ -155,137 +166,148 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
155166
return nil, errors.New("QueryVulnerabilities result was nil")
156167
}
157168

158-
var vulnIDs []string
159-
vulnIDs = append(vulnIDs, queryResult.GetPayload().Resources...)
160-
161-
if len(vulnIDs) == 0 {
162-
return results, nil
163-
}
164-
165-
logrus.WithField("vulns", len(vulnIDs)).Info("found vulnerabilities")
166-
167-
getResult, err := client.SpotlightVulnerabilities.GetVulnerabilities(
168-
&spotlight_vulnerabilities.GetVulnerabilitiesParams{
169-
Ids: vulnIDs,
170-
Context: context.Background(),
171-
},
172-
)
173-
if err != nil || getResult == nil {
174-
return nil, errors.Wrap(err, "could not get Falcon vulnerabilities")
175-
}
176-
177-
if len(getResult.GetPayload().Resources) != len(vulnIDs) {
178-
logrus.Warn("result payload not as large as vuln list")
179-
}
180-
181169
var hostTags []string
182170
devices := map[string]UserDevice{}
183171

184-
var mitigationIDs []string
185-
186-
for _, vuln := range getResult.GetPayload().Resources {
172+
minExpertAIScore := 0
173+
if newScore, err := getSeverityScore(config.Falcon.MinExprtAISeverity); err != nil {
174+
return nil, errors.Wrap(err, "unknown minimum exprtai severity specified")
175+
} else { minExpertAIScore = newScore }
187176

188-
if len(vuln.Remediation.Ids) == 0 && config.Falcon.SkipNoMitigation {
189-
logrus.WithField("app", *vuln.App.ProductNameVersion).
190-
Debug("skipping vulnerability without remediation")
177+
for _, vuln := range queryResult.GetPayload().Resources {
191178

179+
if vuln.Apps == nil {
192180
continue
193181
}
194182

195-
if *vuln.Cve.ID != "" && len(config.Falcon.SkipCVEs) > 0 {
196-
vulnIgnore := false
183+
for _, vulnApp := range vuln.Apps {
197184

198-
for _, cve := range config.Falcon.SkipCVEs {
199-
if strings.EqualFold(cve, *vuln.Cve.ID) {
200-
vulnIgnore = true
201-
break
202-
}
203-
}
185+
if (vulnApp.Remediation == nil || len(vulnApp.Remediation.Ids) == 0) && config.Falcon.SkipNoMitigation {
186+
logrus.WithField("rem", fmt.Sprintf("%+v", vulnApp.Remediation)).Debug("rem")
187+
188+
logrus.WithField("app", vulnApp.ProductNameVersion).
189+
Debug("skipping vulnerability without remediation")
204190

205-
if vulnIgnore {
206-
logrus.WithField("cve", *vuln.Cve.ID).WithField("host", *vuln.HostInfo.Hostname).
207-
Warn("skipping CVE")
208191
continue
209192
}
210-
}
211193

212-
mitigationIDs = appendUnique(mitigationIDs, vuln.Remediation.Ids)
194+
if *vuln.Cve.ID != "" && len(config.Falcon.SkipCVEs) > 0 {
195+
vulnIgnore := false
213196

214-
uniqueDeviceID, err := getUniqueDeviceID(*vuln.HostInfo)
215-
if err != nil {
216-
logrus.WithError(err).Error("could not calculate unique device id")
197+
for _, cve := range config.Falcon.SkipCVEs {
198+
if strings.EqualFold(cve, *vuln.Cve.ID) {
199+
vulnIgnore = true
200+
break
201+
}
202+
}
217203

218-
continue
219-
}
204+
if vulnIgnore {
205+
logrus.WithField("cve", *vuln.Cve.ID).
206+
WithField("host", *vuln.HostInfo.Hostname).
207+
Warn("skipping CVE")
208+
continue
209+
}
210+
}
211+
212+
uniqueDeviceID, err := getUniqueDeviceID(*vuln.HostInfo)
213+
if err != nil {
214+
logrus.WithError(err).Error("could not calculate unique device id")
220215

221-
if config.Falcon.MinCVEBaseScore > 0 {
222-
if int(*vuln.Cve.BaseScore) < config.Falcon.MinCVEBaseScore {
223-
logrus.WithField("cve_score", *vuln.Cve.BaseScore).Debug("skipping vulnerability")
224216
continue
225217
}
226-
}
227218

228-
if len(config.Falcon.SkipSeverities) > 0 {
229-
vulnSev := strings.ToLower(*vuln.Cve.Severity)
230-
skip := false
219+
if config.Falcon.MinCVEBaseScore > 0 {
220+
if int(vuln.Cve.BaseScore) < config.Falcon.MinCVEBaseScore {
221+
logrus.WithField("cve_score", vuln.Cve.BaseScore).Debug("skipping vulnerability")
222+
continue
223+
}
224+
}
231225

232-
for _, sev := range config.Falcon.SkipSeverities {
233-
if strings.EqualFold(sev, vulnSev) {
234-
logrus.WithField("host", *vuln.HostInfo.Hostname).WithField("cve_score", *vuln.Cve.BaseScore).
235-
WithField("severity", *vuln.Cve.Severity).WithField("cve", *vuln.Cve.ID).
236-
Debug("skipping vulnerability")
237-
skip = true
238-
break
226+
if config.Falcon.MinExprtAISeverity != "" {
227+
vulnExpertAISevScore, err := getSeverityScore(config.Falcon.MinExprtAISeverity)
228+
if err != nil {
229+
logrus.WithField("exprtai_score", vuln.Cve.ExprtRating).WithError(err).
230+
Error("unknown exprtai score")
231+
} else {
232+
if vulnExpertAISevScore < minExpertAIScore {
233+
logrus.WithField("min_exprtai_severity", config.Falcon.MinExprtAISeverity).
234+
WithField("exprtai_severity", vuln.Cve.ExprtRating).Debug("skipping vulnerability")
235+
continue
236+
}
239237
}
240238
}
241239

242-
if skip { continue }
243-
}
240+
if len(config.Falcon.SkipSeverities) > 0 {
241+
vulnSev := strings.ToLower(vuln.Cve.Severity)
242+
skip := false
243+
244+
for _, sev := range config.Falcon.SkipSeverities {
245+
if strings.EqualFold(sev, vulnSev) {
246+
logrus.WithField("host", *vuln.HostInfo.Hostname).WithField("cve_score", vuln.Cve.BaseScore).
247+
WithField("severity", vuln.Cve.Severity).WithField("cve", *vuln.Cve.ID).
248+
Debug("skipping vulnerability")
249+
skip = true
250+
break
251+
}
252+
}
253+
254+
if skip {
255+
continue
256+
}
257+
}
244258

245-
logrus.WithField("host", *vuln.HostInfo.Hostname).WithField("cve_score", *vuln.Cve.BaseScore).
246-
WithField("severity", *vuln.Cve.Severity).WithField("cve", *vuln.Cve.ID).
247-
Debug("adding vulnerability")
259+
logrus.WithField("host", *vuln.HostInfo.Hostname).WithField("cve_score", vuln.Cve.BaseScore).
260+
WithField("severity", vuln.Cve.Severity).WithField("cve", *vuln.Cve.ID).
261+
Debug("adding vulnerability")
248262

249-
deviceFinding := UserDeviceFinding{
250-
ProductName: *vuln.App.ProductNameVersion,
251-
CveID: *vuln.Cve.ID,
252-
CveSeverity: *vuln.Cve.Severity,
253-
TimestampFound: *vuln.CreatedTimestamp,
254-
Mitigations: vuln.Remediation.Ids,
255-
}
263+
deviceFinding := UserDeviceFinding{
264+
ProductName: *vulnApp.ProductNameVersion,
265+
CveID: *vuln.Cve.ID,
266+
CveSeverity: vuln.Cve.Severity,
267+
TimestampFound: *vuln.CreatedTimestamp,
268+
}
256269

257-
if _, ok := devices[uniqueDeviceID]; !ok {
258-
devices[uniqueDeviceID] = UserDevice{
259-
MachineName: fmt.Sprintf(
260-
"%s %s",
261-
*vuln.HostInfo.OsVersion,
262-
*vuln.HostInfo.Hostname,
263-
),
264-
Tags: vuln.HostInfo.Tags,
265-
Findings: []UserDeviceFinding{},
270+
for _, mitigation := range vuln.Remediation.Entities {
271+
if strings.HasPrefix(strings.ToLower(*mitigation.Action), "no fix available for ") {
272+
continue
273+
}
274+
275+
deviceFinding.Mitigations = appendUnique(deviceFinding.Mitigations, []string{*mitigation.Action})
276+
}
277+
278+
if _, ok := devices[uniqueDeviceID]; !ok {
279+
devices[uniqueDeviceID] = UserDevice{
280+
MachineName: fmt.Sprintf(
281+
"%s %s",
282+
*vuln.HostInfo.OsVersion,
283+
*vuln.HostInfo.Hostname,
284+
),
285+
Tags: vuln.HostInfo.Tags,
286+
Findings: []UserDeviceFinding{},
287+
}
266288
}
267-
}
268289

269-
device := devices[uniqueDeviceID]
290+
device := devices[uniqueDeviceID]
270291

271-
findingExists := false
292+
findingExists := false
272293

273-
for _, finding := range device.Findings {
274-
if strings.EqualFold(finding.ProductName, deviceFinding.ProductName) {
275-
findingExists = true
276-
break
294+
for _, finding := range device.Findings {
295+
if strings.EqualFold(finding.ProductName, deviceFinding.ProductName) {
296+
findingExists = true
297+
break
298+
}
277299
}
278-
}
279300

280-
if !findingExists {
281-
device.Findings = append(device.Findings, deviceFinding)
282-
}
301+
if !findingExists {
302+
device.Findings = append(device.Findings, deviceFinding)
303+
}
283304

284-
device.Tags = appendUnique(device.Tags, vuln.HostInfo.Tags)
305+
device.Tags = appendUnique(device.Tags, vuln.HostInfo.Tags)
285306

286-
devices[uniqueDeviceID] = device
307+
devices[uniqueDeviceID] = device
287308

288-
hostTags = append(hostTags, device.Tags...)
309+
hostTags = append(hostTags, device.Tags...)
310+
}
289311
}
290312

291313
if len(devices) == 0 {
@@ -296,43 +318,6 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
296318
return nil, errors.New("no tags found on decices")
297319
}
298320

299-
logrus.WithField("remediations", len(mitigationIDs)).Debug("retrieving remediations")
300-
301-
remResp, err := client.SpotlightVulnerabilities.GetRemediationsV2(&spotlight_vulnerabilities.GetRemediationsV2Params{
302-
Ids: mitigationIDs,
303-
Context: ctx,
304-
})
305-
306-
if err != nil {
307-
return nil, errors.Wrap(err, "could not retrieve remediations")
308-
}
309-
310-
remediations := make(map[string]string)
311-
312-
for _, remRes := range remResp.GetPayload().Resources {
313-
logrus.Tracef("%s -> %s", *remRes.ID, *remRes.Action)
314-
remediations[*remRes.ID] = *remRes.Action
315-
}
316-
317-
// remove useless mitigations that start with 'no fix available for'
318-
for a, device := range devices {
319-
for b, finding := range device.Findings {
320-
for c, rem := range finding.Mitigations {
321-
remText, remFound := remediations[rem]
322-
323-
if !remFound || strings.HasPrefix(strings.ToLower(remText), "no fix available for") {
324-
logrus.WithField("rem", rem).WithField("rem_text", remText).WithField("device", device.MachineName).
325-
Warn("skipping mitigation")
326-
327-
devices[a].Findings[b].Mitigations = remove(finding.Mitigations, c)
328-
continue
329-
}
330-
331-
finding.Mitigations[c] = remText
332-
}
333-
}
334-
}
335-
336321
logrus.WithField("devices", len(devices)).Info("found vulnerable devices")
337322

338323
for _, device := range devices {

0 commit comments

Comments
 (0)