Compare commits

...

11 Commits

Author SHA1 Message Date
Kota Kanbe
93059b74c3 feat(report): IgnoredJSONKyes to clear values in result json (#1071)
* feat(report): IgnoredJSONKyes to clear values in result json

* fix(report): marshal indent in JSON everytime
2020-11-05 20:13:09 +09:00
Kota Kanbe
2fc3462d35 fix(libscan): update trivy deps (#1070) 2020-11-05 15:38:12 +09:00
Kota Kanbe
f78dab50cb fix(fast-root): affectedProcs, ports bug (#1067) 2020-10-31 14:21:11 +09:00
Norihiro NAKAOKA
edb324c3d9 fix(portscan): ignore loopback address on remote scan (#1062)
* change ignore loop back address on remote scan

* fix test case

* change append simple

* fix format

* set golangci-lint timeout

* Revert "set golangci-lint timeout"

This reverts commit 56b1c7089a.
2020-10-23 16:40:03 +09:00
Norihiro NAKAOKA
83bcca6e66 experimental: add smart(fast, minimum ports, silently) TCP port scanner (#1060)
* add struct ListenPorts

* change parse to models.ListenPorts from string

* change support models.ListenPorts in TUI

* add scanPort template , detectScanDest

* add Test_detectScanDest

* change impl scanPorts template

* fix build error

* change collect scan success address

* add Test_matchListenPorts

* add Test_updatePortStatus

* change display port scan result on tui

* change display scan emoji on report

* Revert "change display scan emoji on report"

This reverts commit e281882cc6.

* add continue

* change display format

* change no use loop label

* remove comment code

* change display

* fix padding

* change refactoring var , fn name

* fix var name

* fix var name

* change eye icon

* change icon

* delete unuse mod
2020-10-19 17:47:20 +09:00
Kota Kanbe
a124518d78 fix: hard-coded version #1057 (#1059) 2020-10-16 20:42:31 +09:00
Alexander Stein
94bf630e29 Expand negative grep match for any error for lib scans. (#1056)
Many thanks 👍 

Sure, that's better.

Note: FreeBSD
find: `find: /var/run/ppp: Permission denied`
2020-10-12 11:30:11 +09:00
shopper
31bb33fd90 ignore apk warning (#1052) 2020-10-12 10:40:01 +09:00
Kota Kanbe
4b680b9960 fix(scan-freebsd): also get installed with pkg info #1042 (#1051)
* fix(scan-freebsd): also get installed with `pkg info` #1042

* fix test
2020-09-12 05:08:41 +09:00
Kota Kanbe
8a8ab8cb18 feat(libscan): enable to scan vulns of libs with pseudo #1035 (#1050) 2020-09-11 13:09:59 +09:00
Kota Kanbe
8146f5fd1b update readme (#1049) 2020-09-11 10:26:57 +09:00
25 changed files with 937 additions and 331 deletions

View File

@@ -9,7 +9,7 @@
![Vuls-logo](img/vuls_logo.png)
Vulnerability scanner for Linux/FreeBSD, agentless, written in golang.
Vulnerability scanner for Linux/FreeBSD, agent-less, written in Go.
We have a slack team. [Join slack team](http://goo.gl/forms/xm5KFo35tu)
Twitter: [@vuls_en](https://twitter.com/vuls_en)
@@ -23,20 +23,6 @@ Twitter: [@vuls_en](https://twitter.com/vuls_en)
----
## NEWS
| Version | Main Feature | Date |
|:------------|:---------------------------------|:--------------------|
| [v0.8.0](https://github.com/future-architect/vuls/releases/tag/v0.8.0) | secret | Coming soon |
| [v0.7.0](https://github.com/future-architect/vuls/releases/tag/v0.7.0) | WordPress Vulnerability Scan | 2019/Apr/8 |
| [v0.6.3](https://github.com/future-architect/vuls/releases/tag/v0.6.3) | GitHub Integration | 2019/Feb/20 |
| [v0.6.2](https://github.com/future-architect/vuls/releases/tag/v0.6.2) | Add US-CERT/JPCERT Alerts as VulnSrc | 2019/Jan/23 |
| [v0.6.1](https://github.com/future-architect/vuls/releases/tag/v0.6.1) | BugFix | 2018/Nov/16 |
| [v0.6.0](https://github.com/future-architect/vuls/releases/tag/v0.6.0) | Add ExploitDB as VulnSrc | 2018/Nov/3 |
| [v0.5.0](https://github.com/future-architect/vuls/releases/tag/v0.5.0) | Scan accuracy improvement | 2018/Aug/27 |
----
## Abstract
For a system administrator, having to perform security vulnerability analysis and software update on a daily basis can be a burden.
@@ -66,36 +52,47 @@ Vuls is a tool created to solve the problems listed above. It has the following
- Alpine, Amazon Linux, CentOS, Debian, Oracle Linux, Raspbian, RHEL, SUSE Enterprise Linux, and Ubuntu
- FreeBSD
- Cloud, on-premise, Docker Container and Docker Image
- Cloud, on-premise, Running Docker Container
### High-quality scan
Vuls uses multiple vulnerability databases
- Vulnerability Database
- [NVD](https://nvd.nist.gov/)
- [JVN(Japanese)](http://jvndb.jvn.jp/apis/myjvn/)
- [NVD](https://nvd.nist.gov/)
- [JVN(Japanese)](http://jvndb.jvn.jp/apis/myjvn/)
- OVAL
- [Red Hat](https://www.redhat.com/security/data/oval/)
- [Debian](https://www.debian.org/security/oval/)
- [Oracle Linux](https://linux.oracle.com/security/oval/)
- [RedHat](https://www.redhat.com/security/data/oval/)
- [SUSE](http://ftp.suse.com/pub/projects/security/oval/)
- [Ubuntu](https://people.canonical.com/~ubuntu-security/oval/)
- [SUSE](http://ftp.suse.com/pub/projects/security/oval/)
- [Oracle Linux](https://linux.oracle.com/security/oval/)
- [Alpine-secdb](https://git.alpinelinux.org/cgit/alpine-secdb/)
- [Debian Security Bug Tracker](https://security-tracker.debian.org/tracker/)
- [Red Hat Security Advisories](https://access.redhat.com/security/security-updates/)
- Commands (yum, zypper, and pkg-audit)
- RHSA/ALAS/ELSA/FreeBSD-SA
- [Exploit Database](https://www.exploit-db.com/)
- [US-CERT](https://www.us-cert.gov/ncas/alerts)
- [JPCERT](http://www.jpcert.or.jp/at/2019.html)
- [WPVulnDB](https://wpvulndb.com/api)
- [Node.js Security Working Group](https://github.com/nodejs/security-wg)
- [Ruby Advisory Database](https://github.com/rubysec/ruby-advisory-db)
- [Safety DB(Python)](https://github.com/pyupio/safety-db)
- [PHP Security Advisories Database](https://github.com/FriendsOfPHP/security-advisories)
- [RustSec Advisory Database](https://github.com/RustSec/advisory-db)
- Changelog
- Security Advisory
- [Alpine-secdb](https://git.alpinelinux.org/cgit/alpine-secdb/)
- [Red Hat Security Advisories](https://access.redhat.com/security/security-updates/)
- [Debian Security Bug Tracker](https://security-tracker.debian.org/tracker/)
- Commands(yum, zypper, pkg-audit)
- RHSA / ALAS / ELSA / FreeBSD-SA
- Changelog
- PoC, Exploit
- [Exploit Database](https://www.exploit-db.com/)
- [Metasploit-Framework modules](https://www.rapid7.com/db/?q=&type=metasploit)
- CERT
- [US-CERT](https://www.us-cert.gov/ncas/alerts)
- [JPCERT](http://www.jpcert.or.jp/at/2019.html)
- Libraries
- [Node.js Security Working Group](https://github.com/nodejs/security-wg)
- [Ruby Advisory Database](https://github.com/rubysec/ruby-advisory-db)
- [Safety DB(Python)](https://github.com/pyupio/safety-db)
- [PHP Security Advisories Database](https://github.com/FriendsOfPHP/security-advisories)
- [RustSec Advisory Database](https://github.com/RustSec/advisory-db)
- WordPress
- [WPVulnDB](https://wpvulndb.com/api)
### Scan mode
@@ -134,19 +131,6 @@ Vuls uses multiple vulnerability databases
- It is possible to acquire the state of the server by connecting via SSH and executing the command.
- Vuls warns when the scan target server was updated the kernel etc. but not restarting it.
### **Static** Analysis
**Image scan function is no longer supported from Vuls v0.9.5. Use Trivy directry**
~~Vuls v0.8.0 can scan Docker images using [knqyf263/trivy](https://github.com/knqyf263/trivy).
Following Registry supported.~~
- ~~ECR~~
- ~~GCR~~
- ~~Local Image~~
~~For details, see [Scan docker image](https://vuls.io/docs/en/tutorial-scan-docker-image.html)~~
### Scan vulnerabilities of non-OS-packages
- Libraries of programming language
@@ -184,7 +168,7 @@ Vuls has some options to detect the vulnerabilities
## Document
For more information such as Installation, Tutorial, Usage, visit [vuls.io](https://vuls.io/)
For more information such as Installation, Tutorial, Usage, visit [vuls.io](https://vuls.io/)
[日本語翻訳ドキュメント](https://vuls.io/ja/)
----
@@ -195,12 +179,6 @@ kotakanbe ([@kotakanbe](https://twitter.com/kotakanbe)) created vuls and [these
----
## Change Log
Please see [CHANGELOG](https://github.com/future-architect/vuls/blob/master/CHANGELOG.md).
----
## Stargazers over time
[![Stargazers over time](https://starcharts.herokuapp.com/future-architect/vuls.svg)](https://starcharts.herokuapp.com/future-architect/vuls)

View File

@@ -235,85 +235,9 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
return subcommands.ExitFailure
}
// report
reports := []report.ResultWriter{
report.StdoutWriter{},
}
if c.Conf.ToSlack {
reports = append(reports, report.SlackWriter{})
}
if c.Conf.ToStride {
reports = append(reports, report.StrideWriter{})
}
if c.Conf.ToHipChat {
reports = append(reports, report.HipChatWriter{})
}
if c.Conf.ToChatWork {
reports = append(reports, report.ChatWorkWriter{})
}
if c.Conf.ToTelegram {
reports = append(reports, report.TelegramWriter{})
}
if c.Conf.ToEmail {
reports = append(reports, report.EMailWriter{})
}
if c.Conf.ToSyslog {
reports = append(reports, report.SyslogWriter{})
}
if c.Conf.ToHTTP {
reports = append(reports, report.HTTPRequestWriter{})
}
if c.Conf.ToLocalFile {
reports = append(reports, report.LocalFileWriter{
CurrentDir: dir,
})
}
if c.Conf.ToS3 {
if err := report.CheckIfBucketExists(); err != nil {
util.Log.Errorf("Check if there is a bucket beforehand: %s, err: %+v",
c.Conf.AWS.S3Bucket, err)
return subcommands.ExitUsageError
}
reports = append(reports, report.S3Writer{})
}
if c.Conf.ToAzureBlob {
if len(c.Conf.Azure.AccountName) == 0 {
c.Conf.Azure.AccountName = os.Getenv("AZURE_STORAGE_ACCOUNT")
}
if len(c.Conf.Azure.AccountKey) == 0 {
c.Conf.Azure.AccountKey = os.Getenv("AZURE_STORAGE_ACCESS_KEY")
}
if len(c.Conf.Azure.ContainerName) == 0 {
util.Log.Error("Azure storage container name is required with -azure-container option")
return subcommands.ExitUsageError
}
if err := report.CheckIfAzureContainerExists(); err != nil {
util.Log.Errorf("Check if there is a container beforehand: %s, err: %+v",
c.Conf.Azure.ContainerName, err)
return subcommands.ExitUsageError
}
reports = append(reports, report.AzureBlobWriter{})
}
if c.Conf.ToSaas {
if !c.Conf.UUID {
util.Log.Errorf("If you use the -to-saas option, you need to enable the uuid option")
return subcommands.ExitUsageError
}
reports = append(reports, report.SaasWriter{})
util.Log.Info("Validating config...")
if !c.Conf.ValidateOnReport() {
return subcommands.ExitUsageError
}
if !(c.Conf.FormatJSON || c.Conf.FormatOneLineText ||
@@ -321,11 +245,6 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
c.Conf.FormatList = true
}
util.Log.Info("Validating config...")
if !c.Conf.ValidateOnReport() {
return subcommands.ExitUsageError
}
var loaded models.ScanResults
if loaded, err = report.LoadScanResults(dir); err != nil {
util.Log.Error(err)
@@ -437,6 +356,87 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
}
}
// report
reports := []report.ResultWriter{
report.StdoutWriter{},
}
if c.Conf.ToSlack {
reports = append(reports, report.SlackWriter{})
}
if c.Conf.ToStride {
reports = append(reports, report.StrideWriter{})
}
if c.Conf.ToHipChat {
reports = append(reports, report.HipChatWriter{})
}
if c.Conf.ToChatWork {
reports = append(reports, report.ChatWorkWriter{})
}
if c.Conf.ToTelegram {
reports = append(reports, report.TelegramWriter{})
}
if c.Conf.ToEmail {
reports = append(reports, report.EMailWriter{})
}
if c.Conf.ToSyslog {
reports = append(reports, report.SyslogWriter{})
}
if c.Conf.ToHTTP {
reports = append(reports, report.HTTPRequestWriter{})
}
if c.Conf.ToLocalFile {
reports = append(reports, report.LocalFileWriter{
CurrentDir: dir,
})
}
if c.Conf.ToS3 {
if err := report.CheckIfBucketExists(); err != nil {
util.Log.Errorf("Check if there is a bucket beforehand: %s, err: %+v",
c.Conf.AWS.S3Bucket, err)
return subcommands.ExitUsageError
}
reports = append(reports, report.S3Writer{})
}
if c.Conf.ToAzureBlob {
if len(c.Conf.Azure.AccountName) == 0 {
c.Conf.Azure.AccountName = os.Getenv("AZURE_STORAGE_ACCOUNT")
}
if len(c.Conf.Azure.AccountKey) == 0 {
c.Conf.Azure.AccountKey = os.Getenv("AZURE_STORAGE_ACCESS_KEY")
}
if len(c.Conf.Azure.ContainerName) == 0 {
util.Log.Error("Azure storage container name is required with -azure-container option")
return subcommands.ExitUsageError
}
if err := report.CheckIfAzureContainerExists(); err != nil {
util.Log.Errorf("Check if there is a container beforehand: %s, err: %+v",
c.Conf.Azure.ContainerName, err)
return subcommands.ExitUsageError
}
reports = append(reports, report.AzureBlobWriter{})
}
if c.Conf.ToSaas {
if !c.Conf.UUID {
util.Log.Errorf("If you use the -to-saas option, you need to enable the uuid option")
return subcommands.ExitUsageError
}
reports = append(reports, report.SaasWriter{})
}
for _, w := range reports {
if err := w.Write(res...); err != nil {
util.Log.Errorf("Failed to report. err: %+v", err)

View File

@@ -16,7 +16,7 @@ import (
)
// Version of Vuls
var Version = "0.9.9"
var Version = "`make build` or `make install` will show the version"
// Revision of Git
var Revision string
@@ -1121,18 +1121,17 @@ type ServerInfo struct {
Lockfiles []string `toml:"lockfiles,omitempty" json:"lockfiles,omitempty"` // ie) path/to/package-lock.json
FindLock bool `toml:"findLock,omitempty" json:"findLock,omitempty"`
Type string `toml:"type,omitempty" json:"type,omitempty"` // "pseudo" or ""
WordPress WordPressConf `toml:"wordpress,omitempty" json:"wordpress,omitempty"`
IgnoredJSONKeys []string `toml:"ignoredJSONKeys,omitempty" json:"ignoredJSONKeys,omitempty"`
WordPress WordPressConf `toml:"wordpress,omitempty" json:"wordpress,omitempty"`
// used internal
IPv4Addrs []string `toml:"-" json:"ipv4Addrs,omitempty"`
IPv6Addrs []string `toml:"-" json:"ipv6Addrs,omitempty"`
IPSIdentifiers map[IPS]string `toml:"-" json:"ipsIdentifiers,omitempty"`
LogMsgAnsiColor string `toml:"-" json:"-"` // DebugLog Color
Container Container `toml:"-" json:"-"`
Distro Distro `toml:"-" json:"-"`
Mode ScanMode `toml:"-" json:"-"`
// internal use
IPv4Addrs []string `toml:"-" json:"ipv4Addrs,omitempty"`
IPv6Addrs []string `toml:"-" json:"ipv6Addrs,omitempty"`
IPSIdentifiers map[IPS]string `toml:"-" json:"ipsIdentifiers,omitempty"`
LogMsgAnsiColor string `toml:"-" json:"-"` // DebugLog Color
Container Container `toml:"-" json:"-"`
Distro Distro `toml:"-" json:"-"`
Mode ScanMode `toml:"-" json:"-"`
}
// ContainerSetting is used for loading container setting in config.toml

View File

@@ -45,7 +45,7 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
d.KeyPassword = keyPass
}
i := 0
index := 0
for serverName, v := range conf.Servers {
if 0 < len(v.KeyPassword) {
return xerrors.Errorf("[Deprecated] KEYPASSWORD IN CONFIG FILE ARE UNSECURE. REMOVE THEM IMMEDIATELY FOR A SECURITY REASONS. THEY WILL BE REMOVED IN A FUTURE RELEASE: %s", serverName)
@@ -268,8 +268,13 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
s.WordPress.OSUser = v.WordPress.OSUser
s.WordPress.IgnoreInactive = v.WordPress.IgnoreInactive
s.LogMsgAnsiColor = Colors[i%len(Colors)]
i++
s.IgnoredJSONKeys = v.IgnoredJSONKeys
if len(s.IgnoredJSONKeys) == 0 {
s.IgnoredJSONKeys = d.IgnoredJSONKeys
}
s.LogMsgAnsiColor = Colors[index%len(Colors)]
index++
servers[serverName] = s
}

12
go.mod
View File

@@ -10,10 +10,11 @@ replace (
require (
github.com/Azure/azure-sdk-for-go v43.3.0+incompatible
github.com/BurntSushi/toml v0.3.1
github.com/Masterminds/semver/v3 v3.1.0
github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91
github.com/aquasecurity/fanal v0.0.0-20200615091807-df25cfa5f9af
github.com/aquasecurity/trivy v0.9.1
github.com/aquasecurity/trivy-db v0.0.0-20200616161554-cd5b3da29bc8
github.com/aquasecurity/fanal v0.0.0-20200820074632-6de62ef86882
github.com/aquasecurity/trivy v0.12.0
github.com/aquasecurity/trivy-db v0.0.0-20200826140828-6da6467703aa
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
github.com/aws/aws-sdk-go v1.33.21
github.com/boltdb/bolt v1.3.1
@@ -32,7 +33,6 @@ require (
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.4
github.com/kotakanbe/go-cve-dictionary v0.5.0
github.com/kotakanbe/go-pingscanner v0.1.0
@@ -50,9 +50,9 @@ require (
github.com/spf13/afero v1.3.0
github.com/spf13/cobra v1.0.0
github.com/takuzoo3868/go-msfdb v0.1.1
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
k8s.io/utils v0.0.0-20200619165400-6e3d28b6ed19
)

80
go.sum
View File

@@ -44,6 +44,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs=
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk=
github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
@@ -51,6 +53,7 @@ github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXn
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
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/OneOfOne/xxhash v1.2.7/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@@ -68,19 +71,19 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
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/bolt-fixtures v0.0.0-20200825112230-c0f517aea2ed h1:o6vSjobtDn634//l4yBCGCC2RWoRc4K5AUH8W8DZZds=
github.com/aquasecurity/bolt-fixtures v0.0.0-20200825112230-c0f517aea2ed/go.mod h1:eViGpgc5g/JGRHWUfVaNLFJQwXQOVWDDQ40c7uViyZU=
github.com/aquasecurity/fanal v0.0.0-20190819081512-f04452b627c6/go.mod h1:enEz4FFetw4XAbkffaYgyCVq1556R9Ry+noqT4rq9BE=
github.com/aquasecurity/fanal v0.0.0-20200528202907-79693bf4a058/go.mod h1:omM/xBVqAPNzdV/MegrjayEkKEZzI+eUpyjCXpbTMG0=
github.com/aquasecurity/fanal v0.0.0-20200615091807-df25cfa5f9af h1:UG06S07LRZvMzxKyQuMZVtIDim7Ac6MWSc6bMGoiTKE=
github.com/aquasecurity/fanal v0.0.0-20200615091807-df25cfa5f9af/go.mod h1:omM/xBVqAPNzdV/MegrjayEkKEZzI+eUpyjCXpbTMG0=
github.com/aquasecurity/fanal v0.0.0-20200820074632-6de62ef86882 h1:65VcAKqhkKwMpLr9Wz+wNnsk+U+lv+v/qfOK04uXT3E=
github.com/aquasecurity/fanal v0.0.0-20200820074632-6de62ef86882/go.mod h1:VP1+n6hMi6krpA0umEl0CkJp4hbg0R21kXWg0mjrekc=
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/testdocker v0.0.0-20200426142840-5f05bce6f12a/go.mod h1:psfu0MVaiTDLpNxCoNsTeILSKY2EICBwv345f3M+Ffs=
github.com/aquasecurity/trivy v0.1.6/go.mod h1:5hobyhxLzDtxruHzPxpND2PUKOssvGUdE9BocpJUwo4=
github.com/aquasecurity/trivy v0.9.1 h1:pDPZEXGLzQ1ctgD0xX/BRK71+av9+NlmPwGe7zEjqQw=
github.com/aquasecurity/trivy v0.9.1/go.mod h1:J3WSvlfS288/4KqgPTnwV2ja+gUZRle8GPvj3wjdAiQ=
github.com/aquasecurity/trivy-db v0.0.0-20200514134639-7e57e3e02470/go.mod h1:F77bF2nRbcH4EIhhcNEP585MoAKdLpEP3dihF9V1Hbw=
github.com/aquasecurity/trivy-db v0.0.0-20200616161554-cd5b3da29bc8 h1:PvRcn3v8lpccqmEEzmJmXrm47ag47OCt8ui+9APi4hA=
github.com/aquasecurity/trivy-db v0.0.0-20200616161554-cd5b3da29bc8/go.mod h1:EiFA908RL0ACrbYo/9HfT7f9QcdC2bZoIO5XAAcvz9A=
github.com/aquasecurity/trivy v0.12.0 h1:feUx6Q83JjbvzmZe2dYlg+fWi1mrS3xPLBDccT48ayk=
github.com/aquasecurity/trivy v0.12.0/go.mod h1:CnUHYSLGJLt2WqIWIrRvbUTwlgRbmtg4yXxLzXu7Bs4=
github.com/aquasecurity/trivy-db v0.0.0-20200826140828-6da6467703aa h1:v+ghkIw3D3qUP++M3e9XGkkoq59iZdCOT4uxj4l2pXs=
github.com/aquasecurity/trivy-db v0.0.0-20200826140828-6da6467703aa/go.mod h1:/uvzkPkLMA6ZM1M2uIODx5J7b1wYb/goJ34Nidcukaw=
github.com/aquasecurity/vuln-list-update v0.0.0-20191016075347-3d158c2bf9a2/go.mod h1:6NhOP0CjZJL27bZZcaHECtzWdwDDm2g6yCY0QgXEGQQ=
github.com/araddon/dateparse v0.0.0-20190426192744-0d74ffceef83/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@@ -204,6 +207,8 @@ github.com/etcd-io/bbolt v1.3.2/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHj
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
@@ -213,6 +218,7 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/genuinetools/pkg v0.0.0-20180910213200-1c141f661797/go.mod h1:XTcrCYlXPxnxL2UpnwuRn7tcaTn9HAhxFoFJucootk8=
github.com/genuinetools/reg v0.16.0/go.mod h1:12Fe9EIvK3dG/qWhNk5e9O96I8SGmCKLsJ8GsXUbk+Y=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
@@ -240,7 +246,11 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis v6.15.7+incompatible h1:3skhDh95XQMpnqeqNftPkQD9jL9e5e36z/1SUm6dy1U=
@@ -252,11 +262,15 @@ github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gG
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
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/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gocarina/gocsv v0.0.0-20190821091544-020a928c6f4e/go.mod h1:/oj50ZdPq/cUjA02lMZhijk5kR31SEydKyqah1OgBuo=
github.com/goccy/go-yaml v1.8.0 h1:WCe9sBiI0oZb6EC6f3kq3dv0+aEiNdstT7b4xxq4MJQ=
github.com/goccy/go-yaml v1.8.0/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y=
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/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
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=
@@ -268,6 +282,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v0.0.0-20181025225059-d3de96c4c28e/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -314,6 +329,7 @@ github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEo
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v0.0.0-20181024020800-521ea7b17d02/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
@@ -454,6 +470,8 @@ github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
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=
@@ -472,6 +490,8 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@@ -481,7 +501,11 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-jsonpointer v0.0.0-20180225143300-37667080efed/go.mod h1:SDJ4hurDYyQ9/7nc+eCYtXqdufgK4Cq9TJlwPklqEYA=
github.com/mattn/go-runewidth v0.0.0-20181025052659-b20a3daf6a39/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
@@ -557,6 +581,7 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/open-policy-agent/opa v0.21.1/go.mod h1:cZaTfhxsj7QdIiUI0U9aBtOLLTqVNe+XE60+9kZKLHw=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
@@ -571,8 +596,10 @@ github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtb
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/peterh/liner v0.0.0-20170211195444-bf27d3ba8e1d/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/peterhellberg/link v1.0.0/go.mod h1:gtSlOT4jmkY8P47hbTc8PTgiDDWpdPbFYl75keYyBB8=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.0.0-20181023235946-059132a15dd0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -584,6 +611,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prometheus/client_golang v0.0.0-20180924113449-f69c853d21c1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.0.0-20181025174421-f30f42803563/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
@@ -593,6 +621,7 @@ github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@@ -647,6 +676,7 @@ github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk=
github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.0-20181021141114-fe5e611709b0/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
@@ -654,6 +684,7 @@ github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHN
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v0.0.0-20181024212040-082b515c9490/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -668,12 +699,16 @@ 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 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/takuzoo3868/go-msfdb v0.1.1 h1:eaVDXmiKRAe8xSAVagybUdLJE3pLjerXYJIuYazVWHE=
@@ -701,12 +736,13 @@ github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnW
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b/go.mod h1:HptNXiXVDcJjXe9SqMd0v2FsL9f8dz4GnXgltU6q/co=
github.com/ymomoi/goval-parser v0.0.0-20170813122243-0a0be1dd9d08 h1:OsHsjWw5m3P0r+RJITvigJu9dn6L8812S54x42jxeII=
github.com/ymomoi/goval-parser v0.0.0-20170813122243-0a0be1dd9d08/go.mod h1:ox1Nt/rGgWuhVrNg+jKYonAs4BiQG1tRJwj4ue91iy4=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -745,8 +781,9 @@ golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -757,6 +794,7 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181023182221-1baf3a9d7d67/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
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=
@@ -799,11 +837,12 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
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/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -815,6 +854,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -850,15 +890,20 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775 h1:TC0v2RSO1u2kn1ZugjrFXkRZAEaqMN/RW+OTZkBzmLE=
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8 h1:AvbQYmiaaaza3cW3QXRyPo5kYgpFIzOAfeAAN7m3qQ4=
golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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=
@@ -906,6 +951,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
@@ -923,6 +970,7 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww
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-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180924164928-221a8d4f7494/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=
@@ -972,8 +1020,11 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/go-playground/validator.v9 v9.30.0 h1:Wk0Z37oBmKj9/n+tPyBHZmeL19LaCoK3Qq48VwYENss=
gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
@@ -1000,6 +1051,9 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v0.0.0-20181223230014-1083505acf35/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90=
gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=

View File

@@ -17,8 +17,8 @@ import (
"github.com/future-architect/vuls/util"
)
// FillLibrary fills LibraryScanner information
func FillLibrary(r *models.ScanResult) (totalCnt int, err error) {
// DetectLibsCves fills LibraryScanner information
func DetectLibsCves(r *models.ScanResult) (totalCnt int, err error) {
if len(r.LibraryScanners) == 0 {
return
}

View File

@@ -3,6 +3,7 @@ package models
import (
"path/filepath"
"github.com/Masterminds/semver/v3"
"github.com/aquasecurity/trivy-db/pkg/db"
trivyDBTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/detector/library"
@@ -10,9 +11,7 @@ import (
"github.com/aquasecurity/trivy/pkg/types"
"github.com/future-architect/vuls/util"
"golang.org/x/xerrors"
// "github.com/aquasecurity/go-dep-parser/pkg/types"
"github.com/knqyf263/go-version"
)
// LibraryScanners is an array of LibraryScanner
@@ -46,7 +45,7 @@ func (s LibraryScanner) Scan() ([]VulnInfo, error) {
}
var vulnerabilities = []VulnInfo{}
for _, pkg := range s.Libs {
v, err := version.NewVersion(pkg.Version)
v, err := semver.StrictNewVersion(pkg.Version)
if err != nil {
util.Log.Debugf("new version cant detected %s@%s", pkg.Name, pkg.Version)
continue

View File

@@ -174,9 +174,29 @@ type Changelog struct {
// AffectedProcess keep a processes information affected by software update
type AffectedProcess struct {
PID string `json:"pid,omitempty"`
Name string `json:"name,omitempty"`
ListenPorts []string `json:"listenPorts,omitempty"`
PID string `json:"pid,omitempty"`
Name string `json:"name,omitempty"`
ListenPorts []ListenPort `json:"listenPorts,omitempty"`
}
// ListenPort has the result of parsing the port information to the address and port.
type ListenPort struct {
Address string `json:"address"`
Port string `json:"port"`
PortScanSuccessOn []string `json:"portScanSuccessOn"`
}
// HasPortScanSuccessOn checks if Package.AffectedProcs has PortScanSuccessOn
func (p Package) HasPortScanSuccessOn() bool {
for _, ap := range p.AffectedProcs {
for _, lp := range ap.ListenPorts {
if len(lp.PortScanSuccessOn) > 0 {
return true
}
}
}
return false
}
// NeedRestartProcess keep a processes information affected by software update

View File

@@ -3,6 +3,7 @@ package models
import (
"bytes"
"fmt"
"reflect"
"regexp"
"strings"
"time"
@@ -416,6 +417,10 @@ func (r ScanResult) FormatAlertSummary() string {
}
func (r ScanResult) isDisplayUpdatableNum() bool {
if r.Family == config.FreeBSD {
return false
}
var mode config.ScanMode
s, _ := config.Conf.Servers[r.ServerName]
mode = s.Mode
@@ -499,3 +504,23 @@ func (r ScanResult) RemoveRaspbianPackFromResult() ScanResult {
return result
}
func (r ScanResult) ClearFields(targetTagNames []string) ScanResult {
if len(targetTagNames) == 0 {
return r
}
target := map[string]bool{}
for _, n := range targetTagNames {
target[strings.ToLower(n)] = true
}
t := reflect.ValueOf(r).Type()
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
jsonValue := strings.Split(f.Tag.Get("json"), ",")[0]
if ok := target[strings.ToLower(jsonValue)]; ok {
vv := reflect.New(f.Type).Elem().Interface()
reflect.ValueOf(&r).Elem().FieldByName(f.Name).Set(reflect.ValueOf(vv))
}
}
return r
}

View File

@@ -688,7 +688,7 @@ func TestIsDisplayUpdatableNum(t *testing.T) {
{
mode: []byte{config.Fast},
family: config.FreeBSD,
expected: true,
expected: false,
},
{
mode: []byte{config.Fast},

View File

@@ -41,14 +41,8 @@ func (w LocalFileWriter) Write(rs ...models.ScanResult) (err error) {
}
var b []byte
if c.Conf.Debug {
if b, err = json.MarshalIndent(r, "", " "); err != nil {
return xerrors.Errorf("Failed to Marshal to JSON: %w", err)
}
} else {
if b, err = json.Marshal(r); err != nil {
return xerrors.Errorf("Failed to Marshal to JSON: %w", err)
}
if b, err = json.MarshalIndent(r, "", " "); err != nil {
return xerrors.Errorf("Failed to Marshal to JSON: %w", err)
}
if err := writeFile(p, b, 0600); err != nil {
return xerrors.Errorf("Failed to write JSON. path: %s, err: %w", p, err)

View File

@@ -43,99 +43,112 @@ const (
// FillCveInfos fills CVE Detailed Information
func FillCveInfos(dbclient DBClient, rs []models.ScanResult, dir string) ([]models.ScanResult, error) {
var filledResults []models.ScanResult
// Use the same reportedAt for all rs
reportedAt := time.Now()
hostname, _ := os.Hostname()
wpVulnCaches := map[string]string{}
for _, r := range rs {
if c.Conf.RefreshCve || needToRefreshCve(r) {
if !useScannedCves(&r) {
r.ScannedCves = models.VulnInfos{}
}
cpeURIs := []string{}
for i, r := range rs {
if !c.Conf.RefreshCve && !needToRefreshCve(r) {
util.Log.Info("No need to refresh")
continue
}
if len(r.Container.ContainerID) == 0 {
cpeURIs = c.Conf.Servers[r.ServerName].CpeNames
owaspDCXMLPath := c.Conf.Servers[r.ServerName].OwaspDCXMLPath
if owaspDCXMLPath != "" {
cpes, err := parser.Parse(owaspDCXMLPath)
if err != nil {
return nil, xerrors.Errorf("Failed to read OWASP Dependency Check XML on %s, `%s`, err: %w",
r.ServerName, owaspDCXMLPath, err)
}
cpeURIs = append(cpeURIs, cpes...)
}
} else {
// runningContainer
if s, ok := c.Conf.Servers[r.ServerName]; ok {
if con, ok := s.Containers[r.Container.Name]; ok {
cpeURIs = con.Cpes
owaspDCXMLPath := con.OwaspDCXMLPath
if owaspDCXMLPath != "" {
cpes, err := parser.Parse(owaspDCXMLPath)
if err != nil {
return nil, xerrors.Errorf("Failed to read OWASP Dependency Check XML on %s, `%s`, err: %w",
r.ServerInfo(), owaspDCXMLPath, err)
}
cpeURIs = append(cpeURIs, cpes...)
}
}
if !useScannedCves(&r) {
r.ScannedCves = models.VulnInfos{}
}
cpeURIs := []string{}
if len(r.Container.ContainerID) == 0 {
cpeURIs = c.Conf.Servers[r.ServerName].CpeNames
owaspDCXMLPath := c.Conf.Servers[r.ServerName].OwaspDCXMLPath
if owaspDCXMLPath != "" {
cpes, err := parser.Parse(owaspDCXMLPath)
if err != nil {
return nil, xerrors.Errorf("Failed to read OWASP Dependency Check XML on %s, `%s`, err: %w",
r.ServerName, owaspDCXMLPath, err)
}
cpeURIs = append(cpeURIs, cpes...)
}
// Integrations
githubInts := GithubSecurityAlerts(c.Conf.Servers[r.ServerName].GitHubRepos)
wpOpt := WordPressOption{c.Conf.Servers[r.ServerName].WordPress.WPVulnDBToken, &wpVulnCaches}
if err := FillCveInfo(dbclient,
&r,
cpeURIs,
true,
githubInts,
wpOpt); err != nil {
return nil, err
}
r.Lang = c.Conf.Lang
r.ReportedAt = reportedAt
r.ReportedVersion = c.Version
r.ReportedRevision = c.Revision
r.ReportedBy = hostname
r.Config.Report = c.Conf
r.Config.Report.Servers = map[string]c.ServerInfo{
r.ServerName: c.Conf.Servers[r.ServerName],
}
if err := overwriteJSONFile(dir, r); err != nil {
return nil, xerrors.Errorf("Failed to write JSON: %w", err)
}
filledResults = append(filledResults, r)
} else {
util.Log.Debugf("No need to refresh")
filledResults = append(filledResults, r)
// runningContainer
if s, ok := c.Conf.Servers[r.ServerName]; ok {
if con, ok := s.Containers[r.Container.Name]; ok {
cpeURIs = con.Cpes
owaspDCXMLPath := con.OwaspDCXMLPath
if owaspDCXMLPath != "" {
cpes, err := parser.Parse(owaspDCXMLPath)
if err != nil {
return nil, xerrors.Errorf("Failed to read OWASP Dependency Check XML on %s, `%s`, err: %w",
r.ServerInfo(), owaspDCXMLPath, err)
}
cpeURIs = append(cpeURIs, cpes...)
}
}
}
}
nCVEs, err := libmanager.DetectLibsCves(&r)
if err != nil {
return nil, xerrors.Errorf("Failed to fill with Library dependency: %w", err)
}
util.Log.Infof("%s: %d CVEs are detected with Library",
r.FormatServerName(), nCVEs)
// Integrations
githubInts := GithubSecurityAlerts(c.Conf.Servers[r.ServerName].GitHubRepos)
wpVulnCaches := map[string]string{}
wpOpt := WordPressOption{c.Conf.Servers[r.ServerName].WordPress.WPVulnDBToken, &wpVulnCaches}
if err := FillCveInfo(dbclient,
&r,
cpeURIs,
true,
githubInts,
wpOpt); err != nil {
return nil, err
}
r.ReportedBy, _ = os.Hostname()
r.Lang = c.Conf.Lang
r.ReportedAt = reportedAt
r.ReportedVersion = c.Version
r.ReportedRevision = c.Revision
r.Config.Report = c.Conf
r.Config.Report.Servers = map[string]c.ServerInfo{
r.ServerName: c.Conf.Servers[r.ServerName],
}
rs[i] = r
}
// Overwrite the json file every time to clear the fields specified in config.IgnoredJSONKeys
for _, r := range rs {
if s, ok := c.Conf.Servers[r.ServerName]; ok {
r = r.ClearFields(s.IgnoredJSONKeys)
}
if err := overwriteJSONFile(dir, r); err != nil {
return nil, xerrors.Errorf("Failed to write JSON: %w", err)
}
}
if c.Conf.Diff {
prevs, err := loadPrevious(filledResults)
prevs, err := loadPrevious(rs)
if err != nil {
return nil, err
}
diff, err := diff(filledResults, prevs)
diff, err := diff(rs, prevs)
if err != nil {
return nil, err
}
filledResults = []models.ScanResult{}
for _, r := range diff {
if err := fillCveDetail(dbclient.CveDB, &r); err != nil {
for i, r := range diff {
if err := fillCvesWithNvdJvn(dbclient.CveDB, &r); err != nil {
return nil, err
}
filledResults = append(filledResults, r)
rs[i] = r
}
}
filtered := []models.ScanResult{}
for _, r := range filledResults {
for i, r := range rs {
r = r.FilterByCvssOver(c.Conf.CvssScoreOver)
r = r.FilterIgnoreCves()
r = r.FilterUnfixed()
@@ -144,23 +157,15 @@ func FillCveInfos(dbclient DBClient, rs []models.ScanResult, dir string) ([]mode
if c.Conf.IgnoreUnscoredCves {
r.ScannedCves = r.ScannedCves.FindScoredVulns()
}
filtered = append(filtered, r)
rs[i] = r
}
return filtered, nil
return rs, nil
}
// FillCveInfo fill scanResult with cve info.
func FillCveInfo(dbclient DBClient, r *models.ScanResult, cpeURIs []string, ignoreWillNotFix bool, integrations ...Integration) error {
util.Log.Debugf("need to refresh")
nCVEs, err := libmanager.FillLibrary(r)
if err != nil {
return xerrors.Errorf("Failed to fill with Library dependency: %w", err)
}
util.Log.Infof("%s: %d CVEs are detected with Library",
r.FormatServerName(), nCVEs)
nCVEs, err = FillWithOval(dbclient.OvalDB, r)
nCVEs, err := DetectPkgsCvesWithOval(dbclient.OvalDB, r)
if err != nil {
return xerrors.Errorf("Failed to fill with OVAL: %w", err)
}
@@ -176,7 +181,7 @@ func FillCveInfo(dbclient DBClient, r *models.ScanResult, cpeURIs []string, igno
}
}
nCVEs, err = fillVulnByCpeURIs(dbclient.CveDB, r, cpeURIs)
nCVEs, err = DetectCpeURIsCves(dbclient.CveDB, r, cpeURIs)
if err != nil {
return xerrors.Errorf("Failed to detect vulns of `%s`: %w", cpeURIs, err)
}
@@ -190,7 +195,7 @@ func FillCveInfo(dbclient DBClient, r *models.ScanResult, cpeURIs []string, igno
}
util.Log.Infof("%s: %d CVEs are detected with GitHub Security Alerts", r.FormatServerName(), ints.GithubAlertsCveCounts)
nCVEs, err = FillWithGost(dbclient.GostDB, r, ignoreWillNotFix)
nCVEs, err = DetectPkgsCvesWithGost(dbclient.GostDB, r, ignoreWillNotFix)
if err != nil {
return xerrors.Errorf("Failed to fill with gost: %w", err)
}
@@ -198,12 +203,12 @@ func FillCveInfo(dbclient DBClient, r *models.ScanResult, cpeURIs []string, igno
r.FormatServerName(), nCVEs)
util.Log.Infof("Fill CVE detailed information with CVE-DB")
if err := fillCveDetail(dbclient.CveDB, r); err != nil {
if err := fillCvesWithNvdJvn(dbclient.CveDB, r); err != nil {
return xerrors.Errorf("Failed to fill with CVE: %w", err)
}
util.Log.Infof("Fill exploit information with Exploit-DB")
nExploitCve, err := FillWithExploit(dbclient.ExploitDB, r)
nExploitCve, err := FillWithExploitDB(dbclient.ExploitDB, r)
if err != nil {
return xerrors.Errorf("Failed to fill with exploit: %w", err)
}
@@ -222,8 +227,8 @@ func FillCveInfo(dbclient DBClient, r *models.ScanResult, cpeURIs []string, igno
return nil
}
// fillCveDetail fetches NVD, JVN from CVE Database
func fillCveDetail(driver cvedb.DB, r *models.ScanResult) error {
// fillCvesWithNvdJvn fetches NVD, JVN from CVE Database
func fillCvesWithNvdJvn(driver cvedb.DB, r *models.ScanResult) error {
cveIDs := []string{}
for _, v := range r.ScannedCves {
cveIDs = append(cveIDs, v.CveID)
@@ -279,8 +284,8 @@ func fillCertAlerts(cvedetail *cvemodels.CveDetail) (dict models.AlertDict) {
return dict
}
// FillWithOval fetches OVAL database
func FillWithOval(driver ovaldb.DB, r *models.ScanResult) (nCVEs int, err error) {
// DetectPkgsCvesWithOval fetches OVAL database
func DetectPkgsCvesWithOval(driver ovaldb.DB, r *models.ScanResult) (nCVEs int, err error) {
var ovalClient oval.Client
var ovalFamily string
@@ -348,23 +353,23 @@ func FillWithOval(driver ovaldb.DB, r *models.ScanResult) (nCVEs int, err error)
return ovalClient.FillWithOval(driver, r)
}
// FillWithGost fills CVEs with gost dataabase
// DetectPkgsCvesWithGost fills CVEs with gost dataabase
// https://github.com/knqyf263/gost
func FillWithGost(driver gostdb.DB, r *models.ScanResult, ignoreWillNotFix bool) (nCVEs int, err error) {
func DetectPkgsCvesWithGost(driver gostdb.DB, r *models.ScanResult, ignoreWillNotFix bool) (nCVEs int, err error) {
gostClient := gost.NewClient(r.Family)
// TODO chekc if fetched
// TODO chekc if fresh enough
// TODO check if fetched
// TODO check if fresh enough
if nCVEs, err = gostClient.DetectUnfixed(driver, r, ignoreWillNotFix); err != nil {
return
}
return nCVEs, gostClient.FillCVEsWithRedHat(driver, r)
}
// FillWithExploit fills Exploits with exploit dataabase
// FillWithExploitDB fills Exploits with exploit dataabase
// https://github.com/mozqnet/go-exploitdb
func FillWithExploit(driver exploitdb.DB, r *models.ScanResult) (nExploitCve int, err error) {
// TODO chekc if fetched
// TODO chekc if fresh enough
func FillWithExploitDB(driver exploitdb.DB, r *models.ScanResult) (nExploitCve int, err error) {
// TODO check if fetched
// TODO check if fresh enough
return exploit.FillWithExploit(driver, r)
}
@@ -374,9 +379,9 @@ func FillWithMetasploit(driver metasploitdb.DB, r *models.ScanResult) (nMetasplo
return msf.FillWithMetasploit(driver, r)
}
func fillVulnByCpeURIs(driver cvedb.DB, r *models.ScanResult, cpeURIs []string) (nCVEs int, err error) {
func DetectCpeURIsCves(driver cvedb.DB, r *models.ScanResult, cpeURIs []string) (nCVEs int, err error) {
if len(cpeURIs) != 0 && driver == nil && !config.Conf.CveDict.IsFetchViaHTTP() {
return 0, xerrors.Errorf("cpeURIs %s specified, but cve-dictionary DB not found. Fetch cve-dictionary beofre reporting. For details, see `https://github.com/kotakanbe/go-cve-dictionary#deploy-go-cve-dictionary`",
return 0, xerrors.Errorf("cpeURIs %s specified, but cve-dictionary DB not found. Fetch cve-dictionary before reporting. For details, see `https://github.com/kotakanbe/go-cve-dictionary#deploy-go-cve-dictionary`",
cpeURIs)
}
@@ -723,7 +728,7 @@ func EnsureUUIDs(configPath string, results models.ScanResults) (err error) {
}
str := strings.Replace(buf.String(), "\n [", "\n\n [", -1)
str = fmt.Sprintf("%s\n\n%s",
"# See REAME for details: https://vuls.io/docs/en/usage-settings.html",
"# See README for details: https://vuls.io/docs/en/usage-settings.html",
str)
return ioutil.WriteFile(realPath, []byte(str), 0600)

View File

@@ -13,7 +13,7 @@ type StdoutWriter struct{}
// WriteScanSummary prints Scan summary at the end of scan
func (w StdoutWriter) WriteScanSummary(rs ...models.ScanResult) {
fmt.Printf("\n\n")
fmt.Println("One Line Summary")
fmt.Println("Scan Summary")
fmt.Println("================")
fmt.Printf("%s\n", formatScanSummary(rs...))
}

View File

@@ -617,6 +617,14 @@ func summaryLines(r models.ScanResult) string {
pkgNames = append(pkgNames, vinfo.WpPackageFixStats.Names()...)
pkgNames = append(pkgNames, vinfo.LibraryFixedIns.Names()...)
av := vinfo.AttackVector()
for _, pname := range vinfo.AffectedPackages.Names() {
if r.Packages[pname].HasPortScanSuccessOn() {
av = fmt.Sprintf("%s ◉", av)
break
}
}
exploits := ""
if 0 < len(vinfo.Exploits) || 0 < len(vinfo.Metasploits) {
exploits = "POC"
@@ -627,7 +635,7 @@ func summaryLines(r models.ScanResult) string {
fmt.Sprintf(indexFormat, i+1),
vinfo.CveID,
cvssScore + " |",
fmt.Sprintf("%4s |", vinfo.AttackVector()),
fmt.Sprintf("%-6s |", av),
fmt.Sprintf("%3s |", exploits),
fmt.Sprintf("%6s |", vinfo.AlertDict.FormatSource()),
fmt.Sprintf("%7s |", vinfo.PatchStatus(r.Packages)),
@@ -639,6 +647,7 @@ func summaryLines(r models.ScanResult) string {
}
stable.AddRow(icols...)
}
return fmt.Sprintf("%s", stable)
}
@@ -710,8 +719,23 @@ func setChangelogLayout(g *gocui.Gui) error {
if len(pack.AffectedProcs) != 0 {
for _, p := range pack.AffectedProcs {
if len(p.ListenPorts) == 0 {
lines = append(lines, fmt.Sprintf(" * PID: %s %s Port: []",
p.PID, p.Name))
continue
}
var ports []string
for _, pp := range p.ListenPorts {
if len(pp.PortScanSuccessOn) == 0 {
ports = append(ports, fmt.Sprintf("%s:%s", pp.Address, pp.Port))
} else {
ports = append(ports, fmt.Sprintf("%s:%s(◉ Scannable: %s)", pp.Address, pp.Port, pp.PortScanSuccessOn))
}
}
lines = append(lines, fmt.Sprintf(" * PID: %s %s Port: %s",
p.PID, p.Name, p.ListenPorts))
p.PID, p.Name, ports))
}
}
}

View File

@@ -261,8 +261,22 @@ No CVE-IDs are found in updatable packages.
if len(pack.AffectedProcs) != 0 {
for _, p := range pack.AffectedProcs {
if len(p.ListenPorts) == 0 {
data = append(data, []string{"",
fmt.Sprintf(" - PID: %s %s, Port: []", p.PID, p.Name)})
}
var ports []string
for _, pp := range p.ListenPorts {
if len(pp.PortScanSuccessOn) == 0 {
ports = append(ports, fmt.Sprintf("%s:%s", pp.Address, pp.Port))
} else {
ports = append(ports, fmt.Sprintf("%s:%s(◉ Scannable: %s)", pp.Address, pp.Port, pp.PortScanSuccessOn))
}
}
data = append(data, []string{"",
fmt.Sprintf(" - PID: %s %s, Port: %s", p.PID, p.Name, p.ListenPorts)})
fmt.Sprintf(" - PID: %s %s, Port: %s", p.PID, p.Name, ports)})
}
}
}

View File

@@ -147,6 +147,9 @@ func (o *alpine) parseApkInfo(stdout string) (models.Packages, error) {
line := scanner.Text()
ss := strings.Split(line, "-")
if len(ss) < 3 {
if strings.Contains(ss[0], "WARNING") {
continue
}
return nil, xerrors.Errorf("Failed to parse apk info -v: %s", line)
}
name := strings.Join(ss[:len(ss)-2], "-")

View File

@@ -4,6 +4,7 @@ import (
"bufio"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"os"
"regexp"
@@ -545,8 +546,8 @@ func (l *base) scanLibraries() (err error) {
}
// delete last "-o "
// 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"`)
// find / -name "*package-lock.json" -o -name "*yarn.lock" ... 2>&1 | grep -v "find: "
cmd := fmt.Sprintf(`find / ` + findopt[:len(findopt)-3] + ` 2>&1 | grep -v "find: "`)
r := exec(l.ServerInfo, cmd, noSudo)
if r.ExitStatus != 0 && r.ExitStatus != 1 {
return xerrors.Errorf("Failed to find lock files")
@@ -562,12 +563,23 @@ func (l *base) scanLibraries() (err error) {
if _, ok := libFilemap[path]; ok {
continue
}
cmd := fmt.Sprintf("cat %s", path)
r := exec(l.ServerInfo, cmd, noSudo)
if !r.isSuccess() {
return xerrors.Errorf("Failed to get target file: %s, filepath: %s", r, path)
var bytes []byte
switch l.Distro.Family {
case config.ServerTypePseudo:
bytes, err = ioutil.ReadFile(path)
if err != nil {
return xerrors.Errorf("Failed to get target file: %s, filepath: %s", err, path)
}
default:
cmd := fmt.Sprintf("cat %s", path)
r := exec(l.ServerInfo, cmd, noSudo)
if !r.isSuccess() {
return xerrors.Errorf("Failed to get target file: %s, filepath: %s", r, path)
}
bytes = []byte(r.Stdout)
}
libFilemap[path] = []byte(r.Stdout)
libFilemap[path] = bytes
}
for path, b := range libFilemap {
@@ -717,6 +729,113 @@ func (l *base) detectWpPlugins() ([]models.WpPackage, error) {
return plugins, nil
}
func (l *base) scanPorts() (err error) {
dest := l.detectScanDest()
open, err := l.execPortsScan(dest)
if err != nil {
return err
}
l.updatePortStatus(open)
return nil
}
func (l *base) detectScanDest() map[string][]string {
scanIPPortsMap := map[string][]string{}
for _, p := range l.osPackages.Packages {
if p.AffectedProcs == nil {
continue
}
for _, proc := range p.AffectedProcs {
if proc.ListenPorts == nil {
continue
}
for _, port := range proc.ListenPorts {
scanIPPortsMap[port.Address] = append(scanIPPortsMap[port.Address], port.Port)
}
}
}
scanDestIPPorts := map[string][]string{}
for addr, ports := range scanIPPortsMap {
if addr == "*" {
for _, addr := range l.ServerInfo.IPv4Addrs {
scanDestIPPorts[addr] = append(scanDestIPPorts[addr], ports...)
}
} else {
scanDestIPPorts[addr] = append(scanDestIPPorts[addr], ports...)
}
}
uniqScanDestIPPorts := map[string][]string{}
for i, scanDest := range scanDestIPPorts {
m := map[string]bool{}
for _, e := range scanDest {
if !m[e] {
m[e] = true
uniqScanDestIPPorts[i] = append(uniqScanDestIPPorts[i], e)
}
}
}
return uniqScanDestIPPorts
}
func (l *base) execPortsScan(scanDestIPPorts map[string][]string) ([]string, error) {
listenIPPorts := []string{}
for ip, ports := range scanDestIPPorts {
if !isLocalExec(l.ServerInfo.Port, l.ServerInfo.Host) && net.ParseIP(ip).IsLoopback() {
continue
}
for _, port := range ports {
scanDest := ip + ":" + port
conn, err := net.DialTimeout("tcp", scanDest, time.Duration(1)*time.Second)
if err != nil {
continue
}
conn.Close()
listenIPPorts = append(listenIPPorts, scanDest)
}
}
return listenIPPorts, nil
}
func (l *base) updatePortStatus(listenIPPorts []string) {
for name, p := range l.osPackages.Packages {
if p.AffectedProcs == nil {
continue
}
for i, proc := range p.AffectedProcs {
if proc.ListenPorts == nil {
continue
}
for j, port := range proc.ListenPorts {
l.osPackages.Packages[name].AffectedProcs[i].ListenPorts[j].PortScanSuccessOn = l.findPortScanSuccessOn(listenIPPorts, port)
}
}
}
}
func (l *base) findPortScanSuccessOn(listenIPPorts []string, searchListenPort models.ListenPort) []string {
addrs := []string{}
for _, ipPort := range listenIPPorts {
ipPort := l.parseListenPorts(ipPort)
if searchListenPort.Address == "*" {
if searchListenPort.Port == ipPort.Port {
addrs = append(addrs, ipPort.Address)
}
} else if searchListenPort.Address == ipPort.Address && searchListenPort.Port == ipPort.Port {
addrs = append(addrs, ipPort.Address)
}
}
return addrs
}
func (l *base) ps() (stdout string, err error) {
cmd := `LANGUAGE=en_US.UTF-8 ps --no-headers --ppid 2 -p 2 --deselect -o pid,comm`
r := l.exec(util.PrependProxyEnv(cmd), noSudo)
@@ -779,13 +898,13 @@ func (l *base) lsOfListen() (stdout string, err error) {
cmd := `lsof -i -P -n | grep LISTEN`
r := l.exec(util.PrependProxyEnv(cmd), sudo)
if !r.isSuccess(0, 1) {
return "", xerrors.Errorf("Failed to SSH: %s", r)
return "", xerrors.Errorf("Failed to lsof: %s", r)
}
return r.Stdout, nil
}
func (l *base) parseLsOf(stdout string) map[string]string {
portPid := map[string]string{}
func (l *base) parseLsOf(stdout string) map[string][]string {
portPids := map[string][]string{}
scanner := bufio.NewScanner(strings.NewReader(stdout))
for scanner.Scan() {
ss := strings.Fields(scanner.Text())
@@ -793,7 +912,15 @@ func (l *base) parseLsOf(stdout string) map[string]string {
continue
}
pid, ipPort := ss[1], ss[8]
portPid[ipPort] = pid
portPids[ipPort] = util.AppendIfMissing(portPids[ipPort], pid)
}
return portPid
return portPids
}
func (l *base) parseListenPorts(port string) models.ListenPort {
sep := strings.LastIndex(port, ":")
if sep == -1 {
return models.ListenPort{}
}
return models.ListenPort{Address: port[:sep], Port: port[sep+1:]}
}

View File

@@ -12,6 +12,7 @@ import (
_ "github.com/aquasecurity/fanal/analyzer/library/poetry"
_ "github.com/aquasecurity/fanal/analyzer/library/yarn"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
)
func TestParseDockerPs(t *testing.T) {
@@ -243,7 +244,7 @@ func Test_base_parseLsOf(t *testing.T) {
tests := []struct {
name string
args args
wantPortPid map[string]string
wantPortPid map[string][]string
}{
{
name: "lsof",
@@ -256,13 +257,34 @@ node 1498 ubuntu 21u IPv6 20132 0t0 TCP *:35401 (LISTEN
node 1498 ubuntu 22u IPv6 20133 0t0 TCP *:44801 (LISTEN)
docker-pr 9135 root 4u IPv6 297133 0t0 TCP *:6379 (LISTEN)`,
},
wantPortPid: map[string]string{
"localhost:53": "474",
"*:22": "644",
"*:3128": "959",
"*:35401": "1498",
"*:44801": "1498",
"*:6379": "9135",
wantPortPid: map[string][]string{
"localhost:53": {"474"},
"*:22": {"644"},
"*:3128": {"959"},
"*:35401": {"1498"},
"*:44801": {"1498"},
"*:6379": {"9135"},
},
},
{
name: "lsof-duplicate-port",
args: args{
stdout: `sshd 832 root 3u IPv4 15731 0t0 TCP *:22 (LISTEN)
sshd 832 root 4u IPv6 15740 0t0 TCP *:22 (LISTEN)
master 1099 root 13u IPv4 16657 0t0 TCP 127.0.0.1:25 (LISTEN)
master 1099 root 14u IPv6 16658 0t0 TCP [::1]:25 (LISTEN)
httpd 32250 root 4u IPv6 334982 0t0 TCP *:80 (LISTEN)
httpd 32251 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN)
httpd 32252 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN)
httpd 32253 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN)
httpd 32254 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN)
httpd 32255 apache 4u IPv6 334982 0t0 TCP *:80 (LISTEN)`,
},
wantPortPid: map[string][]string{
"*:22": {"832"},
"127.0.0.1:25": {"1099"},
"[::1]:25": {"1099"},
"*:80": {"32250", "32251", "32252", "32253", "32254", "32255"},
},
},
}
@@ -275,3 +297,242 @@ docker-pr 9135 root 4u IPv6 297133 0t0 TCP *:6379 (LISTEN)
})
}
}
func Test_detectScanDest(t *testing.T) {
tests := []struct {
name string
args base
expect map[string][]string
}{
{
name: "empty",
args: base{osPackages: osPackages{
Packages: models.Packages{"curl": models.Package{
Name: "curl",
Version: "7.64.0-4+deb10u1",
NewVersion: "7.64.0-4+deb10u1",
}},
}},
expect: map[string][]string{},
},
{
name: "single-addr",
args: base{osPackages: osPackages{
Packages: models.Packages{"libaudit1": models.Package{
Name: "libaudit1",
Version: "1:2.8.4-3",
NewVersion: "1:2.8.4-3",
AffectedProcs: []models.AffectedProcess{
{PID: "21", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22"}}}, {PID: "10876", Name: "sshd"}},
},
}},
},
expect: map[string][]string{"127.0.0.1": {"22"}},
},
{
name: "dup-addr-port",
args: base{osPackages: osPackages{
Packages: models.Packages{"libaudit1": models.Package{
Name: "libaudit1",
Version: "1:2.8.4-3",
NewVersion: "1:2.8.4-3",
AffectedProcs: []models.AffectedProcess{
{PID: "21", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22"}}}, {PID: "21", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22"}}}},
},
}},
},
expect: map[string][]string{"127.0.0.1": {"22"}},
},
{
name: "multi-addr",
args: base{osPackages: osPackages{
Packages: models.Packages{"libaudit1": models.Package{
Name: "libaudit1",
Version: "1:2.8.4-3",
NewVersion: "1:2.8.4-3",
AffectedProcs: []models.AffectedProcess{
{PID: "21", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22"}}}, {PID: "21", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "192.168.1.1", Port: "22"}}}, {PID: "6261", Name: "nginx", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "80"}}}},
},
}},
},
expect: map[string][]string{"127.0.0.1": {"22", "80"}, "192.168.1.1": {"22"}},
},
{
name: "asterisk",
args: base{
osPackages: osPackages{
Packages: models.Packages{"libaudit1": models.Package{
Name: "libaudit1",
Version: "1:2.8.4-3",
NewVersion: "1:2.8.4-3",
AffectedProcs: []models.AffectedProcess{
{PID: "21", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "*", Port: "22"}}}},
},
}},
ServerInfo: config.ServerInfo{
IPv4Addrs: []string{"127.0.0.1", "192.168.1.1"},
},
},
expect: map[string][]string{"127.0.0.1": {"22"}, "192.168.1.1": {"22"}},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if dest := tt.args.detectScanDest(); !reflect.DeepEqual(dest, tt.expect) {
t.Errorf("base.detectScanDest() = %v, want %v", dest, tt.expect)
}
})
}
}
func Test_updatePortStatus(t *testing.T) {
type args struct {
l base
listenIPPorts []string
}
tests := []struct {
name string
args args
expect models.Packages
}{
{name: "nil_affected_procs",
args: args{
l: base{osPackages: osPackages{
Packages: models.Packages{"libc-bin": models.Package{Name: "libc-bin"}},
}},
listenIPPorts: []string{"127.0.0.1:22"}},
expect: models.Packages{"libc-bin": models.Package{Name: "libc-bin"}}},
{name: "nil_listen_ports",
args: args{
l: base{osPackages: osPackages{
Packages: models.Packages{"bash": models.Package{Name: "bash", AffectedProcs: []models.AffectedProcess{{PID: "1", Name: "bash"}}}},
}},
listenIPPorts: []string{"127.0.0.1:22"}},
expect: models.Packages{"bash": models.Package{Name: "bash", AffectedProcs: []models.AffectedProcess{{PID: "1", Name: "bash"}}}}},
{name: "update_match_single_address",
args: args{
l: base{osPackages: osPackages{
Packages: models.Packages{"libc6": models.Package{Name: "libc6", AffectedProcs: []models.AffectedProcess{{PID: "1", Name: "bash"}, {PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22"}}}}}},
}},
listenIPPorts: []string{"127.0.0.1:22"}},
expect: models.Packages{"libc6": models.Package{Name: "libc6", AffectedProcs: []models.AffectedProcess{{PID: "1", Name: "bash"}, {PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22", PortScanSuccessOn: []string{"127.0.0.1"}}}}}}}},
{name: "update_match_multi_address",
args: args{
l: base{osPackages: osPackages{
Packages: models.Packages{"libc6": models.Package{Name: "libc6", AffectedProcs: []models.AffectedProcess{{PID: "1", Name: "bash"}, {PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22"}, {Address: "192.168.1.1", Port: "22"}}}}}},
}},
listenIPPorts: []string{"127.0.0.1:22", "192.168.1.1:22"}},
expect: models.Packages{"libc6": models.Package{Name: "libc6", AffectedProcs: []models.AffectedProcess{{PID: "1", Name: "bash"}, {PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{
{Address: "127.0.0.1", Port: "22", PortScanSuccessOn: []string{"127.0.0.1"}},
{Address: "192.168.1.1", Port: "22", PortScanSuccessOn: []string{"192.168.1.1"}},
}}}}}},
{name: "update_match_asterisk",
args: args{
l: base{osPackages: osPackages{
Packages: models.Packages{"libc6": models.Package{Name: "libc6", AffectedProcs: []models.AffectedProcess{{PID: "1", Name: "bash"}, {PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "*", Port: "22"}}}}}},
}},
listenIPPorts: []string{"127.0.0.1:22", "127.0.0.1:80", "192.168.1.1:22"}},
expect: models.Packages{"libc6": models.Package{Name: "libc6", AffectedProcs: []models.AffectedProcess{{PID: "1", Name: "bash"}, {PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{
{Address: "*", Port: "22", PortScanSuccessOn: []string{"127.0.0.1", "192.168.1.1"}},
}}}}}},
{name: "update_multi_packages",
args: args{
l: base{osPackages: osPackages{
Packages: models.Packages{
"packa": models.Package{Name: "packa", AffectedProcs: []models.AffectedProcess{{PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "80"}}}}},
"packb": models.Package{Name: "packb", AffectedProcs: []models.AffectedProcess{{PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22"}}}}},
"packc": models.Package{Name: "packc", AffectedProcs: []models.AffectedProcess{{PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22"}, {Address: "192.168.1.1", Port: "22"}}}}},
"packd": models.Package{Name: "packd", AffectedProcs: []models.AffectedProcess{{PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "*", Port: "22"}}}}},
},
}},
listenIPPorts: []string{"127.0.0.1:22", "192.168.1.1:22"}},
expect: models.Packages{
"packa": models.Package{Name: "packa", AffectedProcs: []models.AffectedProcess{{PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "80", PortScanSuccessOn: []string{}}}}}},
"packb": models.Package{Name: "packb", AffectedProcs: []models.AffectedProcess{{PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22", PortScanSuccessOn: []string{"127.0.0.1"}}}}}},
"packc": models.Package{Name: "packc", AffectedProcs: []models.AffectedProcess{{PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "127.0.0.1", Port: "22", PortScanSuccessOn: []string{"127.0.0.1"}}, {Address: "192.168.1.1", Port: "22", PortScanSuccessOn: []string{"192.168.1.1"}}}}}},
"packd": models.Package{Name: "packd", AffectedProcs: []models.AffectedProcess{{PID: "75", Name: "sshd", ListenPorts: []models.ListenPort{{Address: "*", Port: "22", PortScanSuccessOn: []string{"127.0.0.1", "192.168.1.1"}}}}}},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.args.l.updatePortStatus(tt.args.listenIPPorts)
if !reflect.DeepEqual(tt.args.l.osPackages.Packages, tt.expect) {
t.Errorf("l.updatePortStatus() = %v, want %v", tt.args.l.osPackages.Packages, tt.expect)
}
})
}
}
func Test_matchListenPorts(t *testing.T) {
type args struct {
listenIPPorts []string
searchListenPort models.ListenPort
}
tests := []struct {
name string
args args
expect []string
}{
{name: "open_empty", args: args{listenIPPorts: []string{}, searchListenPort: models.ListenPort{Address: "127.0.0.1", Port: "22"}}, expect: []string{}},
{name: "port_empty", args: args{listenIPPorts: []string{"127.0.0.1:22"}, searchListenPort: models.ListenPort{}}, expect: []string{}},
{name: "single_match", args: args{listenIPPorts: []string{"127.0.0.1:22"}, searchListenPort: models.ListenPort{Address: "127.0.0.1", Port: "22"}}, expect: []string{"127.0.0.1"}},
{name: "no_match_address", args: args{listenIPPorts: []string{"127.0.0.1:22"}, searchListenPort: models.ListenPort{Address: "192.168.1.1", Port: "22"}}, expect: []string{}},
{name: "no_match_port", args: args{listenIPPorts: []string{"127.0.0.1:22"}, searchListenPort: models.ListenPort{Address: "127.0.0.1", Port: "80"}}, expect: []string{}},
{name: "asterisk_match", args: args{listenIPPorts: []string{"127.0.0.1:22", "127.0.0.1:80", "192.168.1.1:22"}, searchListenPort: models.ListenPort{Address: "*", Port: "22"}}, expect: []string{"127.0.0.1", "192.168.1.1"}},
}
l := base{}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if match := l.findPortScanSuccessOn(tt.args.listenIPPorts, tt.args.searchListenPort); !reflect.DeepEqual(match, tt.expect) {
t.Errorf("findPortScanSuccessOn() = %v, want %v", match, tt.expect)
}
})
}
}
func Test_base_parseListenPorts(t *testing.T) {
tests := []struct {
name string
args string
expect models.ListenPort
}{{
name: "empty",
args: "",
expect: models.ListenPort{
Address: "",
Port: "",
},
}, {
name: "normal",
args: "127.0.0.1:22",
expect: models.ListenPort{
Address: "127.0.0.1",
Port: "22",
},
}, {
name: "asterisk",
args: "*:22",
expect: models.ListenPort{
Address: "*",
Port: "22",
},
}, {
name: "ipv6_loopback",
args: "[::1]:22",
expect: models.ListenPort{
Address: "[::1]",
Port: "22",
},
}}
l := base{}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if listenPort := l.parseListenPorts(tt.args); !reflect.DeepEqual(listenPort, tt.expect) {
t.Errorf("base.parseListenPorts() = %v, want %v", listenPort, tt.expect)
}
})
}
}

View File

@@ -1294,14 +1294,16 @@ func (o *debian) dpkgPs() error {
pidLoadedFiles[pid] = append(pidLoadedFiles[pid], ss...)
}
pidListenPorts := map[string][]string{}
pidListenPorts := map[string][]models.ListenPort{}
stdout, err = o.lsOfListen()
if err != nil {
return xerrors.Errorf("Failed to ls of: %w", err)
}
portPid := o.parseLsOf(stdout)
for port, pid := range portPid {
pidListenPorts[pid] = append(pidListenPorts[pid], port)
portPids := o.parseLsOf(stdout)
for port, pids := range portPids {
for _, pid := range pids {
pidListenPorts[pid] = append(pidListenPorts[pid], o.parseListenPorts(port))
}
}
for pid, loadedFiles := range pidLoadedFiles {

View File

@@ -163,12 +163,24 @@ func (o *bsd) rebootRequired() (bool, error) {
}
func (o *bsd) scanInstalledPackages() (models.Packages, error) {
cmd := util.PrependProxyEnv("pkg version -v")
// https://github.com/future-architect/vuls/issues/1042
cmd := util.PrependProxyEnv("pkg info")
r := o.exec(cmd, noSudo)
if !r.isSuccess() {
return nil, xerrors.Errorf("Failed to SSH: %s", r)
}
return o.parsePkgVersion(r.Stdout), nil
pkgs := o.parsePkgInfo(r.Stdout)
cmd = util.PrependProxyEnv("pkg version -v")
r = o.exec(cmd, noSudo)
if !r.isSuccess() {
return nil, xerrors.Errorf("Failed to SSH: %s", r)
}
// `pkg-audit` has a new version, overwrite it.
for name, p := range o.parsePkgVersion(r.Stdout) {
pkgs[name] = p
}
return pkgs, nil
}
func (o *bsd) scanUnsecurePackages() (models.VulnInfos, error) {
@@ -247,6 +259,27 @@ func (o *bsd) scanUnsecurePackages() (models.VulnInfos, error) {
return vinfos, nil
}
func (o *bsd) parsePkgInfo(stdout string) models.Packages {
packs := models.Packages{}
lines := strings.Split(stdout, "\n")
for _, l := range lines {
fields := strings.Fields(l)
if len(fields) < 2 {
continue
}
packVer := fields[0]
splitted := strings.Split(packVer, "-")
ver := splitted[len(splitted)-1]
name := strings.Join(splitted[:len(splitted)-1], "-")
packs[name] = models.Package{
Name: name,
Version: ver,
}
}
return packs
}
func (o *bsd) parsePkgVersion(stdout string) models.Packages {
packs := models.Packages{}
lines := strings.Split(stdout, "\n")

View File

@@ -197,3 +197,50 @@ WWW: https://vuxml.FreeBSD.org/freebsd/ab3e98d9-8175-11e4-907d-d050992ecde8.html
}
}
}
func TestParsePkgInfo(t *testing.T) {
var tests = []struct {
in string
expected models.Packages
}{
{
`bash-4.2.45 Universal Command Line Interface for Amazon Web Services
gettext-0.18.3.1 Startup scripts for FreeBSD/EC2 environment
tcl84-8.4.20_2,1 Update the system using freebsd-update when it first boots
ntp-4.2.8p8_1 GNU gettext runtime libraries and programs
teTeX-base-3.0_25 Foreign Function Interface`,
models.Packages{
"bash": {
Name: "bash",
Version: "4.2.45",
},
"gettext": {
Name: "gettext",
Version: "0.18.3.1",
},
"tcl84": {
Name: "tcl84",
Version: "8.4.20_2,1",
},
"teTeX-base": {
Name: "teTeX-base",
Version: "3.0_25",
},
"ntp": {
Name: "ntp",
Version: "4.2.8p8_1",
},
},
},
}
d := newBsd(config.ServerInfo{})
for _, tt := range tests {
actual := d.parsePkgInfo(tt.in)
if !reflect.DeepEqual(tt.expected, actual) {
e := pp.Sprintf("%v", tt.expected)
a := pp.Sprintf("%v", actual)
t.Errorf("expected %s, actual %s", e, a)
}
}
}

View File

@@ -361,7 +361,7 @@ func (o *redhatBase) scanUpdatablePackages() (models.Packages, error) {
return nil, xerrors.Errorf("Failed to SSH: %s", r)
}
// Collect Updateble packages, installed, candidate version and repository.
// Collect Updatable packages, installed, candidate version and repository.
return o.parseUpdatablePacksLines(r.Stdout)
}
@@ -491,14 +491,16 @@ func (o *redhatBase) yumPs() error {
pidLoadedFiles[pid] = append(pidLoadedFiles[pid], ss...)
}
pidListenPorts := map[string][]string{}
pidListenPorts := map[string][]models.ListenPort{}
stdout, err = o.lsOfListen()
if err != nil {
return xerrors.Errorf("Failed to ls of: %w", err)
}
portPid := o.parseLsOf(stdout)
for port, pid := range portPid {
pidListenPorts[pid] = append(pidListenPorts[pid], port)
portPids := o.parseLsOf(stdout)
for port, pids := range portPids {
for _, pid := range pids {
pidListenPorts[pid] = append(pidListenPorts[pid], o.parseListenPorts(port))
}
}
for pid, loadedFiles := range pidLoadedFiles {
@@ -630,8 +632,8 @@ func (o *redhatBase) procPathToFQPN(execCommand string) (string, error) {
func (o *redhatBase) getPkgName(paths []string) (pkgNames []string, err error) {
cmd := o.rpmQf(o.Distro) + strings.Join(paths, " ")
r := o.exec(util.PrependProxyEnv(cmd), noSudo)
if !r.isSuccess() {
return nil, xerrors.Errorf("Failed to SSH: %s", r)
if !r.isSuccess(0, 2, 4, 8) {
return nil, xerrors.Errorf("Failed to rpm -qf: %s, cmd: %s", r, cmd)
}
scanner := bufio.NewScanner(strings.NewReader(r.Stdout))

View File

@@ -48,6 +48,7 @@ type osTypeInterface interface {
postScan() error
scanWordPress() error
scanLibraries() error
scanPorts() error
scanPackages() error
convertToModel() models.ScanResult
@@ -634,6 +635,9 @@ func GetScanResults(scannedAt time.Time, timeoutSec int) (results models.ScanRes
if err = o.scanLibraries(); err != nil {
return xerrors.Errorf("Failed to scan Library: %w", err)
}
if err = o.scanPorts(); err != nil {
return xerrors.Errorf("Failed to scan Ports: %w", err)
}
return nil
}, timeoutSec)
@@ -642,6 +646,7 @@ func GetScanResults(scannedAt time.Time, timeoutSec int) (results models.ScanRes
if err != nil {
util.Log.Errorf("Failed to fetch scannedIPs. err: %+v", err)
}
for _, s := range append(servers, errServers...) {
r := s.convertToModel()
r.ScannedAt = scannedAt

View File

@@ -10,6 +10,7 @@ import (
"time"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/libmanager"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/report"
"github.com/future-architect/vuls/scan"
@@ -56,6 +57,14 @@ func (h VulsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
nCVEs, err := libmanager.DetectLibsCves(&result)
if err != nil {
util.Log.Error("Failed to fill with Library dependency: %w", err)
http.Error(w, err.Error(), http.StatusServiceUnavailable)
}
util.Log.Infof("%s: %d CVEs are detected with Library",
result.FormatServerName(), nCVEs)
if err := report.FillCveInfo(h.DBclient, &result, []string{}, true); err != nil {
util.Log.Error(err)
http.Error(w, err.Error(), http.StatusServiceUnavailable)