mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
Add filter software by CVE and make osquery-perf also push vulnerable software (#3902)
* Add filter software by CVE and make osquery-perf also push vulnerable software * Update based on review comments
This commit is contained in:
parent
99468ff477
commit
e956b0ba04
1
changes/issue-2998-software-cve-search
Normal file
1
changes/issue-2998-software-cve-search
Normal file
@ -0,0 +1 @@
|
||||
* Add filter software by CVE
|
@ -26,6 +26,32 @@ import (
|
||||
//go:embed *.tmpl
|
||||
var templatesFS embed.FS
|
||||
|
||||
//go:embed *.software
|
||||
var softwareFS embed.FS
|
||||
|
||||
var vulnerableSoftware []fleet.Software
|
||||
|
||||
func init() {
|
||||
vulnerableSoftwareData, err := softwareFS.ReadFile("vulnerable.software")
|
||||
if err != nil {
|
||||
log.Fatal("reading vulnerable software file: ", err)
|
||||
}
|
||||
lines := bytes.Split(vulnerableSoftwareData, []byte("\n"))
|
||||
for _, line := range lines {
|
||||
parts := bytes.Split(line, []byte("##"))
|
||||
if len(parts) < 2 {
|
||||
fmt.Println("skipping", string(line))
|
||||
continue
|
||||
}
|
||||
vulnerableSoftware = append(vulnerableSoftware, fleet.Software{
|
||||
Name: string(parts[0]),
|
||||
Version: string(parts[1]),
|
||||
Source: "apps",
|
||||
})
|
||||
}
|
||||
log.Printf("Loaded %d vulnerable software\n", len(vulnerableSoftware))
|
||||
}
|
||||
|
||||
type Stats struct {
|
||||
errors int
|
||||
enrollments int
|
||||
@ -120,7 +146,7 @@ func (n *nodeKeyManager) Add(nodekey string) {
|
||||
|
||||
type agent struct {
|
||||
agentIndex int
|
||||
softwareCount entityCount
|
||||
softwareCount softwareEntityCount
|
||||
userCount entityCount
|
||||
policyPassProb float64
|
||||
strings map[string]string
|
||||
@ -146,10 +172,15 @@ type entityCount struct {
|
||||
unique int
|
||||
}
|
||||
|
||||
type softwareEntityCount struct {
|
||||
entityCount
|
||||
vulnerable int
|
||||
}
|
||||
|
||||
func newAgent(
|
||||
agentIndex int,
|
||||
serverAddress, enrollSecret string, templates *template.Template,
|
||||
configInterval, queryInterval time.Duration, softwareCount, userCount entityCount,
|
||||
configInterval, queryInterval time.Duration, softwareCount softwareEntityCount, userCount entityCount,
|
||||
policyPassProb float64,
|
||||
) *agent {
|
||||
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
@ -386,7 +417,12 @@ func (a *agent) SoftwareMacOS() []fleet.Software {
|
||||
Source: "osquery-perf",
|
||||
}
|
||||
}
|
||||
randomVulnerableSoftware := make([]fleet.Software, a.softwareCount.vulnerable)
|
||||
for i := 0; i < len(randomVulnerableSoftware); i++ {
|
||||
randomVulnerableSoftware[i] = vulnerableSoftware[rand.Intn(len(vulnerableSoftware))]
|
||||
}
|
||||
software := append(commonSoftware, uniqueSoftware...)
|
||||
software = append(software, randomVulnerableSoftware...)
|
||||
rand.Shuffle(len(software), func(i, j int) {
|
||||
software[i], software[j] = software[j], software[i]
|
||||
})
|
||||
@ -575,6 +611,7 @@ func main() {
|
||||
nodeKeyFile := flag.String("node_key_file", "", "File with node keys to use")
|
||||
commonSoftwareCount := flag.Int("common_software_count", 10, "Number of common of installed applications reported to fleet")
|
||||
uniqueSoftwareCount := flag.Int("unique_software_count", 10, "Number of unique installed applications reported to fleet")
|
||||
vulnerableSoftwareCount := flag.Int("vulnerable_software_count", 10, "Number of vulnerable installed applications reported to fleet")
|
||||
commonUserCount := flag.Int("common_user_count", 10, "Number of common host users reported to fleet")
|
||||
uniqueUserCount := flag.Int("unique_user_count", 10, "Number of unique host users reported to fleet")
|
||||
policyPassProb := flag.Float64("policy_pass_prob", 1.0, "Probability of policies to pass [0, 1]")
|
||||
@ -602,9 +639,12 @@ func main() {
|
||||
}
|
||||
|
||||
for i := 0; i < *hostCount; i++ {
|
||||
a := newAgent(i+1, *serverURL, *enrollSecret, tmpl, *configInterval, *queryInterval, entityCount{
|
||||
a := newAgent(i+1, *serverURL, *enrollSecret, tmpl, *configInterval, *queryInterval, softwareEntityCount{
|
||||
entityCount: entityCount{
|
||||
common: *commonSoftwareCount,
|
||||
unique: *uniqueSoftwareCount,
|
||||
},
|
||||
vulnerable: *vulnerableSoftwareCount,
|
||||
}, entityCount{
|
||||
common: *commonUserCount,
|
||||
unique: *uniqueUserCount,
|
||||
|
108
cmd/osquery-perf/vulnerable.software
Normal file
108
cmd/osquery-perf/vulnerable.software
Normal file
@ -0,0 +1,108 @@
|
||||
monal##4.9
|
||||
flash_player##10.3.183.90
|
||||
office##2021
|
||||
meetings##5.8.0
|
||||
kinza##5.0.1
|
||||
insync##6.8.0
|
||||
last.fm_desktop##2.1.39
|
||||
ipvanish##3.0.11
|
||||
galaxy##1.2.54
|
||||
autocad##2022
|
||||
globalprotect##5.1.2
|
||||
malwarebytes##4.0
|
||||
wing_ftp_server##6.2.3
|
||||
wd_discovery##4.0.251.0
|
||||
intercept_x##9.10.1
|
||||
safe##17.7
|
||||
edgerover##1.5.0-576
|
||||
fusion##8.5
|
||||
true_image##2021
|
||||
internet_security##21.1
|
||||
knox##2.2.0
|
||||
remote_desktop##10.6.7
|
||||
1password##7.2.3
|
||||
canvas_draw##5.0.0
|
||||
arq##5.9
|
||||
parallels_desktop##16.5.0
|
||||
windscribe##2.02.9
|
||||
zoom##4.6.9
|
||||
connect##3.2.7
|
||||
armorlock##1.4.1
|
||||
home##10.0.3
|
||||
photoline##20.53
|
||||
vpn_universal_secure_enterprise_client##2.02
|
||||
nordvpn##3.3.10
|
||||
wire##3.9.2943
|
||||
proxifier##3.5
|
||||
pulse_secure_desktop_client##9.0r1
|
||||
liquidvpn##1.37
|
||||
forticlient##7.0.1
|
||||
endpoint_security##10.7.5
|
||||
royal_tsx##3.3
|
||||
realone_player##9.0.0.297
|
||||
anyconnect_secure_mobility_client##4.9.03047
|
||||
macos##9
|
||||
office_long_term_servicing_channel##2021
|
||||
remotepc##7.6.9
|
||||
norton_security##13.0.1
|
||||
macos_server##5.11
|
||||
zoom_plugin_for_microsoft_outlook##5.7.6.76
|
||||
rumpus##8.2.14
|
||||
kanaka##2.8
|
||||
dashlane##6.5.0
|
||||
anti-virus_for_sophos_home##2.2.6
|
||||
origin##10.5.86
|
||||
outlook##2016
|
||||
proxyman##1.9.3
|
||||
forklift##3.4
|
||||
vpn_universal_secure_entry_client##2.02
|
||||
realplayer##12.0.1.1738
|
||||
foxmail##1.2
|
||||
purevpn##6.0.1
|
||||
hipchat##4.30
|
||||
jabber##12.9\(3\)
|
||||
quicken_2018##5.2.2
|
||||
shimo##4.1.5.1
|
||||
evernote##8.3.2
|
||||
vtune_profiler##2020
|
||||
hide.me##3.3.0
|
||||
visual_studio_2019##8.9
|
||||
mcafee_agent##5.6.6
|
||||
antivirus##9.0
|
||||
maxthon_browser##5.1.46
|
||||
renderman##22.3.0
|
||||
install_norton_security##7.6
|
||||
line##4.3.1
|
||||
nextcloud##2.7.0
|
||||
zenmate##1.5.4
|
||||
anti-virus_for_sophos_central##9.9.6
|
||||
ibackup##3.3.1.5
|
||||
join.me##3.9.0.11823
|
||||
ni-pal##20.0.1
|
||||
privatevpn##2.0.31
|
||||
cyber_security##6.8.300.0
|
||||
malion##5.2.1
|
||||
endpoint_protection##14
|
||||
ubridge##0.9.9
|
||||
vyprvpn##3.0
|
||||
skype##8.59.0.77
|
||||
sourcetree##3.1
|
||||
hugo##0.9
|
||||
excel##2019
|
||||
password_manager##5.0.1073
|
||||
cactusvpn##6.5.0
|
||||
spectrum_protect_client##8.1.6
|
||||
horizon##5.2.0
|
||||
airmail_3##3.5.9
|
||||
viscosity##1.4.1
|
||||
switchvpn##2.1012.03
|
||||
pcoip_soft_client##20.10.1
|
||||
keybase##2.12.6
|
||||
backblaze##7.0.1.434
|
||||
hisuite##9.1.0.312
|
||||
anydesk##6.1.0
|
||||
swoole##1.6.7
|
||||
stashcat##3.9.2
|
||||
endpoint_antivirus##6.8.1.0
|
||||
webex_meetings##40.1.8.5
|
||||
autocad_lt##2022
|
@ -5947,7 +5947,7 @@ Transforms a host name into a host id. For example, the Fleet UI use this endpoi
|
||||
| per_page | integer | query | Results per page. |
|
||||
| order_key | string | query | What to order results by. Can be ordered by the following fields: `name`, `hosts_count`. Defaults to the hosts count, descending. |
|
||||
| order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include `asc` and `desc`. Default if not provided is `asc`. |
|
||||
| query | string | query | Search query keywords. Searchable fields include `name`. |
|
||||
| query | string | query | Search query keywords. Searchable fields include `name`, `version`, and `cve`. |
|
||||
| team_id | integer | query | _Available in Fleet Premium_ Filters the software to only include the software installed on the hosts that are assigned to the specified team. |
|
||||
| vulnerable | bool | query | If true or 1, only list software that has detected vulnerabilities |
|
||||
|
||||
|
@ -267,16 +267,6 @@ func selectSoftwareSQL(hostID *uint, opts fleet.SoftwareListOptions) (string, []
|
||||
).Where(goqu.I("h.team_id").Eq(opts.TeamID))
|
||||
}
|
||||
|
||||
if match := opts.MatchQuery; match != "" {
|
||||
match = likePattern(match)
|
||||
ds = ds.Where(
|
||||
goqu.Or(
|
||||
goqu.I("s.name").ILike(match),
|
||||
goqu.I("s.version").ILike(match),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
ds = ds.GroupBy(
|
||||
goqu.I("s.id"),
|
||||
goqu.I("s.name"),
|
||||
@ -304,6 +294,23 @@ func selectSoftwareSQL(hostID *uint, opts fleet.SoftwareListOptions) (string, []
|
||||
goqu.I("s.id").Eq(goqu.I("scp.software_id")),
|
||||
),
|
||||
)
|
||||
if opts.MatchQuery != "" {
|
||||
ds = ds.LeftJoin(
|
||||
goqu.I("software_cve").As("scv"),
|
||||
goqu.On(goqu.I("scp.id").Eq(goqu.I("scv.cpe_id"))),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if match := opts.MatchQuery; match != "" {
|
||||
match = likePattern(match)
|
||||
ds = ds.Where(
|
||||
goqu.Or(
|
||||
goqu.I("s.name").ILike(match),
|
||||
goqu.I("s.version").ILike(match),
|
||||
goqu.I("scv.cve").ILike(match),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if opts.WithHostCounts {
|
||||
|
@ -452,6 +452,24 @@ func testSoftwareList(t *testing.T, ds *Datastore) {
|
||||
test.ElementsMatchSkipID(t, software, expected)
|
||||
})
|
||||
|
||||
t.Run("filters specific cves", func(t *testing.T) {
|
||||
software := listSoftwareCheckCount(t, ds, 1, 1, fleet.SoftwareListOptions{ListOptions: fleet.ListOptions{MatchQuery: "cve-321-432-543"}}, true)
|
||||
expected := []fleet.Software{foo001}
|
||||
test.ElementsMatchSkipID(t, software, expected)
|
||||
|
||||
software = listSoftwareCheckCount(t, ds, 1, 1, fleet.SoftwareListOptions{ListOptions: fleet.ListOptions{MatchQuery: "cve-333-444-555"}}, true)
|
||||
expected = []fleet.Software{foo001}
|
||||
test.ElementsMatchSkipID(t, software, expected)
|
||||
|
||||
// partial cve
|
||||
software = listSoftwareCheckCount(t, ds, 1, 1, fleet.SoftwareListOptions{ListOptions: fleet.ListOptions{MatchQuery: "333-444"}}, true)
|
||||
expected = []fleet.Software{foo001}
|
||||
test.ElementsMatchSkipID(t, software, expected)
|
||||
|
||||
// unknown CVE
|
||||
listSoftwareCheckCount(t, ds, 0, 0, fleet.SoftwareListOptions{ListOptions: fleet.ListOptions{MatchQuery: "cve-000-000-000"}}, true)
|
||||
})
|
||||
|
||||
t.Run("filters by query", func(t *testing.T) {
|
||||
// query by name (case insensitive)
|
||||
software := listSoftwareCheckCount(t, ds, 1, 1, fleet.SoftwareListOptions{ListOptions: fleet.ListOptions{MatchQuery: "baR"}}, true)
|
||||
|
Loading…
Reference in New Issue
Block a user