66 "encoding/hex"
77 "encoding/json"
88 "fmt"
9+ "github.com/crowdstrike/gofalcon/falcon/client/hosts"
910 "github.com/pkg/errors"
1011 "strings"
1112
@@ -19,6 +20,7 @@ import (
1920const (
2021 tagEmailPrefix = "email/"
2122 tagFalconPrefix = "FalconGroupingTags/"
23+ tagSensorPrefix = "SensorGroupingTags/"
2224)
2325
2426type FalconResult struct {
@@ -27,17 +29,18 @@ type FalconResult struct {
2729}
2830
2931type UserDevice struct {
32+ Hostname string
3033 MachineName string
3134 Tags []string
3235 Findings []UserDeviceFinding
3336}
3437
3538type UserDeviceFinding struct {
36- ProductName string
37- CveID string
38- CveSeverity string
39- TimestampFound string
40- Mitigations []string
39+ ProductName string
40+ CveID string
41+ CveSeverity string
42+ TimestampFound string
43+ Mitigations []string
4144}
4245
4346func getUniqueDeviceID (hostInfo models.DomainAPIVulnerabilityHostFacetV2 ) (string , error ) {
@@ -56,6 +59,7 @@ func findEmailTag(tags []string, emailDomains []string) (email string, err error
5659 for _ , tag := range tags {
5760 tag = strings .ToLower (tag )
5861 tag = strings .TrimPrefix (tag , strings .ToLower (tagFalconPrefix ))
62+ tag = strings .TrimPrefix (tag , strings .ToLower (tagSensorPrefix ))
5963
6064 logrus .WithField ("tag" , tag ).Trace ("looking at falcon tag" )
6165
@@ -75,7 +79,7 @@ func findEmailTag(tags []string, emailDomains []string) (email string, err error
7579 for _ , domain := range emailDomains {
7680 encodedDomain := strings .ToLower (strings .ReplaceAll (domain , "." , "/" ))
7781
78- if ! strings .HasSuffix (email , encodedDomain ) {
82+ if ! strings .HasSuffix (email , encodedDomain ) {
7983 continue
8084 }
8185
@@ -110,7 +114,9 @@ func appendUnique(main, adder []string) []string {
110114 }
111115 }
112116
113- if found { continue }
117+ if found {
118+ continue
119+ }
114120
115121 main = append (main , adder [i ])
116122 }
@@ -135,7 +141,7 @@ func getSeverityScore(severity string) (int, error) {
135141 return - 1 , errors .New ("unknown severity: " + severity )
136142}
137143
138- func GetMessages (config * config.Config , ctx context.Context ) (results map [string ]FalconResult , err error ) {
144+ func GetMessages (config * config.Config , ctx context.Context ) (results map [string ]FalconResult , usersWithSensors [] string , err error ) {
139145 falconAPIMaxRecords := int64 (400 )
140146
141147 results = map [string ]FalconResult {}
@@ -147,31 +153,62 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
147153 Context : ctx ,
148154 })
149155 if err != nil {
150- return nil , errors .Wrap (err , "could not initialize Falcon client" )
156+ return nil , nil , errors .Wrap (err , "could not initialize Falcon client" )
157+ }
158+
159+ hostResult , err := client .Hosts .QueryDevicesByFilter (
160+ & hosts.QueryDevicesByFilterParams {
161+ Filter : nil ,
162+ Limit : & falconAPIMaxRecords ,
163+ Offset : nil ,
164+ Sort : nil ,
165+ Context : ctx ,
166+ },
167+ )
168+ if err != nil {
169+ return nil , nil , errors .Wrap (err , "could not query all hosts" )
170+ }
171+
172+ hostDetail , err := client .Hosts .GetDeviceDetails (& hosts.GetDeviceDetailsParams {
173+ Ids : hostResult .Payload .Resources ,
174+ Context : ctx ,
175+ HTTPClient : nil ,
176+ })
177+ if err != nil {
178+ return nil , nil , errors .Wrap (err , "could not query all host details" )
179+ }
180+
181+ for _ , detail := range hostDetail .Payload .Resources {
182+ email , err := findEmailTag (detail .Tags , config .Email .Domains )
183+ if err != nil || email == "" {
184+ email = "_NOTAG/" + detail .Hostname
185+ }
186+
187+ usersWithSensors = append (usersWithSensors , strings .ToLower (email ))
151188 }
152189
153190 queryResult , err := client .SpotlightVulnerabilities .CombinedQueryVulnerabilities (
154191 & spotlight_vulnerabilities.CombinedQueryVulnerabilitiesParams {
155192 Context : ctx ,
156193 Filter : "status:'open'" ,
157194 Limit : & falconAPIMaxRecords ,
158- Facet : []string {"host_info" , "cve" , "remediation" },
195+ Facet : []string {"host_info" , "cve" , "remediation" },
159196 },
160197 )
161198 if err != nil {
162- return nil , errors .Wrap (err , "could not query vulnerabilities" )
199+ return nil , nil , errors .Wrap (err , "could not query vulnerabilities" )
163200 }
164201
165202 if queryResult == nil {
166- return nil , errors .New ("QueryVulnerabilities result was nil" )
203+ return nil , nil , errors .New ("QueryVulnerabilities result was nil" )
167204 }
168205
169206 var hostTags []string
170207 devices := map [string ]UserDevice {}
171208
172209 minExpertAIScore := 0
173210 if newScore , err := getSeverityScore (config .Falcon .MinExprtAISeverity ); err != nil {
174- return nil , errors .Wrap (err , "unknown minimum exprtai severity specified" )
211+ return nil , nil , errors .Wrap (err , "unknown minimum exprtai severity specified" )
175212 } else {
176213 minExpertAIScore = newScore
177214 }
@@ -279,6 +316,7 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
279316
280317 if _ , ok := devices [uniqueDeviceID ]; ! ok {
281318 devices [uniqueDeviceID ] = UserDevice {
319+ Hostname : * vuln .HostInfo .Hostname ,
282320 MachineName : fmt .Sprintf (
283321 "%s %s" ,
284322 * vuln .HostInfo .OsVersion ,
@@ -313,11 +351,11 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
313351 }
314352
315353 if len (devices ) == 0 {
316- return results , nil
354+ return results , nil , nil
317355 }
318356
319357 if len (hostTags ) == 0 {
320- return nil , errors .New ("no tags found on decices" )
358+ return nil , nil , errors .New ("no tags found on decices" )
321359 }
322360
323361 logrus .WithField ("devices" , len (devices )).Info ("found vulnerable devices" )
@@ -335,7 +373,7 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
335373 }
336374 }
337375
338- if ! hasMitigations {
376+ if ! hasMitigations {
339377 logrus .WithField ("device" , device .MachineName ).
340378 Debug ("skipping device with vulnerabilities but no mitigations" )
341379 continue
@@ -366,5 +404,5 @@ func GetMessages(config *config.Config, ctx context.Context) (results map[string
366404 results [userEmail ] = user
367405 }
368406
369- return results , nil
407+ return results , usersWithSensors , nil
370408}
0 commit comments