Skip to content

Commit 867d6ea

Browse files
authored
Merge pull request #21 from hazcod/work/commandbot
Feature: skip useless remediations
2 parents cdeeb00 + 3d43c9e commit 867d6ea

File tree

3 files changed

+75
-14
lines changed

3 files changed

+75
-14
lines changed

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.7
6+
github.com/crowdstrike/gofalcon v0.2.8-0.20210820094121-3d82431e1d1d
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: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,17 @@ github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:o
4747
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg=
4848
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
4949
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
50+
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
51+
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
5052
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
5153
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
5254
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
5355
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
5456
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
5557
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
5658
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
57-
github.com/crowdstrike/gofalcon v0.2.7 h1:aijfM6rg3Y+baE0DIk8F2bAMfieG7BPn2o3vNtVsUY4=
58-
github.com/crowdstrike/gofalcon v0.2.7/go.mod h1:tM+/b9HnHhJxysZmpn2ZXDfv1F4r4VSp6tFdCao/3Gw=
59+
github.com/crowdstrike/gofalcon v0.2.8-0.20210820094121-3d82431e1d1d h1:DdkvCbHPUv2eMT4x2L5E5IIEOjQcP0UrfdI7vuZO6VQ=
60+
github.com/crowdstrike/gofalcon v0.2.8-0.20210820094121-3d82431e1d1d/go.mod h1:iM8EsSSjQZECYz8NS+QTpGcAMBU2keFzUMRA8rXAOVQ=
5961
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6062
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
6163
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -119,8 +121,8 @@ github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g
119121
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
120122
github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
121123
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
122-
github.com/go-openapi/runtime v0.19.29 h1:5IIvCaIDbxetN674vX9eOxvoZ9mYGQ16fV1Q0VSG+NA=
123-
github.com/go-openapi/runtime v0.19.29/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
124+
github.com/go-openapi/runtime v0.19.30 h1:bVDeSf4HU9EMth+lHD1EthaHe1SFoUVPaUvQtkGS9g8=
125+
github.com/go-openapi/runtime v0.19.30/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
124126
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
125127
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
126128
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=

pkg/falcon/extractor.go

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ type UserDeviceFinding struct {
3636
ProductName string
3737
CveID string
3838
CveSeverity string
39-
MitigationAvailable bool
4039
TimestampFound string
40+
Mitigations []string
4141
}
4242

4343
func getUniqueDeviceID(hostInfo models.DomainAPIVulnerabilityHostInfoV2) (string, error) {
@@ -118,6 +118,13 @@ 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
126+
}
127+
121128
func GetMessages(config *config.Config, ctx context.Context) (results map[string]FalconResult, err error) {
122129
falconAPIMaxRecords := int64(400)
123130

@@ -174,6 +181,8 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
174181
var hostTags []string
175182
devices := map[string]UserDevice{}
176183

184+
var mitigationIDs []string
185+
177186
for _, vuln := range getResult.GetPayload().Resources {
178187

179188
if len(vuln.Remediation.Ids) == 0 && config.Falcon.SkipNoMitigation {
@@ -200,6 +209,8 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
200209
}
201210
}
202211

212+
mitigationIDs = appendUnique(mitigationIDs, vuln.Remediation.Ids)
213+
203214
uniqueDeviceID, err := getUniqueDeviceID(*vuln.HostInfo)
204215
if err != nil {
205216
logrus.WithError(err).Error("could not calculate unique device id")
@@ -239,15 +250,8 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
239250
ProductName: *vuln.App.ProductNameVersion,
240251
CveID: *vuln.Cve.ID,
241252
CveSeverity: *vuln.Cve.Severity,
242-
MitigationAvailable: len(vuln.Remediation.Ids) > 0,
243253
TimestampFound: *vuln.CreatedTimestamp,
244-
}
245-
246-
if !deviceFinding.MitigationAvailable {
247-
logrus.WithField("cve",*vuln.Cve.ID).WithField("severity", *vuln.Cve.Severity).
248-
WithField("product", *vuln.App.ProductNameVersion).
249-
Warn("skipping finding without mitigation(s)")
250-
continue
254+
Mitigations: vuln.Remediation.Ids,
251255
}
252256

253257
if _, ok := devices[uniqueDeviceID]; !ok {
@@ -292,9 +296,64 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
292296
return nil, errors.New("no tags found on decices")
293297
}
294298

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+
295336
logrus.WithField("devices", len(devices)).Info("found vulnerable devices")
296337

297338
for _, device := range devices {
339+
if len(device.Findings) == 0 {
340+
continue
341+
}
342+
343+
hasMitigations := false
344+
for _, f := range device.Findings {
345+
if len(f.Mitigations) > 0 {
346+
hasMitigations = true
347+
break
348+
}
349+
}
350+
351+
if !hasMitigations{
352+
logrus.WithField("device", device.MachineName).
353+
Debug("skipping device with vulnerabilities but no mitigations")
354+
continue
355+
}
356+
298357
userEmail, err := findEmailTag(device.Tags, config.Email.Domains)
299358
if err != nil {
300359
logrus.

0 commit comments

Comments
 (0)