From 1e2b93d55b84aa1ff73f4a0af9a69df736304c47 Mon Sep 17 00:00:00 2001 From: Kota Kanbe Date: Fri, 14 Oct 2016 19:58:08 +0900 Subject: [PATCH] Support ignore CveIDs in config --- README.ja.md | 40 ++++++++++++++++++++++++++++++++++++++++ README.md | 43 ++++++++++++++++++++++++++++++++++++++++++- commands/discover.go | 2 ++ config/config.go | 2 ++ config/tomlloader.go | 15 ++++++++++++++- models/models.go | 1 + report/slack.go | 3 --- scan/base.go | 27 ++++++++++++++++++++++++--- 8 files changed, 125 insertions(+), 8 deletions(-) diff --git a/README.ja.md b/README.ja.md index 3978d60730..8b398ff043 100644 --- a/README.ja.md +++ b/README.ja.md @@ -469,6 +469,7 @@ host = "172.31.4.82" # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #containers = ["${running}"] + #ignoreCves = ["CVE-2016-6313"] #optional = [ # ["key", "value"], #] @@ -488,6 +489,7 @@ host = "172.31.4.82" # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #containers = ["${running}"] + #ignoreCves = ["CVE-2016-6314"] #optional = [ # ["key", "value"], #] @@ -502,6 +504,7 @@ host = "172.31.4.82" - keyPath: SSH private key path - cpeNames: see [Usage: Scan vulnerability of non-OS package](https://github.com/future-architect/vuls/blob/master/README.ja.md#usage-scan-vulnerability-of-non-os-package) - containers: see [Usage: Scan Docker containers](https://github.com/future-architect/vuls/blob/master/README.ja.md#usage-scan-docker-containers) + - ignoreCves: CVE IDs that will not be reported. But output to JSON file. - optional: JSONレポートに含めたい追加情報 @@ -782,6 +785,43 @@ $ vuls scan \ -azure-container=vuls ``` +## Example: IgnoreCves + +Slack, Mail, テキスト出力しないくないCVE IDがある場合は、設定ファイルに定義することでレポートされなくなる。 +ただ、JSONファイルには以下のように出力される。 + +- config.toml +```toml +[default] +ignoreCves = ["CVE-2016-6313"] + +[servers.bsd] +host = "192.168.11.11" +user = "kanbe" +ignoreCves = ["CVE-2016-6314"] +``` + +- bsd.json +```json +[ + { + "ServerName": "bsd", + "Family": "FreeBSD", + "Release": "10.3-RELEASE", + "IgnoredCves" : { + "CveDetail" : { + "CVE-2016-6313", + ... + }, + "CveDetail" : { + "CVE-2016-6314", + ... + }, + } + } +] +``` + ## Example: Add optional key-value pairs to JSON 追加情報をJSONに含めることができる。 diff --git a/README.md b/README.md index efe0996650..18980be35c 100644 --- a/README.md +++ b/README.md @@ -389,6 +389,7 @@ subjectPrefix = "[vuls]" # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #containers = ["${running}"] +#ignoreCves = ["CVE-2016-6313"] #optional = [ # ["key", "value"], #] @@ -404,6 +405,7 @@ host = "172.31.4.82" # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #containers = ["${running}"] +#ignoreCves = ["CVE-2016-6313"] #optional = [ # ["key", "value"], #] @@ -476,6 +478,7 @@ You can customize your configuration using this template. # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #containers = ["${running}"] + #ignoreCves = ["CVE-2016-6313"] #optional = [ # ["key", "value"], #] @@ -495,6 +498,7 @@ You can customize your configuration using this template. # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #containers = ["${running}"] + #ignoreCves = ["CVE-2016-6314"] #optional = [ # ["key", "value"], #] @@ -508,6 +512,7 @@ You can customize your configuration using this template. - keyPath: SSH private key path - cpeNames: see [Usage: Scan vulnerability of non-OS package](https://github.com/future-architect/vuls#usage-scan-vulnerability-of-non-os-package) - containers: see [Usage: Scan Docker containers](https://github.com/future-architect/vuls#usage-scan-docker-containers) + - ignoreCves: CVE IDs that will not be reported. But output to JSON file. - optional: Add additional information to JSON report. Vuls supports two types of SSH. One is native go implementation. The other is external SSH command. For details, see [-ssh-external option](https://github.com/future-architect/vuls#-ssh-external-option) @@ -780,6 +785,43 @@ $ vuls scan \ -azure-container=vuls ``` +## Example: IgnoreCves + +Define ignoreCves in config if you don't want to report(slack, mail, text...) specific CVE IDs. But these ignoreCves will be output to JSON file like below. + +- config.toml +```toml +[default] +ignoreCves = ["CVE-2016-6313"] + +[servers.bsd] +host = "192.168.11.11" +user = "kanbe" +ignoreCves = ["CVE-2016-6314"] +``` + +- bsd.json +```json +[ + { + "ServerName": "bsd", + "Family": "FreeBSD", + "Release": "10.3-RELEASE", + "IgnoredCves" : { + "CveDetail" : { + "CVE-2016-6313", + ... + }, + "CveDetail" : { + "CVE-2016-6314", + ... + }, + } + } +] +``` + + ## Example: Add optional key-value pairs to JSON Optional key-value can be outputted to JSON. @@ -1097,4 +1139,3 @@ Please see [CHANGELOG](https://github.com/future-architect/vuls/blob/master/CHAN # License Please see [LICENSE](https://github.com/future-architect/vuls/blob/master/LICENSE). - diff --git a/commands/discover.go b/commands/discover.go index 92d147cd67..cf9111c03d 100644 --- a/commands/discover.go +++ b/commands/discover.go @@ -116,6 +116,7 @@ subjectPrefix = "[vuls]" # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #containers = ["${running}"] +#ignoreCves = ["CVE-2014-6271"] #optional = [ # ["key", "value"], #] @@ -132,6 +133,7 @@ host = "{{$ip}}" # "cpe:/a:rubyonrails:ruby_on_rails:4.2.1", #] #containers = ["${running}"] +#ignoreCves = ["CVE-2014-0160"] #optional = [ # ["key", "value"], #] diff --git a/config/config.go b/config/config.go index 93c3dffabd..6cd6141ebc 100644 --- a/config/config.go +++ b/config/config.go @@ -233,6 +233,8 @@ type ServerInfo struct { // Container Names or IDs Containers []string + IgnoreCves []string + // Optional key-value set that will be outputted to JSON Optional [][]interface{} diff --git a/config/tomlloader.go b/config/tomlloader.go index 0ca05f8d90..21e52640cb 100644 --- a/config/tomlloader.go +++ b/config/tomlloader.go @@ -51,7 +51,6 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) (err error) { i := 0 for name, v := range conf.Servers { - if 0 < len(v.KeyPassword) { log.Warn("[Deprecated] KEYPASSWORD IN CONFIG FILE ARE UNSECURE. REMOVE THEM IMMEDIATELY FOR A SECURITY REASONS. THEY WILL BE REMOVED IN A FUTURE RELEASE.") } @@ -108,6 +107,20 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) (err error) { s.Containers = d.Containers } + s.IgnoreCves = v.IgnoreCves + for _, cve := range d.IgnoreCves { + found := false + for _, c := range s.IgnoreCves { + if cve == c { + found = true + break + } + } + if !found { + s.IgnoreCves = append(s.IgnoreCves, cve) + } + } + s.Optional = v.Optional for _, dkv := range d.Optional { found := false diff --git a/models/models.go b/models/models.go index 7c862cfe18..3a1877748d 100644 --- a/models/models.go +++ b/models/models.go @@ -89,6 +89,7 @@ type ScanResult struct { // NWLinks []NWLink KnownCves []CveInfo UnknownCves []CveInfo + IgnoredCves []CveInfo Optional [][]interface{} `gorm:"-"` } diff --git a/report/slack.go b/report/slack.go index c0faa437a1..655445e67f 100644 --- a/report/slack.go +++ b/report/slack.go @@ -59,7 +59,6 @@ type SlackWriter struct{} func (w SlackWriter) Write(scanResults []models.ScanResult) error { conf := config.Conf.Slack for _, s := range scanResults { - channel := conf.Channel if channel == "${servername}" { channel = fmt.Sprintf("#%s", s.ServerName) @@ -97,7 +96,6 @@ func (w SlackWriter) Write(scanResults []models.ScanResult) error { } func msgText(r models.ScanResult) string { - notifyUsers := "" if 0 < len(r.KnownCves) || 0 < len(r.UnknownCves) { notifyUsers = getNotifyUsers(config.Conf.Slack.NotifyUsers) @@ -108,7 +106,6 @@ func msgText(r models.ScanResult) string { } func toSlackAttachments(scanResult models.ScanResult) (attaches []*attachment) { - cves := scanResult.KnownCves if !config.Conf.IgnoreUnscoredCves { cves = append(cves, scanResult.UnknownCves...) diff --git a/scan/base.go b/scan/base.go index 3a39d6c70a..173c03a5dc 100644 --- a/scan/base.go +++ b/scan/base.go @@ -224,13 +224,31 @@ func (l base) isAwsInstanceID(str string) bool { } func (l *base) convertToModel() (models.ScanResult, error) { - var scoredCves, unscoredCves models.CveInfos + var scoredCves, unscoredCves, ignoredCves models.CveInfos for _, p := range l.UnsecurePackages { + // ignoreCves + found := false + for _, icve := range l.getServerInfo().IgnoreCves { + if icve == p.CveDetail.CveID { + ignoredCves = append(ignoredCves, models.CveInfo{ + CveDetail: p.CveDetail, + Packages: p.Packs, + DistroAdvisories: p.DistroAdvisories, + }) + found = true + break + } + } + if found { + continue + } + + // unscoredCves if p.CveDetail.CvssScore(config.Conf.Lang) <= 0 { unscoredCves = append(unscoredCves, models.CveInfo{ CveDetail: p.CveDetail, Packages: p.Packs, - DistroAdvisories: p.DistroAdvisories, // only Amazon Linux + DistroAdvisories: p.DistroAdvisories, }) continue } @@ -241,10 +259,11 @@ func (l *base) convertToModel() (models.ScanResult, error) { models.CpeName{Name: cpename}) } + // scoredCves cve := models.CveInfo{ CveDetail: p.CveDetail, Packages: p.Packs, - DistroAdvisories: p.DistroAdvisories, // only Amazon Linux + DistroAdvisories: p.DistroAdvisories, CpeNames: cpenames, } scoredCves = append(scoredCves, cve) @@ -257,6 +276,7 @@ func (l *base) convertToModel() (models.ScanResult, error) { sort.Sort(scoredCves) sort.Sort(unscoredCves) + sort.Sort(ignoredCves) return models.ScanResult{ ServerName: l.ServerInfo.ServerName, @@ -267,6 +287,7 @@ func (l *base) convertToModel() (models.ScanResult, error) { Platform: l.Platform, KnownCves: scoredCves, UnknownCves: unscoredCves, + IgnoredCves: ignoredCves, Optional: l.ServerInfo.Optional, }, nil }