Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3be50ab8da | ||
|
|
649f4a6991 | ||
|
|
0ff7641471 | ||
|
|
1679bfae20 | ||
|
|
45aa364436 | ||
|
|
778516c4d9 | ||
|
|
464d523c42 | ||
|
|
0f6a1987d4 | ||
|
|
20c6247ce5 | ||
|
|
a10dd67e0f | ||
|
|
5729ad6026 | ||
|
|
9aa0d87a21 | ||
|
|
fe3f1b9924 | ||
|
|
00e52a88fa | ||
|
|
5811dffe7a | ||
|
|
7278982af4 | ||
|
|
c17b4154ec | ||
|
|
d6e74cce08 | ||
|
|
3f80749241 | ||
|
|
7f72b6ac69 | ||
|
|
03e7b90b9f | ||
|
|
7936b3533b | ||
|
|
bd7e61d7cc | ||
|
|
69214e0c22 | ||
|
|
45bff26558 | ||
|
|
b2e429ccc6 | ||
|
|
76363c227b | ||
|
|
d5a3e5c2c5 | ||
|
|
2b02807ef0 | ||
|
|
be659ae094 | ||
|
|
b2c105adbc | ||
|
|
c61f462948 |
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: kotakanbe
|
||||
@@ -21,6 +21,7 @@ ENV WORKDIR /vuls
|
||||
RUN apk add --no-cache \
|
||||
openssh-client \
|
||||
ca-certificates \
|
||||
git \
|
||||
&& mkdir -p $WORKDIR $LOGDIR
|
||||
|
||||
COPY --from=builder /go/bin/vuls /usr/local/bin/
|
||||
|
||||
@@ -170,7 +170,7 @@ Vuls has some options to detect the vulnerabilities
|
||||
- Auto-generation of configuration file template
|
||||
- Auto-detection of servers set using CIDR, generate configuration file template
|
||||
- Email and Slack notification is possible (supports Japanese language)
|
||||
- Scan result is viewable on accessory software, TUI Viewer in a terminal or Web UI ([VulsRepo](https://github.com/future-architect/vulsrepo)).
|
||||
- Scan result is viewable on accessory software, TUI Viewer in a terminal or Web UI ([VulsRepo](https://github.com/ishiDACo/vulsrepo)).
|
||||
|
||||
----
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
// Version of Vuls
|
||||
var Version = "0.7.0"
|
||||
var Version = "0.9.3"
|
||||
|
||||
// Revision of Git
|
||||
var Revision string
|
||||
@@ -155,7 +155,7 @@ type Config struct {
|
||||
|
||||
// ValidateOnConfigtest validates
|
||||
func (c Config) ValidateOnConfigtest() bool {
|
||||
errs := []error{}
|
||||
errs := c.checkSSHKeyExist()
|
||||
|
||||
if runtime.GOOS == "windows" && !c.SSHNative {
|
||||
errs = append(errs, xerrors.New("-ssh-native-insecure is needed on windows"))
|
||||
@@ -175,14 +175,7 @@ func (c Config) ValidateOnConfigtest() bool {
|
||||
|
||||
// ValidateOnScan validates configuration
|
||||
func (c Config) ValidateOnScan() bool {
|
||||
errs := []error{}
|
||||
|
||||
if len(c.ResultsDir) != 0 {
|
||||
if ok, _ := valid.IsFilePath(c.ResultsDir); !ok {
|
||||
errs = append(errs, xerrors.Errorf(
|
||||
"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
|
||||
}
|
||||
}
|
||||
errs := c.checkSSHKeyExist()
|
||||
|
||||
if runtime.GOOS == "windows" && !c.SSHNative {
|
||||
errs = append(errs, xerrors.New("-ssh-native-insecure is needed on windows"))
|
||||
@@ -215,6 +208,21 @@ func (c Config) ValidateOnScan() bool {
|
||||
return len(errs) == 0
|
||||
}
|
||||
|
||||
func (c Config) checkSSHKeyExist() (errs []error) {
|
||||
for serverName, v := range c.Servers {
|
||||
if v.Type == ServerTypePseudo {
|
||||
continue
|
||||
}
|
||||
if v.KeyPath != "" {
|
||||
if _, err := os.Stat(v.KeyPath); err != nil {
|
||||
errs = append(errs, xerrors.Errorf(
|
||||
"%s is invalid. keypath: %s not exists", serverName, v.KeyPath))
|
||||
}
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// ValidateOnReportDB validates configuration
|
||||
func (c Config) ValidateOnReportDB() bool {
|
||||
errs := []error{}
|
||||
@@ -315,11 +323,6 @@ func (c Config) ValidateOnTui() bool {
|
||||
if err := validateDB("cvedb", c.CveDict.Type, c.CveDict.SQLite3Path, c.CveDict.URL); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if c.CveDict.Type == "sqlite3" {
|
||||
if _, err := os.Stat(c.CveDict.SQLite3Path); os.IsNotExist(err) {
|
||||
errs = append(errs, xerrors.Errorf("SQLite3 DB path (%s) is not exist: %s", "cvedb", c.CveDict.SQLite3Path))
|
||||
}
|
||||
}
|
||||
|
||||
for _, err := range errs {
|
||||
log.Error(err)
|
||||
@@ -1088,6 +1091,7 @@ type WordPressConf struct {
|
||||
type Image struct {
|
||||
Name string `json:"name"`
|
||||
Tag string `json:"tag"`
|
||||
Digest string `json:"digest"`
|
||||
DockerOption types.DockerOption `json:"dockerOption,omitempty"`
|
||||
Cpes []string `json:"cpes,omitempty"`
|
||||
OwaspDCXMLPath string `json:"owaspDCXMLPath"`
|
||||
@@ -1095,6 +1099,13 @@ type Image struct {
|
||||
IgnoreCves []string `json:"ignoreCves,omitempty"`
|
||||
}
|
||||
|
||||
func (i *Image) GetFullName() string {
|
||||
if i.Digest != "" {
|
||||
return i.Name + "@" + i.Digest
|
||||
}
|
||||
return i.Name + ":" + i.Tag
|
||||
}
|
||||
|
||||
// GitHubConf is used for GitHub integration
|
||||
type GitHubConf struct {
|
||||
Token string `json:"-"`
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -92,13 +91,6 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
|
||||
if len(s.KeyPath) == 0 {
|
||||
s.KeyPath = d.KeyPath
|
||||
}
|
||||
if s.KeyPath != "" {
|
||||
if _, err := os.Stat(s.KeyPath); err != nil {
|
||||
return xerrors.Errorf(
|
||||
"%s is invalid. keypath: %s not exists", serverName, s.KeyPath)
|
||||
}
|
||||
}
|
||||
|
||||
s.KeyPassword = v.KeyPassword
|
||||
if len(s.KeyPassword) == 0 {
|
||||
s.KeyPassword = d.KeyPassword
|
||||
@@ -306,8 +298,11 @@ func IsValidImage(c Image) error {
|
||||
if c.Name == "" {
|
||||
return xerrors.New("Invalid arguments : no image name")
|
||||
}
|
||||
if c.Tag == "" {
|
||||
return xerrors.New("Invalid arguments : no image tag")
|
||||
if c.Tag == "" && c.Digest == "" {
|
||||
return xerrors.New("Invalid arguments : no image tag and digest")
|
||||
}
|
||||
if c.Tag != "" && c.Digest != "" {
|
||||
return xerrors.New("Invalid arguments : you can either set image tag or digest")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -42,3 +42,62 @@ func TestToCpeURI(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidImage(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
img Image
|
||||
errOccur bool
|
||||
}{
|
||||
{
|
||||
name: "ok with tag",
|
||||
img: Image{
|
||||
Name: "ok",
|
||||
Tag: "ok",
|
||||
},
|
||||
errOccur: false,
|
||||
},
|
||||
{
|
||||
name: "ok with digest",
|
||||
img: Image{
|
||||
Name: "ok",
|
||||
Digest: "ok",
|
||||
},
|
||||
errOccur: false,
|
||||
},
|
||||
|
||||
{
|
||||
name: "no image name with tag",
|
||||
img: Image{
|
||||
Tag: "ok",
|
||||
},
|
||||
errOccur: true,
|
||||
},
|
||||
|
||||
{
|
||||
name: "no image name with digest",
|
||||
img: Image{
|
||||
Digest: "ok",
|
||||
},
|
||||
errOccur: true,
|
||||
},
|
||||
|
||||
{
|
||||
name: "no tag and digest",
|
||||
img: Image{
|
||||
Name: "ok",
|
||||
},
|
||||
errOccur: true,
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := IsValidImage(tt.img)
|
||||
actual := err != nil
|
||||
if actual != tt.errOccur {
|
||||
t.Errorf("[%d] act: %v, exp: %v",
|
||||
i, actual, tt.errOccur)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/knqyf263/go-cpe/naming"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
@@ -15,12 +16,11 @@ type analysis struct {
|
||||
}
|
||||
|
||||
type dependency struct {
|
||||
Identifiers []identifier `xml:"identifiers>identifier"`
|
||||
Identifiers []vulnerabilityId `xml:"identifiers>vulnerabilityIds"`
|
||||
}
|
||||
|
||||
type identifier struct {
|
||||
Name string `xml:"name"`
|
||||
Type string `xml:"type,attr"`
|
||||
type vulnerabilityId struct {
|
||||
Id string `xml:"id"`
|
||||
}
|
||||
|
||||
func appendIfMissing(slice []string, str string) []string {
|
||||
@@ -55,11 +55,16 @@ func Parse(path string) ([]string, error) {
|
||||
cpes := []string{}
|
||||
for _, d := range anal.Dependencies {
|
||||
for _, ident := range d.Identifiers {
|
||||
if ident.Type == "cpe" {
|
||||
name := strings.TrimPrefix(ident.Name, "(")
|
||||
name = strings.TrimSuffix(name, ")")
|
||||
cpes = appendIfMissing(cpes, name)
|
||||
id := ident.Id // Start with cpe:2.3:
|
||||
// Convert from CPE 2.3 to CPE 2.2
|
||||
if strings.HasPrefix(id, "cpe:2.3:") {
|
||||
wfn, err := naming.UnbindFS(id)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
id = naming.BindToURI(wfn)
|
||||
}
|
||||
cpes = appendIfMissing(cpes, id)
|
||||
}
|
||||
}
|
||||
return cpes, nil
|
||||
|
||||
33
cwe/cwe.go
Normal file
33
cwe/cwe.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package cwe
|
||||
|
||||
// CweTopTwentyfive2019 has CWE-ID in CWE Top 25
|
||||
var CweTopTwentyfive2019 = map[string]string{
|
||||
"119": "1",
|
||||
"79": "2",
|
||||
"20": "3",
|
||||
"200": "4",
|
||||
"125": "5",
|
||||
"89": "6",
|
||||
"416": "7",
|
||||
"190": "8",
|
||||
"352": "9",
|
||||
"22": "10",
|
||||
"78": "11",
|
||||
"787": "12",
|
||||
"287": "13",
|
||||
"476": "14",
|
||||
"732": "16",
|
||||
"434": "16",
|
||||
"611": "17",
|
||||
"94": "18",
|
||||
"798": "19",
|
||||
"400": "20",
|
||||
"772": "21",
|
||||
"426": "22",
|
||||
"502": "23",
|
||||
"269": "24",
|
||||
"295": "25",
|
||||
}
|
||||
|
||||
// CweTopTwentyfive2019URL has CWE Top25 links
|
||||
var CweTopTwentyfive2019URL = "https://cwe.mitre.org/top25/archive/2019/2019_cwe_top25.html"
|
||||
33
cwe/sans.go
Normal file
33
cwe/sans.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package cwe
|
||||
|
||||
// SansTopTwentyfive has CWE-ID in CWE/SANS Top 25
|
||||
var SansTopTwentyfive = map[string]string{
|
||||
"89": "1",
|
||||
"78": "2",
|
||||
"120": "3",
|
||||
"79": "4",
|
||||
"306": "5",
|
||||
"862": "6",
|
||||
"798": "7",
|
||||
"311": "8",
|
||||
"434": "9",
|
||||
"807": "10",
|
||||
"250": "11",
|
||||
"352": "12",
|
||||
"22": "13",
|
||||
"494": "14",
|
||||
"863": "15",
|
||||
"829": "16",
|
||||
"732": "17",
|
||||
"676": "18",
|
||||
"327": "19",
|
||||
"131": "20",
|
||||
"307": "21",
|
||||
"601": "22",
|
||||
"134": "23",
|
||||
"190": "24",
|
||||
"759": "25",
|
||||
}
|
||||
|
||||
// SansTopTwentyfiveURL
|
||||
var SansTopTwentyfiveURL = "https://www.sans.org/top25-software-errors/"
|
||||
@@ -44,6 +44,9 @@ func FillWithExploit(driver db.DB, r *models.ScanResult) (nExploitCve int, err e
|
||||
return 0, nil
|
||||
}
|
||||
for cveID, vuln := range r.ScannedCves {
|
||||
if cveID == "" {
|
||||
continue
|
||||
}
|
||||
es := driver.GetExploitByCveID(cveID)
|
||||
if len(es) == 0 {
|
||||
continue
|
||||
|
||||
20
go.mod
20
go.mod
@@ -9,41 +9,39 @@ replace (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go v33.1.0+incompatible
|
||||
github.com/Azure/azure-sdk-for-go v33.2.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest v0.9.1 // indirect
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91
|
||||
github.com/aquasecurity/fanal v0.0.0-20190819081512-f04452b627c6
|
||||
github.com/aquasecurity/fanal v0.0.0-20200124194549-91468b8e0460
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20190819075924-ea223f0ef24b
|
||||
github.com/aquasecurity/trivy v0.1.6
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
|
||||
github.com/aws/aws-sdk-go v1.23.17
|
||||
github.com/aws/aws-sdk-go v1.25.31
|
||||
github.com/boltdb/bolt v1.3.1
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible
|
||||
github.com/dnaeon/go-vcr v1.0.1 // indirect
|
||||
github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2 // indirect
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 // indirect
|
||||
github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1 // indirect
|
||||
github.com/google/subcommands v1.0.1
|
||||
github.com/gosuri/uitable v0.0.3
|
||||
github.com/hashicorp/go-version v1.2.0
|
||||
github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c
|
||||
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c
|
||||
github.com/jroimartin/gocui v0.4.0
|
||||
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
|
||||
github.com/k0kubun/pp v3.0.1+incompatible
|
||||
github.com/knqyf263/go-cpe v0.0.0-20180327054844-659663f6eca2
|
||||
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
|
||||
github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936
|
||||
github.com/knqyf263/go-version v1.1.1
|
||||
github.com/knqyf263/gost v0.1.2
|
||||
github.com/kotakanbe/go-cve-dictionary v0.4.0
|
||||
github.com/kotakanbe/go-cve-dictionary v0.4.1
|
||||
github.com/kotakanbe/go-pingscanner v0.1.0
|
||||
github.com/kotakanbe/goval-dictionary v0.2.2
|
||||
github.com/kotakanbe/goval-dictionary v0.2.3
|
||||
github.com/kotakanbe/logrus-prefixed-formatter v0.0.0-20180123152602-928f7356cb96
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mozqnet/go-exploitdb v0.0.0-20190426034301-a055cc2c195d
|
||||
github.com/mozqnet/go-exploitdb v0.0.0-20190911093644-f647f17ea8ca
|
||||
github.com/nlopes/slack v0.6.0
|
||||
github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190607075207-195002e6e56a
|
||||
@@ -52,7 +50,7 @@ require (
|
||||
github.com/satori/go.uuid v1.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
|
||||
)
|
||||
|
||||
92
go.sum
92
go.sum
@@ -2,8 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
|
||||
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
||||
github.com/Azure/azure-sdk-for-go v33.1.0+incompatible h1:OAEdTDI/pJ7ee7W7PtRsd6W5s4mzvxjn0WhBTCN5eZg=
|
||||
github.com/Azure/azure-sdk-for-go v33.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v33.2.0+incompatible h1:eDPeIqsD1UxYEcrn/DMxhfA47QcvaOXGtj4MkGIHIio=
|
||||
github.com/Azure/azure-sdk-for-go v33.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
@@ -31,6 +31,7 @@ github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcy
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
|
||||
github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91 h1:vX+gnvBc56EbWYrmlhYbFYRaeikAke1GL84N4BEYOFE=
|
||||
github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91/go.mod h1:cDLGBht23g0XQdLjzn6xOGXDkLK182YfINAaZEQLCHQ=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
@@ -39,11 +40,14 @@ github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBb
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/aquasecurity/fanal v0.0.0-20190819081512-f04452b627c6 h1:pkl+kEW4KeLDPLfDtzjXa+zHOcS4YWSQuSTZ2kWO2GE=
|
||||
github.com/aquasecurity/fanal v0.0.0-20190819081512-f04452b627c6/go.mod h1:enEz4FFetw4XAbkffaYgyCVq1556R9Ry+noqT4rq9BE=
|
||||
github.com/aquasecurity/fanal v0.0.0-20200124194549-91468b8e0460 h1:8Dsyp9pt2I7MTSTbUlf/lLBK7IsIrcPTfXrl7Bx3NrA=
|
||||
github.com/aquasecurity/fanal v0.0.0-20200124194549-91468b8e0460/go.mod h1:S2D937GMywJzh6KiLQEyt/0yqmfAngUFvuQ9UmkIZSw=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20190819075924-ea223f0ef24b h1:55Ulc/gvfWm4ylhVaR7MxOwujRjA6et7KhmUbSgUFf4=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20190819075924-ea223f0ef24b/go.mod h1:BpNTD9vHfrejKsED9rx04ldM1WIbeyXGYxUrqTVwxVQ=
|
||||
github.com/aquasecurity/trivy v0.1.6 h1:bATT+9swX+tKw1QibOHQbofMUflRRpPF9wmiMTcZQgI=
|
||||
@@ -52,8 +56,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-sdk-go v1.19.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.23.17 h1:IGNAvtR7ckMEHhy+ObG9xw6DFqEE4Ual0LYXsVTZSLQ=
|
||||
github.com/aws/aws-sdk-go v1.23.17/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.25.31 h1:14mdh3HsTgRekePPkYcCbAaEXJknc3mN7f4XfsiMMDA=
|
||||
github.com/aws/aws-sdk-go v1.25.31/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@@ -84,8 +88,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
|
||||
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 h1:tkum0XDgfR0jcVVXuTsYv/erY2NnEDqwRojbxR1rBYA=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190909000816-272160613861 h1:qLpBq6uLTG2OUlPqS6D3uQf8zJteDR5vOJGPjF2Elu4=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190909000816-272160613861/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
@@ -113,8 +118,8 @@ github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNE
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2 h1:aZtFdDNWY/yH86JPR2WX/PN63635VsE/f/nXNPAbYxY=
|
||||
github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1 h1:yY9rWGoXv1U5pl4gxqlULARMQD7x0QG85lqEXTWysik=
|
||||
github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
|
||||
github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
@@ -138,16 +143,20 @@ github.com/gliderlabs/ssh v0.1.3/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-redis/redis v6.15.5+incompatible h1:pLky8I0rgiblWfa8C1EV7fPEUv0aH6vKRaYHc/YRHVk=
|
||||
github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gocarina/gocsv v0.0.0-20190821091544-020a928c6f4e/go.mod h1:/oj50ZdPq/cUjA02lMZhijk5kR31SEydKyqah1OgBuo=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@@ -155,8 +164,9 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
@@ -191,8 +201,8 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c h1:nQcv325vxv2fFHJsOt53eSRf1eINt6vOdYUFfXs4rgk=
|
||||
github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c/go.mod h1:fHzc09UnyJyqyW+bFuq864eh+wC7dj65aXmXLRe5to0=
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0=
|
||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
|
||||
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c h1:aY2hhxLhjEAbfXOx2nRJxCXezC6CO2V/yN+OCr1srtk=
|
||||
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/htcat/htcat v1.0.2 h1:zro95dGwkKDeZOgq9ei+9szd5qurGxBGfHY8hRehA7k=
|
||||
@@ -243,12 +253,12 @@ github.com/knqyf263/nested v0.0.1/go.mod h1:zwhsIhMkBg90DTOJQvxPkKIypEHPYkgWHs4g
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kotakanbe/go-cve-dictionary v0.4.0 h1:krAnrobpEoZDH/2L1uCSFzjjdZTwWvH5UKMsp+VKTtA=
|
||||
github.com/kotakanbe/go-cve-dictionary v0.4.0/go.mod h1:CNVaCVSeqjxCFQm93uCWPT8mR+a0514XHiiBJx9yrkQ=
|
||||
github.com/kotakanbe/go-cve-dictionary v0.4.1 h1:TkGClRLDFmg4mdk5Uohhl5DivCp+g3w3fsHTtqCJCT8=
|
||||
github.com/kotakanbe/go-cve-dictionary v0.4.1/go.mod h1:zgnFBROvdhyd30KU0yekNI0J1kQkjTMND8GqlL8y25k=
|
||||
github.com/kotakanbe/go-pingscanner v0.1.0 h1:VG4/9l0i8WeToXclj7bIGoAZAu7a07Z3qmQiIfU0gT0=
|
||||
github.com/kotakanbe/go-pingscanner v0.1.0/go.mod h1:/761QZzuZFcfN8h/1QuawUA+pKukp3qcNj5mxJCOiAk=
|
||||
github.com/kotakanbe/goval-dictionary v0.2.2 h1:WDsc/V59GaTf4rT2mg4bHSFA/915zHAaaaRd+UF9eVo=
|
||||
github.com/kotakanbe/goval-dictionary v0.2.2/go.mod h1:OozI5ZbKWHIPcjYgOITYHRy+Vo6ZbksY1FU8aCwojK4=
|
||||
github.com/kotakanbe/goval-dictionary v0.2.3 h1:HFcLFxocBCSeR+b15w7G9WmU0akWTdEo3dOWNjB3CaM=
|
||||
github.com/kotakanbe/goval-dictionary v0.2.3/go.mod h1:OozI5ZbKWHIPcjYgOITYHRy+Vo6ZbksY1FU8aCwojK4=
|
||||
github.com/kotakanbe/logrus-prefixed-formatter v0.0.0-20180123152602-928f7356cb96 h1:xNVK0mQJdQjw+QYeaMM4G6fvucWr8rTGGIhlPakx1wU=
|
||||
github.com/kotakanbe/logrus-prefixed-formatter v0.0.0-20180123152602-928f7356cb96/go.mod h1:ljq48H1V+0Vh0u7ucA3LjR4AfkAeCpxrf7LaaCk8Vmo=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
@@ -260,10 +270,12 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
|
||||
github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
|
||||
github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
|
||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.1.0 h1:v2XXALHHh6zHfYTJ+cSkwtyffnaOyR1MXaA91mTrb8o=
|
||||
@@ -274,8 +286,9 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.6 h1:SrwhHcpV4nWrMGdNcC2kXpMfcBVYGDuTArqyhocJgvA=
|
||||
github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
@@ -293,8 +306,8 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
|
||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||
github.com/mozqnet/go-exploitdb v0.0.0-20190426034301-a055cc2c195d h1:ujS/a5AnCh6CNKIBfvrisDw2edwFa0TmHQHEQ6g5COg=
|
||||
github.com/mozqnet/go-exploitdb v0.0.0-20190426034301-a055cc2c195d/go.mod h1:tqVnRPFR/8bkvCzGsGjwq+vb5dS6jwFFa+sEAbWPbDI=
|
||||
github.com/mozqnet/go-exploitdb v0.0.0-20190911093644-f647f17ea8ca h1:YdnY8FDl9NbO++O+q/kx1iledsHAk1KZLICZpEhqWFo=
|
||||
github.com/mozqnet/go-exploitdb v0.0.0-20190911093644-f647f17ea8ca/go.mod h1:TsEciLihBvN8yO9iCHBahCLxZff11NxbBO/xm8nVH9g=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nlopes/slack v0.6.0 h1:jt0jxVQGhssx1Ib7naAOZEZcGdtIhTzkP0nopK0AsRA=
|
||||
github.com/nlopes/slack v0.6.0/go.mod h1:JzQ9m3PMAqcpeCam7UaHSuBuupz7CmpjehYMayT6YOk=
|
||||
@@ -306,10 +319,12 @@ github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXW
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190607075207-195002e6e56a h1:0LD5FJGQpEyD78OdhX97W75RjYmMjfLPp1ePrk5URxs=
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190607075207-195002e6e56a/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2 h1:QhPf3A2AZW3tTGvHPg0TA+CR3oHbVLlXUhlghqISp1I=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
@@ -354,11 +369,13 @@ github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5H
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/httpfs v0.0.0-20181222201310-74dc9339e414/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
@@ -387,8 +404,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/tealeg/xlsx v1.0.3/go.mod h1:uxu5UY2ovkuRPWKQ8Q7JG0JbSivrISjdPzZQKeo74mA=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tomoyamachi/reg v0.16.1-0.20190706172545-2a2250fd7c00 h1:0e4vRd9YqnQBIAIAE39jLKDWffRfJWxloyWwcaMAQho=
|
||||
@@ -424,13 +442,16 @@ golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83 h1:mgAKeshyNqWKdENOnQsg+8dRTwZFIwFaO3HNl52sweA=
|
||||
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190907121410-71b5226ff739/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -442,8 +463,13 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc=
|
||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191108221443-4ba9e2ef068c h1:SRpq/kuj/xNci/RdvEs+RSvpfxqvLAzTKuKGlzoGdZQ=
|
||||
golang.org/x/net v0.0.0-20191108221443-4ba9e2ef068c/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||
@@ -468,8 +494,13 @@ golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190506115046-ca7f33d4116e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed h1:uPxWBzB3+mlnjy9W58qY1j/cjyFjutgw/Vhan2zLy/A=
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190909082730-f460065e899a h1:mIzbOulag9/gXacgxKlFVwpCOWSfBT3/pDyyCwGA9as=
|
||||
golang.org/x/sys v0.0.0-20190909082730-f460065e899a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd h1:3x5uuvBgE6oaXJjCOvpCC1IpgJogqQ+PqGGU3ZxAgII=
|
||||
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
@@ -486,13 +517,15 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190503185657-3b6f9c0030f7/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.2 h1:j8RI1yW0SkI+paT6uGwMlrMI/6zwYA6/CFil8rxOzGI=
|
||||
google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
@@ -507,8 +540,9 @@ gopkg.in/VividCortex/ewma.v1 v1.1.1 h1:tWHEKkKq802K/JT9RiqGCBU5fW3raAPnJGTE9ostZ
|
||||
gopkg.in/VividCortex/ewma.v1 v1.1.1/go.mod h1:TekXuFipeiHWiAlO1+wSS23vTcyFau5u3rxXUSXj710=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/cheggaaa/pb.v2 v2.0.7 h1:beaAg8eacCdMQS9Y7obFEtkY7gQl0uZ6Zayb3ry41VY=
|
||||
|
||||
51
gost/base.go
Normal file
51
gost/base.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package gost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
cnf "github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/knqyf263/gost/db"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// Base is a base struct
|
||||
type Base struct {
|
||||
}
|
||||
|
||||
// FillCVEsWithRedHat fills cve information that has in Gost
|
||||
func (b Base) FillCVEsWithRedHat(driver db.DB, r *models.ScanResult) error {
|
||||
return RedHat{}.fillFixed(driver, r)
|
||||
}
|
||||
|
||||
// CheckHTTPHealth do health check
|
||||
func (b Base) CheckHTTPHealth() error {
|
||||
if !cnf.Conf.Gost.IsFetchViaHTTP() {
|
||||
return nil
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/health", cnf.Conf.Gost.URL)
|
||||
var errs []error
|
||||
var resp *http.Response
|
||||
resp, _, errs = gorequest.New().Get(url).End()
|
||||
// resp, _, errs = gorequest.New().SetDebug(config.Conf.Debug).Get(url).End()
|
||||
// resp, _, errs = gorequest.New().Proxy(api.httpProxy).Get(url).End()
|
||||
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
|
||||
return xerrors.Errorf("Failed to connect to gost server. url: %s, errs: %w", url, errs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckIfGostFetched checks if oval entries are in DB by family, release.
|
||||
func (b Base) CheckIfGostFetched(driver db.DB, osFamily string) (fetched bool, err error) {
|
||||
//TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// CheckIfGostFresh checks if oval entries are fresh enough
|
||||
func (b Base) CheckIfGostFresh(driver db.DB, osFamily string) (ok bool, err error) {
|
||||
//TODO
|
||||
return true, nil
|
||||
}
|
||||
@@ -21,8 +21,8 @@ type packCves struct {
|
||||
cves []models.CveContent
|
||||
}
|
||||
|
||||
// FillWithGost fills cve information that has in Gost
|
||||
func (deb Debian) FillWithGost(driver db.DB, r *models.ScanResult, _ bool) (nCVEs int, err error) {
|
||||
// DetectUnfixed fills cve information that has in Gost
|
||||
func (deb Debian) DetectUnfixed(driver db.DB, r *models.ScanResult, _ bool) (nCVEs int, err error) {
|
||||
linuxImage := "linux-image-" + r.RunningKernel.Release
|
||||
// Add linux and set the version of running kernel to search OVAL.
|
||||
if r.Container.ContainerID == "" {
|
||||
|
||||
58
gost/gost.go
58
gost/gost.go
@@ -1,20 +1,15 @@
|
||||
package gost
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
cnf "github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/knqyf263/gost/db"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// Client is the interface of OVAL client.
|
||||
type Client interface {
|
||||
FillWithGost(db.DB, *models.ScanResult, bool) (int, error)
|
||||
DetectUnfixed(db.DB, *models.ScanResult, bool) (int, error)
|
||||
FillCVEsWithRedHat(db.DB, *models.ScanResult) error
|
||||
|
||||
//TODO implement
|
||||
// CheckHTTPHealth() error
|
||||
@@ -36,52 +31,3 @@ func NewClient(family string) Client {
|
||||
return Pseudo{}
|
||||
}
|
||||
}
|
||||
|
||||
// Base is a base struct
|
||||
type Base struct {
|
||||
family string
|
||||
}
|
||||
|
||||
// CheckHTTPHealth do health check
|
||||
func (b Base) CheckHTTPHealth() error {
|
||||
if !cnf.Conf.Gost.IsFetchViaHTTP() {
|
||||
return nil
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/health", cnf.Conf.Gost.URL)
|
||||
var errs []error
|
||||
var resp *http.Response
|
||||
resp, _, errs = gorequest.New().Get(url).End()
|
||||
// resp, _, errs = gorequest.New().SetDebug(config.Conf.Debug).Get(url).End()
|
||||
// resp, _, errs = gorequest.New().Proxy(api.httpProxy).Get(url).End()
|
||||
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
|
||||
return xerrors.Errorf("Failed to connect to gost server. url: %s, errs: %w", url, errs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckIfGostFetched checks if oval entries are in DB by family, release.
|
||||
func (b Base) CheckIfGostFetched(driver db.DB, osFamily string) (fetched bool, err error) {
|
||||
//TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// CheckIfGostFresh checks if oval entries are fresh enough
|
||||
func (b Base) CheckIfGostFresh(driver db.DB, osFamily string) (ok bool, err error) {
|
||||
//TODO
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Pseudo is Gost client except for RedHat family and Debian
|
||||
type Pseudo struct {
|
||||
Base
|
||||
}
|
||||
|
||||
// FillWithGost fills cve information that has in Gost
|
||||
func (pse Pseudo) FillWithGost(driver db.DB, r *models.ScanResult, _ bool) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func major(osVer string) (majorVersion string) {
|
||||
return strings.Split(osVer, ".")[0]
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ type Microsoft struct {
|
||||
Base
|
||||
}
|
||||
|
||||
// FillWithGost fills cve information that has in Gost
|
||||
func (ms Microsoft) FillWithGost(driver db.DB, r *models.ScanResult, _ bool) (nCVEs int, err error) {
|
||||
// DetectUnfixed fills cve information that has in Gost
|
||||
func (ms Microsoft) DetectUnfixed(driver db.DB, r *models.ScanResult, _ bool) (nCVEs int, err error) {
|
||||
if driver == nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
21
gost/pseudo.go
Normal file
21
gost/pseudo.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package gost
|
||||
|
||||
import (
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/knqyf263/gost/db"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Pseudo is Gost client except for RedHat family and Debian
|
||||
type Pseudo struct {
|
||||
Base
|
||||
}
|
||||
|
||||
// DetectUnfixed fills cve information that has in Gost
|
||||
func (pse Pseudo) DetectUnfixed(driver db.DB, r *models.ScanResult, _ bool) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func major(osVer string) (majorVersion string) {
|
||||
return strings.Split(osVer, ".")[0]
|
||||
}
|
||||
@@ -17,12 +17,9 @@ type RedHat struct {
|
||||
Base
|
||||
}
|
||||
|
||||
// FillWithGost fills cve information that has in Gost
|
||||
func (red RedHat) FillWithGost(driver db.DB, r *models.ScanResult, ignoreWillNotFix bool) (nCVEs int, err error) {
|
||||
if nCVEs, err = red.fillUnfixed(driver, r, ignoreWillNotFix); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return nCVEs, red.fillFixed(driver, r)
|
||||
// DetectUnfixed fills cve information that has in Gost
|
||||
func (red RedHat) DetectUnfixed(driver db.DB, r *models.ScanResult, ignoreWillNotFix bool) (nCVEs int, err error) {
|
||||
return red.fillUnfixed(driver, r, ignoreWillNotFix)
|
||||
}
|
||||
|
||||
func (red RedHat) fillFixed(driver db.DB, r *models.ScanResult) error {
|
||||
@@ -71,7 +68,7 @@ func (red RedHat) fillFixed(driver db.DB, r *models.ScanResult) error {
|
||||
return nil
|
||||
}
|
||||
for cveID, redCve := range driver.GetRedhatMulti(cveIDs) {
|
||||
if redCve.ID == 0 {
|
||||
if len(redCve.Name) == 0 {
|
||||
continue
|
||||
}
|
||||
cveCont := red.ConvertToModel(&redCve)
|
||||
|
||||
@@ -120,18 +120,23 @@ func (p Package) FormatNewVer() string {
|
||||
}
|
||||
|
||||
// FormatVersionFromTo formats installed and new package version
|
||||
func (p Package) FormatVersionFromTo(notFixedYet bool, status string) string {
|
||||
func (p Package) FormatVersionFromTo(stat PackageFixStatus) string {
|
||||
to := p.FormatNewVer()
|
||||
if notFixedYet {
|
||||
if status != "" {
|
||||
to = status
|
||||
if stat.NotFixedYet {
|
||||
if stat.FixState != "" {
|
||||
to = stat.FixState
|
||||
} else {
|
||||
to = "Not Fixed Yet"
|
||||
}
|
||||
} else if p.NewVersion == "" {
|
||||
to = "Unknown"
|
||||
}
|
||||
return fmt.Sprintf("%s-%s -> %s", p.Name, p.FormatVer(), to)
|
||||
var fixedIn string
|
||||
if stat.FixedIn != "" {
|
||||
fixedIn = fmt.Sprintf(" (FixedIn: %s)", stat.FixedIn)
|
||||
}
|
||||
return fmt.Sprintf("%s-%s -> %s%s",
|
||||
p.Name, p.FormatVer(), to, fixedIn)
|
||||
}
|
||||
|
||||
// FormatChangelog formats the changelog
|
||||
|
||||
@@ -175,3 +175,125 @@ func TestFindByBinName(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPackage_FormatVersionFromTo(t *testing.T) {
|
||||
type fields struct {
|
||||
Name string
|
||||
Version string
|
||||
Release string
|
||||
NewVersion string
|
||||
NewRelease string
|
||||
Arch string
|
||||
Repository string
|
||||
Changelog Changelog
|
||||
AffectedProcs []AffectedProcess
|
||||
NeedRestartProcs []NeedRestartProcess
|
||||
}
|
||||
type args struct {
|
||||
stat PackageFixStatus
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "fixed",
|
||||
fields: fields{
|
||||
Name: "packA",
|
||||
Version: "1.0.0",
|
||||
Release: "a",
|
||||
NewVersion: "1.0.1",
|
||||
NewRelease: "b",
|
||||
},
|
||||
args: args{
|
||||
stat: PackageFixStatus{
|
||||
NotFixedYet: false,
|
||||
FixedIn: "1.0.1-b",
|
||||
},
|
||||
},
|
||||
want: "packA-1.0.0-a -> 1.0.1-b (FixedIn: 1.0.1-b)",
|
||||
},
|
||||
{
|
||||
name: "nfy",
|
||||
fields: fields{
|
||||
Name: "packA",
|
||||
Version: "1.0.0",
|
||||
Release: "a",
|
||||
},
|
||||
args: args{
|
||||
stat: PackageFixStatus{
|
||||
NotFixedYet: true,
|
||||
},
|
||||
},
|
||||
want: "packA-1.0.0-a -> Not Fixed Yet",
|
||||
},
|
||||
{
|
||||
name: "nfy",
|
||||
fields: fields{
|
||||
Name: "packA",
|
||||
Version: "1.0.0",
|
||||
Release: "a",
|
||||
},
|
||||
args: args{
|
||||
stat: PackageFixStatus{
|
||||
NotFixedYet: false,
|
||||
FixedIn: "1.0.1-b",
|
||||
},
|
||||
},
|
||||
want: "packA-1.0.0-a -> Unknown (FixedIn: 1.0.1-b)",
|
||||
},
|
||||
{
|
||||
name: "nfy2",
|
||||
fields: fields{
|
||||
Name: "packA",
|
||||
Version: "1.0.0",
|
||||
Release: "a",
|
||||
},
|
||||
args: args{
|
||||
stat: PackageFixStatus{
|
||||
NotFixedYet: true,
|
||||
FixedIn: "1.0.1-b",
|
||||
FixState: "open",
|
||||
},
|
||||
},
|
||||
want: "packA-1.0.0-a -> open (FixedIn: 1.0.1-b)",
|
||||
},
|
||||
{
|
||||
name: "nfy3",
|
||||
fields: fields{
|
||||
Name: "packA",
|
||||
Version: "1.0.0",
|
||||
Release: "a",
|
||||
},
|
||||
args: args{
|
||||
stat: PackageFixStatus{
|
||||
NotFixedYet: true,
|
||||
FixedIn: "1.0.1-b",
|
||||
FixState: "open",
|
||||
},
|
||||
},
|
||||
want: "packA-1.0.0-a -> open (FixedIn: 1.0.1-b)",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := Package{
|
||||
Name: tt.fields.Name,
|
||||
Version: tt.fields.Version,
|
||||
Release: tt.fields.Release,
|
||||
NewVersion: tt.fields.NewVersion,
|
||||
NewRelease: tt.fields.NewRelease,
|
||||
Arch: tt.fields.Arch,
|
||||
Repository: tt.fields.Repository,
|
||||
Changelog: tt.fields.Changelog,
|
||||
AffectedProcs: tt.fields.AffectedProcs,
|
||||
NeedRestartProcs: tt.fields.NeedRestartProcs,
|
||||
}
|
||||
if got := p.FormatVersionFromTo(tt.args.stat); got != tt.want {
|
||||
t.Errorf("Package.FormatVersionFromTo() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ type ScanResult struct {
|
||||
type CweDict map[string]CweDictEntry
|
||||
|
||||
// Get the name, url, top10URL for the specified cweID, lang
|
||||
func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string) {
|
||||
func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL, cweTop25Rank, cweTop25URL, sansTop25Rank, sansTop25URL string) {
|
||||
cweNum := strings.TrimPrefix(cweID, "CWE-")
|
||||
switch config.Conf.Lang {
|
||||
case "ja":
|
||||
@@ -70,6 +70,14 @@ func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string)
|
||||
top10Rank = dict.OwaspTopTen2017
|
||||
top10URL = cwe.OwaspTopTen2017GitHubURLJa[dict.OwaspTopTen2017]
|
||||
}
|
||||
if dict, ok := c[cweNum]; ok && dict.CweTopTwentyfive2019 != "" {
|
||||
cweTop25Rank = dict.CweTopTwentyfive2019
|
||||
cweTop25URL = cwe.CweTopTwentyfive2019URL
|
||||
}
|
||||
if dict, ok := c[cweNum]; ok && dict.SansTopTwentyfive != "" {
|
||||
sansTop25Rank = dict.SansTopTwentyfive
|
||||
sansTop25URL = cwe.SansTopTwentyfiveURL
|
||||
}
|
||||
if dict, ok := cwe.CweDictJa[cweNum]; ok {
|
||||
name = dict.Name
|
||||
url = fmt.Sprintf("http://jvndb.jvn.jp/ja/cwe/%s.html", cweID)
|
||||
@@ -84,6 +92,14 @@ func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string)
|
||||
top10Rank = dict.OwaspTopTen2017
|
||||
top10URL = cwe.OwaspTopTen2017GitHubURLEn[dict.OwaspTopTen2017]
|
||||
}
|
||||
if dict, ok := c[cweNum]; ok && dict.CweTopTwentyfive2019 != "" {
|
||||
cweTop25Rank = dict.CweTopTwentyfive2019
|
||||
cweTop25URL = cwe.CweTopTwentyfive2019URL
|
||||
}
|
||||
if dict, ok := c[cweNum]; ok && dict.SansTopTwentyfive != "" {
|
||||
sansTop25Rank = dict.SansTopTwentyfive
|
||||
sansTop25URL = cwe.SansTopTwentyfiveURL
|
||||
}
|
||||
url = fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", cweID)
|
||||
if dict, ok := cwe.CweDictEn[cweNum]; ok {
|
||||
name = dict.Name
|
||||
@@ -94,9 +110,11 @@ func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string)
|
||||
|
||||
// CweDictEntry is a entry of CWE
|
||||
type CweDictEntry struct {
|
||||
En *cwe.Cwe `json:"en,omitempty"`
|
||||
Ja *cwe.Cwe `json:"ja,omitempty"`
|
||||
OwaspTopTen2017 string `json:"owaspTopTen2017"`
|
||||
En *cwe.Cwe `json:"en,omitempty"`
|
||||
Ja *cwe.Cwe `json:"ja,omitempty"`
|
||||
OwaspTopTen2017 string `json:"owaspTopTen2017"`
|
||||
CweTopTwentyfive2019 string `json:"cweTopTwentyfive2019"`
|
||||
SansTopTwentyfive string `json:"sansTopTwentyfive"`
|
||||
}
|
||||
|
||||
// Kernel has the Release, version and whether need restart
|
||||
@@ -255,7 +273,7 @@ func (r ScanResult) FilterInactiveWordPressLibs() ScanResult {
|
||||
return r
|
||||
}
|
||||
|
||||
// ReportFileName returns the filename on localhost without extention
|
||||
// ReportFileName returns the filename on localhost without extension
|
||||
func (r ScanResult) ReportFileName() (name string) {
|
||||
if len(r.Container.ContainerID) == 0 {
|
||||
return fmt.Sprintf("%s", r.ServerName)
|
||||
@@ -263,7 +281,7 @@ func (r ScanResult) ReportFileName() (name string) {
|
||||
return fmt.Sprintf("%s@%s", r.Container.Name, r.ServerName)
|
||||
}
|
||||
|
||||
// ReportKeyName returns the name of key on S3, Azure-Blob without extention
|
||||
// ReportKeyName returns the name of key on S3, Azure-Blob without extension
|
||||
func (r ScanResult) ReportKeyName() (name string) {
|
||||
timestr := r.ScannedAt.Format(time.RFC3339)
|
||||
if len(r.Container.ContainerID) == 0 {
|
||||
@@ -445,8 +463,9 @@ type Container struct {
|
||||
|
||||
// Image has Container information
|
||||
type Image struct {
|
||||
Name string `json:"name"`
|
||||
Tag string `json:"tag"`
|
||||
Name string `json:"name"`
|
||||
Tag string `json:"tag"`
|
||||
Digest string `json:"digest"`
|
||||
}
|
||||
|
||||
// Platform has platform information
|
||||
|
||||
@@ -136,9 +136,10 @@ func (ps PackageFixStatuses) Sort() {
|
||||
|
||||
// PackageFixStatus has name and other status abount the package
|
||||
type PackageFixStatus struct {
|
||||
Name string `json:"name"`
|
||||
NotFixedYet bool `json:"notFixedYet"`
|
||||
FixState string `json:"fixState"`
|
||||
Name string `json:"name,omitempty"`
|
||||
NotFixedYet bool `json:"notFixedYet,omitempty"`
|
||||
FixState string `json:"fixState,omitempty"`
|
||||
FixedIn string `json:"fixedIn,omitempty"`
|
||||
}
|
||||
|
||||
// VulnInfo has a vulnerability information and unsecure packages
|
||||
@@ -276,7 +277,7 @@ func (v VulnInfo) Summaries(lang, myFamily string) (values []CveContentStr) {
|
||||
}
|
||||
}
|
||||
|
||||
order := CveContentTypes{Nvd, NvdXML, NewCveContentType(myFamily)}
|
||||
order := CveContentTypes{NewCveContentType(myFamily), Nvd, NvdXML}
|
||||
order = append(order, AllCveContetTypes.Except(append(order, Jvn)...)...)
|
||||
for _, ctype := range order {
|
||||
if cont, found := v.CveContents[ctype]; found && 0 < len(cont.Summary) {
|
||||
@@ -534,16 +535,17 @@ func (v VulnInfo) MaxCvss2Score() CveContentCvss {
|
||||
func (v VulnInfo) AttackVector() string {
|
||||
for _, cnt := range v.CveContents {
|
||||
if strings.HasPrefix(cnt.Cvss2Vector, "AV:N") ||
|
||||
strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:N") {
|
||||
return "N"
|
||||
strings.Contains(cnt.Cvss3Vector, "AV:N") {
|
||||
return "AV:N"
|
||||
} else if strings.HasPrefix(cnt.Cvss2Vector, "AV:A") ||
|
||||
strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:A") {
|
||||
return "A"
|
||||
strings.Contains(cnt.Cvss3Vector, "AV:A") {
|
||||
return "AV:A"
|
||||
} else if strings.HasPrefix(cnt.Cvss2Vector, "AV:L") ||
|
||||
strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:L") {
|
||||
return "L"
|
||||
} else if strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:P") {
|
||||
return "P"
|
||||
strings.Contains(cnt.Cvss3Vector, "AV:L") {
|
||||
return "AV:L"
|
||||
} else if strings.Contains(cnt.Cvss3Vector, "AV:P") {
|
||||
// no AV:P in CVSS v2
|
||||
return "AV:P"
|
||||
}
|
||||
}
|
||||
if cont, found := v.CveContents[DebianSecurityTracker]; found {
|
||||
@@ -565,6 +567,13 @@ func (v VulnInfo) PatchStatus(packs Packages) string {
|
||||
return "unfixed"
|
||||
}
|
||||
|
||||
// Fast and offline mode can not get the candidate version.
|
||||
// Vuls can be considered as 'fixed' if not-fixed-yet==true and
|
||||
// the fixed-in-version (information in the oval) is not an empty.
|
||||
if p.FixedIn != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// fast, offline mode doesn't have new version
|
||||
if pack, ok := packs[p.Name]; ok {
|
||||
if pack.NewVersion == "" {
|
||||
|
||||
@@ -143,14 +143,14 @@ func TestSummaries(t *testing.T) {
|
||||
Type: Jvn,
|
||||
Value: "Title JVN\nSummary JVN",
|
||||
},
|
||||
{
|
||||
Type: NvdXML,
|
||||
Value: "Summary NVD",
|
||||
},
|
||||
{
|
||||
Type: RedHat,
|
||||
Value: "Summary RedHat",
|
||||
},
|
||||
{
|
||||
Type: NvdXML,
|
||||
Value: "Summary NVD",
|
||||
},
|
||||
},
|
||||
},
|
||||
// lang: en
|
||||
@@ -177,14 +177,14 @@ func TestSummaries(t *testing.T) {
|
||||
},
|
||||
},
|
||||
out: []CveContentStr{
|
||||
{
|
||||
Type: NvdXML,
|
||||
Value: "Summary NVD",
|
||||
},
|
||||
{
|
||||
Type: RedHat,
|
||||
Value: "Summary RedHat",
|
||||
},
|
||||
{
|
||||
Type: NvdXML,
|
||||
Value: "Summary NVD",
|
||||
},
|
||||
},
|
||||
},
|
||||
// lang: empty
|
||||
@@ -1080,3 +1080,86 @@ func TestDistroAdvisories_AppendIfMissing(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVulnInfo_AttackVector(t *testing.T) {
|
||||
type fields struct {
|
||||
CveContents CveContents
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "2.0:N",
|
||||
fields: fields{
|
||||
CveContents: NewCveContents(
|
||||
CveContent{
|
||||
Type: "foo",
|
||||
Cvss2Vector: "AV:N/AC:L/Au:N/C:C/I:C/A:C",
|
||||
},
|
||||
),
|
||||
},
|
||||
want: "AV:N",
|
||||
},
|
||||
{
|
||||
name: "2.0:A",
|
||||
fields: fields{
|
||||
CveContents: NewCveContents(
|
||||
CveContent{
|
||||
Type: "foo",
|
||||
Cvss2Vector: "AV:A/AC:L/Au:N/C:C/I:C/A:C",
|
||||
},
|
||||
),
|
||||
},
|
||||
want: "AV:A",
|
||||
},
|
||||
{
|
||||
name: "2.0:L",
|
||||
fields: fields{
|
||||
CveContents: NewCveContents(
|
||||
CveContent{
|
||||
Type: "foo",
|
||||
Cvss2Vector: "AV:L/AC:L/Au:N/C:C/I:C/A:C",
|
||||
},
|
||||
),
|
||||
},
|
||||
want: "AV:L",
|
||||
},
|
||||
|
||||
{
|
||||
name: "3.0:N",
|
||||
fields: fields{
|
||||
CveContents: NewCveContents(
|
||||
CveContent{
|
||||
Type: "foo",
|
||||
Cvss3Vector: "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
|
||||
},
|
||||
),
|
||||
},
|
||||
want: "AV:N",
|
||||
},
|
||||
{
|
||||
name: "3.1:N",
|
||||
fields: fields{
|
||||
CveContents: NewCveContents(
|
||||
CveContent{
|
||||
Type: "foo",
|
||||
Cvss3Vector: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
|
||||
},
|
||||
),
|
||||
},
|
||||
want: "AV:N",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
v := VulnInfo{
|
||||
CveContents: tt.fields.CveContents,
|
||||
}
|
||||
if got := v.AttackVector(); got != tt.want {
|
||||
t.Errorf("VulnInfo.AttackVector() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
207
oval/debian.go
207
oval/debian.go
@@ -2,6 +2,7 @@ package oval
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
@@ -42,17 +43,28 @@ func (o DebianBase) update(r *models.ScanResult, defPacks defPacks) {
|
||||
vinfo.CveContents = cveContents
|
||||
}
|
||||
|
||||
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
|
||||
// uniq(vinfo.PackNames + defPacks.binpkgStat)
|
||||
for _, pack := range vinfo.AffectedPackages {
|
||||
defPacks.actuallyAffectedPackNames[pack.Name] = pack.NotFixedYet
|
||||
defPacks.binpkgFixstat[pack.Name] = fixStat{
|
||||
notFixedYet: pack.NotFixedYet,
|
||||
fixedIn: pack.FixedIn,
|
||||
isSrcPack: false,
|
||||
}
|
||||
}
|
||||
|
||||
// update notFixedYet of SrcPackage
|
||||
for binName := range defPacks.actuallyAffectedPackNames {
|
||||
// Update package status of source packages.
|
||||
// In the case of Debian based Linux, sometimes source package name is difined as affected package in OVAL.
|
||||
// To display binary package name showed in apt-get, need to convert source name to binary name.
|
||||
for binName := range defPacks.binpkgFixstat {
|
||||
if srcPack, ok := r.SrcPackages.FindByBinName(binName); ok {
|
||||
for _, p := range defPacks.def.AffectedPacks {
|
||||
if p.Name == srcPack.Name {
|
||||
defPacks.actuallyAffectedPackNames[binName] = p.NotFixedYet
|
||||
defPacks.binpkgFixstat[binName] = fixStat{
|
||||
notFixedYet: p.NotFixedYet,
|
||||
fixedIn: p.Version,
|
||||
isSrcPack: true,
|
||||
srcPackName: srcPack.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,9 +146,9 @@ func (o Debian) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err
|
||||
for _, defPacks := range relatedDefs.entries {
|
||||
// Remove "linux" added above for oval search
|
||||
// linux is not a real package name (key of affected packages in OVAL)
|
||||
if notFixedYet, ok := defPacks.actuallyAffectedPackNames["linux"]; ok {
|
||||
defPacks.actuallyAffectedPackNames[linuxImage] = notFixedYet
|
||||
delete(defPacks.actuallyAffectedPackNames, "linux")
|
||||
if notFixedYet, ok := defPacks.binpkgFixstat["linux"]; ok {
|
||||
defPacks.binpkgFixstat[linuxImage] = notFixedYet
|
||||
delete(defPacks.binpkgFixstat, "linux")
|
||||
for i, p := range defPacks.def.AffectedPacks {
|
||||
if p.Name == "linux" {
|
||||
p.Name = linuxImage
|
||||
@@ -178,61 +190,107 @@ func (o Ubuntu) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err
|
||||
switch major(r.Release) {
|
||||
case "14":
|
||||
kernelNamesInOval := []string{
|
||||
"linux",
|
||||
"linux-aws",
|
||||
"linux-azure",
|
||||
"linux-firmware",
|
||||
"linux-lts-utopic",
|
||||
"linux-lts-vivid",
|
||||
"linux-lts-wily",
|
||||
"linux-lts-xenial",
|
||||
"linux-meta",
|
||||
"linux-meta-aws",
|
||||
"linux-meta-azure",
|
||||
"linux-meta-lts-xenial",
|
||||
"linux-signed",
|
||||
"linux-signed-azure",
|
||||
"linux-signed-lts-xenial",
|
||||
"linux",
|
||||
}
|
||||
return o.fillWithOval(driver, r, kernelNamesInOval)
|
||||
case "16":
|
||||
kernelNamesInOval := []string{
|
||||
"linux-image-aws",
|
||||
"linux-image-aws-hwe",
|
||||
"linux-image-azure",
|
||||
"linux-image-extra-virtual",
|
||||
"linux-image-extra-virtual-lts-utopic",
|
||||
"linux-image-extra-virtual-lts-vivid",
|
||||
"linux-image-extra-virtual-lts-wily",
|
||||
"linux-image-extra-virtual-lts-xenial",
|
||||
"linux-image-gcp",
|
||||
"linux-image-generic-lpae",
|
||||
"linux-image-generic-lpae-hwe-16.04",
|
||||
"linux-image-generic-lpae-lts-utopic",
|
||||
"linux-image-generic-lpae-lts-vivid",
|
||||
"linux-image-generic-lpae-lts-wily",
|
||||
"linux-image-generic-lpae-lts-xenial",
|
||||
"linux-image-generic-lts-utopic",
|
||||
"linux-image-generic-lts-vivid",
|
||||
"linux-image-generic-lts-wily",
|
||||
"linux-image-generic-lts-xenial",
|
||||
"linux-image-gke",
|
||||
"linux-image-hwe-generic-trusty",
|
||||
"linux-image-hwe-virtual-trusty",
|
||||
"linux-image-kvm",
|
||||
"linux-image-lowlatency",
|
||||
"linux-image-lowlatency-lts-utopic",
|
||||
"linux-image-lowlatency-lts-vivid",
|
||||
"linux-image-lowlatency-lts-wily",
|
||||
"linux-aws",
|
||||
"linux-aws-hwe",
|
||||
"linux-azure",
|
||||
"linux-euclid",
|
||||
"linux-flo",
|
||||
"linux-gcp",
|
||||
"linux-gke",
|
||||
"linux-goldfish",
|
||||
"linux-hwe",
|
||||
"linux-kvm",
|
||||
"linux-mako",
|
||||
"linux-meta",
|
||||
"linux-meta-aws",
|
||||
"linux-meta-aws-hwe",
|
||||
"linux-meta-azure",
|
||||
"linux-meta-gcp",
|
||||
"linux-meta-hwe",
|
||||
"linux-meta-kvm",
|
||||
"linux-meta-oracle",
|
||||
"linux-meta-raspi2",
|
||||
"linux-meta-snapdragon",
|
||||
"linux-oem",
|
||||
"linux-oracle",
|
||||
"linux-raspi2",
|
||||
"linux-signed",
|
||||
"linux-signed-azure",
|
||||
"linux-signed-gcp",
|
||||
"linux-signed-hwe",
|
||||
"linux-signed-oracle",
|
||||
"linux-snapdragon",
|
||||
"linux",
|
||||
}
|
||||
return o.fillWithOval(driver, r, kernelNamesInOval)
|
||||
case "18":
|
||||
kernelNamesInOval := []string{
|
||||
"linux-image-aws",
|
||||
"linux-image-azure",
|
||||
"linux-image-extra-virtual",
|
||||
"linux-image-gcp",
|
||||
"linux-image-generic-lpae",
|
||||
"linux-image-kvm",
|
||||
"linux-image-lowlatency",
|
||||
"linux-image-oem",
|
||||
"linux-image-oracle",
|
||||
"linux-image-raspi2",
|
||||
"linux-image-snapdragon",
|
||||
"linux-image-virtual",
|
||||
"linux-aws",
|
||||
"linux-aws-5.0",
|
||||
"linux-azure",
|
||||
"linux-gcp",
|
||||
"linux-gcp-5.3",
|
||||
"linux-gke-4.15",
|
||||
"linux-gke-5.0",
|
||||
"linux-gke-5.3",
|
||||
"linux-hwe",
|
||||
"linux-kvm",
|
||||
"linux-meta",
|
||||
"linux-meta-aws",
|
||||
"linux-meta-aws-5.0",
|
||||
"linux-meta-azure",
|
||||
"linux-meta-gcp",
|
||||
"linux-meta-gcp-5.3",
|
||||
"linux-meta-gke-4.15",
|
||||
"linux-meta-gke-5.0",
|
||||
"linux-meta-gke-5.3",
|
||||
"linux-meta-hwe",
|
||||
"linux-meta-kvm",
|
||||
"linux-meta-oem",
|
||||
"linux-meta-oem-osp1",
|
||||
"linux-meta-oracle",
|
||||
"linux-meta-oracle-5.0",
|
||||
"linux-meta-oracle-5.3",
|
||||
"linux-meta-raspi2",
|
||||
"linux-meta-raspi2-5.3",
|
||||
"linux-meta-snapdragon",
|
||||
"linux-oem",
|
||||
"linux-oem-osp1",
|
||||
"linux-oracle",
|
||||
"linux-oracle-5.0",
|
||||
"linux-oracle-5.3",
|
||||
"linux-raspi2",
|
||||
"linux-raspi2-5.3",
|
||||
"linux-signed",
|
||||
"linux-signed-azure",
|
||||
"linux-signed-gcp",
|
||||
"linux-signed-gcp-5.3",
|
||||
"linux-signed-gke-4.15",
|
||||
"linux-signed-gke-5.0",
|
||||
"linux-signed-gke-5.3",
|
||||
"linux-signed-hwe",
|
||||
"linux-signed-oem",
|
||||
"linux-signed-oem-osp1",
|
||||
"linux-signed-oracle",
|
||||
"linux-signed-oracle-5.0",
|
||||
"linux-signed-oracle-5.3",
|
||||
"linux-snapdragon",
|
||||
"linux",
|
||||
}
|
||||
return o.fillWithOval(driver, r, kernelNamesInOval)
|
||||
}
|
||||
@@ -240,12 +298,12 @@ func (o Ubuntu) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err
|
||||
}
|
||||
|
||||
func (o Ubuntu) fillWithOval(driver db.DB, r *models.ScanResult, kernelNamesInOval []string) (nCVEs int, err error) {
|
||||
// kernel names in OVAL except for linux-image-generic
|
||||
linuxImage := "linux-image-" + r.RunningKernel.Release
|
||||
runningKernelVersion := ""
|
||||
kernelPkgInOVAL := ""
|
||||
isOVALKernelPkgAdded := true
|
||||
isOVALKernelPkgAdded := false
|
||||
unusedKernels := []models.Package{}
|
||||
copiedSourcePkgs := models.SrcPackages{}
|
||||
|
||||
if r.Container.ContainerID == "" {
|
||||
if v, ok := r.Packages[linuxImage]; ok {
|
||||
@@ -270,17 +328,31 @@ func (o Ubuntu) fillWithOval(driver db.DB, r *models.ScanResult, kernelNamesInOv
|
||||
}
|
||||
}
|
||||
|
||||
if kernelPkgInOVAL == "" {
|
||||
if r.Release == "14" {
|
||||
kernelPkgInOVAL = "linux"
|
||||
} else if _, ok := r.Packages["linux-image-generic"]; !ok {
|
||||
util.Log.Warnf("The OVAL name of the running kernel image %s is not found. So vulns of linux-image-generic wll be detected. server: %s",
|
||||
r.RunningKernel.Version, r.ServerName)
|
||||
kernelPkgInOVAL = "linux-image-generic"
|
||||
} else {
|
||||
isOVALKernelPkgAdded = false
|
||||
// Remove linux-* in order to detect only vulnerabilities in the running kernel.
|
||||
for n := range r.Packages {
|
||||
if n != kernelPkgInOVAL && strings.HasPrefix(n, "linux-") {
|
||||
unusedKernels = append(unusedKernels, r.Packages[n])
|
||||
delete(r.Packages, n)
|
||||
}
|
||||
}
|
||||
for srcPackName, srcPack := range r.SrcPackages {
|
||||
copiedSourcePkgs[srcPackName] = srcPack
|
||||
targetBianryNames := []string{}
|
||||
for _, n := range srcPack.BinaryNames {
|
||||
if n == kernelPkgInOVAL || !strings.HasPrefix(n, "linux-") {
|
||||
targetBianryNames = append(targetBianryNames, n)
|
||||
}
|
||||
}
|
||||
srcPack.BinaryNames = targetBianryNames
|
||||
r.SrcPackages[srcPackName] = srcPack
|
||||
}
|
||||
|
||||
if kernelPkgInOVAL == "" {
|
||||
util.Log.Warnf("The OVAL name of the running kernel image %+v is not found. So vulns of `linux` wll be detected. server: %s",
|
||||
r.RunningKernel, r.ServerName)
|
||||
kernelPkgInOVAL = "linux"
|
||||
isOVALKernelPkgAdded = true
|
||||
}
|
||||
|
||||
if runningKernelVersion != "" {
|
||||
r.Packages[kernelPkgInOVAL] = models.Package{
|
||||
@@ -307,13 +379,14 @@ func (o Ubuntu) fillWithOval(driver db.DB, r *models.ScanResult, kernelNamesInOv
|
||||
for _, p := range unusedKernels {
|
||||
r.Packages[p.Name] = p
|
||||
}
|
||||
r.SrcPackages = copiedSourcePkgs
|
||||
|
||||
for _, defPacks := range relatedDefs.entries {
|
||||
// Remove "linux" added above to search for oval
|
||||
// Remove "linux" added above for searching oval
|
||||
// "linux" is not a real package name (key of affected packages in OVAL)
|
||||
if nfy, ok := defPacks.actuallyAffectedPackNames[kernelPkgInOVAL]; isOVALKernelPkgAdded && ok {
|
||||
defPacks.actuallyAffectedPackNames[linuxImage] = nfy
|
||||
delete(defPacks.actuallyAffectedPackNames, kernelPkgInOVAL)
|
||||
if nfy, ok := defPacks.binpkgFixstat[kernelPkgInOVAL]; isOVALKernelPkgAdded && ok {
|
||||
defPacks.binpkgFixstat[linuxImage] = nfy
|
||||
delete(defPacks.binpkgFixstat, kernelPkgInOVAL)
|
||||
for i, p := range defPacks.def.AffectedPacks {
|
||||
if p.Name == kernelPkgInOVAL {
|
||||
p.Name = linuxImage
|
||||
|
||||
@@ -33,8 +33,11 @@ func TestPackNamesOfUpdateDebian(t *testing.T) {
|
||||
CveID: "CVE-2000-1000",
|
||||
},
|
||||
},
|
||||
actuallyAffectedPackNames: map[string]bool{
|
||||
"packB": true,
|
||||
binpkgFixstat: map[string]fixStat{
|
||||
"packB": fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "1.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
out: models.ScanResult{
|
||||
@@ -42,7 +45,7 @@ func TestPackNamesOfUpdateDebian(t *testing.T) {
|
||||
"CVE-2000-1000": models.VulnInfo{
|
||||
AffectedPackages: models.PackageFixStatuses{
|
||||
{Name: "packA"},
|
||||
{Name: "packB", NotFixedYet: true},
|
||||
{Name: "packB", NotFixedYet: true, FixedIn: "1.0.0"},
|
||||
{Name: "packC"},
|
||||
},
|
||||
},
|
||||
@@ -57,7 +60,7 @@ func TestPackNamesOfUpdateDebian(t *testing.T) {
|
||||
e := tt.out.ScannedCves["CVE-2000-1000"].AffectedPackages
|
||||
a := tt.in.ScannedCves["CVE-2000-1000"].AffectedPackages
|
||||
if !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("[%d] expected: %v\n actual: %v\n", i, e, a)
|
||||
t.Errorf("[%d] expected: %#v\n actual: %#v\n", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,10 +120,16 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int)
|
||||
|
||||
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
|
||||
for _, pack := range vinfo.AffectedPackages {
|
||||
if nfy, ok := defPacks.actuallyAffectedPackNames[pack.Name]; !ok {
|
||||
defPacks.actuallyAffectedPackNames[pack.Name] = pack.NotFixedYet
|
||||
} else if nfy {
|
||||
defPacks.actuallyAffectedPackNames[pack.Name] = true
|
||||
if stat, ok := defPacks.binpkgFixstat[pack.Name]; !ok {
|
||||
defPacks.binpkgFixstat[pack.Name] = fixStat{
|
||||
notFixedYet: pack.NotFixedYet,
|
||||
fixedIn: pack.FixedIn,
|
||||
}
|
||||
} else if stat.notFixedYet {
|
||||
defPacks.binpkgFixstat[pack.Name] = fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: pack.FixedIn,
|
||||
}
|
||||
}
|
||||
}
|
||||
vinfo.AffectedPackages = defPacks.toPackStatuses()
|
||||
@@ -219,12 +225,17 @@ func (o RedHatBase) parseCvss2(scoreVector string) (score float64, vector string
|
||||
// 5.6/CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L
|
||||
func (o RedHatBase) parseCvss3(scoreVector string) (score float64, vector string) {
|
||||
var err error
|
||||
ss := strings.Split(scoreVector, "/CVSS:3.0/")
|
||||
if 1 < len(ss) {
|
||||
if score, err = strconv.ParseFloat(ss[0], 64); err != nil {
|
||||
return 0, ""
|
||||
for _, s := range []string{
|
||||
"/CVSS:3.0/",
|
||||
"/CVSS:3.1/",
|
||||
} {
|
||||
ss := strings.Split(scoreVector, s)
|
||||
if 1 < len(ss) {
|
||||
if score, err = strconv.ParseFloat(ss[0], 64); err != nil {
|
||||
return 0, ""
|
||||
}
|
||||
return score, strings.TrimPrefix(s, "/") + ss[1]
|
||||
}
|
||||
return score, fmt.Sprintf("CVSS:3.0/%s", ss[1])
|
||||
}
|
||||
return 0, ""
|
||||
}
|
||||
|
||||
@@ -59,6 +59,13 @@ func TestParseCvss3(t *testing.T) {
|
||||
vector: "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
|
||||
},
|
||||
},
|
||||
{
|
||||
in: "6.1/CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
|
||||
out: out{
|
||||
score: 6.1,
|
||||
vector: "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
|
||||
},
|
||||
},
|
||||
{
|
||||
in: "",
|
||||
out: out{
|
||||
@@ -103,8 +110,11 @@ func TestPackNamesOfUpdate(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
actuallyAffectedPackNames: map[string]bool{
|
||||
"packB": true,
|
||||
binpkgFixstat: map[string]fixStat{
|
||||
"packB": fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "1.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
out: models.ScanResult{
|
||||
|
||||
@@ -75,7 +75,10 @@ func (o SUSE) update(r *models.ScanResult, defPacks defPacks) {
|
||||
|
||||
// uniq(vinfo.PackNames + defPacks.actuallyAffectedPackNames)
|
||||
for _, pack := range vinfo.AffectedPackages {
|
||||
defPacks.actuallyAffectedPackNames[pack.Name] = pack.NotFixedYet
|
||||
defPacks.binpkgFixstat[pack.Name] = fixStat{
|
||||
notFixedYet: pack.NotFixedYet,
|
||||
fixedIn: pack.FixedIn,
|
||||
}
|
||||
}
|
||||
vinfo.AffectedPackages = defPacks.toPackStatuses()
|
||||
vinfo.AffectedPackages.Sort()
|
||||
|
||||
79
oval/util.go
79
oval/util.go
@@ -27,32 +27,42 @@ type defPacks struct {
|
||||
def ovalmodels.Definition
|
||||
|
||||
// BinaryPackageName : NotFixedYet
|
||||
actuallyAffectedPackNames map[string]bool
|
||||
binpkgFixstat map[string]fixStat
|
||||
}
|
||||
|
||||
type fixStat struct {
|
||||
notFixedYet bool
|
||||
fixedIn string
|
||||
isSrcPack bool
|
||||
srcPackName string
|
||||
}
|
||||
|
||||
func (e defPacks) toPackStatuses() (ps models.PackageFixStatuses) {
|
||||
for name, notFixedYet := range e.actuallyAffectedPackNames {
|
||||
for name, stat := range e.binpkgFixstat {
|
||||
ps = append(ps, models.PackageFixStatus{
|
||||
Name: name,
|
||||
NotFixedYet: notFixedYet,
|
||||
NotFixedYet: stat.notFixedYet,
|
||||
FixedIn: stat.fixedIn,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (e *ovalResult) upsert(def ovalmodels.Definition, packName string, notFixedYet bool) (upserted bool) {
|
||||
func (e *ovalResult) upsert(def ovalmodels.Definition, packName string, fstat fixStat) (upserted bool) {
|
||||
// alpine's entry is empty since Alpine secdb is not OVAL format
|
||||
if def.DefinitionID != "" {
|
||||
for i, entry := range e.entries {
|
||||
if entry.def.DefinitionID == def.DefinitionID {
|
||||
e.entries[i].actuallyAffectedPackNames[packName] = notFixedYet
|
||||
e.entries[i].binpkgFixstat[packName] = fstat
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
e.entries = append(e.entries, defPacks{
|
||||
def: def,
|
||||
actuallyAffectedPackNames: map[string]bool{packName: notFixedYet},
|
||||
def: def,
|
||||
binpkgFixstat: map[string]fixStat{
|
||||
packName: fstat,
|
||||
},
|
||||
})
|
||||
|
||||
return false
|
||||
@@ -134,17 +144,27 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult) (
|
||||
select {
|
||||
case res := <-resChan:
|
||||
for _, def := range res.defs {
|
||||
affected, notFixedYet := isOvalDefAffected(def, res.request, r.Family, r.RunningKernel)
|
||||
affected, notFixedYet, fixedIn := isOvalDefAffected(def, res.request, r.Family, r.RunningKernel)
|
||||
if !affected {
|
||||
continue
|
||||
}
|
||||
|
||||
if res.request.isSrcPack {
|
||||
for _, n := range res.request.binaryPackNames {
|
||||
relatedDefs.upsert(def, n, false)
|
||||
fs := fixStat{
|
||||
srcPackName: res.request.packName,
|
||||
isSrcPack: true,
|
||||
notFixedYet: notFixedYet,
|
||||
fixedIn: fixedIn,
|
||||
}
|
||||
relatedDefs.upsert(def, n, fs)
|
||||
}
|
||||
} else {
|
||||
relatedDefs.upsert(def, res.request.packName, notFixedYet)
|
||||
fs := fixStat{
|
||||
notFixedYet: notFixedYet,
|
||||
fixedIn: fixedIn,
|
||||
}
|
||||
relatedDefs.upsert(def, res.request.packName, fs)
|
||||
}
|
||||
}
|
||||
case err := <-errChan:
|
||||
@@ -227,17 +247,27 @@ func getDefsByPackNameFromOvalDB(driver db.DB, r *models.ScanResult) (relatedDef
|
||||
return relatedDefs, xerrors.Errorf("Failed to get %s OVAL info by package: %#v, err: %w", r.Family, req, err)
|
||||
}
|
||||
for _, def := range definitions {
|
||||
affected, notFixedYet := isOvalDefAffected(def, req, r.Family, r.RunningKernel)
|
||||
affected, notFixedYet, fixedIn := isOvalDefAffected(def, req, r.Family, r.RunningKernel)
|
||||
if !affected {
|
||||
continue
|
||||
}
|
||||
|
||||
if req.isSrcPack {
|
||||
for _, n := range req.binaryPackNames {
|
||||
relatedDefs.upsert(def, n, false)
|
||||
for _, binName := range req.binaryPackNames {
|
||||
fs := fixStat{
|
||||
notFixedYet: false,
|
||||
isSrcPack: true,
|
||||
fixedIn: fixedIn,
|
||||
srcPackName: req.packName,
|
||||
}
|
||||
relatedDefs.upsert(def, binName, fs)
|
||||
}
|
||||
} else {
|
||||
relatedDefs.upsert(def, req.packName, notFixedYet)
|
||||
fs := fixStat{
|
||||
notFixedYet: notFixedYet,
|
||||
fixedIn: fixedIn,
|
||||
}
|
||||
relatedDefs.upsert(def, req.packName, fs)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,7 +285,7 @@ func major(version string) string {
|
||||
return ver[0:strings.Index(ver, ".")]
|
||||
}
|
||||
|
||||
func isOvalDefAffected(def ovalmodels.Definition, req request, family string, running models.Kernel) (affected, notFixedYet bool) {
|
||||
func isOvalDefAffected(def ovalmodels.Definition, req request, family string, running models.Kernel) (affected, notFixedYet bool, fixedIn string) {
|
||||
for _, ovalPack := range def.AffectedPacks {
|
||||
if req.packName != ovalPack.Name {
|
||||
continue
|
||||
@@ -274,7 +304,7 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru
|
||||
}
|
||||
|
||||
if ovalPack.NotFixedYet {
|
||||
return true, true
|
||||
return true, true, ovalPack.Version
|
||||
}
|
||||
|
||||
// Compare between the installed version vs the version in OVAL
|
||||
@@ -282,9 +312,14 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru
|
||||
if err != nil {
|
||||
util.Log.Debugf("Failed to parse versions: %s, Ver: %#v, OVAL: %#v, DefID: %s",
|
||||
err, req.versionRelease, ovalPack, def.DefinitionID)
|
||||
return false, false
|
||||
return false, false, ovalPack.Version
|
||||
}
|
||||
if less {
|
||||
if req.isSrcPack {
|
||||
// Unable to judge whether fixed or not-fixed of src package(Ubuntu, Debian)
|
||||
return true, false, ovalPack.Version
|
||||
}
|
||||
|
||||
// If the version of installed is less than in OVAL
|
||||
switch family {
|
||||
case config.RedHat,
|
||||
@@ -293,7 +328,7 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru
|
||||
config.Debian,
|
||||
config.Ubuntu:
|
||||
// Use fixed state in OVAL for these distros.
|
||||
return true, false
|
||||
return true, false, ovalPack.Version
|
||||
}
|
||||
|
||||
// But CentOS can't judge whether fixed or unfixed.
|
||||
@@ -304,7 +339,7 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru
|
||||
// In these mode, the blow field was set empty.
|
||||
// Vuls can not judge fixed or unfixed.
|
||||
if req.newVersionRelease == "" {
|
||||
return true, false
|
||||
return true, false, ovalPack.Version
|
||||
}
|
||||
|
||||
// compare version: newVer vs oval
|
||||
@@ -312,12 +347,12 @@ func isOvalDefAffected(def ovalmodels.Definition, req request, family string, ru
|
||||
if err != nil {
|
||||
util.Log.Debugf("Failed to parse versions: %s, NewVer: %#v, OVAL: %#v, DefID: %s",
|
||||
err, req.newVersionRelease, ovalPack, def.DefinitionID)
|
||||
return false, false
|
||||
return false, false, ovalPack.Version
|
||||
}
|
||||
return true, less
|
||||
return true, less, ovalPack.Version
|
||||
}
|
||||
}
|
||||
return false, false
|
||||
return false, false, ""
|
||||
}
|
||||
|
||||
var centosVerPattern = regexp.MustCompile(`\.[es]l(\d+)(?:_\d+)?(?:\.centos)?`)
|
||||
|
||||
@@ -12,12 +12,12 @@ import (
|
||||
|
||||
func TestUpsert(t *testing.T) {
|
||||
var tests = []struct {
|
||||
res ovalResult
|
||||
def ovalmodels.Definition
|
||||
packName string
|
||||
notFixedYet bool
|
||||
upserted bool
|
||||
out ovalResult
|
||||
res ovalResult
|
||||
def ovalmodels.Definition
|
||||
packName string
|
||||
fixStat fixStat
|
||||
upserted bool
|
||||
out ovalResult
|
||||
}{
|
||||
//insert
|
||||
{
|
||||
@@ -25,17 +25,23 @@ func TestUpsert(t *testing.T) {
|
||||
def: ovalmodels.Definition{
|
||||
DefinitionID: "1111",
|
||||
},
|
||||
packName: "pack1",
|
||||
notFixedYet: true,
|
||||
upserted: false,
|
||||
packName: "pack1",
|
||||
fixStat: fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "1.0.0",
|
||||
},
|
||||
upserted: false,
|
||||
out: ovalResult{
|
||||
[]defPacks{
|
||||
{
|
||||
def: ovalmodels.Definition{
|
||||
DefinitionID: "1111",
|
||||
},
|
||||
actuallyAffectedPackNames: map[string]bool{
|
||||
"pack1": true,
|
||||
binpkgFixstat: map[string]fixStat{
|
||||
"pack1": fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "1.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -49,16 +55,22 @@ func TestUpsert(t *testing.T) {
|
||||
def: ovalmodels.Definition{
|
||||
DefinitionID: "1111",
|
||||
},
|
||||
actuallyAffectedPackNames: map[string]bool{
|
||||
"pack1": true,
|
||||
binpkgFixstat: map[string]fixStat{
|
||||
"pack1": fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "1.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
def: ovalmodels.Definition{
|
||||
DefinitionID: "2222",
|
||||
},
|
||||
actuallyAffectedPackNames: map[string]bool{
|
||||
"pack3": true,
|
||||
binpkgFixstat: map[string]fixStat{
|
||||
"pack3": fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "2.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -66,26 +78,38 @@ func TestUpsert(t *testing.T) {
|
||||
def: ovalmodels.Definition{
|
||||
DefinitionID: "1111",
|
||||
},
|
||||
packName: "pack2",
|
||||
notFixedYet: false,
|
||||
upserted: true,
|
||||
packName: "pack2",
|
||||
fixStat: fixStat{
|
||||
notFixedYet: false,
|
||||
fixedIn: "3.0.0",
|
||||
},
|
||||
upserted: true,
|
||||
out: ovalResult{
|
||||
[]defPacks{
|
||||
{
|
||||
def: ovalmodels.Definition{
|
||||
DefinitionID: "1111",
|
||||
},
|
||||
actuallyAffectedPackNames: map[string]bool{
|
||||
"pack1": true,
|
||||
"pack2": false,
|
||||
binpkgFixstat: map[string]fixStat{
|
||||
"pack1": fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "1.0.0",
|
||||
},
|
||||
"pack2": fixStat{
|
||||
notFixedYet: false,
|
||||
fixedIn: "3.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
def: ovalmodels.Definition{
|
||||
DefinitionID: "2222",
|
||||
},
|
||||
actuallyAffectedPackNames: map[string]bool{
|
||||
"pack3": true,
|
||||
binpkgFixstat: map[string]fixStat{
|
||||
"pack3": fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "2.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -93,7 +117,7 @@ func TestUpsert(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
upserted := tt.res.upsert(tt.def, tt.packName, tt.notFixedYet)
|
||||
upserted := tt.res.upsert(tt.def, tt.packName, tt.fixStat)
|
||||
if tt.upserted != upserted {
|
||||
t.Errorf("[%d]\nexpected: %t\n actual: %t\n", i, tt.upserted, upserted)
|
||||
}
|
||||
@@ -121,17 +145,27 @@ func TestDefpacksToPackStatuses(t *testing.T) {
|
||||
{
|
||||
Name: "a",
|
||||
NotFixedYet: true,
|
||||
Version: "1.0.0",
|
||||
},
|
||||
{
|
||||
Name: "b",
|
||||
NotFixedYet: false,
|
||||
Version: "2.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
actuallyAffectedPackNames: map[string]bool{
|
||||
"a": true,
|
||||
"b": true,
|
||||
"c": true,
|
||||
binpkgFixstat: map[string]fixStat{
|
||||
"a": fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "1.0.0",
|
||||
isSrcPack: false,
|
||||
},
|
||||
"b": fixStat{
|
||||
notFixedYet: true,
|
||||
fixedIn: "1.0.0",
|
||||
isSrcPack: true,
|
||||
srcPackName: "lib-b",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -139,14 +173,12 @@ func TestDefpacksToPackStatuses(t *testing.T) {
|
||||
{
|
||||
Name: "a",
|
||||
NotFixedYet: true,
|
||||
FixedIn: "1.0.0",
|
||||
},
|
||||
{
|
||||
Name: "b",
|
||||
NotFixedYet: true,
|
||||
},
|
||||
{
|
||||
Name: "c",
|
||||
NotFixedYet: true,
|
||||
FixedIn: "1.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -173,6 +205,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
in in
|
||||
affected bool
|
||||
notFixedYet bool
|
||||
fixedIn string
|
||||
}{
|
||||
// 0. Ubuntu ovalpack.NotFixedYet == true
|
||||
{
|
||||
@@ -187,6 +220,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
{
|
||||
Name: "b",
|
||||
NotFixedYet: true,
|
||||
Version: "1.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -196,6 +230,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: true,
|
||||
fixedIn: "1.0.0",
|
||||
},
|
||||
// 1. Ubuntu
|
||||
// ovalpack.NotFixedYet == false
|
||||
@@ -226,6 +261,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "1.0.0-1",
|
||||
},
|
||||
// 2. Ubuntu
|
||||
// ovalpack.NotFixedYet == false
|
||||
@@ -285,6 +321,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
},
|
||||
affected: true,
|
||||
fixedIn: "1.0.0-3",
|
||||
notFixedYet: false,
|
||||
},
|
||||
// 4. Ubuntu
|
||||
@@ -318,6 +355,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "1.0.0-2",
|
||||
},
|
||||
// 5 RedHat
|
||||
{
|
||||
@@ -345,6 +383,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
// 6 RedHat
|
||||
{
|
||||
@@ -372,6 +411,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
// 7 RedHat
|
||||
{
|
||||
@@ -451,6 +491,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
// 10 RedHat
|
||||
{
|
||||
@@ -478,6 +519,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
// 11 RedHat
|
||||
{
|
||||
@@ -504,6 +546,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
// 12 RedHat
|
||||
{
|
||||
@@ -583,6 +626,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
// 15
|
||||
{
|
||||
@@ -662,6 +706,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: true,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
// 18
|
||||
{
|
||||
@@ -689,6 +734,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
// 19
|
||||
{
|
||||
@@ -716,6 +762,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
// 20
|
||||
{
|
||||
@@ -794,6 +841,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
{
|
||||
in: in{
|
||||
@@ -870,6 +918,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: true,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
{
|
||||
in: in{
|
||||
@@ -896,6 +945,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
{
|
||||
in: in{
|
||||
@@ -922,6 +972,7 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "0:1.2.3-45.el6_7.8",
|
||||
},
|
||||
{
|
||||
in: in{
|
||||
@@ -1021,16 +1072,20 @@ func TestIsOvalDefAffected(t *testing.T) {
|
||||
},
|
||||
affected: true,
|
||||
notFixedYet: false,
|
||||
fixedIn: "3.1.0",
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
affected, notFixedYet := isOvalDefAffected(tt.in.def, tt.in.req, tt.in.family, tt.in.kernel)
|
||||
affected, notFixedYet, fixedIn := isOvalDefAffected(tt.in.def, tt.in.req, tt.in.family, tt.in.kernel)
|
||||
if tt.affected != affected {
|
||||
t.Errorf("[%d] affected\nexpected: %v\n actual: %v\n", i, tt.affected, affected)
|
||||
}
|
||||
if tt.notFixedYet != notFixedYet {
|
||||
t.Errorf("[%d] notfixedyet\nexpected: %v\n actual: %v\n", i, tt.notFixedYet, notFixedYet)
|
||||
}
|
||||
if tt.fixedIn != fixedIn {
|
||||
t.Errorf("[%d] fixedIn\nexpected: %v\n actual: %v\n", i, tt.fixedIn, fixedIn)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ func fillCertAlerts(cvedetail *cvemodels.CveDetail) (dict models.AlertDict) {
|
||||
dict.Ja = append(dict.Ja, models.Alert{
|
||||
URL: cert.Link,
|
||||
Title: cert.Title,
|
||||
Team: "ja",
|
||||
Team: "jp",
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -346,7 +346,10 @@ func FillWithGost(driver gostdb.DB, r *models.ScanResult, ignoreWillNotFix bool)
|
||||
gostClient := gost.NewClient(r.Family)
|
||||
// TODO chekc if fetched
|
||||
// TODO chekc if fresh enough
|
||||
return gostClient.FillWithGost(driver, r, ignoreWillNotFix)
|
||||
if nCVEs, err = gostClient.DetectUnfixed(driver, r, ignoreWillNotFix); err != nil {
|
||||
return
|
||||
}
|
||||
return nCVEs, gostClient.FillCVEsWithRedHat(driver, r)
|
||||
}
|
||||
|
||||
// FillWithExploit fills Exploits with exploit dataabase
|
||||
@@ -464,6 +467,12 @@ func fillCweDict(r *models.ScanResult) {
|
||||
if rank, ok := cwe.OwaspTopTen2017[id]; ok {
|
||||
entry.OwaspTopTen2017 = rank
|
||||
}
|
||||
if rank, ok := cwe.CweTopTwentyfive2019[id]; ok {
|
||||
entry.CweTopTwentyfive2019 = rank
|
||||
}
|
||||
if rank, ok := cwe.SansTopTwentyfive[id]; ok {
|
||||
entry.SansTopTwentyfive = rank
|
||||
}
|
||||
entry.En = &e
|
||||
} else {
|
||||
util.Log.Debugf("CWE-ID %s is not found in English CWE Dict", id)
|
||||
@@ -475,6 +484,12 @@ func fillCweDict(r *models.ScanResult) {
|
||||
if rank, ok := cwe.OwaspTopTen2017[id]; ok {
|
||||
entry.OwaspTopTen2017 = rank
|
||||
}
|
||||
if rank, ok := cwe.CweTopTwentyfive2019[id]; ok {
|
||||
entry.CweTopTwentyfive2019 = rank
|
||||
}
|
||||
if rank, ok := cwe.SansTopTwentyfive[id]; ok {
|
||||
entry.SansTopTwentyfive = rank
|
||||
}
|
||||
entry.Ja = &e
|
||||
} else {
|
||||
util.Log.Debugf("CWE-ID %s is not found in Japanese CWE Dict", id)
|
||||
@@ -527,7 +542,7 @@ func EnsureUUIDs(configPath string, results models.ScanResults) error {
|
||||
server.UUIDs[r.ServerName] = uuid
|
||||
}
|
||||
} else if r.IsImage() {
|
||||
name = fmt.Sprintf("%s:%s@%s", r.Image.Name, r.Image.Tag, r.ServerName)
|
||||
name = fmt.Sprintf("%s%s@%s", r.Image.Tag, r.Image.Digest, r.ServerName)
|
||||
if uuid := getOrCreateServerUUID(r, server); uuid != "" {
|
||||
server.UUIDs[r.ServerName] = uuid
|
||||
}
|
||||
|
||||
@@ -329,14 +329,24 @@ func attachmentText(vinfo models.VulnInfo, osFamily string, cweDict map[string]m
|
||||
func cweIDs(vinfo models.VulnInfo, osFamily string, cweDict models.CweDict) string {
|
||||
links := []string{}
|
||||
for _, c := range vinfo.CveContents.UniqCweIDs(osFamily) {
|
||||
name, url, top10Rank, top10URL := cweDict.Get(c.Value, osFamily)
|
||||
name, url, top10Rank, top10URL, cweTop25Rank, cweTop25URL, sansTop25Rank, sansTop25URL := cweDict.Get(c.Value, osFamily)
|
||||
line := ""
|
||||
if top10Rank != "" {
|
||||
line = fmt.Sprintf("<%s|[OWASP Top %s]>",
|
||||
top10URL, top10Rank)
|
||||
}
|
||||
links = append(links, fmt.Sprintf("%s <%s|%s>: %s",
|
||||
line, url, c.Value, name))
|
||||
if cweTop25Rank != "" {
|
||||
line = fmt.Sprintf("<%s|[CWE Top %s]>",
|
||||
cweTop25URL, cweTop25Rank)
|
||||
}
|
||||
if sansTop25Rank != "" {
|
||||
line = fmt.Sprintf("<%s|[CWE/SANS Top %s]>",
|
||||
sansTop25URL, sansTop25Rank)
|
||||
}
|
||||
if top10Rank == "" && cweTop25Rank == "" && sansTop25Rank == "" {
|
||||
links = append(links, fmt.Sprintf("%s <%s|%s>: %s",
|
||||
line, url, c.Value, name))
|
||||
}
|
||||
}
|
||||
return strings.Join(links, "\n")
|
||||
}
|
||||
|
||||
@@ -622,14 +622,20 @@ func summaryLines(r models.ScanResult) string {
|
||||
pkgNames = append(pkgNames, vinfo.GitHubSecurityAlerts.Names()...)
|
||||
pkgNames = append(pkgNames, vinfo.WpPackageFixStats.Names()...)
|
||||
|
||||
exploits := ""
|
||||
if 0 < len(vinfo.Exploits) {
|
||||
exploits = "POC"
|
||||
}
|
||||
|
||||
var cols []string
|
||||
cols = []string{
|
||||
fmt.Sprintf(indexFormat, i+1),
|
||||
vinfo.CveID,
|
||||
cvssScore + " |",
|
||||
fmt.Sprintf("%1s |", vinfo.AttackVector()),
|
||||
fmt.Sprintf("%7s |", vinfo.PatchStatus(r.Packages)),
|
||||
fmt.Sprintf("%4s |", vinfo.AttackVector()),
|
||||
fmt.Sprintf("%3s |", exploits),
|
||||
fmt.Sprintf("%6s |", vinfo.AlertDict.FormatSource()),
|
||||
fmt.Sprintf("%7s |", vinfo.PatchStatus(r.Packages)),
|
||||
strings.Join(pkgNames, ", "),
|
||||
}
|
||||
icols := make([]interface{}, len(cols))
|
||||
@@ -700,12 +706,10 @@ func setChangelogLayout(g *gocui.Gui) error {
|
||||
var line string
|
||||
if pack.Repository != "" {
|
||||
line = fmt.Sprintf("* %s (%s)",
|
||||
pack.FormatVersionFromTo(affected.NotFixedYet, affected.FixState),
|
||||
pack.FormatVersionFromTo(affected),
|
||||
pack.Repository)
|
||||
} else {
|
||||
line = fmt.Sprintf("* %s",
|
||||
pack.FormatVersionFromTo(affected.NotFixedYet, affected.FixState),
|
||||
)
|
||||
line = fmt.Sprintf("* %s", pack.FormatVersionFromTo(affected))
|
||||
}
|
||||
lines = append(lines, line)
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ No CVE-IDs are found in updatable packages.
|
||||
|
||||
exploits := ""
|
||||
if 0 < len(vinfo.Exploits) {
|
||||
exploits = " Y"
|
||||
exploits = "POC"
|
||||
}
|
||||
|
||||
link := ""
|
||||
@@ -139,13 +139,13 @@ No CVE-IDs are found in updatable packages.
|
||||
|
||||
data = append(data, []string{
|
||||
vinfo.CveID,
|
||||
fmt.Sprintf("%7s", vinfo.PatchStatus(r.Packages)),
|
||||
vinfo.AlertDict.FormatSource(),
|
||||
fmt.Sprintf("%4.1f", max),
|
||||
fmt.Sprintf("%5s", vinfo.AttackVector()),
|
||||
// fmt.Sprintf("%4.1f", v2max),
|
||||
// fmt.Sprintf("%4.1f", v3max),
|
||||
fmt.Sprintf("%2s", vinfo.AttackVector()),
|
||||
exploits,
|
||||
vinfo.AlertDict.FormatSource(),
|
||||
fmt.Sprintf("%7s", vinfo.PatchStatus(r.Packages)),
|
||||
link,
|
||||
})
|
||||
}
|
||||
@@ -154,13 +154,13 @@ No CVE-IDs are found in updatable packages.
|
||||
table := tablewriter.NewWriter(&b)
|
||||
table.SetHeader([]string{
|
||||
"CVE-ID",
|
||||
"Fixed",
|
||||
"CERT",
|
||||
"CVSS",
|
||||
"Attack",
|
||||
// "v3",
|
||||
// "v2",
|
||||
"AV",
|
||||
"PoC",
|
||||
"CERT",
|
||||
"Fixed",
|
||||
"NVD",
|
||||
})
|
||||
table.SetBorder(true)
|
||||
@@ -217,14 +217,28 @@ No CVE-IDs are found in updatable packages.
|
||||
}
|
||||
|
||||
cweURLs, top10URLs := []string{}, []string{}
|
||||
cweTop25URLs, sansTop25URLs := []string{}, []string{}
|
||||
for _, v := range vuln.CveContents.UniqCweIDs(r.Family) {
|
||||
name, url, top10Rank, top10URL := r.CweDict.Get(v.Value, r.Lang)
|
||||
name, url, top10Rank, top10URL, cweTop25Rank, cweTop25URL, sansTop25Rank, sansTop25URL := r.CweDict.Get(v.Value, r.Lang)
|
||||
if top10Rank != "" {
|
||||
data = append(data, []string{"CWE",
|
||||
fmt.Sprintf("[OWASP Top%s] %s: %s (%s)",
|
||||
top10Rank, v.Value, name, v.Type)})
|
||||
top10URLs = append(top10URLs, top10URL)
|
||||
} else {
|
||||
}
|
||||
if cweTop25Rank != "" {
|
||||
data = append(data, []string{"CWE",
|
||||
fmt.Sprintf("[CWE Top%s] %s: %s (%s)",
|
||||
cweTop25Rank, v.Value, name, v.Type)})
|
||||
cweTop25URLs = append(cweTop25URLs, cweTop25URL)
|
||||
}
|
||||
if sansTop25Rank != "" {
|
||||
data = append(data, []string{"CWE",
|
||||
fmt.Sprintf("[CWE/SANS Top%s] %s: %s (%s)",
|
||||
sansTop25Rank, v.Value, name, v.Type)})
|
||||
sansTop25URLs = append(sansTop25URLs, sansTop25URL)
|
||||
}
|
||||
if top10Rank == "" && cweTop25Rank == "" && sansTop25Rank == "" {
|
||||
data = append(data, []string{"CWE", fmt.Sprintf("%s: %s (%s)",
|
||||
v.Value, name, v.Type)})
|
||||
}
|
||||
@@ -237,12 +251,10 @@ No CVE-IDs are found in updatable packages.
|
||||
var line string
|
||||
if pack.Repository != "" {
|
||||
line = fmt.Sprintf("%s (%s)",
|
||||
pack.FormatVersionFromTo(affected.NotFixedYet, affected.FixState),
|
||||
pack.FormatVersionFromTo(affected),
|
||||
pack.Repository)
|
||||
} else {
|
||||
line = fmt.Sprintf("%s",
|
||||
pack.FormatVersionFromTo(affected.NotFixedYet, affected.FixState),
|
||||
)
|
||||
line = pack.FormatVersionFromTo(affected)
|
||||
}
|
||||
data = append(data, []string{"Affected Pkg", line})
|
||||
|
||||
@@ -309,6 +321,12 @@ No CVE-IDs are found in updatable packages.
|
||||
for _, url := range top10URLs {
|
||||
data = append(data, []string{"OWASP Top10", url})
|
||||
}
|
||||
if len(cweTop25URLs) != 0 {
|
||||
data = append(data, []string{"CWE Top25", cweTop25URLs[0]})
|
||||
}
|
||||
if len(sansTop25URLs) != 0 {
|
||||
data = append(data, []string{"SANS/CWE Top25", sansTop25URLs[0]})
|
||||
}
|
||||
|
||||
for _, alert := range vuln.AlertDict.Ja {
|
||||
data = append(data, []string{"JPCERT Alert", alert.URL})
|
||||
|
||||
@@ -75,7 +75,8 @@ func (o *alpine) apkUpdate() error {
|
||||
func (o *alpine) preCure() error {
|
||||
o.log.Infof("Scanning in %s", o.getServerInfo().Mode)
|
||||
if err := o.detectIPAddr(); err != nil {
|
||||
o.log.Debugf("Failed to detect IP addresses: %s", err)
|
||||
o.log.Warnf("Failed to detect IP addresses: %s", err)
|
||||
o.warns = append(o.warns, err)
|
||||
}
|
||||
// Ignore this error as it just failed to detect the IP addresses
|
||||
return nil
|
||||
|
||||
11
scan/base.go
11
scan/base.go
@@ -417,8 +417,9 @@ func (l *base) convertToModel() models.ScanResult {
|
||||
}
|
||||
|
||||
image := models.Image{
|
||||
Name: l.ServerInfo.Image.Name,
|
||||
Tag: l.ServerInfo.Image.Tag,
|
||||
Name: l.ServerInfo.Image.Name,
|
||||
Tag: l.ServerInfo.Image.Tag,
|
||||
Digest: l.ServerInfo.Image.Digest,
|
||||
}
|
||||
|
||||
errs, warns := []string{}, []string{}
|
||||
@@ -555,7 +556,7 @@ func (l *base) scanLibraries() (err error) {
|
||||
// find / -name "*package-lock.json" -o -name "*yarn.lock" ... 2>&1 | grep -v "Permission denied"
|
||||
cmd := fmt.Sprintf(`find / ` + findopt[:len(findopt)-3] + ` 2>&1 | grep -v "Permission denied"`)
|
||||
r := exec(l.ServerInfo, cmd, noSudo)
|
||||
if !r.isSuccess() {
|
||||
if r.ExitStatus != 0 && r.ExitStatus != 1 {
|
||||
return xerrors.Errorf("Failed to find lock files")
|
||||
}
|
||||
detectFiles = append(detectFiles, strings.Split(r.Stdout, "\n")...)
|
||||
@@ -670,7 +671,7 @@ func (l *base) detectWpCore() (string, error) {
|
||||
}
|
||||
|
||||
func (l *base) detectWpThemes() ([]models.WpPackage, error) {
|
||||
cmd := fmt.Sprintf("sudo -u %s -i -- %s theme list --path=%s --format=json --allow-root",
|
||||
cmd := fmt.Sprintf("sudo -u %s -i -- %s theme list --path=%s --format=json --allow-root 2>/dev/null",
|
||||
l.ServerInfo.WordPress.OSUser,
|
||||
l.ServerInfo.WordPress.CmdPath,
|
||||
l.ServerInfo.WordPress.DocRoot)
|
||||
@@ -691,7 +692,7 @@ func (l *base) detectWpThemes() ([]models.WpPackage, error) {
|
||||
}
|
||||
|
||||
func (l *base) detectWpPlugins() ([]models.WpPackage, error) {
|
||||
cmd := fmt.Sprintf("sudo -u %s -i -- %s plugin list --path=%s --format=json --allow-root",
|
||||
cmd := fmt.Sprintf("sudo -u %s -i -- %s plugin list --path=%s --format=json --allow-root 2>/dev/null",
|
||||
l.ServerInfo.WordPress.OSUser,
|
||||
l.ServerInfo.WordPress.CmdPath,
|
||||
l.ServerInfo.WordPress.DocRoot)
|
||||
|
||||
@@ -49,11 +49,8 @@ func (o *centos) depsFast() []string {
|
||||
}
|
||||
|
||||
// repoquery
|
||||
majorVersion, _ := o.Distro.MajorVersion()
|
||||
if majorVersion < 8 {
|
||||
return []string{"yum-utils"}
|
||||
}
|
||||
return []string{"dnf-utils"}
|
||||
// `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8
|
||||
return []string{"yum-utils"}
|
||||
}
|
||||
|
||||
func (o *centos) depsFastRoot() []string {
|
||||
@@ -62,11 +59,8 @@ func (o *centos) depsFastRoot() []string {
|
||||
}
|
||||
|
||||
// repoquery
|
||||
majorVersion, _ := o.Distro.MajorVersion()
|
||||
if majorVersion < 8 {
|
||||
return []string{"yum-utils"}
|
||||
}
|
||||
return []string{"dnf-utils"}
|
||||
// `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8
|
||||
return []string{"yum-utils"}
|
||||
}
|
||||
|
||||
func (o *centos) depsDeep() []string {
|
||||
|
||||
@@ -7,6 +7,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aquasecurity/fanal/analyzer"
|
||||
"github.com/aquasecurity/fanal/cache"
|
||||
"github.com/aquasecurity/fanal/extractor/docker"
|
||||
"github.com/aquasecurity/fanal/utils"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
fanalos "github.com/aquasecurity/fanal/analyzer/os"
|
||||
@@ -28,8 +31,8 @@ import (
|
||||
_ "github.com/aquasecurity/fanal/analyzer/os/alpine"
|
||||
_ "github.com/aquasecurity/fanal/analyzer/os/amazonlinux"
|
||||
_ "github.com/aquasecurity/fanal/analyzer/os/debianbase"
|
||||
_ "github.com/aquasecurity/fanal/analyzer/os/opensuse"
|
||||
_ "github.com/aquasecurity/fanal/analyzer/os/redhatbase"
|
||||
_ "github.com/aquasecurity/fanal/analyzer/os/suse"
|
||||
|
||||
// Register package analyzers
|
||||
_ "github.com/aquasecurity/fanal/analyzer/pkg/apk"
|
||||
@@ -102,15 +105,21 @@ func convertLibWithScanner(libs map[analyzer.FilePath][]godeptypes.Library) ([]m
|
||||
func scanImage(c config.ServerInfo) (os *analyzer.OS, pkgs []analyzer.Package, libs map[analyzer.FilePath][]godeptypes.Library, err error) {
|
||||
|
||||
ctx := context.Background()
|
||||
domain := c.Image.Name + ":" + c.Image.Tag
|
||||
domain := c.Image.GetFullName()
|
||||
util.Log.Info("Start fetch container... ", domain)
|
||||
|
||||
fanalCache := cache.Initialize(utils.CacheDir())
|
||||
// Configure dockerOption
|
||||
dockerOption := c.Image.DockerOption
|
||||
if dockerOption.Timeout == 0 {
|
||||
dockerOption.Timeout = 60 * time.Second
|
||||
}
|
||||
files, err := analyzer.Analyze(ctx, domain, dockerOption)
|
||||
ext, err := docker.NewDockerExtractor(dockerOption, fanalCache)
|
||||
if err != nil {
|
||||
return nil, nil, nil, xerrors.Errorf("Failed initialize docker extractor%w", err)
|
||||
}
|
||||
ac := analyzer.Config{Extractor: ext}
|
||||
files, err := ac.Analyze(ctx, domain, dockerOption)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, nil, xerrors.Errorf("Failed scan files %q, %w", domain, err)
|
||||
|
||||
@@ -241,7 +241,8 @@ func (o *debian) checkDeps() error {
|
||||
func (o *debian) preCure() error {
|
||||
o.log.Infof("Scanning in %s", o.getServerInfo().Mode)
|
||||
if err := o.detectIPAddr(); err != nil {
|
||||
o.log.Debugf("Failed to detect IP addresses: %s", err)
|
||||
o.log.Warnf("Failed to detect IP addresses: %s", err)
|
||||
o.warns = append(o.warns, err)
|
||||
}
|
||||
// Ignore this error as it just failed to detect the IP addresses
|
||||
return nil
|
||||
|
||||
@@ -3,6 +3,7 @@ package scan
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/future-architect/vuls/cache"
|
||||
@@ -729,8 +730,8 @@ dpkg-query: no path found matching pattern /lib/udev/hwdb.bin
|
||||
libuuid1:amd64: /lib/x86_64-linux-gnu/libuuid.so.1.3.0`,
|
||||
},
|
||||
wantPkgNames: []string{
|
||||
"udev",
|
||||
"libuuid1",
|
||||
"udev",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -738,6 +739,7 @@ libuuid1:amd64: /lib/x86_64-linux-gnu/libuuid.so.1.3.0`,
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
o := &debian{}
|
||||
gotPkgNames := o.parseGetPkgName(tt.args.stdout)
|
||||
sort.Strings(gotPkgNames)
|
||||
if !reflect.DeepEqual(gotPkgNames, tt.wantPkgNames) {
|
||||
t.Errorf("debian.parseGetPkgName() = %v, want %v", gotPkgNames, tt.wantPkgNames)
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ if-not-architecture 0 100 200 amzn-main`
|
||||
}
|
||||
|
||||
func TestParseNeedsRestarting(t *testing.T) {
|
||||
r := newCentOS(config.ServerInfo{})
|
||||
r := newRHEL(config.ServerInfo{})
|
||||
r.Distro = config.Distro{Family: "centos"}
|
||||
|
||||
var tests = []struct {
|
||||
@@ -323,7 +323,7 @@ func TestParseNeedsRestarting(t *testing.T) {
|
||||
out []models.NeedRestartProcess
|
||||
}{
|
||||
{
|
||||
`1 : /usr/lib/systemd/systemd --switched-root --system --deserialize 21
|
||||
`1 : /usr/lib/systemd/systemd --switched-root --system --deserialize 21kk
|
||||
437 : /usr/sbin/NetworkManager --no-daemon`,
|
||||
[]models.NeedRestartProcess{
|
||||
{
|
||||
|
||||
@@ -55,11 +55,8 @@ func (o *rhel) depsFastRoot() []string {
|
||||
}
|
||||
|
||||
// repoquery
|
||||
majorVersion, _ := o.Distro.MajorVersion()
|
||||
if majorVersion < 8 {
|
||||
return []string{"yum-utils"}
|
||||
}
|
||||
return []string{"dnf-utils"}
|
||||
// `rpm -qa` shows dnf-utils as yum-utils on RHEL8, CentOS8
|
||||
return []string{"yum-utils"}
|
||||
}
|
||||
|
||||
func (o *rhel) depsDeep() []string {
|
||||
|
||||
@@ -497,11 +497,11 @@ func detectImageOSesOnServer(containerHost osTypeInterface) (oses []osTypeInterf
|
||||
return
|
||||
}
|
||||
|
||||
for idx, containerConf := range containerHostInfo.Images {
|
||||
for idx, img := range containerHostInfo.Images {
|
||||
copied := containerHostInfo
|
||||
// change servername for original
|
||||
copied.ServerName = fmt.Sprintf("%s:%s@%s", idx, containerConf.Tag, containerHostInfo.ServerName)
|
||||
copied.Image = containerConf
|
||||
copied.ServerName = fmt.Sprintf("%s@%s", idx, containerHostInfo.ServerName)
|
||||
copied.Image = img
|
||||
copied.Type = ""
|
||||
os := detectOS(copied)
|
||||
oses = append(oses, os)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -62,7 +63,7 @@ func NewCustomLogger(c config.ServerInfo) *logrus.Entry {
|
||||
}
|
||||
|
||||
if _, err := os.Stat(logDir); err == nil {
|
||||
path := filepath.Join(logDir, whereami)
|
||||
path := filepath.Join(logDir, fmt.Sprintf("%s.log", whereami))
|
||||
log.Hooks.Add(lfshook.NewHook(lfshook.PathMap{
|
||||
logrus.DebugLevel: path,
|
||||
logrus.InfoLevel: path,
|
||||
|
||||
Reference in New Issue
Block a user