Compare commits

...

109 Commits

Author SHA1 Message Date
Kota Kanbe
3be50ab8da bump up version 2020-04-19 09:06:01 +09:00
Kota Kanbe
649f4a6991 fix(report): kernel vulns detection BUG in Ubuntu (#958)
* fix(report): kernel vulns detection in Ubuntu

* fix(ubuntu): remove linux-* to detect only running kernel vulns
2020-04-19 09:04:08 +09:00
Kota Kanbe
0ff7641471 feat(report): display "fixed" when updatable even in fast mode (#957) 2020-04-13 18:20:32 +09:00
Kota Kanbe
1679bfae20 Update FUNDING.yml 2020-04-10 21:25:10 +09:00
Kota Kanbe
45aa364436 Update FUNDING.yml 2020-04-10 21:24:24 +09:00
Kota Kanbe
778516c4d9 Create FUNDING.yml 2020-04-10 21:21:30 +09:00
Kota Kanbe
464d523c42 Display fixed-in version for each package in report (#801)
* refactor(model): PackageFixStatus.Name to BinName

* refacotr(oval): change var name

* feat(report): Add FixedIn in JSON

* refactor(tui): chage args

* display fixedin in report

* refactor(model): change fileld name

* remove unused field of PackageFixStatus
2020-04-08 21:26:34 +09:00
Kota Kanbe
0f6a1987d4 fix(configtest): yum-utils instead of dnf-utils on RHEL8, Cent8 (#948) 2020-04-06 19:40:05 +09:00
Shigechika AIKAWA
20c6247ce5 fix CentOS8 configtest always failed (#947) 2020-04-06 15:47:08 +09:00
gy741
a10dd67e0f Fix typo in models/scanresults.go (#942) 2020-04-06 15:00:43 +09:00
segatomo
5729ad6026 Add CWE Top25 and SANS Top25 (#925)
* add top25 rank

* add CweTop25 and SansTop25

* fix report

* add cwetop25 and sanstop25 url

* fix condition branch

* fix condition branch
2020-03-03 17:33:06 +09:00
Tomoya Amachi
9aa0d87a21 feat : scan with image digest (#939) 2020-03-03 16:51:06 +09:00
ishiDACo
fe3f1b9924 Update OWASP Dependency Check parser for dependency-check.2.2.xsd schema (#936) 2020-02-27 10:08:26 +09:00
Kota Kanbe
00e52a88fa Update README.md 2020-02-01 09:27:17 +09:00
Kota Kanbe
5811dffe7a fix(report): Support CVSS 3.1 for Red Hat OVAL #930 (#932) 2020-01-30 22:48:04 +09:00
sadayuki-matsuno
7278982af4 update fanal (#931) 2020-01-30 20:40:49 +09:00
nyao
c17b4154ec fix(config): fix double checking ResultsDir Path (#927) 2019-12-12 09:29:12 +09:00
Kota Kanbe
d6e74cce08 bump up version (#923) 2019-11-26 09:54:30 +09:00
Kota Kanbe
3f80749241 Merge branch 'master' of github.com:future-architect/vuls 2019-11-26 09:44:10 +09:00
Kota Kanbe
7f72b6ac69 Warn no ip (#922)
* fix(scan): ignore wp-cli stderr messages (#825) (#915)

* fix(scan): warn if unable to get ip address on the scan tareget server

* fix test case
2019-11-26 09:40:38 +09:00
Kota Kanbe
03e7b90b9f Merge branch 'master' of github.com:future-architect/vuls 2019-11-26 08:53:03 +09:00
Kota Kanbe
7936b3533b Fill Red Hat CVE data for all distros (#920)
* fix(scan): ignore wp-cli stderr messages (#825) (#915)

* refactor

* feat(report): fill Red Hat CVE data for all distros

* fix lint err

* fix cve judgment (#921)
2019-11-25 17:01:18 +09:00
Shigechika AIKAWA
bd7e61d7cc fix(scan): ignore wp-cli stderr messages (#825) (#915) 2019-11-22 20:58:24 +09:00
Shigechika AIKAWA
69214e0c22 fix(scan): ignore wp-cli stderr messages (#825) (#915) 2019-11-01 10:01:50 +09:00
Wagde Zabit
45bff26558 Consider grep return value 1 as success (#907)
* Allow Offline scanning on Alpine

* Consider grep return value 1 as success
2019-09-18 23:26:37 +09:00
Kota Kanbe
b2e429ccc6 fix(log): add .log extension to vuls logfile (#910) 2019-09-18 23:21:06 +09:00
Kota Kanbe
76363c227b fix(report): enable to report when the sshkey not exist (#909) 2019-09-18 22:40:36 +09:00
Kota Kanbe
d5a3e5c2c5 fix(report): fix cert key in result json ja to jp (#908) 2019-09-18 19:30:32 +09:00
Kota Kanbe
2b02807ef0 fix(report): ignore exploits of no-cve-id vulns (#906) 2019-09-13 12:49:57 +09:00
Kota Kanbe
be659ae094 fix(docker): add git to image (#905) 2019-09-13 01:10:27 +09:00
Kota Kanbe
b2c105adbc fix(tui): enable to exec tui mode without cve.sqlite3 (#904) 2019-09-12 18:35:21 +09:00
Kota Kanbe
c61f462948 fix(report): show POC, CERT in tui and format-list. use vendor summary over NVD (#902)
* fix(report): show POC, CERT in tui and format-list. show vendor summary

* fix test case
2019-09-10 10:00:17 +09:00
Kota Kanbe
3ffed18e02 Change GPL v3 to AGPL v3 because of aquasecurity/trivy dependency (#897) 2019-09-09 21:12:17 +09:00
Kota Kanbe
f54e7257d1 fix(report): fill cert alerts from NVD and JVN feeds (#899)
* fix(report): fill cert alerts from NVD and JVN feeds

* fix import alias cve to cvemodels

* fix import alias cve to cvemodels

* remove unnecessary func
2019-09-09 21:11:59 +09:00
Kota Kanbe
cc13b6a27c fix(report): enable to report without NVD, exit if no OVAL data (#900)
* feat(report): enable to report without NVD

* fix(report): enable to report without NVD and exit if no OVAL data

* update deps

* go mod tidy

* fix err msg
2019-09-09 21:00:34 +09:00
Kota Kanbe
8877db1979 udpate deps, go 1.13 (#901) 2019-09-09 20:26:26 +09:00
Tomoya Amachi
af58122c91 for Amazon Linux image (#896)
* fit amazon linux image's version to OVAL

* add Arch to SrcPackage

* lint go.mod

* make fmt
2019-09-06 10:34:14 +09:00
Kota Kanbe
b7ca5e5590 feat(scan): add -wordpress-only and -libs-only flag (#898) 2019-09-06 10:33:03 +09:00
Tomoya Amachi
69b6d875e6 scanVuln => GetScanResults and writeScanResults (#891) 2019-09-04 13:28:34 +09:00
Kota Kanbe
1fbd516b83 fix(report): fix too many variables while reporting (#888) 2019-08-25 17:56:47 +09:00
DjinnS
dec5d3b165 No warning(s) in the output file with -quiet option. Report command (#885) 2019-08-25 10:56:42 +09:00
DjinnS
d5e2040cef awk is useless because ps already formats the output. Also, this syntaxe isn't correct when the command is excuted on a container because of the ' . (#883) 2019-08-25 10:13:58 +09:00
wagdez
4326befdec Allow Offline scanning on Alpine (#877) 2019-07-30 17:47:01 +09:00
Kota Kanbe
3d4a5d9917 fix(report): Unsupport family: centos (#876)
* fix(report): Unsupport family: centos

* go mod tidy
2019-07-25 12:47:41 +09:00
Shigechika AIKAWA
d770034788 fix centos yum makecache --assumeyes (#872) 2019-07-17 11:10:20 +09:00
Masahiro Fujimura
a977533c78 Fix performance and bug (#867)
* Fix performance

* Update goval-dictionary

* Go mod tidy
2019-07-15 21:20:01 +09:00
Kota Kanbe
c5e13dd5e4 fix(configtest): remove yum-plugin-ps check on Amazon Linux (#870) 2019-07-12 07:25:47 +09:00
Kota Kanbe
a8040fe4d2 fix(wordpress): add --allow-root to wp cmd for docker based wp (#865) 2019-07-07 19:15:17 +09:00
Tomoya Amachi
9e066008c3 fix go module problems & update trivy version (#864)
* update trivy version

* use goval-dictionary@v0.1.4
2019-07-07 17:04:52 +09:00
Kota Kanbe
22c6601526 make fmt 2019-07-06 23:25:46 +09:00
Kota Kanbe
425464fd76 fix(scan): allow exit 1 for no match lsof | grep (#863) 2019-07-06 23:15:34 +09:00
Kota Kanbe
ccb0751ffd fix(scan): show listening ip:port of procs (#862) 2019-07-06 14:10:08 +09:00
Kota Kanbe
f832de81b7 feat(saas): log.info done after uploading 2019-07-05 17:30:31 +09:00
Tomoya Amachi
8a37de0686 Add ips flag to scan (#861)
* add scan -ips flag

* fix usage
2019-07-04 18:42:12 +09:00
Kota Kanbe
836e4704f8 feat(scan): Display listen port of affected procs for each vulnerable pkgs (#859)
* refactor(redhat): move rpmQa and rpmQf to redhatbase.go

* feat(scan): Display listen port of affected procs
2019-07-03 23:01:59 +09:00
Kota Kanbe
3e5390309c feat(redhat): ignore will not fix vulns (#858) 2019-07-03 20:59:23 +09:00
Kota Kanbe
f8c0b38716 feat(fast-root): get running procs for each pkgs (all RHEL, CentOS, AmazonLinux, Ubuntu, Debian) (#855)
* fix(scan): exec yum-plugin-ps on RHEL6 and 7

* feat(yumps): get affected procs on RHEL6 and RHEL8

* feat(scan): get affected processes for each packages

* tuning

* feat(scan): get running procs for each pkgs on Debian, Ubuntu
2019-07-02 14:55:46 +09:00
Masahiro Fujimura
65e6070e5f Fix race condition in server mode (#857) 2019-07-02 10:11:36 +09:00
Tomoya Amachi
7b78ebbc42 retrieve ips(deep security) identifiers (#852)
* retrieve ips identifiers

* fix golangci

* use IPS type

* fix log message

* fix lockfiles config

* change label

* IPS : only work with fast-root mode
2019-07-02 10:06:30 +09:00
Masahiro Fujimura
03c3189c02 Changes don't required config.toml in server mode (#853) 2019-06-26 21:21:17 +09:00
Masahiro Fujimura
4a34dfe0e9 Support amazonlinux via http text/plain (#850) 2019-06-25 10:00:54 +09:00
Kota Kanbe
4cf9a723fe set GO111MODULE=on in .goreleaser.yml 2019-06-18 10:15:42 +09:00
Kota Kanbe
bd1b135db3 Add vulsrepo issue template 2019-06-17 14:15:23 +09:00
alfe
8c3b305149 fix(readme): typo in news (#841) 2019-06-15 18:39:00 +09:00
Kota Kanbe
a3719038b8 fix(scan): scan Amazon Linux with offline mode (#840) 2019-06-14 19:10:07 +09:00
Kota Kanbe
c68a261c0b Update README.md 2019-06-14 19:02:21 +09:00
Kota Kanbe
75fea79ac1 feat(scan): Support RHEL8 (#813)
* feat(scan): Support RHEL8

* fix(scan): check if `dnf-uils` is installed
2019-06-14 12:28:16 +09:00
Kota Kanbe
eb9f9680ec refactor(scan): remove yum-security related code (#836)
* refactor(scan): remove yum-security related code

* fix(reporting): error if no OVAL entry
2019-06-14 11:42:38 +09:00
Tomoya Amachi
3634afdb81 enhance issue_template (#837) 2019-06-14 11:34:36 +09:00
Sajan Alexander
77b5df896a update goval-dictionary dependency to valid version (#839) 2019-06-14 09:28:39 +09:00
Kota Kanbe
b81f64058c fix(report): remove extra check logic #802 (#835) 2019-06-13 21:45:22 +09:00
Kota Kanbe
a8a90d7c63 refactor(report): speed up oval reporting #833 (#834) 2019-06-13 17:47:36 +09:00
Kota Kanbe
17bb575002 fix(scan): enable to report if some warnings occured on scanning (#805)
* fix(scan): enable to report if some warnings occured on scanning

* alpine, debian, freebsd, suse

* -format-full-text, -format-list, -format-one-line-text

* implement slack.go

* implement tui.go

* go fmt
2019-06-12 21:35:21 +09:00
Tomoya Amachi
abcea1a14d add Library Scan (with image scan) (#829)
* add static container image scan

* server has many staticContainers

* use go module

* for staticContainer

* fix typo

* fix setErrs error

* change name : StaticContainer -> Image

* add scan -images-only flag

* fix makefile

* fix makefile for go module

* use rpmcmd instead of rpm

* add scrutinizer.yml

* change scrutinizer.yml

* fix scrutinizer.yml

* fix scrutinizer.yml

* fix scrutinizer.yml

* fix scrutinizer.yml

* delete scrutinizer

* add report test

* add sourcePackages and Arch

* fix for sider

* fix staticContainer -> image

* init scan library

* add library scan for servers

* fix tui bug

* fix lint error

* divide WpPackageFixStats and LibraryPackageFixedIns

* fix error

* Delete libManager_test.go

* stop use alpine os if err occurred in container

* merge upstream/master

* Delete libManager.go

* update goval-dictionary

* fix go.mod

* update Readme

* add feature : auto detect lockfiles
2019-06-12 18:50:07 +09:00
Kota Kanbe
10942f7c08 fix(scan): fetch only updatable package changelogs (#815) 2019-06-12 15:08:03 +09:00
Kota Kanbe
87ee829e80 fix(scan): exec yum makecache to update metadata on RedHat based linux (#810)
* fix(scan): exec `yum makecache` to update metadata on RedHat based linux

* sudo
2019-06-12 14:44:42 +09:00
Chandrapal Badshah
fcc2c1e4c7 Changing the scannedAt time in the original result (#823) 2019-06-12 07:55:29 +09:00
Kota Kanbe
269095d034 feat(report): support Amazon OVAL scanning (#824)
* feat(report): support Amazon OVAL scanning

* add distroAdvisories

* see goval/master
2019-06-10 23:20:39 +09:00
Neal McBurnett
40492ee00a fix typos, extraneous text (#831) 2019-06-10 09:55:17 +09:00
Shigechika AIKAWA
64cdd5aedc fix(report): WordPress(WPVULNDB API) 429 Too Many Requests (#826)
* fix(report): WordPress(WPVULNDB API) 429 Too Many Requests

* fix(report): WordPress(WPVULNDB API) 429 Too Many Requests
2019-06-04 12:11:40 +09:00
Kota Kanbe
3bb650cb77 fix(report-redhat): fix false negative of affected vulns #827 (#828) 2019-06-04 09:55:32 +09:00
Kota Kanbe
774544c975 fix(report): warning only if the kernel version is unknown (#822) 2019-05-24 10:09:11 +09:00
Kota Kanbe
299805a726 [WIP]fix(scan): false negative of kernel related vulns on Ubuntu 16 (#819)
* fix(scan): a bug of detect kernel vulns on Ubuntu 16

* fix(scan): support Ubuntu 14
2019-05-23 23:52:00 +09:00
Kota Kanbe
276363e793 fix(scan): a bug of kernel Vulns detection on Ubuntu18 (#818)
* fix(scan): a bug of kernel Vulns detection on Ubuntu18

* fix the test case
2019-05-23 17:00:33 +09:00
Kota Kanbe
e750bd53fc fix(report): fix the number of fixed/total in reporting (#817) 2019-05-20 14:30:29 +09:00
sadayuki-matsuno
98fee7b5d2 Implement Vuls's own error code (#812)
* add error pkg

* fix fmt format

* fix NewError -> New

* fix err msg format
2019-05-15 17:42:09 +09:00
sadayuki-matsuno
53aaea9fe2 add scannedVia field to know the way of access such as SSH, local or pseudo (#811)
* add sacnned via

* change scannedVia type to const
2019-05-15 13:33:09 +09:00
Chandrapal
824fbb6368 Updated config.toml reference url (#809)
* Update URL in scan.go

* Update URL in configtest.go
2019-05-10 07:11:30 +09:00
Kota Kanbe
80566b91ab fix(report): exit 1 when scan result has errors (#804) 2019-04-25 15:09:29 +09:00
Kota Kanbe
533d05a1b5 fix(report): Error when GitHub integration failed (#800) 2019-04-15 21:51:04 +09:00
Kota Kanbe
6a1fc4fade Merge branch 'master' of https://github.com/future-architect/vuls
* 'master' of https://github.com/future-architect/vuls:
  fix goreleaser.yml
  Add news to readme
2019-04-08 21:19:12 +09:00
Kota Kanbe
9008d0ddf0 Add news to readme 2019-04-08 21:17:05 +09:00
Kota Kanbe
583f4577bc fix goreleaser.yml 2019-04-08 19:51:58 +09:00
Kota Kanbe
e5716d5092 Add news to readme 2019-04-08 18:22:03 +09:00
Kota Kanbe
7192ae1287 Bump up version 2019-04-08 17:33:57 +09:00
kazuminn
99c65eff48 feat(scan): WordPress Vulnerability Scan (core, plugin, theme) (#769)
https://github.com/future-architect/vuls/pull/769
2019-04-08 17:27:44 +09:00
Josh Soref
91df593566 Editorial fixes (#798)
mostly suggested by app.grammarly.com

* articles
* brand name fixes
* hyphenation
* Oxford comma
* sorting lists
* spelling
2019-04-04 22:51:06 +09:00
sadayuki-matsuno
07aeaeb989 update go-exploitdb (#797) 2019-03-28 00:49:31 +09:00
sadayuki-matsuno
cfeecdacd0 update pkgs (#796) 2019-03-26 10:56:14 +09:00
sadayuki-matsuno
564dfa8b62 update cve dictionary (#795) 2019-03-26 10:10:40 +09:00
seph
75dd6f2010 Specify VOLUME using json syntax (#791)
When using a json array for VOLUME, values must be quoted. Else it's interpreted as a string, eg /[vuls

Fixes https://github.com/kotakanbe/goval-dictionary/issues/58
2019-03-22 16:30:23 +09:00
Kota Kanbe
e26fd0b759 fix(report): Critical Bug Fix for CPE based scanning #793 (#794) 2019-03-22 16:28:40 +09:00
Kota Kanbe
d630680a51 feat(slack): enable -format-one-line-text with -to-slack (#792) 2019-03-18 13:56:49 +09:00
Kota Kanbe
1723c3f6a0 fix(report): cpe match bug: go-cve-dictionary#120 (#790) 2019-03-15 21:31:21 +09:00
Kota Kanbe
53dd90302e fix(scan): parse error on SUSE #515 (#786) 2019-03-12 17:36:27 +09:00
b3tyar
5c6e06b05e Handle no-auth SMTP Servers and one liner email fix (#772)
* Handle no-auth SMTP Servers

* Remove unneeded else block

* Fix for Issue #633
2019-03-12 16:45:25 +09:00
Iskander (Alex) Sharipov
cf6fb0c8a5 models: fix no-op append calls (#785)
Fixed simplest cases of append calls that have no
effect aside from driving Go static analysis tools crazy.

One issue remains (#784) since I'm not sure
what would be the right behavior there.
2019-03-07 11:28:44 +09:00
sadayuki-matsuno
e0e71b2eae add scanner info in -to-saas (#783) 2019-03-04 16:36:32 +09:00
sadayuki-matsuno
53f4a29fb1 change implemention of integration (#780) 2019-02-21 14:06:21 +09:00
133 changed files with 5215 additions and 10584 deletions

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
# These are supported funding model platforms
github: kotakanbe

View File

@@ -1,3 +1,8 @@
---
name: Bug Report
labels: bug
about: If something isn't working as expected.
---
# What did you do? (required. The issue will be **closed** when not provided.)

View File

@@ -0,0 +1,9 @@
---
name: Feature Request
labels: enhancement
about: I have a suggestion (and might want to implement myself)!
---
<!--
If this is a FEATURE REQUEST, request format does not matter!
-->

View File

@@ -0,0 +1,10 @@
---
name: Support Question
labels: question
about: If you have a question about Vuls.
---
<!--
If you have a trouble, feel free to ask.
Make sure you're not asking duplicate question by searching on the issues lists.
-->

7
.github/ISSUE_TEMPLATE/VULSREPO.md vendored Normal file
View File

@@ -0,0 +1,7 @@
---
name: Vuls Repo
labels: vulsrepo
about: If something isn't working as expected.
---

3
.gitignore vendored
View File

@@ -13,3 +13,6 @@ log/
results/
*config.toml
!setup/docker/*
.DS_Store
dist/
.idea

View File

@@ -1,4 +1,6 @@
project_name: vuls
env:
- GO111MODULE=on
release:
github:
owner: future-architect
@@ -9,7 +11,9 @@ builds:
goarch:
- amd64
main: .
ldflags: -s -w -X main.version={{.Version}} -X main.revision={{.Commit}}
flags:
- -a
ldflags: -s -w -X main.version={{.Version}} -X main.revision={{.Commit}}
binary: vuls
archive:
format: tar.gz

View File

@@ -1,7 +1,7 @@
language: go
go:
- "1.11.x"
- "1.13.x"
after_success:
- test -n "$TRAVIS_TAG" && curl -sL https://git.io/goreleaser | bash

View File

@@ -21,11 +21,12 @@ 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/
VOLUME [$WORKDIR, $LOGDIR]
VOLUME ["$WORKDIR", "$LOGDIR"]
WORKDIR $WORKDIR
ENV PWD $WORKDIR

View File

@@ -1,11 +1,9 @@
.PHONY: \
dep \
depup \
build \
install \
all \
vendor \
lint \
lint \
vet \
fmt \
fmtcheck \
@@ -21,31 +19,27 @@ REVISION := $(shell git rev-parse --short HEAD)
BUILDTIME := $(shell date "+%Y%m%d_%H%M%S")
LDFLAGS := -X 'github.com/future-architect/vuls/config.Version=$(VERSION)' \
-X 'github.com/future-architect/vuls/config.Revision=build-$(BUILDTIME)_$(REVISION)'
GO := GO111MODULE=on go
GO_OFF := GO111MODULE=off go
all: dep build
dep:
go get -u github.com/golang/dep/...
dep ensure -v
all: build
depup:
go get -u github.com/golang/dep/...
dep ensure -update -v
build: main.go pretest fmt
$(GO) build -a -ldflags "$(LDFLAGS)" -o vuls $<
build: main.go dep pretest
go build -ldflags "$(LDFLAGS)" -o vuls $<
install: main.go dep pretest
go install -ldflags "$(LDFLAGS)"
b: main.go pretest fmt
$(GO) build -ldflags "$(LDFLAGS)" -o vuls $<
install: main.go pretest
$(GO) install -ldflags "$(LDFLAGS)"
lint:
@ go get -v golang.org/x/lint/golint
$(GO_OFF) get -u golang.org/x/lint/golint
golint $(PKGS)
vet:
# @-go get -v golang.org/x/tools/cmd/vet
go vet ./... || exit;
echo $(PKGS) | xargs env $(GO) vet || exit;
fmt:
gofmt -s -w $(SRCS)
@@ -59,7 +53,7 @@ fmtcheck:
pretest: lint vet fmtcheck
test:
echo $(PKGS) | xargs go test -cover -v || exit;
$(GO) test -cover -v ./... || exit;
unused:
$(foreach pkg,$(PKGS),unused $(pkg);)

991
Gopkg.lock generated
View File

@@ -1,991 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
digest = "1:b92928b73320648b38c93cacb9082c0fe3f8ac3383ad9bd537eef62c380e0e7a"
name = "contrib.go.opencensus.io/exporter/ocagent"
packages = ["."]
pruneopts = "UT"
revision = "00af367e65149ff1f2f4b93bbfbb84fd9297170d"
version = "v0.2.0"
[[projects]]
digest = "1:a90dbfc07d4cf47b5f113a2d52227e0b098592b22c0bd7afd731f6cb8bd9d55c"
name = "github.com/Azure/azure-sdk-for-go"
packages = [
"storage",
"version",
]
pruneopts = "UT"
revision = "1951233eb944a49aa5f7278cba8e3e32a8c958af"
version = "v24.0.0"
[[projects]]
digest = "1:e6c692a2dd5f978216331f2ab41b45dfdf01d5b2a74c596a9f69bcef77b7d67b"
name = "github.com/Azure/go-autorest"
packages = [
"autorest",
"autorest/adal",
"autorest/azure",
"autorest/date",
"logger",
"tracing",
]
pruneopts = "UT"
revision = "be17756531f50014397912b7aa557ec335e39b98"
version = "v11.3.0"
[[projects]]
digest = "1:9f3b30d9f8e0d7040f729b82dcbc8f0dead820a133b3147ce355fc451f32d761"
name = "github.com/BurntSushi/toml"
packages = ["."]
pruneopts = "UT"
revision = "3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005"
version = "v0.3.1"
[[projects]]
branch = "master"
digest = "1:bb6c15391e666c4f44bdc604772301b93102233ed687be6df6d1c2abbde4f15c"
name = "github.com/RackSec/srslog"
packages = ["."]
pruneopts = "UT"
revision = "a4725f04ec91af1a91b380da679d6e0c2f061e59"
[[projects]]
digest = "1:320e7ead93de9fd2b0e59b50fd92a4d50c1f8ab455d96bc2eb083267453a9709"
name = "github.com/asaskevich/govalidator"
packages = ["."]
pruneopts = "UT"
revision = "ccb8e960c48f04d6935e72476ae4a51028f9e22f"
version = "v9"
[[projects]]
digest = "1:5652bf3ce03ccaeb93cd5e11fcaab25467f78275fd9c4b4d1ffe88aae6faed12"
name = "github.com/aws/aws-sdk-go"
packages = [
"aws",
"aws/awserr",
"aws/awsutil",
"aws/client",
"aws/client/metadata",
"aws/corehandlers",
"aws/credentials",
"aws/credentials/ec2rolecreds",
"aws/credentials/endpointcreds",
"aws/credentials/processcreds",
"aws/credentials/stscreds",
"aws/csm",
"aws/defaults",
"aws/ec2metadata",
"aws/endpoints",
"aws/request",
"aws/session",
"aws/signer/v4",
"internal/ini",
"internal/s3err",
"internal/sdkio",
"internal/sdkrand",
"internal/sdkuri",
"internal/shareddefaults",
"private/protocol",
"private/protocol/eventstream",
"private/protocol/eventstream/eventstreamapi",
"private/protocol/query",
"private/protocol/query/queryutil",
"private/protocol/rest",
"private/protocol/restxml",
"private/protocol/xml/xmlutil",
"service/s3",
"service/sts",
]
pruneopts = "UT"
revision = "aabf189db35ba7eb5a35afe6d681fc0f70954fca"
version = "v1.16.18"
[[projects]]
digest = "1:0f98f59e9a2f4070d66f0c9c39561f68fcd1dc837b22a852d28d0003aebd1b1e"
name = "github.com/boltdb/bolt"
packages = ["."]
pruneopts = "UT"
revision = "2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8"
version = "v1.3.1"
[[projects]]
digest = "1:166438587ed45ac211dab8a3ecebf4fa0c186d0db63430fb9127bbc2e5fcdc67"
name = "github.com/cenkalti/backoff"
packages = ["."]
pruneopts = "UT"
revision = "1e4cf3da559842a91afcb6ea6141451e6c30c618"
version = "v2.1.1"
[[projects]]
digest = "1:65b0d980b428a6ad4425f2df4cd5410edd81f044cf527bd1c345368444649e58"
name = "github.com/census-instrumentation/opencensus-proto"
packages = [
"gen-go/agent/common/v1",
"gen-go/agent/trace/v1",
"gen-go/resource/v1",
"gen-go/trace/v1",
]
pruneopts = "UT"
revision = "7f2434bc10da710debe5c4315ed6d4df454b4024"
version = "v0.1.0"
[[projects]]
digest = "1:e04c00d619875ce5fa67180891984a9b1fadcc031af36bcd7a3509cbdad1df15"
name = "github.com/cheggaaa/pb"
packages = ["."]
pruneopts = "UT"
revision = "c112833d014c77e8bde723fd0158e3156951639f"
version = "v2.0.6"
[[projects]]
digest = "1:76dc72490af7174349349838f2fe118996381b31ea83243812a97e5a0fd5ed55"
name = "github.com/dgrijalva/jwt-go"
packages = ["."]
pruneopts = "UT"
revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
version = "v3.2.0"
[[projects]]
digest = "1:865079840386857c809b72ce300be7580cb50d3d3129ce11bf9aa6ca2bc1934a"
name = "github.com/fatih/color"
packages = ["."]
pruneopts = "UT"
revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
version = "v1.7.0"
[[projects]]
digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd"
name = "github.com/fsnotify/fsnotify"
packages = ["."]
pruneopts = "UT"
revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9"
version = "v1.4.7"
[[projects]]
digest = "1:ad53d1f710522a38d1f0e5e0a55a194b1c6b2cd8e84313568e43523271f0cf62"
name = "github.com/go-redis/redis"
packages = [
".",
"internal",
"internal/consistenthash",
"internal/hashtag",
"internal/pool",
"internal/proto",
"internal/util",
]
pruneopts = "UT"
revision = "22be8a3eaf992c828cecb69dc07348313bf08d2e"
version = "v6.15.1"
[[projects]]
digest = "1:ec6f9bf5e274c833c911923c9193867f3f18788c461f76f05f62bb1510e0ae65"
name = "github.com/go-sql-driver/mysql"
packages = ["."]
pruneopts = "UT"
revision = "72cd26f257d44c1114970e19afddcd812016007e"
version = "v1.4.1"
[[projects]]
digest = "1:586ea76dbd0374d6fb649a91d70d652b7fe0ccffb8910a77468e7702e7901f3d"
name = "github.com/go-stack/stack"
packages = ["."]
pruneopts = "UT"
revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a"
version = "v1.8.0"
[[projects]]
digest = "1:8f0705fa33e8957018611cc81c65cb373b626c092d39931bb86882489fc4c3f4"
name = "github.com/golang/protobuf"
packages = [
"proto",
"ptypes",
"ptypes/any",
"ptypes/duration",
"ptypes/timestamp",
"ptypes/wrappers",
]
pruneopts = "UT"
revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
version = "v1.2.0"
[[projects]]
branch = "master"
digest = "1:df265b7f54410945dad5cf5979d91461b9fa7ff9b397ab58d2d577002a8a0e24"
name = "github.com/google/subcommands"
packages = ["."]
pruneopts = "UT"
revision = "46f0354f63152e8801bb460d26f5b6c4c878efbb"
[[projects]]
digest = "1:7b5c6e2eeaa9ae5907c391a91c132abfd5c9e8a784a341b5625e750c67e6825d"
name = "github.com/gorilla/websocket"
packages = ["."]
pruneopts = "UT"
revision = "66b9c49e59c6c48f0ffce28c2d8b8a5678502c6d"
version = "v1.4.0"
[[projects]]
branch = "master"
digest = "1:4e08dc2383a46b3107f0b34ca338c4459e8fc8ee90e46a60e728aa8a2b21d558"
name = "github.com/gosuri/uitable"
packages = [
".",
"util/strutil",
"util/wordwrap",
]
pruneopts = "UT"
revision = "36ee7e946282a3fb1cfecd476ddc9b35d8847e42"
[[projects]]
branch = "master"
digest = "1:8dbe76014be3c83806abc61befcb5e1789d2d872bc8f98a8fb955405550c63be"
name = "github.com/grokify/html-strip-tags-go"
packages = ["."]
pruneopts = "UT"
revision = "e9e44961e26f513866063f54bf85070db95600f7"
[[projects]]
digest = "1:950caca7dfcf796419232ba996c9c3539d09f26af27ba848c4508e604c13efbb"
name = "github.com/hashicorp/go-version"
packages = ["."]
pruneopts = "UT"
revision = "d40cf49b3a77bba84a7afdbd7f1dc295d114efb1"
version = "v1.1.0"
[[projects]]
digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10"
name = "github.com/hashicorp/hcl"
packages = [
".",
"hcl/ast",
"hcl/parser",
"hcl/printer",
"hcl/scanner",
"hcl/strconv",
"hcl/token",
"json/parser",
"json/scanner",
"json/token",
]
pruneopts = "UT"
revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241"
version = "v1.0.0"
[[projects]]
branch = "master"
digest = "1:0f8b63af5601a93b6b6a63a420c857819e98a252369262d8faf66f3566ba294e"
name = "github.com/hashicorp/uuid"
packages = ["."]
pruneopts = "UT"
revision = "ebb0a03e909c9c642a36d2527729104324c44fdb"
[[projects]]
branch = "master"
digest = "1:0778dc7fce1b4669a8bfa7ae506ec1f595b6ab0f8989c1c0d22a8ca1144e9972"
name = "github.com/howeyc/gopass"
packages = ["."]
pruneopts = "UT"
revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8"
[[projects]]
digest = "1:e96640e5b9ce93e2d7ee18f48048483080fd23e72e3c38bc17e9c8b77062031a"
name = "github.com/inconshreveable/log15"
packages = ["."]
pruneopts = "UT"
revision = "67afb5ed74ec82fd7ac8f49d27c509ac6f991970"
version = "v2.14"
[[projects]]
digest = "1:ff312c4d510c67954a6fc6a11c9ff72a2b2169584776b7419c7b8c729e2b13ac"
name = "github.com/jinzhu/gorm"
packages = [
".",
"dialects/mysql",
"dialects/postgres",
"dialects/sqlite",
]
pruneopts = "UT"
revision = "472c70caa40267cb89fd8facb07fe6454b578626"
version = "v1.9.2"
[[projects]]
branch = "master"
digest = "1:fd97437fbb6b7dce04132cf06775bd258cce305c44add58eb55ca86c6c325160"
name = "github.com/jinzhu/inflection"
packages = ["."]
pruneopts = "UT"
revision = "04140366298a54a039076d798123ffa108fff46c"
[[projects]]
digest = "1:bb81097a5b62634f3e9fec1014657855610c82d19b9a40c17612e32651e35dca"
name = "github.com/jmespath/go-jmespath"
packages = ["."]
pruneopts = "UT"
revision = "c2b33e84"
[[projects]]
digest = "1:114ecad51af93a73ae6781fd0d0bc28e52b433c852b84ab4b4c109c15e6c6b6d"
name = "github.com/jroimartin/gocui"
packages = ["."]
pruneopts = "UT"
revision = "c055c87ae801372cd74a0839b972db4f7697ae5f"
version = "v0.4.0"
[[projects]]
digest = "1:16dd6b893b78a50564cdde1d9f7ea67224dece11bb0886bd882f1dc3dc1d440d"
name = "github.com/k0kubun/pp"
packages = ["."]
pruneopts = "UT"
revision = "027a6d1765d673d337e687394dbe780dd64e2a1e"
version = "v2.3.0"
[[projects]]
branch = "master"
digest = "1:bdf08c9b41c029c60ba5dc99443a3ce74eedad842cf2adf9c255513f432422e2"
name = "github.com/knqyf263/go-cpe"
packages = [
"common",
"matching",
"naming",
]
pruneopts = "UT"
revision = "659663f6eca2ff32258e282557e7808115ea498a"
[[projects]]
branch = "master"
digest = "1:a9955a589c7f6f28bd5a5f69da3f1e2cc857c23c7605c5fa7b605f065ba8f3fe"
name = "github.com/knqyf263/go-deb-version"
packages = ["."]
pruneopts = "UT"
revision = "9865fe14d09b1c729188ac810466dde90f897ee3"
[[projects]]
branch = "master"
digest = "1:5734c5362ef66c39ddf1b4a11dfe75fa3c1adb70e78059543c83c0c6e89f2bc0"
name = "github.com/knqyf263/go-rpm-version"
packages = ["."]
pruneopts = "UT"
revision = "74609b86c936dff800c69ec89fcf4bc52d5f13a4"
[[projects]]
branch = "master"
digest = "1:acca5c567e76e94e81f8d65893e2a9cd12d914dd688731f461a5ebdb180d4938"
name = "github.com/knqyf263/gost"
packages = [
"config",
"db",
"models",
"util",
]
pruneopts = "UT"
revision = "5afeda5e8e1f8f3561738d3d6fa6549c88feb31e"
[[projects]]
digest = "1:0a69a1c0db3591fcefb47f115b224592c8dfa4368b7ba9fae509d5e16cdc95c8"
name = "github.com/konsorten/go-windows-terminal-sequences"
packages = ["."]
pruneopts = "UT"
revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242"
version = "v1.0.1"
[[projects]]
branch = "master"
digest = "1:fa59fec07121e6190139b5134524c4fc7a6abe5143a775a0e17313b6997e17a7"
name = "github.com/kotakanbe/go-cve-dictionary"
packages = [
"config",
"db",
"log",
"models",
]
pruneopts = "UT"
revision = "b083bedef97055c27d1f039428ab183eca7c6450"
[[projects]]
digest = "1:54d3c90db1164399906830313a6fce7770917d7e4a12da8f2d8693d18ff5ef27"
name = "github.com/kotakanbe/go-pingscanner"
packages = ["."]
pruneopts = "UT"
revision = "641dc2cc2d3cbf295dad356667b74c69bcbd6f70"
version = "v0.1.0"
[[projects]]
digest = "1:8fd95e6bab4d09a0f610bd5c02ef6ec7d0d91da5a72b7cfcbfd67254bcb72b75"
name = "github.com/kotakanbe/goval-dictionary"
packages = [
"config",
"db",
"db/rdb",
"models",
]
pruneopts = "UT"
revision = "5070051ecafdf15cbe2490e71ec038de7d25b71e"
version = "v0.1.1"
[[projects]]
branch = "master"
digest = "1:0daead102d7ca3af110dfb832e8c14393f197d94e5ffe3f0639f10ea2cc55530"
name = "github.com/kotakanbe/logrus-prefixed-formatter"
packages = ["."]
pruneopts = "UT"
revision = "928f7356cb964637e2489a6ef37eee55181676c5"
[[projects]]
digest = "1:01eb0269028d3c2e21b5b6cd9b1ba81bc4170ab293fcffa84e3aa3a6138a92e8"
name = "github.com/labstack/gommon"
packages = [
"color",
"log",
]
pruneopts = "UT"
revision = "7fd9f68ece0bcb1a905fac8f1549f0083f71c51b"
version = "v0.2.8"
[[projects]]
digest = "1:b18ffc558326ebaed3b4a175617f1e12ed4e3f53d6ebfe5ba372a3de16d22278"
name = "github.com/lib/pq"
packages = [
".",
"hstore",
"oid",
]
pruneopts = "UT"
revision = "4ded0e9383f75c197b3a2aaa6d590ac52df6fd79"
version = "v1.0.0"
[[projects]]
digest = "1:c568d7727aa262c32bdf8a3f7db83614f7af0ed661474b24588de635c20024c7"
name = "github.com/magiconair/properties"
packages = ["."]
pruneopts = "UT"
revision = "c2353362d570a7bfa228149c62842019201cfb71"
version = "v1.8.0"
[[projects]]
digest = "1:4e878df5f4e9fd625bf9c9aac77ef7cbfa4a74c01265505527c23470c0e40300"
name = "github.com/marstr/guid"
packages = ["."]
pruneopts = "UT"
revision = "8bd9a64bf37eb297b492a4101fb28e80ac0b290f"
version = "v1.1.0"
[[projects]]
digest = "1:c658e84ad3916da105a761660dcaeb01e63416c8ec7bc62256a9b411a05fcd67"
name = "github.com/mattn/go-colorable"
packages = ["."]
pruneopts = "UT"
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
version = "v0.0.9"
[[projects]]
digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5"
name = "github.com/mattn/go-isatty"
packages = ["."]
pruneopts = "UT"
revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c"
version = "v0.0.4"
[[projects]]
digest = "1:0356f3312c9bd1cbeda81505b7fd437501d8e778ab66998ef69f00d7f9b3a0d7"
name = "github.com/mattn/go-runewidth"
packages = ["."]
pruneopts = "UT"
revision = "3ee7d812e62a0804a7d0a324e0249ca2db3476d3"
version = "v0.0.4"
[[projects]]
digest = "1:4a49346ca45376a2bba679ca0e83bec949d780d4e927931317904bad482943ec"
name = "github.com/mattn/go-sqlite3"
packages = ["."]
pruneopts = "UT"
revision = "c7c4067b79cc51e6dfdcef5c702e74b1e0fa7c75"
version = "v1.10.0"
[[projects]]
branch = "master"
digest = "1:2b32af4d2a529083275afc192d1067d8126b578c7a9613b26600e4df9c735155"
name = "github.com/mgutz/ansi"
packages = ["."]
pruneopts = "UT"
revision = "9520e82c474b0a04dd04f8a40959027271bab992"
[[projects]]
digest = "1:78bbb1ba5b7c3f2ed0ea1eab57bdd3859aec7e177811563edc41198a760b06af"
name = "github.com/mitchellh/go-homedir"
packages = ["."]
pruneopts = "UT"
revision = "ae18d6b8b3205b561c79e8e5f69bff09736185f4"
version = "v1.0.0"
[[projects]]
digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318"
name = "github.com/mitchellh/mapstructure"
packages = ["."]
pruneopts = "UT"
revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe"
version = "v1.1.2"
[[projects]]
digest = "1:7aefb397a53fc437c90f0fdb3e1419c751c5a3a165ced52325d5d797edf1aca6"
name = "github.com/moul/http2curl"
packages = ["."]
pruneopts = "UT"
revision = "9ac6cf4d929b2fa8fd2d2e6dec5bb0feb4f4911d"
version = "v1.0.0"
[[projects]]
branch = "master"
digest = "1:a440c18972e9499a1e8de68915e5a9119008d86efc2a9c6c6edddc323ce6f3ed"
name = "github.com/mozqnet/go-exploitdb"
packages = [
"db",
"models",
"util",
]
pruneopts = "UT"
revision = "652ae1f6aa234a4e22c8a6c9566ef4018a1d28c8"
[[projects]]
digest = "1:95d38d218bf2290987c6b0e885a9f0f2d3d3239235acaddca01c3fe36e5e5566"
name = "github.com/nlopes/slack"
packages = [
".",
"slackutilsx",
]
pruneopts = "UT"
revision = "b9033a72a20bf84563485e86a2adbea4bf265804"
version = "v0.4.0"
[[projects]]
branch = "master"
digest = "1:f3fc7efada7606d5abc88372e1f838ed897fa522077957070fbc2207a50d6faa"
name = "github.com/nsf/termbox-go"
packages = ["."]
pruneopts = "UT"
revision = "0938b5187e61bb8c4dcac2b0a9cf4047d83784fc"
[[projects]]
digest = "1:abcdbf03ca6ca13d3697e2186edc1f33863bbdac2b3a44dfa39015e8903f7409"
name = "github.com/olekukonko/tablewriter"
packages = ["."]
pruneopts = "UT"
revision = "e6d60cf7ba1f42d86d54cdf5508611c4aafb3970"
version = "v0.0.1"
[[projects]]
digest = "1:d776f3e95774a8719f2e57fabbbb33103035fe072dcf6f1864f33abd17b753e5"
name = "github.com/parnurzeal/gorequest"
packages = ["."]
pruneopts = "UT"
revision = "a578a48e8d6ca8b01a3b18314c43c6716bb5f5a3"
version = "v0.2.15"
[[projects]]
digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e"
name = "github.com/pelletier/go-toml"
packages = ["."]
pruneopts = "UT"
revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194"
version = "v1.2.0"
[[projects]]
digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b"
name = "github.com/pkg/errors"
packages = ["."]
pruneopts = "UT"
revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
version = "v0.8.1"
[[projects]]
digest = "1:1a23fdd843129ef761ffe7651bc5fe7c5b09fbe933e92783ab06cc11c37b7b37"
name = "github.com/rifflock/lfshook"
packages = ["."]
pruneopts = "UT"
revision = "b9218ef580f59a2e72dad1aa33d660150445d05a"
version = "v2.4"
[[projects]]
digest = "1:274f67cb6fed9588ea2521ecdac05a6d62a8c51c074c1fccc6a49a40ba80e925"
name = "github.com/satori/go.uuid"
packages = ["."]
pruneopts = "UT"
revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3"
version = "v1.2.0"
[[projects]]
branch = "master"
digest = "1:9c3c856c4bd09733de5727aeb85fc484b8b87a6eb9e6a632c47e3f17142757ee"
name = "github.com/sirupsen/logrus"
packages = ["."]
pruneopts = "UT"
revision = "78fb3852d92683dc28da6cc3d5f965100677c27d"
[[projects]]
digest = "1:d707dbc1330c0ed177d4642d6ae102d5e2c847ebd0eb84562d0dc4f024531cfc"
name = "github.com/spf13/afero"
packages = [
".",
"mem",
]
pruneopts = "UT"
revision = "a5d6946387efe7d64d09dcba68cdd523dc1273a3"
version = "v1.2.0"
[[projects]]
digest = "1:08d65904057412fc0270fc4812a1c90c594186819243160dc779a402d4b6d0bc"
name = "github.com/spf13/cast"
packages = ["."]
pruneopts = "UT"
revision = "8c9545af88b134710ab1cd196795e7f2388358d7"
version = "v1.3.0"
[[projects]]
digest = "1:68ea4e23713989dc20b1bded5d9da2c5f9be14ff9885beef481848edd18c26cb"
name = "github.com/spf13/jwalterweatherman"
packages = ["."]
pruneopts = "UT"
revision = "4a4406e478ca629068e7768fc33f3f044173c0a6"
version = "v1.0.0"
[[projects]]
digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2"
name = "github.com/spf13/pflag"
packages = ["."]
pruneopts = "UT"
revision = "298182f68c66c05229eb03ac171abe6e309ee79a"
version = "v1.0.3"
[[projects]]
digest = "1:de37e343c64582d7026bf8ab6ac5b22a72eac54f3a57020db31524affed9f423"
name = "github.com/spf13/viper"
packages = ["."]
pruneopts = "UT"
revision = "6d33b5a963d922d182c91e8a1c88d81fd150cfd4"
version = "v1.3.1"
[[projects]]
digest = "1:c468422f334a6b46a19448ad59aaffdfc0a36b08fdcc1c749a0b29b6453d7e59"
name = "github.com/valyala/bytebufferpool"
packages = ["."]
pruneopts = "UT"
revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
version = "v1.0.0"
[[projects]]
branch = "master"
digest = "1:268b8bce0064e8c057d7b913605459f9a26dcab864c0886a56d196540fbf003f"
name = "github.com/valyala/fasttemplate"
packages = ["."]
pruneopts = "UT"
revision = "dcecefd839c4193db0d35b88ec65b4c12d360ab0"
[[projects]]
branch = "master"
digest = "1:0792df7c7ff49b81c7a8c5a2a47aee897c5bab31fb348c8e2f80a560d675f941"
name = "github.com/ymomoi/goval-parser"
packages = ["oval"]
pruneopts = "UT"
revision = "0a0be1dd9d0855b50be0be5a10ad3085382b6d59"
[[projects]]
digest = "1:2ae8314c44cd413cfdb5b1df082b350116dd8d2fff973e62c01b285b7affd89e"
name = "go.opencensus.io"
packages = [
".",
"exemplar",
"internal",
"internal/tagencoding",
"plugin/ochttp",
"plugin/ochttp/propagation/b3",
"plugin/ochttp/propagation/tracecontext",
"stats",
"stats/internal",
"stats/view",
"tag",
"trace",
"trace/internal",
"trace/propagation",
"trace/tracestate",
]
pruneopts = "UT"
revision = "b7bf3cdb64150a8c8c53b769fdeb2ba581bd4d4b"
version = "v0.18.0"
[[projects]]
branch = "master"
digest = "1:30e9f5bea4df0d1a573ed89a85cc680ab05dfc078f6a21e627db236f29650a11"
name = "golang.org/x/crypto"
packages = [
"curve25519",
"ed25519",
"ed25519/internal/edwards25519",
"internal/chacha20",
"internal/subtle",
"poly1305",
"ssh",
"ssh/agent",
"ssh/terminal",
]
pruneopts = "UT"
revision = "ff983b9c42bc9fbf91556e191cc8efb585c16908"
[[projects]]
branch = "master"
digest = "1:25c965216c188afcd5f430f65acc28d4f193c5a88e7c6c54ae876b1898f86368"
name = "golang.org/x/net"
packages = [
"context",
"context/ctxhttp",
"http/httpguts",
"http2",
"http2/hpack",
"idna",
"internal/timeseries",
"publicsuffix",
"trace",
]
pruneopts = "UT"
revision = "915654e7eabcea33ae277abbecf52f0d8b7a9fdc"
[[projects]]
branch = "master"
digest = "1:e007b54f54cbd4214aa6d97a67d57bc2539991adb4e22ea92c482bbece8de469"
name = "golang.org/x/oauth2"
packages = [
".",
"internal",
]
pruneopts = "UT"
revision = "99b60b757ec124ebb7d6b7e97f153b19c10ce163"
[[projects]]
branch = "master"
digest = "1:75515eedc0dc2cb0b40372008b616fa2841d831c63eedd403285ff286c593295"
name = "golang.org/x/sync"
packages = ["semaphore"]
pruneopts = "UT"
revision = "37e7f081c4d4c64e13b10787722085407fe5d15f"
[[projects]]
branch = "master"
digest = "1:5ee4df7ab18e945607ac822de8d10b180baea263b5e8676a1041727543b9c1e4"
name = "golang.org/x/sys"
packages = [
"unix",
"windows",
]
pruneopts = "UT"
revision = "48ac38b7c8cbedd50b1613c0fccacfc7d88dfcdf"
[[projects]]
digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18"
name = "golang.org/x/text"
packages = [
"collate",
"collate/build",
"internal/colltab",
"internal/gen",
"internal/tag",
"internal/triegen",
"internal/ucd",
"language",
"secure/bidirule",
"transform",
"unicode/bidi",
"unicode/cldr",
"unicode/norm",
"unicode/rangetable",
]
pruneopts = "UT"
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
version = "v0.3.0"
[[projects]]
digest = "1:5f003878aabe31d7f6b842d4de32b41c46c214bb629bb485387dbcce1edf5643"
name = "google.golang.org/api"
packages = ["support/bundler"]
pruneopts = "UT"
revision = "19e022d8cf43ce81f046bae8cc18c5397cc7732f"
version = "v0.1.0"
[[projects]]
digest = "1:9e29a0ec029d012437d88da3ccccf18adcdce069cab08d462056c2c6bb006505"
name = "google.golang.org/appengine"
packages = [
"cloudsql",
"internal",
"internal/base",
"internal/datastore",
"internal/log",
"internal/remote_api",
"internal/urlfetch",
"urlfetch",
]
pruneopts = "UT"
revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1"
version = "v1.4.0"
[[projects]]
branch = "master"
digest = "1:077c1c599507b3b3e9156d17d36e1e61928ee9b53a5b420f10f28ebd4a0b275c"
name = "google.golang.org/genproto"
packages = ["googleapis/rpc/status"]
pruneopts = "UT"
revision = "db91494dd46c1fdcbbde05e5ff5eb56df8f7d79a"
[[projects]]
digest = "1:9edd250a3c46675d0679d87540b30c9ed253b19bd1fd1af08f4f5fb3c79fc487"
name = "google.golang.org/grpc"
packages = [
".",
"balancer",
"balancer/base",
"balancer/roundrobin",
"binarylog/grpc_binarylog_v1",
"codes",
"connectivity",
"credentials",
"credentials/internal",
"encoding",
"encoding/proto",
"grpclog",
"internal",
"internal/backoff",
"internal/binarylog",
"internal/channelz",
"internal/envconfig",
"internal/grpcrand",
"internal/grpcsync",
"internal/syscall",
"internal/transport",
"keepalive",
"metadata",
"naming",
"peer",
"resolver",
"resolver/dns",
"resolver/passthrough",
"stats",
"status",
"tap",
]
pruneopts = "UT"
revision = "df014850f6dee74ba2fc94874043a9f3f75fbfd8"
version = "v1.17.0"
[[projects]]
digest = "1:e626376fab8608a972d47e91b3c1bbbddaecaf1d42b82be6dcc52d10a7557893"
name = "gopkg.in/VividCortex/ewma.v1"
packages = ["."]
pruneopts = "UT"
revision = "b24eb346a94c3ba12c1da1e564dbac1b498a77ce"
version = "v1.1.1"
[[projects]]
digest = "1:94cad6e2359d57da6652e689189c5b6ef19f99db6304d2c41de54f6632e15143"
name = "gopkg.in/cheggaaa/pb.v1"
packages = ["."]
pruneopts = "UT"
revision = "1cc5bbe20449079337944d56292c7383510c534c"
version = "v1.0.27"
[[projects]]
digest = "1:256938e7d43c73bd5e7bb97dd281d1ebe294b2928403ee1fbec96249915d1150"
name = "gopkg.in/cheggaaa/pb.v2"
packages = ["termutil"]
pruneopts = "UT"
revision = "c112833d014c77e8bde723fd0158e3156951639f"
version = "v2.0.6"
[[projects]]
digest = "1:865079840386857c809b72ce300be7580cb50d3d3129ce11bf9aa6ca2bc1934a"
name = "gopkg.in/fatih/color.v1"
packages = ["."]
pruneopts = "UT"
revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
version = "v1.7.0"
[[projects]]
digest = "1:c658e84ad3916da105a761660dcaeb01e63416c8ec7bc62256a9b411a05fcd67"
name = "gopkg.in/mattn/go-colorable.v0"
packages = ["."]
pruneopts = "UT"
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
version = "v0.0.9"
[[projects]]
digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5"
name = "gopkg.in/mattn/go-isatty.v0"
packages = ["."]
pruneopts = "UT"
revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c"
version = "v0.0.4"
[[projects]]
digest = "1:0356f3312c9bd1cbeda81505b7fd437501d8e778ab66998ef69f00d7f9b3a0d7"
name = "gopkg.in/mattn/go-runewidth.v0"
packages = ["."]
pruneopts = "UT"
revision = "3ee7d812e62a0804a7d0a324e0249ca2db3476d3"
version = "v0.0.4"
[[projects]]
digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96"
name = "gopkg.in/yaml.v2"
packages = ["."]
pruneopts = "UT"
revision = "51d6538a90f86fe93ac480b35f37b2be17fef232"
version = "v2.2.2"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
input-imports = [
"github.com/Azure/azure-sdk-for-go/storage",
"github.com/BurntSushi/toml",
"github.com/RackSec/srslog",
"github.com/asaskevich/govalidator",
"github.com/aws/aws-sdk-go/aws",
"github.com/aws/aws-sdk-go/aws/credentials",
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
"github.com/aws/aws-sdk-go/aws/ec2metadata",
"github.com/aws/aws-sdk-go/aws/session",
"github.com/aws/aws-sdk-go/service/s3",
"github.com/aws/aws-sdk-go/service/sts",
"github.com/boltdb/bolt",
"github.com/cenkalti/backoff",
"github.com/google/subcommands",
"github.com/gosuri/uitable",
"github.com/hashicorp/uuid",
"github.com/howeyc/gopass",
"github.com/jroimartin/gocui",
"github.com/k0kubun/pp",
"github.com/knqyf263/go-cpe/naming",
"github.com/knqyf263/go-deb-version",
"github.com/knqyf263/go-rpm-version",
"github.com/knqyf263/gost/db",
"github.com/knqyf263/gost/models",
"github.com/kotakanbe/go-cve-dictionary/db",
"github.com/kotakanbe/go-cve-dictionary/log",
"github.com/kotakanbe/go-cve-dictionary/models",
"github.com/kotakanbe/go-pingscanner",
"github.com/kotakanbe/goval-dictionary/db",
"github.com/kotakanbe/goval-dictionary/models",
"github.com/kotakanbe/logrus-prefixed-formatter",
"github.com/mitchellh/go-homedir",
"github.com/mozqnet/go-exploitdb/db",
"github.com/mozqnet/go-exploitdb/models",
"github.com/nlopes/slack",
"github.com/olekukonko/tablewriter",
"github.com/parnurzeal/gorequest",
"github.com/pkg/errors",
"github.com/rifflock/lfshook",
"github.com/sirupsen/logrus",
"golang.org/x/crypto/ssh",
"golang.org/x/crypto/ssh/agent",
"golang.org/x/oauth2",
]
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -1,41 +0,0 @@
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
[[constraint]]
name = "github.com/knqyf263/gost"
branch = "master"
[[constraint]]
name = "github.com/kotakanbe/go-cve-dictionary"
branch = "master"
[[constraint]]
name = "github.com/mozqnet/go-exploitdb"
branch = "master"
[prune]
go-tests = true
unused-packages = true

153
LICENSE
View File

@@ -1,23 +1,21 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
@@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
@@ -72,7 +60,7 @@ modification follow.
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
@@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
@@ -631,44 +629,33 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Affero General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Vuls Copyright (C) 2016 Future Corporation , Japan.
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.

135
README.md
View File

@@ -23,14 +23,28 @@ Twitter: [@vuls_en](https://twitter.com/vuls_en)
----
# Abstract
## 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.
To avoid downtime in production environment, it is common for system administrator to choose not to use the automatic update option provided by package manager and to perform update manually.
To avoid downtime in a production environment, it is common for a system administrator to choose not to use the automatic update option provided by the package manager and to perform update manually.
This leads to the following problems.
- System administrator will have to constantly watch out for any new vulnerabilities in NVD(National Vulnerability Database) or similar databases.
- It might be impossible for the system administrator to monitor all the software if there are a large number of software installed in server.
- The system administrator will have to constantly watch out for any new vulnerabilities in NVD (National Vulnerability Database) or similar databases.
- It might be impossible for the system administrator to monitor all the software if there are a large number of software packages installed in the server.
- It is expensive to perform analysis to determine the servers affected by new vulnerabilities. The possibility of overlooking a server or two during analysis is there.
Vuls is a tool created to solve the problems listed above. It has the following characteristics.
@@ -38,134 +52,159 @@ Vuls is a tool created to solve the problems listed above. It has the following
- Informs users of the vulnerabilities that are related to the system.
- Informs users of the servers that are affected.
- Vulnerability detection is done automatically to prevent any oversight.
- Report is generated on regular basis using CRON or other methods. to manage vulnerability.
- A report is generated on a regular basis using CRON or other methods. to manage vulnerability.
![Vuls-Motivation](img/vuls-motivation.png)
----
# Main Features
## Main Features
## Scan for any vulnerabilities in Linux/FreeBSD Server
### Scan for any vulnerabilities in Linux/FreeBSD Server
[Supports major Linux/FreeBSD](https://vuls.io/docs/en/supported-os.html)
- Alpine, Ubuntu, Debian, CentOS, Amazon Linux, RHEL, Oracle Linux, SUSE Enterprise Linux and Raspbian, FreeBSD
- Cloud, on-premise, Docker
- Alpine, Amazon Linux, CentOS, Debian, Oracle Linux, Raspbian, RHEL, SUSE Enterprise Linux, and Ubuntu
- FreeBSD
- Cloud, on-premise, Docker Container and Docker Image
## High quality scan
### High-quality scan
Vuls uses Multiple vulnerability databases
Vuls uses multiple vulnerability databases
- [NVD](https://nvd.nist.gov/)
- [JVN(Japanese)](http://jvndb.jvn.jp/apis/myjvn/)
- OVAL
- [RedHat](https://www.redhat.com/security/data/oval/)
- [Debian](https://www.debian.org/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/)
- [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/)
- [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)
- [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
## Fast scan and Deep scan
### Scan mode
[Fast Scan](https://vuls.io/docs/en/architecture-fast-scan.html)
- Scan without root privilege, no dependencies
- Almost no load on the scan target server
- Offline mode scan with no internet access. (Red Hat, CentOS, OracleLinux, Ubuntu, Debian)
- Offline mode scan with no internet access. (CentOS, Debian, Oracle Linux, Red Hat, and Ubuntu)
[Fast Root Scan](https://vuls.io/docs/en/architecture-fast-root-scan.html)
- Scan with root privilege
- Almost no load on the scan target server
- Detect processes affected by update using yum-ps (RedHat, CentOS, Oracle Linux and Amazon Linux)
- Detect processes affected by update using yum-ps (Amazon Linux, CentOS, Oracle Linux, and RedHat)
- Detect processes which updated before but not restarting yet using checkrestart of debian-goodies (Debian and Ubuntu)
- Offline mode scan with no internet access. (RedHat, CentOS, OracleLinux, Ubuntu, Debian)
- Offline mode scan with no internet access. (CentOS, Debian, Oracle Linux, Red Hat, and Ubuntu)
[Deep Scan](https://vuls.io/docs/en/architecture-deep-scan.html)
### [Remote, Local scan mode, Server mode](https://vuls.io/docs/en/architecture-remote-local.html)
- Scan with root privilege
- Parses the Changelog
Changelog has a history of version changes. When a security issue is fixed, the relevant CVE ID is listed.
By parsing the changelog and analysing the updates between the installed version of software on the server and the newest version of that software
it's possible to create a list of all vulnerabilities that need to be fixed.
- Sometimes load on the scan target server
[Remote scan mode](https://vuls.io/docs/en/architecture-remote-scan.html)
## [Remote scan and Local scan](https://vuls.io/docs/en/architecture-remote-local.html)
- User is required to only set up one machine that is connected to other target servers via SSH
[Remote Scan](https://vuls.io/docs/en/architecture-remote-scan.html)
- User is required to only setup one machine that is connected to other target servers via SSH
[Local Scan](https://vuls.io/docs/en/architecture-local-scan.html)
[Local scan mode](https://vuls.io/docs/en/architecture-local-scan.html)
- If you don't want the central Vuls server to connect to each server by SSH, you can use Vuls in the Local Scan mode.
## **Dynamic** Analysis
[Server mode](https://vuls.io/docs/en/usage-server.html)
- First, start Vuls in server mode and listen as an HTTP server.
- Next, issue a command on the scan target server to collect software information. Then send the result to Vuls Server via HTTP. You receive the scan results as JSON format.
- No SSH needed, No Scanner needed. Only issuing Linux commands directory on the scan target server.
### **Dynamic** Analysis
- 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.
## Scan vulnerabilites of non-OS packages
### **Static** Analysis
- [Common Platform Enumeration (CPE) based Scan](https://vuls.io/docs/en/usage-scan-non-os-packages.html#how-to-search-cpe-name-by-software-name)
- NW equipment, middleware, programming language libraries and framework for vulnerability
- Integrate with [GitHub Security Alerts](https://vuls.io/docs/en/usage-scan-non-os-packages.html#usage-integrate-with-github-security-alerts)
- Integrate with [OWASP Dependency Check](https://vuls.io/docs/en/usage-scan-non-os-packages.html#usage-integrate-with-owasp-dependency-check-to-automatic-update-when-the-libraries-are-updated-experimental)
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
- Self-compiled software
- Network Devices
Vuls has some options to detect the vulnerabilities
- [Lockfile based Scan](https://vuls.io/docs/en/usage-scan-non-os-packages.html#library-vulns-scan)
- [GitHub Integration](https://vuls.io/docs/en/usage-scan-non-os-packages.html#usage-integrate-with-github-security-alerts)
- [Common Platform Enumeration (CPE) based Scan](https://vuls.io/docs/en/usage-scan-non-os-packages.html#cpe-scan)
- [OWASP Dependency Check Integration](https://vuls.io/docs/en/usage-scan-non-os-packages.html#usage-integrate-with-owasp-dependency-check-to-automatic-update-when-the-libraries-are-updated-experimental)
## Scan WordPress core, themes, plugins
- [Scan WordPress](https://vuls.io/docs/en/usage-scan-wordpress.html)
## MISC
- Nondestructive testing
- Pre-authorization is *NOT* necessary before scanning on AWS
- Vuls works well with Continuous Integration since tests can be run every day. This allows you to find vulnerabilities very quickly.
- Auto generation of configuration file template
- Auto detection of servers set using CIDR, generate configuration file template
- 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 on terminal or Web UI ([VulsRepo](https://github.com/usiusi360/vulsrepo)).
- Scan result is viewable on accessory software, TUI Viewer in a terminal or Web UI ([VulsRepo](https://github.com/ishiDACo/vulsrepo)).
----
# What Vuls Doesn't Do
## What Vuls Doesn't Do
- Vuls doesn't update the vulnerable packages.
----
# Document
## Document
For more information such as Installation, Tutorial, Usage, visit [vuls.io](https://vuls.io/)
[日本語翻訳ドキュメント](https://vuls.io/ja/)
----
# Authors
## Authors
kotakanbe ([@kotakanbe](https://twitter.com/kotakanbe)) created vuls and [these fine people](https://github.com/future-architect/vuls/graphs/contributors) have contributed.
----
# Change Log
## Change Log
Please see [CHANGELOG](https://github.com/future-architect/vuls/blob/master/CHANGELOG.md).
----
# Stargazers over time
## Stargazers over time
[![Stargazers over time](https://starcharts.herokuapp.com/future-architect/vuls.svg)](https://starcharts.herokuapp.com/future-architect/vuls)
-----;
# License
## License
Please see [LICENSE](https://github.com/future-architect/vuls/blob/master/LICENSE).

File diff suppressed because it is too large Load Diff

View File

@@ -1,920 +0,0 @@
package alert
// AlertDictEn has USCERT alerts
var AlertDictEn = map[string]Alert{
"https://www.us-cert.gov/ncas/alerts/TA08-352A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA08-352A",
Title: `Microsoft Internet Explorer Data Binding Vulnerability`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA08-350A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA08-350A",
Title: `Apple Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA08-344A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA08-344A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA08-340A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA08-340A",
Title: `Sun Java Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA08-319A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA08-319A",
Title: `Mozilla Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-132A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-132A",
Title: `Microsoft PowerPoint Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-041A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-041A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-343A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-343A",
Title: `Adobe Flash Vulnerabilities Affect Flash Player and Adobe AIR`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-218A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-218A",
Title: `Apple Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-195A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-195A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-342A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-342A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-286B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-286B",
Title: `Adobe Reader and Acrobat Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-160B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-160B",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-069A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-069A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-223A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-223A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-013A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-013A",
Title: `Microsoft Updates for Multiple SMB Protocol Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-294A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-294A",
Title: `Oracle Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-020A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-020A",
Title: `Microsoft Windows Does Not Disable AutoRun Properly`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-133A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-133A",
Title: `Apple Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-022A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-022A",
Title: `Apple QuickTime Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-051A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-051A",
Title: `Adobe Acrobat and Reader Vulnerability`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-015A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-015A",
Title: `Oracle Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-251A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-251A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-209A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-209A",
Title: `Microsoft Windows, Internet Explorer, and Active Template Library (ATL) Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-204A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-204A",
Title: `Adobe Flash Vulnerability Affects Flash Player and Other Adobe Products`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-161A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-161A",
Title: `Adobe Acrobat and Reader Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-133B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-133B",
Title: `Adobe Reader and Acrobat JavaScript Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-088A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-088A",
Title: `Conficker Worm Targets Microsoft Windows Systems`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-314A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-314A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-105A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-105A",
Title: `Oracle Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-104A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-104A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-286A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-286A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA09-187A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA09-187A",
Title: `Microsoft Video ActiveX Control Vulnerability`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-238A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-238A",
Title: `Microsoft Windows Insecurely Loads Dynamic Libraries`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-159B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-159B",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-103B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-103B",
Title: `Oracle Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-021A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-021A",
Title: `Microsoft Internet Explorer Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-012A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-012A",
Title: `Oracle Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-313A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-313A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-285A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-285A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-263A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-263A",
Title: `Adobe Flash Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-103C": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-103C",
Title: `Adobe Reader and Acrobat Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-040A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-040A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-194B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-194B",
Title: `Oracle Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-194A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-194A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-131A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-131A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-068A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-068A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-348A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-348A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-257A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-257A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-231A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-231A",
Title: `Adobe Reader and Acrobat Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-222A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-222A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-162A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-162A",
Title: `Adobe Flash and AIR Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-159A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-159A",
Title: `Adobe Flash, Reader, and Acrobat Vulnerability`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-089A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-089A",
Title: `Microsoft Internet Explorer Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-013A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-013A",
Title: `Adobe Reader and Acrobat Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-287A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-287A",
Title: `Oracle Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-279A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-279A",
Title: `Adobe Reader and Acrobat Affected by Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-223A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-223A",
Title: `Adobe Flash and AIR Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA10-012B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA10-012B",
Title: `Microsoft Windows EOT Font and Adobe Flash Player 6 Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-165A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-165A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-067A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-067A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-039A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-039A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-222A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-222A",
Title: `Adobe Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-193A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-193A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-201A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-201A",
Title: `Oracle Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-166A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-166A",
Title: `Adobe Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-130A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-130A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-312A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-312A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-286A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-286A",
Title: `Apple Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-350A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-350A",
Title: `Adobe Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-221A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-221A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-256A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-256A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-200A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-200A",
Title: `Security Recommendations to Prevent Cyber Intrusions`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-102A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-102A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-011A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-011A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-347A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-347A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA11-284A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA11-284A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-262A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-262A",
Title: `Microsoft Security Advisory for Internet Explorer Exploit`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-240A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-240A",
Title: `Oracle Java 7 Security Manager Bypass Vulnerability`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-227A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-227A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-129A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-129A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-101B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-101B",
Title: `Adobe Reader and Acrobat Security Updates and Architectural Improvements`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-010A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-010A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-006A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-006A",
Title: `Wi-Fi Protected Setup (WPS) Vulnerable to Brute-Force Attack`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-265A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-265A",
Title: `Microsoft Releases Patch for Internet Explorer Exploit`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-255A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-255A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-251A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-251A",
Title: `Microsoft Update For Minimum Certificate Key Length`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-174A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-174A",
Title: `Microsoft XML Core Services Attack Activity`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-164A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-164A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-101A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-101A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-318A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-318A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-283A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-283A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-346A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-346A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-192A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-192A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-073A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-073A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-045A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-045A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA12-024A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA12-024A",
Title: `&quot;Anonymous&quot; DDoS Activity`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-134A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-134A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-043B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-043B",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-008A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-008A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-051A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-051A",
Title: `Oracle Java Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-043A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-043A",
Title: `Adobe Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-225A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-225A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-207A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-207A",
Title: `Risks of Using the Intelligent Platform Management Interface (IPMI)`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-141A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-141A",
Title: `Washington, DC Radio Station Web Site Compromises`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-175A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-175A",
Title: `Risks of Default Passwords on the Internet`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-169A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-169A",
Title: `Oracle Releases Updates for Javadoc and Other Java SE Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-168A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-168A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-100A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-100A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-088A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-088A",
Title: `DNS Amplification Attacks`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-317A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-317A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-309A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-309A",
Title: `CryptoLocker Ransomware Infections`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-288A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-288A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-064A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-064A",
Title: `Oracle Java Contains Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-032A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-032A",
Title: `Oracle Java Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-024A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-024A",
Title: `Content Management Systems Security and Associated Risks`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-107A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-107A",
Title: `Oracle Has Released Multiple Updates for Java SE`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-071A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-071A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-015A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-015A",
Title: `Microsoft Releases Update for Internet Explorer Vulnerability CVE-2012-4792`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-010A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-010A",
Title: `Oracle Java 7 Security Manager Bypass Vulnerability`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-253A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-253A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-193A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-193A",
Title: `Exploit Tool Targets Vulnerabilities in McAfee ePolicy Orchestrator (ePO)`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA13-190A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA13-190A",
Title: `Microsoft Updates for Multiple Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-323A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-323A",
Title: `Microsoft Windows Kerberos KDC Remote Privilege Escalation Vulnerability `,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-300A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-300A",
Title: `Phishing Campaign Linked with “Dyre” Banking Malware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-295A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-295A",
Title: `Crypto Ransomware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-318B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-318B",
Title: `Microsoft Windows OLE Automation Array Remote Code Execution Vulnerability `,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-317A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-317A",
Title: `Apple iOS &#039;Masque Attack&#039; Technique`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-290A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-290A",
Title: `SSL 3.0 Protocol Vulnerability and POODLE Attack`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-017A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-017A",
Title: `UDP-Based Amplification Attacks`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-002A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-002A",
Title: `Malware Targeting Point of Sale Systems`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-318A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-318A",
Title: `Microsoft Secure Channel (Schannel) Vulnerability (CVE-2014-6321) `,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-310A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-310A",
Title: `Microsoft Ending Support for Windows Server 2003 Operating System`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-268A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-268A",
Title: `GNU Bourne-Again Shell (Bash) Shellshock Vulnerability (CVE-2014-6271, CVE-2014-7169, CVE-2014-7186, CVE-2014-7187, CVE-2014-6277 and CVE 2014-6278) `,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-098A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-098A",
Title: `OpenSSL &#039;Heartbleed&#039; vulnerability (CVE-2014-0160)`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-353A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-353A",
Title: `Targeted Destructive Malware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-329A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-329A",
Title: `Regin Malware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-212A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-212A",
Title: `Backoff Point-of-Sale Malware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-150A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-150A",
Title: `GameOver Zeus P2P Malware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA14-013A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA14-013A",
Title: `NTP Amplification Attacks Using CVE-2013-5211`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-195A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-195A",
Title: `Adobe Flash and Microsoft Windows Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-337A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-337A",
Title: `Dorkbot`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-240A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-240A",
Title: `Controlling Outbound DNS Access`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-213A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-213A",
Title: `Recent Email Phishing Campaigns Mitigation and Response Recommendations`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-120A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-120A",
Title: `Securing End-to-End Communications`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-119A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-119A",
Title: `Top 30 Targeted High Risk Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-105A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-105A",
Title: `Simda Botnet`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-103A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-103A",
Title: `DNS Zone Transfer AXFR Requests May Leak Domain Information`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-098A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-098A",
Title: `AAEH`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-314A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-314A",
Title: `Compromised Web Servers and Web Shells - Threat Awareness and Guidance `,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-286A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-286A",
Title: `Dridex P2P Malware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA15-051A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA15-051A",
Title: `Lenovo Superfish Adware Vulnerable to HTTPS Spoofing`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA16-187A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA16-187A",
Title: `Symantec and Norton Security Products Contain Critical Vulnerabilities`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA16-144A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA16-144A",
Title: `WPAD Name Collision Vulnerability`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA16-132A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA16-132A",
Title: `Exploitation of SAP Business Applications`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA16-105A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA16-105A",
Title: `Apple Ends Support for QuickTime for Windows; New Vulnerabilities Announced`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA16-091A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA16-091A",
Title: `Ransomware and Recent Variants`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA16-336A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA16-336A",
Title: `Avalanche (crimeware-as-a-service infrastructure)`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA16-288A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA16-288A",
Title: `Heightened DDoS Threat Posed by Mirai and Other Botnets`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA16-250A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA16-250A",
Title: `The Increasing Threat to Network Infrastructure Devices and Recommended Mitigations`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-117A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-117A",
Title: `Intrusions Affecting Multiple Victims Across Multiple Sectors`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-318B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-318B",
Title: `HIDDEN COBRA North Korean Trojan: Volgmer`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-318A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-318A",
Title: `HIDDEN COBRA North Korean Remote Administration Tool: FALLCHILL`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-181A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-181A",
Title: `Petya Ransomware `,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-132A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-132A",
Title: `Indicators Associated With WannaCry Ransomware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-075A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-075A",
Title: `HTTPS Interception Weakens TLS Security`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-293A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-293A",
Title: `Advanced Persistent Threat Activity Targeting Energy and Other Critical Infrastructure Sectors`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-164A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-164A",
Title: `HIDDEN COBRA North Koreas DDoS Botnet Infrastructure`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-163A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-163A",
Title: `CrashOverride Malware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA17-156A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA17-156A",
Title: `Reducing the Risk of SNMP Abuse`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-141A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-141A",
Title: `Side-Channel Vulnerability Variants 3a and 4`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-086A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-086A",
Title: `Brute Force Attacks Conducted by Cyber Actors `,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-004A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-004A",
Title: `Meltdown and Spectre Side-Channel Vulnerability Guidance`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-331A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-331A",
Title: `3ve Major Online Ad Fraud Operation`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/AA18-284A": {
URL: "https://www.us-cert.gov/ncas/alerts/AA18-284A",
Title: `Publicly Available Tools Seen in Cyber Incidents Worldwide`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-276B": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-276B",
Title: `Advanced Persistent Threat Activity Exploiting Managed Service Providers`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-275A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-275A",
Title: `HIDDEN COBRA FASTCash Campaign`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-201A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-201A",
Title: `Emotet Malware`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-276A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-276A",
Title: `Using Rigorous Credential Control to Mitigate Trusted Network Exploitation`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-149A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-149A",
Title: `HIDDEN COBRA Joanap Backdoor Trojan and Brambul Server Message Block Worm`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-145A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-145A",
Title: `Cyber Actors Target Home and Office Routers and Networked Devices Worldwide`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-106A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-106A",
Title: `Russian State-Sponsored Cyber Actors Targeting Network Infrastructure Devices`,
Team: "us",
},
"https://www.us-cert.gov/ncas/alerts/TA18-074A": {
URL: "https://www.us-cert.gov/ncas/alerts/TA18-074A",
Title: `Russian Government Cyber Activity Targeting Energy and Other Critical Infrastructure Sectors`,
Team: "us",
},
}

View File

@@ -1,534 +0,0 @@
package alert
// CveDictJa has CVE-ID key which included JPCERT alerts
var CveDictJa = map[string][]string{
"CVE-2006-0003": {"https://www.jpcert.or.jp/at/2007/at070016.html"},
"CVE-2006-0005": {"https://www.jpcert.or.jp/at/2007/at070016.html"},
"CVE-2006-1173": {"https://www.jpcert.or.jp/at/2006/at060008.html"},
"CVE-2006-3014": {"https://www.jpcert.or.jp/at/2006/at060009.html"},
"CVE-2006-3059": {"https://www.jpcert.or.jp/at/2006/at060009.html"},
"CVE-2006-3086": {"https://www.jpcert.or.jp/at/2006/at060009.html"},
"CVE-2006-3643": {"https://www.jpcert.or.jp/at/2007/at070016.html"},
"CVE-2006-3730": {"https://www.jpcert.or.jp/at/2007/at070016.html"},
"CVE-2006-3877": {"https://www.jpcert.or.jp/at/2007/at070005.html"},
"CVE-2006-5198": {"https://www.jpcert.or.jp/at/2007/at070016.html"},
"CVE-2006-5745": {"https://www.jpcert.or.jp/at/2007/at070016.html"},
"CVE-2007-0015": {"https://www.jpcert.or.jp/at/2007/at070016.html"},
"CVE-2007-0038": {"https://www.jpcert.or.jp/at/2007/at070016.html"},
"CVE-2008-4609": {"https://www.jpcert.or.jp/at/2009/at090019.html"},
"CVE-2010-0886": {"https://www.jpcert.or.jp/at/2010/at100010.html"},
"CVE-2010-0887": {"https://www.jpcert.or.jp/at/2010/at100010.html"},
"CVE-2011-1910": {"https://www.jpcert.or.jp/at/2011/at110014.html"},
"CVE-2011-2444": {"https://www.jpcert.or.jp/at/2011/at110026.html"},
"CVE-2011-2462": {"https://www.jpcert.or.jp/at/2011/at110034.html"},
"CVE-2011-2465": {"https://www.jpcert.or.jp/at/2011/at110019.html"},
"CVE-2011-3192": {"https://www.jpcert.or.jp/at/2011/at110023.html"},
"CVE-2011-3348": {"https://www.jpcert.or.jp/at/2011/at110023.html"},
"CVE-2011-3544": {"https://www.jpcert.or.jp/at/2011/at110032.html"},
"CVE-2011-4313": {"https://www.jpcert.or.jp/at/2011/at110031.html"},
"CVE-2012-0002": {"https://www.jpcert.or.jp/at/2012/at120009.html"},
"CVE-2012-0507": {"https://www.jpcert.or.jp/at/2012/at120010.html"},
"CVE-2012-0767": {"https://www.jpcert.or.jp/at/2012/at120006.html"},
"CVE-2012-0779": {"https://www.jpcert.or.jp/at/2012/at120014.html"},
"CVE-2012-0830": {"https://www.jpcert.or.jp/at/2012/at120004.html"},
"CVE-2012-2311": {"https://www.jpcert.or.jp/at/2012/at120016.html"},
"CVE-2012-4244": {"https://www.jpcert.or.jp/at/2012/at120029.html"},
"CVE-2012-4681": {"https://www.jpcert.or.jp/at/2012/at120028.html"},
"CVE-2012-4969": {"https://www.jpcert.or.jp/at/2012/at120030.html"},
"CVE-2012-5166": {"https://www.jpcert.or.jp/at/2012/at120033.html"},
"CVE-2013-0422": {"https://www.jpcert.or.jp/at/2013/at130004.html"},
"CVE-2013-1493": {"https://www.jpcert.or.jp/at/2013/at130014.html"},
"CVE-2013-2266": {"https://www.jpcert.or.jp/at/2013/at130017.html"},
"CVE-2013-2494": {"https://www.jpcert.or.jp/at/2013/at130017.html"},
"CVE-2013-3893": {"https://www.jpcert.or.jp/at/2013/at130040.html", "https://www.jpcert.or.jp/at/2013/at130041.html"},
"CVE-2013-3906": {"https://www.jpcert.or.jp/at/2013/at130044.html"},
"CVE-2013-3918": {"https://www.jpcert.or.jp/at/2013/at130045.html"},
"CVE-2013-3919": {"https://www.jpcert.or.jp/at/2013/at130026.html"},
"CVE-2013-4854": {"https://www.jpcert.or.jp/at/2013/at130034.html"},
"CVE-2014-0050": {"https://www.jpcert.or.jp/at/2014/at140007.html"},
"CVE-2014-0160": {"https://www.jpcert.or.jp/at/2014/at140013.html"},
"CVE-2014-0322": {"https://www.jpcert.or.jp/at/2014/at140009.html"},
"CVE-2014-1776": {"https://www.jpcert.or.jp/at/2014/at140018.html", "https://www.jpcert.or.jp/at/2014/at140020.html"},
"CVE-2014-3383": {"https://www.jpcert.or.jp/at/2015/at150021.html"},
"CVE-2014-3859": {"https://www.jpcert.or.jp/at/2014/at140027.html"},
"CVE-2014-4114": {"https://www.jpcert.or.jp/at/2014/at140039.html"},
"CVE-2014-6271": {"https://www.jpcert.or.jp/at/2014/at140037.html", "https://www.jpcert.or.jp/at/2014/at140038.html"},
"CVE-2014-6277": {"https://www.jpcert.or.jp/at/2014/at140037.html"},
"CVE-2014-6278": {"https://www.jpcert.or.jp/at/2014/at140037.html"},
"CVE-2014-6324": {"https://www.jpcert.or.jp/at/2014/at140048.html"},
"CVE-2014-6332": {"https://www.jpcert.or.jp/at/2015/at150015.html"},
"CVE-2014-6352": {"https://www.jpcert.or.jp/at/2014/at140043.html"},
"CVE-2014-7169": {"https://www.jpcert.or.jp/at/2014/at140037.html"},
"CVE-2014-7186": {"https://www.jpcert.or.jp/at/2014/at140037.html"},
"CVE-2014-7187": {"https://www.jpcert.or.jp/at/2014/at140037.html"},
"CVE-2014-8361": {"https://www.jpcert.or.jp/at/2017/at170049.html"},
"CVE-2014-8500": {"https://www.jpcert.or.jp/at/2014/at140050.html"},
"CVE-2014-9163": {"https://www.jpcert.or.jp/at/2014/at140052.html"},
"CVE-2015-0313": {"https://www.jpcert.or.jp/at/2015/at150015.html"},
"CVE-2015-1769": {"https://www.jpcert.or.jp/at/2015/at150028.html"},
"CVE-2015-5119": {"https://www.jpcert.or.jp/at/2015/at150019.html"},
"CVE-2015-5122": {"https://www.jpcert.or.jp/at/2015/at150020.html"},
"CVE-2015-5123": {"https://www.jpcert.or.jp/at/2015/at150020.html"},
"CVE-2015-5477": {"https://www.jpcert.or.jp/at/2015/at150027.html"},
"CVE-2015-5986": {"https://www.jpcert.or.jp/at/2015/at150031.html"},
"CVE-2015-6835": {"https://www.jpcert.or.jp/at/2016/at160036.html"},
"CVE-2015-7547": {"https://www.jpcert.or.jp/at/2016/at160009.html"},
"CVE-2015-7645": {"https://www.jpcert.or.jp/at/2015/at150036.html", "https://www.jpcert.or.jp/at/2015/at150037.html"},
"CVE-2015-8000": {"https://www.jpcert.or.jp/at/2015/at150043.html"},
"CVE-2015-8461": {"https://www.jpcert.or.jp/at/2015/at150043.html"},
"CVE-2015-8562": {"https://www.jpcert.or.jp/at/2016/at160036.html"},
"CVE-2015-8651": {"https://www.jpcert.or.jp/at/2016/at160001.html"},
"CVE-2015-8704": {"https://www.jpcert.or.jp/at/2016/at160006.html"},
"CVE-2015-8705": {"https://www.jpcert.or.jp/at/2016/at160006.html"},
"CVE-2016-0189": {"https://www.jpcert.or.jp/at/2016/at160022.html"},
"CVE-2016-0636": {"https://www.jpcert.or.jp/at/2016/at160015.html"},
"CVE-2016-0800": {"https://www.jpcert.or.jp/at/2016/at160010.html"},
"CVE-2016-1000109": {"https://www.jpcert.or.jp/at/2016/at160031.html"},
"CVE-2016-1000110": {"https://www.jpcert.or.jp/at/2016/at160031.html"},
"CVE-2016-1010": {"https://www.jpcert.or.jp/at/2016/at160014.html"},
"CVE-2016-1019": {"https://www.jpcert.or.jp/at/2016/at160016.html"},
"CVE-2016-1204": {"https://www.jpcert.or.jp/at/2016/at160019.html"},
"CVE-2016-1286": {"https://www.jpcert.or.jp/at/2016/at160013.html", "https://www.jpcert.or.jp/at/2016/at160037.html"},
"CVE-2016-2776": {"https://www.jpcert.or.jp/at/2016/at160037.html"},
"CVE-2016-3081": {"https://www.jpcert.or.jp/at/2016/at160020.html"},
"CVE-2016-3227": {"https://www.jpcert.or.jp/at/2016/at160025.html"},
"CVE-2016-3714": {"https://www.jpcert.or.jp/at/2016/at160021.html"},
"CVE-2016-3715": {"https://www.jpcert.or.jp/at/2016/at160021.html"},
"CVE-2016-3716": {"https://www.jpcert.or.jp/at/2016/at160021.html"},
"CVE-2016-3717": {"https://www.jpcert.or.jp/at/2016/at160021.html"},
"CVE-2016-3718": {"https://www.jpcert.or.jp/at/2016/at160021.html"},
"CVE-2016-4117": {"https://www.jpcert.or.jp/at/2016/at160024.html"},
"CVE-2016-4171": {"https://www.jpcert.or.jp/at/2016/at160026.html"},
"CVE-2016-4438": {"https://www.jpcert.or.jp/at/2016/at160027.html"},
"CVE-2016-5385": {"https://www.jpcert.or.jp/at/2016/at160031.html"},
"CVE-2016-5386": {"https://www.jpcert.or.jp/at/2016/at160031.html"},
"CVE-2016-5387": {"https://www.jpcert.or.jp/at/2016/at160031.html"},
"CVE-2016-5388": {"https://www.jpcert.or.jp/at/2016/at160031.html"},
"CVE-2016-6307": {"https://www.jpcert.or.jp/at/2016/at160038.html"},
"CVE-2016-6309": {"https://www.jpcert.or.jp/at/2016/at160038.html"},
"CVE-2016-7189": {"https://www.jpcert.or.jp/at/2016/at160039.html"},
"CVE-2016-7836": {"https://www.jpcert.or.jp/at/2016/at160051.html", "https://www.jpcert.or.jp/at/2017/at170023.html"},
"CVE-2016-7855": {"https://www.jpcert.or.jp/at/2016/at160039.html", "https://www.jpcert.or.jp/at/2016/at160043.html"},
"CVE-2016-7892": {"https://www.jpcert.or.jp/at/2016/at160048.html", "https://www.jpcert.or.jp/at/2016/at160049.html"},
"CVE-2016-8864": {"https://www.jpcert.or.jp/at/2016/at160044.html"},
"CVE-2016-9131": {"https://www.jpcert.or.jp/at/2017/at170004.html"},
"CVE-2016-9147": {"https://www.jpcert.or.jp/at/2017/at170004.html"},
"CVE-2016-9444": {"https://www.jpcert.or.jp/at/2017/at170004.html"},
"CVE-2016-9778": {"https://www.jpcert.or.jp/at/2017/at170004.html"},
"CVE-2017-0093": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0106": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0145": {"https://www.jpcert.or.jp/at/2017/at170020.html"},
"CVE-2017-0158": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0160": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0161": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-0162": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0163": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0180": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0181": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0199": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0200": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0201": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0202": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0205": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0210": {"https://www.jpcert.or.jp/at/2017/at170015.html"},
"CVE-2017-0221": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0222": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0224": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0227": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0228": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0229": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0235": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0236": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0240": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0250": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-0261": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0263": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0266": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0272": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0277": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0278": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0279": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0283": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-0290": {"https://www.jpcert.or.jp/at/2017/at170019.html"},
"CVE-2017-0291": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-0292": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-0293": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-0294": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-0781": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
"CVE-2017-0782": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
"CVE-2017-0783": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
"CVE-2017-0785": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
"CVE-2017-1000250": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
"CVE-2017-1000251": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
"CVE-2017-10271": {"https://www.jpcert.or.jp/at/2018/at180004.html"},
"CVE-2017-10845": {"https://www.jpcert.or.jp/at/2017/at170034.html"},
"CVE-2017-10846": {"https://www.jpcert.or.jp/at/2017/at170034.html"},
"CVE-2017-11223": {"https://www.jpcert.or.jp/at/2017/at170031.html"},
"CVE-2017-11292": {"https://www.jpcert.or.jp/at/2017/at170040.html"},
"CVE-2017-11762": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11763": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11764": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-11766": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-11771": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11779": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11792": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11793": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11796": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11798": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11799": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11800": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11802": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11804": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11805": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11806": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11807": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11808": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11809": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11810": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11811": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11812": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11813": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11819": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11821": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11822": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11826": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-11836": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11837": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11838": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11839": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11840": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11841": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11843": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11845": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11846": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11855": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11856": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11858": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11861": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11862": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11866": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11869": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11870": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11871": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11873": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11882": {"https://www.jpcert.or.jp/at/2017/at170044.html"},
"CVE-2017-11886": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11888": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11889": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11890": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11893": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11894": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11895": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11901": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11903": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11905": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11907": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11908": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11909": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11910": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11911": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11912": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11914": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11918": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11930": {"https://www.jpcert.or.jp/at/2017/at170048.html"},
"CVE-2017-11937": {"https://www.jpcert.or.jp/at/2017/at170046.html"},
"CVE-2017-12615": {"https://www.jpcert.or.jp/at/2017/at170038.html"},
"CVE-2017-12616": {"https://www.jpcert.or.jp/at/2017/at170038.html"},
"CVE-2017-12617": {"https://www.jpcert.or.jp/at/2017/at170038.html"},
"CVE-2017-13872": {"https://www.jpcert.or.jp/at/2017/at170045.html"},
"CVE-2017-14315": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
"CVE-2017-3135": {"https://www.jpcert.or.jp/at/2017/at170007.html"},
"CVE-2017-3136": {"https://www.jpcert.or.jp/at/2017/at170016.html"},
"CVE-2017-3137": {"https://www.jpcert.or.jp/at/2017/at170016.html"},
"CVE-2017-3138": {"https://www.jpcert.or.jp/at/2017/at170016.html"},
"CVE-2017-3142": {"https://www.jpcert.or.jp/at/2017/at170024.html"},
"CVE-2017-3143": {"https://www.jpcert.or.jp/at/2017/at170024.html"},
"CVE-2017-3145": {"https://www.jpcert.or.jp/at/2018/at180005.html"},
"CVE-2017-5638": {"https://www.jpcert.or.jp/at/2017/at170009.html"},
"CVE-2017-6753": {"https://www.jpcert.or.jp/at/2017/at170028.html"},
"CVE-2017-8463": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8464": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8496": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8497": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8499": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8517": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8520": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8522": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8524": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8527": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8528": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8543": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8548": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8549": {"https://www.jpcert.or.jp/at/2017/at170022.html"},
"CVE-2017-8584": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8589": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8591": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8594": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8595": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8596": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8598": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8601": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8603": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8604": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8605": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8606": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8607": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8608": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8609": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8610": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8617": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8618": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8619": {"https://www.jpcert.or.jp/at/2017/at170027.html"},
"CVE-2017-8620": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8622": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8628": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
"CVE-2017-8634": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8635": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8636": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8638": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8639": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8640": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8641": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8645": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8646": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8647": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8649": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8653": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8655": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8656": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8657": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8660": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8661": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8669": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8670": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8671": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8672": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8674": {"https://www.jpcert.or.jp/at/2017/at170032.html"},
"CVE-2017-8676": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8682": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8686": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8696": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8727": {"https://www.jpcert.or.jp/at/2017/at170039.html"},
"CVE-2017-8728": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8729": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8731": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8734": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8737": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8738": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8740": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8741": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8747": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8748": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8749": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8750": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8751": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8752": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8753": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8755": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8756": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8757": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-8759": {"https://www.jpcert.or.jp/at/2017/at170036.html"},
"CVE-2017-9791": {"https://www.jpcert.or.jp/at/2017/at170025.html"},
"CVE-2017-9805": {"https://www.jpcert.or.jp/at/2017/at170033.html"},
"CVE-2018-0171": {"https://www.jpcert.or.jp/at/2018/at180013.html"},
"CVE-2018-0758": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0762": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0763": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0767": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0769": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0770": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0772": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0773": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0774": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0775": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0776": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0777": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0778": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0780": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0781": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0797": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0800": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0802": {"https://www.jpcert.or.jp/at/2018/at180002.html"},
"CVE-2018-0825": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0834": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0835": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0837": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0838": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0840": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0852": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0856": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0857": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0859": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0860": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0861": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-0870": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0872": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0874": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0876": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0889": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0893": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0930": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0931": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0932": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0933": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0934": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0936": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0937": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0939": {"https://www.jpcert.or.jp/at/2018/at180011.html"},
"CVE-2018-0943": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-0945": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-0946": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-0950": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0951": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-0953": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-0954": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-0955": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-0959": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-0961": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-0965": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-0979": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0980": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0981": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0988": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0990": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0991": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0993": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0994": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0995": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-0996": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1000": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1004": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1010": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1012": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1013": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1015": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1016": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1018": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1019": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1020": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-1022": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-1023": {"https://www.jpcert.or.jp/at/2018/at180016.html"},
"CVE-2018-11776": {"https://www.jpcert.or.jp/at/2018/at180036.html"},
"CVE-2018-1270": {"https://www.jpcert.or.jp/at/2018/at180014.html"},
"CVE-2018-1271": {"https://www.jpcert.or.jp/at/2018/at180014.html"},
"CVE-2018-1272": {"https://www.jpcert.or.jp/at/2018/at180014.html"},
"CVE-2018-1273": {"https://www.jpcert.or.jp/at/2018/at180017.html"},
"CVE-2018-1274": {"https://www.jpcert.or.jp/at/2018/at180017.html"},
"CVE-2018-1275": {"https://www.jpcert.or.jp/at/2018/at180014.html"},
"CVE-2018-12794": {"https://www.jpcert.or.jp/at/2018/at180039.html"},
"CVE-2018-1336": {"https://www.jpcert.or.jp/at/2018/at180030.html"},
"CVE-2018-15442": {"https://www.jpcert.or.jp/at/2018/at180043.html"},
"CVE-2018-15979": {"https://www.jpcert.or.jp/at/2018/at180045.html"},
"CVE-2018-2628": {"https://www.jpcert.or.jp/at/2018/at180029.html"},
"CVE-2018-2893": {"https://www.jpcert.or.jp/at/2018/at180029.html"},
"CVE-2018-2894": {"https://www.jpcert.or.jp/at/2018/at180029.html"},
"CVE-2018-2933": {"https://www.jpcert.or.jp/at/2018/at180029.html"},
"CVE-2018-2983": {"https://www.jpcert.or.jp/at/2018/at180029.html"},
"CVE-2018-2998": {"https://www.jpcert.or.jp/at/2018/at180029.html"},
"CVE-2018-4877": {"https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-4878": {"https://www.jpcert.or.jp/at/2018/at180006.html", "https://www.jpcert.or.jp/at/2018/at180008.html"},
"CVE-2018-4945": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-5000": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-5001": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-5002": {"https://www.jpcert.or.jp/at/2018/at180024.html", "https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-5740": {"https://www.jpcert.or.jp/at/2018/at180031.html"},
"CVE-2018-7600": {"https://www.jpcert.or.jp/at/2018/at180012.html"},
"CVE-2018-7602": {"https://www.jpcert.or.jp/at/2018/at180019.html"},
"CVE-2018-8034": {"https://www.jpcert.or.jp/at/2018/at180030.html"},
"CVE-2018-8037": {"https://www.jpcert.or.jp/at/2018/at180030.html"},
"CVE-2018-8110": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8111": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8114": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8120": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8122": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8128": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8130": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8133": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8137": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8139": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8154": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8174": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8178": {"https://www.jpcert.or.jp/at/2018/at180021.html"},
"CVE-2018-8213": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8225": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8229": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8231": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8236": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8242": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8249": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8251": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8262": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8266": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8267": {"https://www.jpcert.or.jp/at/2018/at180025.html"},
"CVE-2018-8273": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8274": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8275": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8279": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8280": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8286": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8288": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8290": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8291": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8294": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8296": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8301": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8302": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8324": {"https://www.jpcert.or.jp/at/2018/at180028.html"},
"CVE-2018-8332": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8344": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8345": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8350": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8355": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8367": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8371": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8372": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8373": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8377": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8380": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8381": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8385": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8387": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8390": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8397": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8403": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8414": {"https://www.jpcert.or.jp/at/2018/at180034.html"},
"CVE-2018-8420": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8421": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8439": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8440": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8447": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8453": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8456": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8457": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8459": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8460": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8461": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8464": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8465": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8466": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8467": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8473": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8475": {"https://www.jpcert.or.jp/at/2018/at180038.html"},
"CVE-2018-8476": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8489": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8490": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8491": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8494": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8505": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8509": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8510": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8511": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8513": {"https://www.jpcert.or.jp/at/2018/at180041.html"},
"CVE-2018-8541": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8542": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8543": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8544": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8551": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8553": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8555": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8556": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8557": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8588": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8589": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
"CVE-2018-8609": {"https://www.jpcert.or.jp/at/2018/at180046.html"},
}

View File

@@ -1,96 +0,0 @@
package alert
// CveDictEn has CVE-ID key which included USCERT alerts
var CveDictEn = map[string][]string{
"CVE-1999-0532": {"https://www.us-cert.gov/ncas/alerts/TA15-103A"},
"CVE-2006-3227": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2008-0015": {"https://www.us-cert.gov/ncas/alerts/TA09-195A", "https://www.us-cert.gov/ncas/alerts/TA09-209A"},
"CVE-2008-2244": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2009-0658": {"https://www.us-cert.gov/ncas/alerts/TA09-051A"},
"CVE-2009-0927": {"https://www.us-cert.gov/ncas/alerts/TA13-141A"},
"CVE-2009-1492": {"https://www.us-cert.gov/ncas/alerts/TA09-133B"},
"CVE-2009-1493": {"https://www.us-cert.gov/ncas/alerts/TA09-133B"},
"CVE-2009-1537": {"https://www.us-cert.gov/ncas/alerts/TA09-195A"},
"CVE-2009-3103": {"https://www.us-cert.gov/ncas/alerts/TA17-181A"},
"CVE-2009-3129": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2009-3674": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2009-3953": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2010-0018": {"https://www.us-cert.gov/ncas/alerts/TA10-012B"},
"CVE-2010-0188": {"https://www.us-cert.gov/ncas/alerts/TA13-141A", "https://www.us-cert.gov/ncas/alerts/TA14-300A", "https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2010-0806": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2010-1297": {"https://www.us-cert.gov/ncas/alerts/TA10-162A", "https://www.us-cert.gov/ncas/alerts/TA10-159A"},
"CVE-2010-2883": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2010-3333": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2011-0101": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2011-0611": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2011-2462": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2012-0158": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2012-1723": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2012-1856": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2012-1889": {"https://www.us-cert.gov/ncas/alerts/TA12-174A"},
"CVE-2012-3174": {"https://www.us-cert.gov/ncas/alerts/TA13-010A"},
"CVE-2012-4681": {"https://www.us-cert.gov/ncas/alerts/TA12-240A"},
"CVE-2012-4792": {"https://www.us-cert.gov/ncas/alerts/TA13-015A", "https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2013-0074": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2013-0140": {"https://www.us-cert.gov/ncas/alerts/TA13-193A"},
"CVE-2013-0141": {"https://www.us-cert.gov/ncas/alerts/TA13-193A"},
"CVE-2013-0422": {"https://www.us-cert.gov/ncas/alerts/TA13-141A", "https://www.us-cert.gov/ncas/alerts/TA13-010A"},
"CVE-2013-0625": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2013-0632": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2013-0809": {"https://www.us-cert.gov/ncas/alerts/TA13-064A"},
"CVE-2013-1347": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2013-1493": {"https://www.us-cert.gov/ncas/alerts/TA13-064A"},
"CVE-2013-1571": {"https://www.us-cert.gov/ncas/alerts/TA13-169A"},
"CVE-2013-2465": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2013-2729": {"https://www.us-cert.gov/ncas/alerts/TA14-300A", "https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2013-3336": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2013-5211": {"https://www.us-cert.gov/ncas/alerts/TA14-017A", "https://www.us-cert.gov/ncas/alerts/TA14-013A"},
"CVE-2013-5326": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2014-0160": {"https://www.us-cert.gov/ncas/alerts/TA14-098A", "https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2014-0322": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2014-0564": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2014-1761": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2014-1776": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2014-3393": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
"CVE-2014-3566": {"https://www.us-cert.gov/ncas/alerts/TA14-290A", "https://www.us-cert.gov/ncas/alerts/TA15-120A"},
"CVE-2014-4114": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
"CVE-2014-6271": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
"CVE-2014-6277": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
"CVE-2014-6278": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
"CVE-2014-6321": {"https://www.us-cert.gov/ncas/alerts/TA14-318A"},
"CVE-2014-6332": {"https://www.us-cert.gov/ncas/alerts/TA14-318B"},
"CVE-2014-7169": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
"CVE-2014-7186": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
"CVE-2014-7187": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
"CVE-2014-8730": {"https://www.us-cert.gov/ncas/alerts/TA14-290A"},
"CVE-2015-2387": {"https://www.us-cert.gov/ncas/alerts/TA15-195A"},
"CVE-2015-5119": {"https://www.us-cert.gov/ncas/alerts/TA15-195A", "https://www.us-cert.gov/ncas/alerts/TA15-213A"},
"CVE-2015-5122": {"https://www.us-cert.gov/ncas/alerts/TA15-195A"},
"CVE-2015-5123": {"https://www.us-cert.gov/ncas/alerts/TA15-195A"},
"CVE-2015-6585": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
"CVE-2015-8651": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
"CVE-2016-0034": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
"CVE-2016-1019": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
"CVE-2016-2207": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
"CVE-2016-2208": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
"CVE-2016-2209": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
"CVE-2016-2210": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
"CVE-2016-2211": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
"CVE-2016-3644": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
"CVE-2016-3645": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
"CVE-2016-4117": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
"CVE-2016-6366": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
"CVE-2016-6367": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
"CVE-2016-6415": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
"CVE-2016-6909": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
"CVE-2016-7089": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
"CVE-2017-0144": {"https://www.us-cert.gov/ncas/alerts/TA17-181A"},
"CVE-2017-0145": {"https://www.us-cert.gov/ncas/alerts/TA17-181A"},
"CVE-2017-3066": {"https://www.us-cert.gov/ncas/alerts/AA18-284A"},
"CVE-2017-5715": {"https://www.us-cert.gov/ncas/alerts/TA18-141A", "https://www.us-cert.gov/ncas/alerts/TA18-004A"},
"CVE-2017-5753": {"https://www.us-cert.gov/ncas/alerts/TA18-141A", "https://www.us-cert.gov/ncas/alerts/TA18-004A"},
"CVE-2017-5754": {"https://www.us-cert.gov/ncas/alerts/TA18-141A", "https://www.us-cert.gov/ncas/alerts/TA18-004A"},
"CVE-2018-1038": {"https://www.us-cert.gov/ncas/alerts/TA18-004A"},
"CVE-2018-3639": {"https://www.us-cert.gov/ncas/alerts/TA18-141A"},
"CVE-2018-3640": {"https://www.us-cert.gov/ncas/alerts/TA18-141A"},
}

View File

@@ -1,21 +0,0 @@
package alert
// GenerateAlertDict returns XCERT alert slice by cveID
func GenerateAlertDict(cveID string, lang string) (alerts []Alert) {
if lang == "ja" {
if keys, ok := CveDictJa[cveID]; ok {
for _, key := range keys {
alerts = append(alerts, AlertDictJa[key])
}
}
return alerts
}
// default language is English
if keys, ok := CveDictEn[cveID]; ok {
for _, key := range keys {
alerts = append(alerts, AlertDictEn[key])
}
}
return alerts
}

29
cache/bolt.go vendored
View File

@@ -1,30 +1,13 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cache
import (
"encoding/json"
"fmt"
"time"
"github.com/boltdb/bolt"
"github.com/future-architect/vuls/util"
"github.com/sirupsen/logrus"
"golang.org/x/xerrors"
)
// Bolt holds a pointer of bolt.DB
@@ -69,7 +52,7 @@ func (b *Bolt) createBucketIfNotExists(name string) error {
return b.db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucketIfNotExists([]byte(name))
if err != nil {
return fmt.Errorf("Failed to create bucket: %s", err)
return xerrors.Errorf("Failed to create bucket: %w", err)
}
return nil
})
@@ -98,7 +81,7 @@ func (b Bolt) RefreshMeta(meta Meta) error {
meta.CreatedAt = time.Now()
jsonBytes, err := json.Marshal(meta)
if err != nil {
return fmt.Errorf("Failed to marshal to JSON: %s", err)
return xerrors.Errorf("Failed to marshal to JSON: %w", err)
}
return b.db.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(metabucket))
@@ -114,7 +97,7 @@ func (b Bolt) RefreshMeta(meta Meta) error {
func (b Bolt) EnsureBuckets(meta Meta) error {
jsonBytes, err := json.Marshal(meta)
if err != nil {
return fmt.Errorf("Failed to marshal to JSON: %s", err)
return xerrors.Errorf("Failed to marshal to JSON: %w", err)
}
return b.db.Update(func(tx *bolt.Tx) error {
b.Log.Debugf("Put to meta: %s", meta.Name)
@@ -163,7 +146,7 @@ func (b Bolt) GetChangelog(servername, packName string) (changelog string, err e
err = b.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(servername))
if bkt == nil {
return fmt.Errorf("Failed to get Bucket: %s", servername)
return xerrors.Errorf("Failed to get Bucket: %s", servername)
}
v := bkt.Get([]byte(packName))
if v == nil {
@@ -181,7 +164,7 @@ func (b Bolt) PutChangelog(servername, packName, changelog string) error {
return b.db.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(servername))
if bkt == nil {
return fmt.Errorf("Failed to get Bucket: %s", servername)
return xerrors.Errorf("Failed to get Bucket: %s", servername)
}
return bkt.Put([]byte(packName), []byte(changelog))
})

17
cache/bolt_test.go vendored
View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cache
import (

17
cache/db.go vendored
View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cache
import (

View File

@@ -1,27 +1,12 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package commands
import (
"context"
"flag"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/google/subcommands"
@@ -98,7 +83,7 @@ func (p *ConfigtestCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interfa
util.Log = util.NewCustomLogger(c.ServerInfo{})
if err := mkdirDotVuls(); err != nil {
util.Log.Errorf("Failed to create .vuls: %s", err)
util.Log.Errorf("Failed to create .vuls. err: %+v", err)
return subcommands.ExitUsageError
}
@@ -114,9 +99,12 @@ func (p *ConfigtestCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interfa
err = c.Load(p.configPath, keyPass)
if err != nil {
util.Log.Errorf("Error loading %s, %s", p.configPath, err)
util.Log.Errorf("If you update Vuls and get this error, there may be incompatible changes in config.toml")
util.Log.Errorf("Please check README: https://github.com/future-architect/vuls#configuration")
msg := []string{
fmt.Sprintf("Error loading %s", p.configPath),
"If you update Vuls and get this error, there may be incompatible changes in config.toml",
"Please check config.toml template : https://vuls.io/docs/en/usage-settings.html",
}
util.Log.Errorf("%s\n%+v", strings.Join(msg, "\n"), err)
return subcommands.ExitUsageError
}
@@ -151,13 +139,13 @@ func (p *ConfigtestCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interfa
util.Log.Info("Detecting Server/Container OS... ")
if err := scan.InitServers(p.timeoutSec); err != nil {
util.Log.Errorf("Failed to init servers: %s", err)
util.Log.Errorf("Failed to init servers. err: %+v", err)
return subcommands.ExitFailure
}
util.Log.Info("Checking Scan Modes...")
if err := scan.CheckScanModes(); err != nil {
util.Log.Errorf("Fix config.toml: %s", err)
util.Log.Errorf("Fix config.toml. err: %+v", err)
return subcommands.ExitFailure
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package commands
import (
@@ -223,6 +206,13 @@ host = "{{$ip}}"
#[servers.{{index $names $i}}.githubs."owner/repo"]
#token = "yourToken"
#[servers.{{index $names $i}}.wordpress]
#cmdPath = "/usr/local/bin/wp"
#osUser = "wordpress"
#docRoot = "/path/to/DocumentRoot/"
#wpVulnDBToken = "xxxxTokenxxxx"
#ignoreInactive = true
#[servers.{{index $names $i}}.optional]
#key = "value1"

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package commands
import (

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package commands
import (
@@ -87,6 +70,7 @@ func (*ReportCmd) Usage() string {
[-http-proxy=http://192.168.0.1:8080]
[-debug]
[-debug-sql]
[-quiet]
[-pipe]
[-cvedb-type=sqlite3|mysql|postgres|redis|http]
[-cvedb-sqlite3-path=/path/to/cve.sqlite3]
@@ -112,6 +96,8 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&c.Conf.Debug, "debug", false, "debug mode")
f.BoolVar(&c.Conf.DebugSQL, "debug-sql", false, "SQL debug mode")
f.BoolVar(&c.Conf.Quiet, "quiet", false, "Quiet mode. No output on stdout")
wd, _ := os.Getwd()
defaultConfPath := filepath.Join(wd, "config.toml")
f.StringVar(&p.configPath, "config", defaultConfPath, "/path/to/toml")
@@ -209,7 +195,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
cvelog.SetLogger(c.Conf.LogDir, false, c.Conf.Debug, false)
if err := c.Load(p.configPath, ""); err != nil {
util.Log.Errorf("Error loading %s, %s", p.configPath, err)
util.Log.Errorf("Error loading %s, %+v", p.configPath, err)
return subcommands.ExitUsageError
}
@@ -227,7 +213,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
dir, err = report.JSONDir(f.Args())
}
if err != nil {
util.Log.Errorf("Failed to read from JSON: %s", err)
util.Log.Errorf("Failed to read from JSON: %+v", err)
return subcommands.ExitFailure
}
@@ -276,7 +262,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
if c.Conf.ToS3 {
if err := report.CheckIfBucketExists(); err != nil {
util.Log.Errorf("Check if there is a bucket beforehand: %s, err: %s",
util.Log.Errorf("Check if there is a bucket beforehand: %s, err: %+v",
c.Conf.AWS.S3Bucket, err)
return subcommands.ExitUsageError
}
@@ -297,7 +283,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
return subcommands.ExitUsageError
}
if err := report.CheckIfAzureContainerExists(); err != nil {
util.Log.Errorf("Check if there is a container beforehand: %s, err: %s",
util.Log.Errorf("Check if there is a container beforehand: %s, err: %+v",
c.Conf.Azure.ContainerName, err)
return subcommands.ExitUsageError
}
@@ -330,15 +316,21 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
util.Log.Infof("Loaded: %s", dir)
var res models.ScanResults
hasError := false
for _, r := range loaded {
if len(r.Errors) == 0 {
res = append(res, r)
} else {
util.Log.Warnf("Ignored since errors occurred during scanning: %s",
r.ServerName)
util.Log.Errorf("Ignored since errors occurred during scanning: %s, err: %v",
r.ServerName, r.Errors)
hasError = true
}
}
if len(res) == 0 {
return subcommands.ExitFailure
}
for _, r := range res {
util.Log.Debugf("%s: %s",
r.ServerInfo(),
@@ -348,7 +340,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
if c.Conf.UUID {
// Ensure UUIDs of scan target servers in config.toml
if err := report.EnsureUUIDs(p.configPath, res); err != nil {
util.Log.Errorf("Failed to ensure UUIDs: %s", err)
util.Log.Errorf("Failed to ensure UUIDs. err: %+v", err)
return subcommands.ExitFailure
}
}
@@ -361,7 +353,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
if c.Conf.CveDict.URL != "" {
if err := report.CveClient.CheckHealth(); err != nil {
util.Log.Errorf("CVE HTTP server is not running. err: %s", err)
util.Log.Errorf("CVE HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run go-cve-dictionary as server mode before reporting or run with `-cvedb-type=sqlite3 -cvedb-sqlite3-path` option instead of -cvedb-url")
return subcommands.ExitFailure
}
@@ -370,7 +362,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
if c.Conf.OvalDict.URL != "" {
err := oval.Base{}.CheckHTTPHealth()
if err != nil {
util.Log.Errorf("OVAL HTTP server is not running. err: %s", err)
util.Log.Errorf("OVAL HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run goval-dictionary as server mode before reporting or run with `-ovaldb-type=sqlite3 -ovaldb-sqlite3-path` option instead of -ovaldb-url")
return subcommands.ExitFailure
}
@@ -380,7 +372,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
util.Log.Infof("gost: %s", c.Conf.Gost.URL)
err := gost.Base{}.CheckHTTPHealth()
if err != nil {
util.Log.Errorf("gost HTTP server is not running. err: %s", err)
util.Log.Errorf("gost HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run gost as server mode before reporting or run with `-gostdb-type=sqlite3 -gostdb-sqlite3-path` option instead of -gostdb-url")
return subcommands.ExitFailure
}
@@ -389,7 +381,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
if c.Conf.Exploit.URL != "" {
err := exploit.CheckHTTPHealth()
if err != nil {
util.Log.Errorf("exploit HTTP server is not running. err: %s", err)
util.Log.Errorf("exploit HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run go-exploitdb as server mode before reporting")
return subcommands.ExitFailure
}
@@ -402,27 +394,31 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
DebugSQL: c.Conf.DebugSQL,
})
if locked {
util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %s", err)
util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again. err: %+v", err)
return subcommands.ExitFailure
}
if err != nil {
util.Log.Errorf("Failed to init DB Clients: %s", err)
util.Log.Errorf("Failed to init DB Clients. err: %+v", err)
return subcommands.ExitFailure
}
defer dbclient.CloseDB()
if res, err = report.FillCveInfos(*dbclient, res, dir); err != nil {
util.Log.Error(err)
util.Log.Errorf("%+v", err)
return subcommands.ExitFailure
}
}
for _, w := range reports {
if err := w.Write(res...); err != nil {
util.Log.Errorf("Failed to report: %s", err)
util.Log.Errorf("Failed to report. err: %+v", err)
return subcommands.ExitFailure
}
}
if hasError {
return subcommands.ExitFailure
}
return subcommands.ExitSuccess
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package commands
import (
@@ -58,6 +41,9 @@ func (*ScanCmd) Usage() string {
[-ssh-native-insecure]
[-ssh-config]
[-containers-only]
[-images-only]
[-libs-only]
[-wordpress-only]
[-skip-broken]
[-http-proxy=http://192.168.0.1:8080]
[-ask-key-password]
@@ -66,6 +52,8 @@ func (*ScanCmd) Usage() string {
[-debug]
[-pipe]
[-vvv]
[-ips]
[SERVER]...
`
@@ -96,7 +84,16 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
"Use SSH options specified in ssh_config preferentially")
f.BoolVar(&c.Conf.ContainersOnly, "containers-only", false,
"Scan containers only. Default: Scan both of hosts and containers")
"Scan running containers only. Default: Scan both of hosts and running containers")
f.BoolVar(&c.Conf.ImagesOnly, "images-only", false,
"Scan container images only. Default: Scan both of hosts and images")
f.BoolVar(&c.Conf.LibsOnly, "libs-only", false,
"Scan libraries (lock files) specified in config.toml only.")
f.BoolVar(&c.Conf.WordPressOnly, "wordpress-only", false,
"Scan WordPress only.")
f.BoolVar(&c.Conf.SkipBroken, "skip-broken", false,
"[For CentOS] yum update changelog with --skip-broken option")
@@ -109,6 +106,8 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
)
f.BoolVar(&c.Conf.Pipe, "pipe", false, "Use stdin via PIPE")
f.BoolVar(&c.Conf.DetectIPS, "ips", false, "retrieve IPS information")
f.BoolVar(&c.Conf.Vvv, "vvv", false, "ssh -vvv")
f.IntVar(&p.timeoutSec, "timeout", 5*60,
@@ -126,7 +125,7 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
util.Log = util.NewCustomLogger(c.ServerInfo{})
if err := mkdirDotVuls(); err != nil {
util.Log.Errorf("Failed to create .vuls: %s", err)
util.Log.Errorf("Failed to create .vuls. err: %+v", err)
return subcommands.ExitUsageError
}
@@ -142,9 +141,12 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
err = c.Load(p.configPath, keyPass)
if err != nil {
util.Log.Errorf("Error loading %s, %s", p.configPath, err)
util.Log.Errorf("If you update Vuls and get this error, there may be incompatible changes in config.toml")
util.Log.Errorf("Please check README: https://github.com/future-architect/vuls#configuration")
msg := []string{
fmt.Sprintf("Error loading %s", p.configPath),
"If you update Vuls and get this error, there may be incompatible changes in config.toml",
"Please check config.toml template : https://vuls.io/docs/en/usage-settings.html",
}
util.Log.Errorf("%s\n%+v", strings.Join(msg, "\n"), err)
return subcommands.ExitUsageError
}
@@ -157,7 +159,7 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
} else if c.Conf.Pipe {
bytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
util.Log.Errorf("Failed to read stdin: %s", err)
util.Log.Errorf("Failed to read stdin. err: %+v", err)
return subcommands.ExitFailure
}
fields := strings.Fields(string(bytes))
@@ -193,22 +195,24 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
util.Log.Info("Detecting Server/Container OS... ")
if err := scan.InitServers(p.timeoutSec); err != nil {
util.Log.Errorf("Failed to init servers: %s", err)
util.Log.Errorf("Failed to init servers: %+v", err)
return subcommands.ExitFailure
}
util.Log.Info("Checking Scan Modes... ")
if err := scan.CheckScanModes(); err != nil {
util.Log.Errorf("Fix config.toml: %s", err)
util.Log.Errorf("Fix config.toml. err: %+v", err)
return subcommands.ExitFailure
}
util.Log.Info("Detecting Platforms... ")
scan.DetectPlatforms(p.timeoutSec)
util.Log.Info("Detecting IPS identifiers... ")
scan.DetectIPSs(p.timeoutSec)
util.Log.Info("Scanning vulnerabilities... ")
if err := scan.Scan(p.scanTimeoutSec); err != nil {
util.Log.Errorf("Failed to scan. err: %s", err)
util.Log.Errorf("Failed to scan. err: %+v", err)
return subcommands.ExitFailure
}
fmt.Printf("\n\n\n")

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Architect, Inc. Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package commands
import (
@@ -94,8 +77,7 @@ func (p *ServerCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&c.Conf.DebugSQL, "debug-sql", false, "SQL debug mode")
wd, _ := os.Getwd()
defaultConfPath := filepath.Join(wd, "config.toml")
f.StringVar(&p.configPath, "config", defaultConfPath, "/path/to/toml")
f.StringVar(&p.configPath, "config", "", "/path/to/toml")
defaultResultsDir := filepath.Join(wd, "results")
f.StringVar(&c.Conf.ResultsDir, "results-dir", defaultResultsDir, "/path/to/results")
@@ -151,9 +133,11 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
util.Log = util.NewCustomLogger(c.ServerInfo{})
cvelog.SetLogger(c.Conf.LogDir, false, c.Conf.Debug, false)
if err := c.Load(p.configPath, ""); err != nil {
util.Log.Errorf("Error loading %s, %s", p.configPath, err)
return subcommands.ExitUsageError
if p.configPath != "" {
if err := c.Load(p.configPath, ""); err != nil {
util.Log.Errorf("Error loading %s. err: %+v", p.configPath, err)
return subcommands.ExitUsageError
}
}
c.Conf.CveDict.Overwrite(p.cveDict)
@@ -173,7 +157,7 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
if c.Conf.CveDict.URL != "" {
if err := report.CveClient.CheckHealth(); err != nil {
util.Log.Errorf("CVE HTTP server is not running. err: %s", err)
util.Log.Errorf("CVE HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run go-cve-dictionary as server mode before reporting or run with `-cvedb-type=sqlite3 -cvedb-sqlite3-path` option instead of -cvedb-url")
return subcommands.ExitFailure
}
@@ -192,7 +176,7 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
util.Log.Infof("gost: %s", c.Conf.Gost.URL)
err := gost.Base{}.CheckHTTPHealth()
if err != nil {
util.Log.Errorf("gost HTTP server is not running. err: %s", err)
util.Log.Errorf("gost HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run gost as server mode before reporting or run with `-gostdb-type=sqlite3 -gostdb-sqlite3-path` option instead of -gostdb-url")
return subcommands.ExitFailure
}
@@ -201,7 +185,7 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
if c.Conf.Exploit.URL != "" {
err := exploit.CheckHTTPHealth()
if err != nil {
util.Log.Errorf("exploit HTTP server is not running. err: %s", err)
util.Log.Errorf("exploit HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run go-exploitdb as server mode before reporting")
return subcommands.ExitFailure
}
@@ -215,12 +199,12 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
DebugSQL: c.Conf.DebugSQL,
})
if locked {
util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %s", err)
util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %+v", err)
return subcommands.ExitFailure
}
if err != nil {
util.Log.Errorf("Failed to init DB Clients: %s", err)
util.Log.Errorf("Failed to init DB Clients. err: %+v", err)
return subcommands.ExitFailure
}
@@ -232,7 +216,7 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
})
util.Log.Infof("Listening on %s", p.listen)
if err := http.ListenAndServe(p.listen, nil); err != nil {
util.Log.Errorf("Failed to start server: %s", err)
util.Log.Errorf("Failed to start server. err: %+v", err)
return subcommands.ExitFailure
}
return subcommands.ExitSuccess

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package commands
import (
@@ -149,7 +132,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
cvelog.SetLogger(c.Conf.LogDir, false, c.Conf.Debug, false)
if err := c.Load(p.configPath, ""); err != nil {
util.Log.Errorf("Error loading %s, %s", p.configPath, err)
util.Log.Errorf("Error loading %s, err: %+v", p.configPath, err)
return subcommands.ExitUsageError
}
@@ -166,7 +149,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
dir, err = report.JSONDir(f.Args())
}
if err != nil {
util.Log.Errorf("Failed to read from JSON: %s", err)
util.Log.Errorf("Failed to read from JSON. err: %+v", err)
return subcommands.ExitFailure
}
@@ -189,7 +172,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
if c.Conf.CveDict.URL != "" {
if err := report.CveClient.CheckHealth(); err != nil {
util.Log.Errorf("CVE HTTP server is not running. err: %s", err)
util.Log.Errorf("CVE HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run go-cve-dictionary as server mode before reporting or run with `-cvedb-type=sqlite3 -cvedb-sqlite3-path` option instead of -cvedb-url")
return subcommands.ExitFailure
}
@@ -198,7 +181,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
if c.Conf.OvalDict.URL != "" {
err := oval.Base{}.CheckHTTPHealth()
if err != nil {
util.Log.Errorf("OVAL HTTP server is not running. err: %s", err)
util.Log.Errorf("OVAL HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run goval-dictionary as server mode before reporting or run with `-ovaldb-type=sqlite3 -ovaldb-sqlite3-path` option instead of -ovaldb-url")
return subcommands.ExitFailure
}
@@ -208,7 +191,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
util.Log.Infof("gost: %s", c.Conf.Gost.URL)
err := gost.Base{}.CheckHTTPHealth()
if err != nil {
util.Log.Errorf("gost HTTP server is not running. err: %s", err)
util.Log.Errorf("gost HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run gost as server mode before reporting or run with `-gostdb-type=sqlite3 -gostdb-sqlite3-path` option instead of -gostdb-url")
return subcommands.ExitFailure
}
@@ -217,7 +200,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
if c.Conf.Exploit.URL != "" {
err := exploit.CheckHTTPHealth()
if err != nil {
util.Log.Errorf("exploit HTTP server is not running. err: %s", err)
util.Log.Errorf("exploit HTTP server is not running. err: %+v", err)
util.Log.Errorf("Run go-exploitdb as server mode before reporting")
return subcommands.ExitFailure
}
@@ -230,12 +213,12 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
DebugSQL: c.Conf.DebugSQL,
})
if locked {
util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %s", err)
util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %+v", err)
return subcommands.ExitFailure
}
if err != nil {
util.Log.Errorf("Failed to init DB Clients: %s", err)
util.Log.Errorf("Failed to init DB Clients. err: %+v", err)
return subcommands.ExitFailure
}
@@ -245,5 +228,13 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
util.Log.Error(err)
return subcommands.ExitFailure
}
for _, r := range res {
if len(r.Warnings) != 0 {
util.Log.Warnf("Warning: Some warnings occurred while scanning on %s: %s",
r.FormatServerName(), r.Warnings)
}
}
return report.RunTui(res)
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package commands
import (
@@ -24,6 +7,7 @@ import (
"github.com/howeyc/gopass"
homedir "github.com/mitchellh/go-homedir"
"golang.org/x/xerrors"
)
func getPasswd(prompt string) (string, error) {
@@ -31,7 +15,7 @@ func getPasswd(prompt string) (string, error) {
fmt.Print(prompt)
pass, err := gopass.GetPasswdMasked()
if err != nil {
return "", fmt.Errorf("Failed to read password")
return "", xerrors.New("Failed to read a password")
}
if 0 < len(pass) {
return string(pass), nil

View File

@@ -1,18 +0,0 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package commands

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
var (

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
import (
@@ -27,13 +10,14 @@ import (
"strings"
syslog "github.com/RackSec/srslog"
"github.com/aquasecurity/fanal/types"
valid "github.com/asaskevich/govalidator"
log "github.com/sirupsen/logrus"
"golang.org/x/xerrors"
)
// Version of Vuls
var Version = "0.6.3"
var Version = "0.9.3"
// Revision of Git
var Revision string
@@ -105,6 +89,7 @@ type Config struct {
LogDir string `json:"logDir,omitempty"`
ResultsDir string `json:"resultsDir,omitempty"`
Pipe bool `json:"pipe,omitempty"`
Quiet bool `json:"quiet,omitempty"`
Default ServerInfo `json:"default,omitempty"`
Servers map[string]ServerInfo `json:"servers,omitempty"`
@@ -114,13 +99,19 @@ type Config struct {
IgnoreUnfixed bool `json:"ignoreUnfixed,omitempty"`
IgnoreGitHubDismissed bool `json:"ignore_git_hub_dismissed,omitempty"`
SSHNative bool `json:"sshNative,omitempty"`
SSHConfig bool `json:"sshConfig,omitempty"`
ContainersOnly bool `json:"containersOnly,omitempty"`
SkipBroken bool `json:"skipBroken,omitempty"`
CacheDBPath string `json:"cacheDBPath,omitempty"`
Vvv bool `json:"vvv,omitempty"`
UUID bool `json:"uuid,omitempty"`
SSHNative bool `json:"sshNative,omitempty"`
SSHConfig bool `json:"sshConfig,omitempty"`
ContainersOnly bool `json:"containersOnly,omitempty"`
ImagesOnly bool `json:"imagesOnly,omitempty"`
LibsOnly bool `json:"libsOnly,omitempty"`
WordPressOnly bool `json:"wordpressOnly,omitempty"`
SkipBroken bool `json:"skipBroken,omitempty"`
CacheDBPath string `json:"cacheDBPath,omitempty"`
Vvv bool `json:"vvv,omitempty"`
UUID bool `json:"uuid,omitempty"`
DetectIPS bool `json:"detectIps,omitempty"`
CveDict GoCveDictConf `json:"cveDict,omitempty"`
OvalDict GovalDictConf `json:"ovalDict,omitempty"`
@@ -164,10 +155,10 @@ type Config struct {
// ValidateOnConfigtest validates
func (c Config) ValidateOnConfigtest() bool {
errs := []error{}
errs := c.checkSSHKeyExist()
if runtime.GOOS == "windows" && !c.SSHNative {
errs = append(errs, fmt.Errorf("-ssh-native-insecure is needed on windows"))
errs = append(errs, xerrors.New("-ssh-native-insecure is needed on windows"))
}
_, err := valid.ValidateStruct(c)
@@ -184,29 +175,22 @@ 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, fmt.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, fmt.Errorf("-ssh-native-insecure is needed on windows"))
errs = append(errs, xerrors.New("-ssh-native-insecure is needed on windows"))
}
if len(c.ResultsDir) != 0 {
if ok, _ := valid.IsFilePath(c.ResultsDir); !ok {
errs = append(errs, fmt.Errorf(
errs = append(errs, xerrors.Errorf(
"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
}
}
if len(c.CacheDBPath) != 0 {
if ok, _ := valid.IsFilePath(c.CacheDBPath); !ok {
errs = append(errs, fmt.Errorf(
errs = append(errs, xerrors.Errorf(
"Cache DB path must be a *Absolute* file path. -cache-dbpath: %s",
c.CacheDBPath))
}
@@ -224,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{}
@@ -231,11 +230,6 @@ func (c Config) ValidateOnReportDB() 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, fmt.Errorf("SQLite3 DB path (%s) is not exist: %s", "cvedb", c.CveDict.SQLite3Path))
}
}
if err := validateDB("ovaldb", c.OvalDict.Type, c.OvalDict.SQLite3Path, c.OvalDict.URL); err != nil {
errs = append(errs, err)
@@ -262,7 +256,7 @@ func (c Config) ValidateOnReport() bool {
if len(c.ResultsDir) != 0 {
if ok, _ := valid.IsFilePath(c.ResultsDir); !ok {
errs = append(errs, fmt.Errorf(
errs = append(errs, xerrors.Errorf(
"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
}
}
@@ -321,7 +315,7 @@ func (c Config) ValidateOnTui() bool {
if len(c.ResultsDir) != 0 {
if ok, _ := valid.IsFilePath(c.ResultsDir); !ok {
errs = append(errs, fmt.Errorf(
errs = append(errs, xerrors.Errorf(
"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
}
}
@@ -329,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, fmt.Errorf("SQLite3 DB path (%s) is not exist: %s", "cvedb", c.CveDict.SQLite3Path))
}
}
for _, err := range errs {
log.Error(err)
@@ -351,35 +340,35 @@ func validateDB(dictionaryDBName, dbType, dbPath, dbURL string) error {
switch dbType {
case "sqlite3":
if dbURL != "" {
return fmt.Errorf("To use SQLite3, specify -%s-type=sqlite3 and -%s-path. To use as http server mode, specify -%s-type=http and -%s-url",
return xerrors.Errorf("To use SQLite3, specify -%s-type=sqlite3 and -%s-path. To use as http server mode, specify -%s-type=http and -%s-url",
dictionaryDBName, dictionaryDBName, dictionaryDBName, dictionaryDBName)
}
if ok, _ := valid.IsFilePath(dbPath); !ok {
return fmt.Errorf("SQLite3 path must be a *Absolute* file path. -%s-path: %s",
return xerrors.Errorf("SQLite3 path must be a *Absolute* file path. -%s-path: %s",
dictionaryDBName, dbPath)
}
case "mysql":
if dbURL == "" {
return fmt.Errorf(`MySQL connection string is needed. -%s-url="user:pass@tcp(localhost:3306)/dbname"`,
return xerrors.Errorf(`MySQL connection string is needed. -%s-url="user:pass@tcp(localhost:3306)/dbname"`,
dictionaryDBName)
}
case "postgres":
if dbURL == "" {
return fmt.Errorf(`PostgreSQL connection string is needed. -%s-url="host=myhost user=user dbname=dbname sslmode=disable password=password"`,
return xerrors.Errorf(`PostgreSQL connection string is needed. -%s-url="host=myhost user=user dbname=dbname sslmode=disable password=password"`,
dictionaryDBName)
}
case "redis":
if dbURL == "" {
return fmt.Errorf(`Redis connection string is needed. -%s-url="redis://localhost/0"`,
return xerrors.Errorf(`Redis connection string is needed. -%s-url="redis://localhost/0"`,
dictionaryDBName)
}
case "http":
if dbURL == "" {
return fmt.Errorf(`URL is needed. -%s-url="http://localhost:1323"`,
return xerrors.Errorf(`URL is needed. -%s-url="http://localhost:1323"`,
dictionaryDBName)
}
default:
return fmt.Errorf("%s type must be either 'sqlite3', 'mysql', 'postgres', 'redis' or 'http'. -%s-type: %s",
return xerrors.Errorf("%s type must be either 'sqlite3', 'mysql', 'postgres', 'redis' or 'http'. -%s-type: %s",
dictionaryDBName, dictionaryDBName, dbType)
}
return nil
@@ -403,7 +392,7 @@ func checkEmails(emails []string) (errs []error) {
return
}
if ok := valid.IsEmail(addr); !ok {
errs = append(errs, fmt.Errorf("Invalid email address. email: %s", addr))
errs = append(errs, xerrors.Errorf("Invalid email address. email: %s", addr))
}
}
return
@@ -425,16 +414,16 @@ func (c *SMTPConf) Validate() (errs []error) {
}
if len(c.SMTPAddr) == 0 {
errs = append(errs, fmt.Errorf("email.smtpAddr must not be empty"))
errs = append(errs, xerrors.New("email.smtpAddr must not be empty"))
}
if len(c.SMTPPort) == 0 {
errs = append(errs, fmt.Errorf("email.smtpPort must not be empty"))
errs = append(errs, xerrors.New("email.smtpPort must not be empty"))
}
if len(c.To) == 0 {
errs = append(errs, fmt.Errorf("email.To required at least one address"))
errs = append(errs, xerrors.New("email.To required at least one address"))
}
if len(c.From) == 0 {
errs = append(errs, fmt.Errorf("email.From required at least one address"))
errs = append(errs, xerrors.New("email.From required at least one address"))
}
_, err := valid.ValidateStruct(c)
@@ -457,11 +446,11 @@ func (c *StrideConf) Validate() (errs []error) {
}
if len(c.HookURL) == 0 {
errs = append(errs, fmt.Errorf("stride.HookURL must not be empty"))
errs = append(errs, xerrors.New("stride.HookURL must not be empty"))
}
if len(c.AuthToken) == 0 {
errs = append(errs, fmt.Errorf("stride.AuthToken must not be empty"))
errs = append(errs, xerrors.New("stride.AuthToken must not be empty"))
}
_, err := valid.ValidateStruct(c)
@@ -489,21 +478,21 @@ func (c *SlackConf) Validate() (errs []error) {
}
if len(c.HookURL) == 0 && len(c.LegacyToken) == 0 {
errs = append(errs, fmt.Errorf("slack.hookURL or slack.LegacyToken must not be empty"))
errs = append(errs, xerrors.New("slack.hookURL or slack.LegacyToken must not be empty"))
}
if len(c.Channel) == 0 {
errs = append(errs, fmt.Errorf("slack.channel must not be empty"))
errs = append(errs, xerrors.New("slack.channel must not be empty"))
} else {
if !(strings.HasPrefix(c.Channel, "#") ||
c.Channel == "${servername}") {
errs = append(errs, fmt.Errorf(
errs = append(errs, xerrors.Errorf(
"channel's prefix must be '#', channel: %s", c.Channel))
}
}
if len(c.AuthUser) == 0 {
errs = append(errs, fmt.Errorf("slack.authUser must not be empty"))
errs = append(errs, xerrors.New("slack.authUser must not be empty"))
}
_, err := valid.ValidateStruct(c)
@@ -526,11 +515,11 @@ func (c *HipChatConf) Validate() (errs []error) {
return
}
if len(c.Room) == 0 {
errs = append(errs, fmt.Errorf("hipcaht.room must not be empty"))
errs = append(errs, xerrors.New("hipcaht.room must not be empty"))
}
if len(c.AuthToken) == 0 {
errs = append(errs, fmt.Errorf("hipcaht.AuthToken must not be empty"))
errs = append(errs, xerrors.New("hipcaht.AuthToken must not be empty"))
}
_, err := valid.ValidateStruct(c)
@@ -552,11 +541,11 @@ func (c *ChatWorkConf) Validate() (errs []error) {
return
}
if len(c.Room) == 0 {
errs = append(errs, fmt.Errorf("chatworkcaht.room must not be empty"))
errs = append(errs, xerrors.New("chatworkcaht.room must not be empty"))
}
if len(c.APIToken) == 0 {
errs = append(errs, fmt.Errorf("chatworkcaht.ApiToken must not be empty"))
errs = append(errs, xerrors.New("chatworkcaht.ApiToken must not be empty"))
}
_, err := valid.ValidateStruct(c)
@@ -578,11 +567,11 @@ func (c *TelegramConf) Validate() (errs []error) {
return
}
if len(c.ChatID) == 0 {
errs = append(errs, fmt.Errorf("TelegramConf.ChatID must not be empty"))
errs = append(errs, xerrors.New("TelegramConf.ChatID must not be empty"))
}
if len(c.Token) == 0 {
errs = append(errs, fmt.Errorf("TelegramConf.Token must not be empty"))
errs = append(errs, xerrors.New("TelegramConf.Token must not be empty"))
}
_, err := valid.ValidateStruct(c)
@@ -606,15 +595,15 @@ func (c *SaasConf) Validate() (errs []error) {
}
if c.GroupID == 0 {
errs = append(errs, fmt.Errorf("saas.GroupID must not be empty"))
errs = append(errs, xerrors.New("saas.GroupID must not be empty"))
}
if len(c.Token) == 0 {
errs = append(errs, fmt.Errorf("saas.Token must not be empty"))
errs = append(errs, xerrors.New("saas.Token must not be empty"))
}
if len(c.URL) == 0 {
errs = append(errs, fmt.Errorf("saas.URL must not be empty"))
errs = append(errs, xerrors.New("saas.URL must not be empty"))
}
_, err := valid.ValidateStruct(c)
@@ -688,7 +677,7 @@ func (c *SyslogConf) GetSeverity() (syslog.Priority, error) {
case "debug":
return syslog.LOG_DEBUG, nil
default:
return -1, fmt.Errorf("Invalid severity: %s", c.Severity)
return -1, xerrors.Errorf("Invalid severity: %s", c.Severity)
}
}
@@ -740,7 +729,7 @@ func (c *SyslogConf) GetFacility() (syslog.Priority, error) {
case "local7":
return syslog.LOG_LOCAL7, nil
default:
return -1, fmt.Errorf("Invalid facility: %s", c.Facility)
return -1, xerrors.Errorf("Invalid facility: %s", c.Facility)
}
}
@@ -1041,16 +1030,16 @@ type Azure struct {
// ServerInfo has SSH Info, additional CPE packages to scan.
type ServerInfo struct {
ServerName string `toml:"-" json:"serverName"`
User string `toml:"user,omitempty" json:"user"`
Host string `toml:"host,omitempty" json:"host"`
Port string `toml:"port,omitempty" json:"port"`
KeyPath string `toml:"keyPath,omitempty" json:"keyPath"`
KeyPassword string `json:"-" toml:"-"`
ServerName string `toml:"-" json:"serverName,omitempty"`
User string `toml:"user,omitempty" json:"user,omitempty"`
Host string `toml:"host,omitempty" json:"host,omitempty"`
Port string `toml:"port,omitempty" json:"port,omitempty"`
KeyPath string `toml:"keyPath,omitempty" json:"keyPath,omitempty"`
KeyPassword string `json:"-,omitempty" toml:"-"`
CpeNames []string `toml:"cpeNames,omitempty" json:"cpeNames,omitempty"`
ScanMode []string `toml:"scanMode,omitempty" json:"scanMode,omitempty"`
DependencyCheckXMLPath string `toml:"dependencyCheckXMLPath,omitempty" json:"-"` // TODO Deprecated remove in near future
OwaspDCXMLPath string `toml:"owaspDCXMLPath,omitempty" json:"owaspDCXMLPath"`
OwaspDCXMLPath string `toml:"owaspDCXMLPath,omitempty" json:"owaspDCXMLPath,omitempty"`
ContainersIncluded []string `toml:"containersIncluded,omitempty" json:"containersIncluded,omitempty"`
ContainersExcluded []string `toml:"containersExcluded,omitempty" json:"containersExcluded,omitempty"`
ContainerType string `toml:"containerType,omitempty" json:"containerType,omitempty"`
@@ -1058,17 +1047,25 @@ type ServerInfo struct {
IgnoreCves []string `toml:"ignoreCves,omitempty" json:"ignoreCves,omitempty"`
IgnorePkgsRegexp []string `toml:"ignorePkgsRegexp,omitempty" json:"ignorePkgsRegexp,omitempty"`
GitHubRepos map[string]GitHubConf `toml:"githubs" json:"githubs,omitempty"` // key: owner/repo
Images map[string]Image `toml:"images" json:"images,omitempty"`
UUIDs map[string]string `toml:"uuids,omitempty" json:"uuids,omitempty"`
Memo string `toml:"memo,omitempty" json:"memo"`
Memo string `toml:"memo,omitempty" json:"memo,omitempty"`
Enablerepo []string `toml:"enablerepo,omitempty" json:"enablerepo,omitempty"` // For CentOS, RHEL, Amazon
Optional map[string]interface{} `toml:"optional,omitempty" json:"optional,omitempty"` // Optional key-value set that will be outputted to JSON
Type string `toml:"type,omitempty" json:"type"` // "pseudo" or ""
IPv4Addrs []string `toml:"-" json:"ipv4Addrs,omitempty"`
IPv6Addrs []string `toml:"-" json:"ipv6Addrs,omitempty"`
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"`
// 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:"-"`
Image Image `toml:"-" json:"-"`
Distro Distro `toml:"-" json:"-"`
Mode ScanMode `toml:"-" json:"-"`
}
@@ -1081,21 +1078,37 @@ type ContainerSetting struct {
IgnoreCves []string `json:"ignoreCves,omitempty"`
}
// IntegrationConf is used for integration configuration
type IntegrationConf struct {
GitHubConf map[string]GitHubConf
// WordPressConf used for WordPress Scanning
type WordPressConf struct {
OSUser string `toml:"osUser" json:"osUser,omitempty"`
DocRoot string `toml:"docRoot" json:"docRoot,omitempty"`
CmdPath string `toml:"cmdPath" json:"cmdPath,omitempty"`
WPVulnDBToken string `toml:"wpVulnDBToken" json:"-,omitempty"`
IgnoreInactive bool `json:"ignoreInactive,omitempty"`
}
// New creates IntegrationConf and initialize fields
func (c IntegrationConf) New() IntegrationConf {
return IntegrationConf{
GitHubConf: map[string]GitHubConf{},
// Image is a scan container image info
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"`
IgnorePkgsRegexp []string `json:"ignorePkgsRegexp,omitempty"`
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:"token"`
Token string `json:"-"`
}
// ScanMode has a type of scan mode. fast, fast-root, deep and offline
@@ -1138,9 +1151,9 @@ func (s ScanMode) validate() error {
if numTrue == 0 {
s.Set(Fast)
} else if s.IsDeep() && s.IsOffline() {
return fmt.Errorf("Don't specify both of -deep and offline")
return xerrors.New("Don't specify both of -deep and offline")
} else if numTrue != 1 {
return fmt.Errorf("Specify only one of -fast, -fast-root or -deep")
return xerrors.New("Specify only one of -fast, -fast-root or -deep")
}
return nil
}
@@ -1203,7 +1216,7 @@ func (l Distro) MajorVersion() (ver int, err error) {
if 0 < len(l.Release) {
ver, err = strconv.Atoi(strings.Split(l.Release, ".")[0])
} else {
err = fmt.Errorf("Release is empty")
err = xerrors.New("Release is empty")
}
return
}

9
config/ips.go Normal file
View File

@@ -0,0 +1,9 @@
package config
// IPS is
type IPS string
const (
// DeepSecurity is
DeepSecurity IPS = "deepsecurity"
)

View File

@@ -1,23 +1,6 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
import "fmt"
import "golang.org/x/xerrors"
// JSONLoader loads configuration
type JSONLoader struct {
@@ -25,5 +8,5 @@ type JSONLoader struct {
// Load load the configuration JSON file specified by path arg.
func (c JSONLoader) Load(path, sudoPass, keyPass string) (err error) {
return fmt.Errorf("Not implement yet")
return xerrors.New("Not implement yet")
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
// Load loads configuration

View File

@@ -1,30 +1,12 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package config
import (
"fmt"
"os"
"regexp"
"strings"
"github.com/BurntSushi/toml"
"github.com/knqyf263/go-cpe/naming"
"golang.org/x/xerrors"
)
// TOMLLoader loads config
@@ -65,14 +47,24 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
i := 0
for serverName, v := range conf.Servers {
if 0 < len(v.KeyPassword) {
return fmt.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)
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)
}
s := ServerInfo{ServerName: serverName}
s.Images = make(map[string]Image)
// image are able to set any server type
for name, image := range v.Images {
if err := IsValidImage(image); err != nil {
return err
}
s.Images[name] = image
}
if v.Type != ServerTypePseudo {
s.Host = v.Host
if len(s.Host) == 0 {
return fmt.Errorf("%s is invalid. host is empty", serverName)
return xerrors.Errorf("%s is invalid. host is empty", serverName)
}
switch {
@@ -91,7 +83,7 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
s.User = d.User
default:
if s.Port != "local" {
return fmt.Errorf("%s is invalid. User is empty", serverName)
return xerrors.Errorf("%s is invalid. User is empty", serverName)
}
}
@@ -99,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 fmt.Errorf(
"%s is invalid. keypath: %s not exists", serverName, s.KeyPath)
}
}
s.KeyPassword = v.KeyPassword
if len(s.KeyPassword) == 0 {
s.KeyPassword = d.KeyPassword
@@ -130,11 +115,11 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
case "offline":
s.Mode.Set(Offline)
default:
return fmt.Errorf("scanMode: %s of %s is invalie. Specify -fast, -fast-root, -deep or offline", m, serverName)
return xerrors.Errorf("scanMode: %s of %s is invalie. Specify -fast, -fast-root, -deep or offline", m, serverName)
}
}
if err := s.Mode.validate(); err != nil {
return fmt.Errorf("%s in %s", err, serverName)
return xerrors.Errorf("%s in %s", err, serverName)
}
s.CpeNames = v.CpeNames
@@ -142,10 +127,17 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
s.CpeNames = d.CpeNames
}
s.Lockfiles = v.Lockfiles
if len(s.Lockfiles) == 0 {
s.Lockfiles = d.Lockfiles
}
s.FindLock = v.FindLock
for i, n := range s.CpeNames {
uri, err := toCpeURI(n)
if err != nil {
return fmt.Errorf("Failed to parse CPENames %s in %s: %s", n, serverName, err)
return xerrors.Errorf("Failed to parse CPENames %s in %s, err: %w", n, serverName, err)
}
s.CpeNames[i] = uri
}
@@ -172,7 +164,7 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
}
if len(v.DependencyCheckXMLPath) != 0 || len(d.DependencyCheckXMLPath) != 0 {
return fmt.Errorf("[DEPRECATED] dependencyCheckXMLPath IS DEPRECATED. USE owaspDCXMLPath INSTEAD: %s", serverName)
return xerrors.Errorf("[DEPRECATED] dependencyCheckXMLPath IS DEPRECATED. USE owaspDCXMLPath INSTEAD: %s", serverName)
}
s.OwaspDCXMLPath = v.OwaspDCXMLPath
@@ -215,14 +207,14 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
for _, reg := range s.IgnorePkgsRegexp {
_, err := regexp.Compile(reg)
if err != nil {
return fmt.Errorf("Faild to parse %s in %s. err: %s", reg, serverName, err)
return xerrors.Errorf("Faild to parse %s in %s. err: %w", reg, serverName, err)
}
}
for contName, cont := range s.Containers {
for _, reg := range cont.IgnorePkgsRegexp {
_, err := regexp.Compile(reg)
if err != nil {
return fmt.Errorf("Faild to parse %s in %s@%s. err: %s",
return xerrors.Errorf("Faild to parse %s in %s@%s. err: %w",
reg, contName, serverName, err)
}
}
@@ -247,7 +239,7 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
case "base", "updates":
// nop
default:
return fmt.Errorf(
return xerrors.Errorf(
"For now, enablerepo have to be base or updates: %s, servername: %s",
s.Enablerepo, serverName)
}
@@ -257,11 +249,11 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
s.GitHubRepos = v.GitHubRepos
for ownerRepo, githubSetting := range s.GitHubRepos {
if ss := strings.Split(ownerRepo, "/"); len(ss) != 2 {
return fmt.Errorf("Failed to parse GitHub owner/repo: %s in %s",
return xerrors.Errorf("Failed to parse GitHub owner/repo: %s in %s",
ownerRepo, serverName)
}
if githubSetting.Token == "" {
return fmt.Errorf("GitHub owner/repo: %s in %s token is empty",
return xerrors.Errorf("GitHub owner/repo: %s in %s token is empty",
ownerRepo, serverName)
}
}
@@ -269,6 +261,12 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
s.UUIDs = v.UUIDs
s.Type = v.Type
s.WordPress.WPVulnDBToken = v.WordPress.WPVulnDBToken
s.WordPress.CmdPath = v.WordPress.CmdPath
s.WordPress.DocRoot = v.WordPress.DocRoot
s.WordPress.OSUser = v.WordPress.OSUser
s.WordPress.IgnoreInactive = v.WordPress.IgnoreInactive
s.LogMsgAnsiColor = Colors[i%len(Colors)]
i++
@@ -292,5 +290,19 @@ func toCpeURI(cpename string) (string, error) {
}
return naming.BindToURI(wfn), nil
}
return "", fmt.Errorf("Unknow CPE format: %s", cpename)
return "", xerrors.Errorf("Unknow CPE format: %s", cpename)
}
// IsValidImage checks a container configuration
func IsValidImage(c Image) error {
if c.Name == "" {
return xerrors.New("Invalid arguments : no image name")
}
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
}

View File

@@ -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)
}
})
}
}

View File

@@ -2,12 +2,13 @@ package parser
import (
"encoding/xml"
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/knqyf263/go-cpe/naming"
log "github.com/sirupsen/logrus"
"golang.org/x/xerrors"
)
type analysis struct {
@@ -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 {
@@ -49,17 +49,22 @@ func Parse(path string) ([]string, error) {
var anal analysis
if err := xml.Unmarshal(b, &anal); err != nil {
return nil, fmt.Errorf("Failed to unmarshal: %s", err)
return nil, xerrors.Errorf("Failed to unmarshal: %s", err)
}
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
View 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
View 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/"

27
errof/errof.go Normal file
View File

@@ -0,0 +1,27 @@
package errof
// ErrorCode is vuls error code
type ErrorCode string
// Error is vuls error
type Error struct {
Code ErrorCode
Message string
}
func (e Error) Error() string {
return e.Message
}
var (
// ErrFailedToAccessGithubAPI is error of github alert's api access
ErrFailedToAccessGithubAPI ErrorCode = "ErrFailedToAccessGithubAPI"
)
// New :
func New(code ErrorCode, msg string) Error {
return Error{
Code: code,
Message: msg,
}
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Architect, Inc. Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package exploit
import (
@@ -28,6 +11,7 @@ import (
"github.com/mozqnet/go-exploitdb/db"
exploitmodels "github.com/mozqnet/go-exploitdb/models"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
// FillWithExploit fills exploit information that has in Exploit
@@ -60,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
@@ -112,8 +99,7 @@ func CheckHTTPHealth() error {
// 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 fmt.Errorf("Failed to connect to exploit server. url: %s, errs: %v",
url, errs)
return xerrors.Errorf("Failed to connect to exploit server. url: %s, errs: %w", url, errs)
}
return nil
}

View File

@@ -1,8 +0,0 @@
package exploit
import (
"testing"
)
func TestSetPackageStates(t *testing.T) {
}

View File

@@ -1,30 +1,13 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Architect, Inc. Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package exploit
import (
"fmt"
"net/http"
"time"
"github.com/cenkalti/backoff"
"github.com/future-architect/vuls/util"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
type response struct {
@@ -79,11 +62,11 @@ func getCvesViaHTTP(cveIDs []string, urlPrefix string) (
case err := <-errChan:
errs = append(errs, err)
case <-timeout:
return nil, fmt.Errorf("Timeout Fetching OVAL")
return nil, xerrors.New("Timeout Fetching OVAL")
}
}
if len(errs) != 0 {
return nil, fmt.Errorf("Failed to fetch OVAL. err: %v", errs)
return nil, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
}
return
}
@@ -108,8 +91,7 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
if count == retryMax {
return nil
}
return fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
errs, url, resp)
return xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %w", url, resp, errs)
}
return nil
}
@@ -118,11 +100,11 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
}
err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
if err != nil {
errChan <- fmt.Errorf("HTTP Error %s", err)
errChan <- xerrors.Errorf("HTTP Error %w", err)
return
}
if count == retryMax {
errChan <- fmt.Errorf("HRetry count exceeded")
errChan <- xerrors.New("Retry count exceeded")
return
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package github
import (
@@ -26,6 +9,7 @@ import (
"time"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/errof"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/k0kubun/pp"
@@ -73,6 +57,12 @@ func FillGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string) (
}
util.Log.Debugf("%s", pp.Sprint(alerts))
if alerts.Data.Repository.URL == "" {
return 0, errof.New(
errof.ErrFailedToAccessGithubAPI,
fmt.Sprintf("Failed to access to GitHub API. Response: %#v", alerts),
)
}
for _, v := range alerts.Data.Repository.VulnerabilityAlerts.Edges {
if config.Conf.IgnoreGitHubDismissed && v.Node.DismissReason != "" {

56
go.mod Normal file
View File

@@ -0,0 +1,56 @@
module github.com/future-architect/vuls
go 1.13
replace (
github.com/genuinetools/reg => github.com/tomoyamachi/reg v0.16.1-0.20190706172545-2a2250fd7c00
gopkg.in/mattn/go-colorable.v0 => github.com/mattn/go-colorable v0.1.0
gopkg.in/mattn/go-isatty.v0 => github.com/mattn/go-isatty v0.0.6
)
require (
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-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.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-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-20190910152052-7cb4b85ec19c
github.com/jroimartin/gocui v0.4.0
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.1
github.com/kotakanbe/go-pingscanner v0.1.0
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-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
github.com/parnurzeal/gorequest v0.2.15
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
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-20190911031432-227b76d455e7
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
)

577
go.sum Normal file
View File

@@ -0,0 +1,577 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
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.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=
github.com/Azure/go-autorest/autorest v0.9.1 h1:JB7Mqhna/7J8gZfVHjxDSTLSD6ciz2YgSMb/4qLXTtY=
github.com/Azure/go-autorest/autorest v0.9.1/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8=
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0 h1:wykTgKwhVr2t2qs+xI020s6W5dt614QqCHV+7W9dg64=
github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs=
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
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=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
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=
github.com/aquasecurity/trivy v0.1.6/go.mod h1:5hobyhxLzDtxruHzPxpND2PUKOssvGUdE9BocpJUwo4=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
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.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=
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/briandowns/spinner v0.0.0-20190319032542-ac46072a5a91 h1:GMmnK0dvr0Sf0gx3DvTbln0c8DE07B7sPVD9dgHOqo4=
github.com/briandowns/spinner v0.0.0-20190319032542-ac46072a5a91/go.mod h1:hw/JEQBIE+c/BLI4aKM8UU8v+ZqrD3h7HC27kKt8JQU=
github.com/caarlos0/env/v6 v6.0.0 h1:NZt6FAoB8ieKO5lEwRdwCzYxWFx7ZYF2R7UcoyaWtyc=
github.com/caarlos0/env/v6 v6.0.0/go.mod h1:+wdyOmtjoZIW2GJOc2OYa5NoOFuWD/bIpWqm30NgtRk=
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cheggaaa/pb v2.0.7+incompatible h1:gLKifR1UkZ/kLkda5gC0K6c8g+jU2sINPtBeOiNlMhU=
github.com/cheggaaa/pb v2.0.7+incompatible/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/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=
github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/cli v0.0.0-20180920165730-54c19e67f69c h1:QlAVcyoF7QQVN7zV+xYBjgwtRVlRU3WCTCpb2mcqQrM=
github.com/docker/cli v0.0.0-20180920165730-54c19e67f69c/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.0.0-20180924202107-a9c061deec0f h1:W4fbqg0JUwy6lLesoJaV/rE0fwAmtdtinMa64X1CEh0=
github.com/docker/docker v0.0.0-20180924202107-a9c061deec0f/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-ce v0.0.0-20180924210327-f53bd8bb8e43 h1:gZ4lWixV821UVbYtr+oz1ZPCHkbtE+ivfmHyZRgyl2Y=
github.com/docker/docker-ce v0.0.0-20180924210327-f53bd8bb8e43/go.mod h1:l1FUGRYBvbjnZ8MS6A2xOji4aZFlY/Qmgz7p4oXH7ac=
github.com/docker/docker-credential-helpers v0.6.2 h1:CrW9H1VMf3a4GrtyAi7IUJjkJVpwBBpX0+mvkvYJaus=
github.com/docker/docker-credential-helpers v0.6.2/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/go-connections v0.0.0-20180821093606-97c2040d34df/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 h1:X0fj836zx99zFu83v/M79DuBn84IL/Syx1SY6Y5ZEMA=
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
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-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=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/etcd-io/bbolt v1.3.2 h1:RLRQ0TKLX7DlBRXAJHvbmXL17Q3KNnTBtZ9B6Qo+/Y0=
github.com/etcd-io/bbolt v1.3.2/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
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=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/genuinetools/pkg v0.0.0-20181022210355-2fcf164d37cb/go.mod h1:XTcrCYlXPxnxL2UpnwuRn7tcaTn9HAhxFoFJucootk8=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/gliderlabs/ssh v0.1.3 h1:cBU46h1lYQk5f2Z+jZbewFKy+1zzE2aUX/ilcPDAm9M=
github.com/gliderlabs/ssh v0.1.3/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
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/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=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
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/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=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k=
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
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 v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.1 h1:Dw4jY2nghMMRsh1ol8dv1axHkDwMQK2DHerMNJsIpJU=
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gosuri/uitable v0.0.3 h1:9ZY4qCODg6JL1Ui4dL9LqCF4ghWnAOSV2h7xG98SkHE=
github.com/gosuri/uitable v0.0.3/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
github.com/grokify/html-strip-tags-go v0.0.0-20190424092004-025bd760b278 h1:DZo48DQFIDo/YWjUeFip1dfJztBhRuaxfUnPd+gAfcs=
github.com/grokify/html-strip-tags-go v0.0.0-20190424092004-025bd760b278/go.mod h1:Xk7G0nwBiIloTMbLddk4WWJOqi4i/JLhadLd0HUXO30=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
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-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=
github.com/htcat/htcat v1.0.2/go.mod h1:i8ViQbjSi2+lJzM6Lx20FIxHENCz6mzJglK3HH06W3s=
github.com/inconshreveable/log15 v0.0.0-20180818164646-67afb5ed74ec h1:CGkYB1Q7DSsH/ku+to+foV4agt2F2miquaLUgF6L178=
github.com/inconshreveable/log15 v0.0.0-20180818164646-67afb5ed74ec/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/gorm v1.9.10 h1:HvrsqdhCW78xpJF67g1hMxS6eCToo9PZH4LDB8WKPac=
github.com/jinzhu/gorm v1.9.10/go.mod h1:Kh6hTsSGffh4ui079FHrR5Gg+5D0hgihqDcsDN2BBJY=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jroimartin/gocui v0.4.0 h1:52jnalstgmc25FmtGcWqa0tcbMEWS6RpFLsOIO+I+E8=
github.com/jroimartin/gocui v0.4.0/go.mod h1:7i7bbj99OgFHzo7kB2zPb8pXLqMBSQegY7azfqXMkyY=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8=
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/knqyf263/berkeleydb v0.0.0-20190501065933-fafe01fb9662/go.mod h1:bu1CcN4tUtoRcI/B/RFHhxMNKFHVq/c3SV+UTyduoXg=
github.com/knqyf263/go-cpe v0.0.0-20180327054844-659663f6eca2 h1:9CYbtr3i56D/rD6u6jJ/Aocsic9G+MupyVu7gb+QHF4=
github.com/knqyf263/go-cpe v0.0.0-20180327054844-659663f6eca2/go.mod h1:XM58Cg7dN+g0J9UPVmKjiXWlGi55lx+9IMs0IMoFWQo=
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d h1:X4cedH4Kn3JPupAwwWuo4AzYp16P0OyLO9d7OnMZc/c=
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d/go.mod h1:o8sgWoz3JADecfc/cTYD92/Et1yMqMy0utV1z+VaZao=
github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936 h1:HDjRqotkViMNcGMGicb7cgxklx8OwnjtCBmyWEqrRvM=
github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936/go.mod h1:i4sF0l1fFnY1aiw08QQSwVAFxHEm311Me3WsU/X7nL0=
github.com/knqyf263/go-rpmdb v0.0.0-20190501070121-10a1c42a10dc/go.mod h1:MrSSvdMpTSymaQWk1yFr9sxFSyQmKMj6jkbvGrchBV8=
github.com/knqyf263/go-version v1.1.1 h1:+MpcBC9b7rk5ihag8Y/FLG8get1H2GjniwKQ+9DxI2o=
github.com/knqyf263/go-version v1.1.1/go.mod h1:0tBvHvOBSf5TqGNcY+/ih9o8qo3R16iZCpB9rP0D3VM=
github.com/knqyf263/gost v0.1.2 h1:EQ8EB6QkRaLKgW426QmFPxzjMTiuPcqnz1n0duLUqfE=
github.com/knqyf263/gost v0.1.2/go.mod h1:c9z8ZoLxyxt5U8/ORyAUJY2GKjP1Pco5vbXOL3MrjJU=
github.com/knqyf263/nested v0.0.1 h1:Sv26CegUMhjt19zqbBKntjwESdxe5hxVPSk0+AKjdUc=
github.com/knqyf263/nested v0.0.1/go.mod h1:zwhsIhMkBg90DTOJQvxPkKIypEHPYkgWHs4gybdlUmk=
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.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.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=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
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/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
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=
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
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/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=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
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-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=
github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317 h1:hhGN4SFXgXo61Q4Sjj/X9sBjyeSa2kdpaOzCO+8EVQw=
github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
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/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
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=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/parnurzeal/gorequest v0.2.15 h1:oPjDCsF5IkD4gUk6vIgsxYNaSgvAnIh1EJeROn3HdJU=
github.com/parnurzeal/gorequest v0.2.15/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
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/peterhellberg/link v1.0.0 h1:mUWkiegowUXEcmlb+ybF75Q/8D2Y0BjZtR8cxoKhaQo=
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.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
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 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
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 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo=
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM=
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=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
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.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
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 v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
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/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=
github.com/tomoyamachi/reg v0.16.1-0.20190706172545-2a2250fd7c00/go.mod h1:RQE7h2jyIxekQZ24/wad0c9RGP+KSq4XzHh7h83ALi8=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
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/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 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
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-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=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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/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=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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/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=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
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/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=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/VividCortex/ewma.v1 v1.1.1 h1:tWHEKkKq802K/JT9RiqGCBU5fW3raAPnJGTE9ostZvg=
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/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=
gopkg.in/cheggaaa/pb.v2 v2.0.7/go.mod h1:0CiZ1p8pvtxBlQpLXkHuUTpdJ1shm3OqCF1QugkjHL4=
gopkg.in/fatih/color.v1 v1.7.0 h1:bYGjb+HezBM6j/QmgBfgm1adxHpzzrss6bj4r9ROppk=
gopkg.in/fatih/color.v1 v1.7.0/go.mod h1:P7yosIhqIl/sX8J8UypY5M+dDpD2KmyfP5IRs5v/fo0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/mattn/go-runewidth.v0 v0.0.4 h1:r0P71TnzQDlNIcizCqvPSSANoFa3WVGtcNJf3TWurcY=
gopkg.in/mattn/go-runewidth.v0 v0.0.4/go.mod h1:BmXejnxvhwdaATwiJbB1vZ2dtXkQKZGu9yLFCZb4msQ=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
gopkg.in/src-d/go-billy.v4 v4.3.0 h1:KtlZ4c1OWbIs4jCv5ZXrTqG8EQocr0g/d4DjNg70aek=
gopkg.in/src-d/go-billy.v4 v4.3.0/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
gopkg.in/src-d/go-git-fixtures.v3 v3.4.0 h1:KFpaNTUcLHLoP/OkdcRXR+MA5p55MhA41YVb7Wd8EfM=
gopkg.in/src-d/go-git-fixtures.v3 v3.4.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
gopkg.in/src-d/go-git.v4 v4.10.0 h1:NWjTJTQnk8UpIGlssuefyDZ6JruEjo5s88vm88uASbw=
gopkg.in/src-d/go-git.v4 v4.10.0/go.mod h1:Vtut8izDyrM8BUVQnzJ+YvmNcem2J89EmfZYCkLokZk=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

51
gost/base.go Normal file
View 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
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Architect, Inc. Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gost
import (
@@ -38,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) (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 == "" {
@@ -147,7 +130,7 @@ func (deb Debian) FillWithGost(driver db.DB, r *models.ScanResult) (nCVEs int, e
}
for _, name := range names {
v.AffectedPackages = v.AffectedPackages.Store(models.PackageStatus{
v.AffectedPackages = v.AffectedPackages.Store(models.PackageFixStatus{
Name: name,
FixState: "open",
NotFixedYet: true,

View File

@@ -1,36 +1,15 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Architect, Inc. Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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"
)
// Client is the interface of OVAL client.
type Client interface {
FillWithGost(db.DB, *models.ScanResult) (int, error)
DetectUnfixed(db.DB, *models.ScanResult, bool) (int, error)
FillCVEsWithRedHat(db.DB, *models.ScanResult) error
//TODO implement
// CheckHTTPHealth() error
@@ -52,53 +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 fmt.Errorf("Failed to connect to gost server. url: %s, errs: %v",
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) (int, error) {
return 0, nil
}
func major(osVer string) (majorVersion string) {
return strings.Split(osVer, ".")[0]
}

View File

@@ -14,7 +14,7 @@ func TestSetPackageStates(t *testing.T) {
installed models.Packages
release string
in models.VulnInfo
out models.PackageStatuses
out models.PackageFixStatuses
}{
//0 one
@@ -31,7 +31,7 @@ func TestSetPackageStates(t *testing.T) {
},
release: "7",
in: models.VulnInfo{},
out: []models.PackageStatus{
out: []models.PackageFixStatus{
{
Name: "bouncycastle",
FixState: "Will not fix",
@@ -66,7 +66,7 @@ func TestSetPackageStates(t *testing.T) {
},
release: "7",
in: models.VulnInfo{},
out: []models.PackageStatus{
out: []models.PackageFixStatus{
{
Name: "bouncycastle",
FixState: "Will not fix",
@@ -94,9 +94,9 @@ func TestSetPackageStates(t *testing.T) {
},
release: "7",
in: models.VulnInfo{
AffectedPackages: models.PackageStatuses{},
AffectedPackages: models.PackageFixStatuses{},
},
out: models.PackageStatuses{},
out: models.PackageFixStatuses{},
},
//3 look only the same os release.
@@ -113,9 +113,9 @@ func TestSetPackageStates(t *testing.T) {
},
release: "7",
in: models.VulnInfo{
AffectedPackages: models.PackageStatuses{},
AffectedPackages: models.PackageFixStatuses{},
},
out: models.PackageStatuses{},
out: models.PackageFixStatuses{},
},
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gost
import (
@@ -30,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) (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
View 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]
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Architect, Inc. Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gost
import (
@@ -34,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) (nCVEs int, err error) {
if nCVEs, err = red.fillUnfixed(driver, r); 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 {
@@ -88,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)
@@ -113,7 +93,7 @@ func (red RedHat) fillFixed(driver db.DB, r *models.ScanResult) error {
return nil
}
func (red RedHat) fillUnfixed(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
func (red RedHat) fillUnfixed(driver db.DB, r *models.ScanResult, ignoreWillNotFix bool) (nCVEs int, err error) {
if config.Conf.Gost.IsFetchViaHTTP() {
prefix, _ := util.URLPathJoin(config.Conf.Gost.URL,
"redhat", major(r.Release), "pkgs")
@@ -160,7 +140,7 @@ func (red RedHat) fillUnfixed(driver db.DB, r *models.ScanResult) (nCVEs int, er
for _, pack := range r.Packages {
// CVE-ID: RedhatCVE
cves := map[string]gostmodels.RedhatCVE{}
cves = driver.GetUnfixedCvesRedhat(major(r.Release), pack.Name)
cves = driver.GetUnfixedCvesRedhat(major(r.Release), pack.Name, ignoreWillNotFix)
for _, cve := range cves {
cveCont := red.ConvertToModel(&cve)
v, ok := r.ScannedCves[cve.Name]
@@ -191,7 +171,7 @@ func (red RedHat) fillUnfixed(driver db.DB, r *models.ScanResult) (nCVEs int, er
return nCVEs, nil
}
func (red RedHat) mergePackageStates(v models.VulnInfo, ps []gostmodels.RedhatPackageState, installed models.Packages, release string) (pkgStats models.PackageStatuses) {
func (red RedHat) mergePackageStates(v models.VulnInfo, ps []gostmodels.RedhatPackageState, installed models.Packages, release string) (pkgStats models.PackageFixStatuses) {
pkgStats = v.AffectedPackages
for _, pstate := range ps {
if pstate.Cpe !=
@@ -200,7 +180,8 @@ func (red RedHat) mergePackageStates(v models.VulnInfo, ps []gostmodels.RedhatPa
}
if !(pstate.FixState == "Will not fix" ||
pstate.FixState == "Fix deferred") {
pstate.FixState == "Fix deferred" ||
pstate.FixState == "Affected") {
return
}
@@ -210,11 +191,11 @@ func (red RedHat) mergePackageStates(v models.VulnInfo, ps []gostmodels.RedhatPa
notFixedYet := false
switch pstate.FixState {
case "Will not fix", "Fix deferred":
case "Will not fix", "Fix deferred", "Affected":
notFixedYet = true
}
pkgStats = pkgStats.Store(models.PackageStatus{
pkgStats = pkgStats.Store(models.PackageFixStatus{
Name: pstate.PackageName,
FixState: pstate.FixState,
NotFixedYet: notFixedYet,

View File

@@ -1,24 +1,6 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Architect, Inc. Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gost
import (
"fmt"
"net/http"
"time"
@@ -26,6 +8,7 @@ import (
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
type response struct {
@@ -80,11 +63,11 @@ func getCvesViaHTTP(cveIDs []string, urlPrefix string) (
case err := <-errChan:
errs = append(errs, err)
case <-timeout:
return nil, fmt.Errorf("Timeout Fetching OVAL")
return nil, xerrors.New("Timeout Fetching OVAL")
}
}
if len(errs) != 0 {
return nil, fmt.Errorf("Failed to fetch OVAL. err: %v", errs)
return nil, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
}
return
}
@@ -154,11 +137,11 @@ func getAllUnfixedCvesViaHTTP(r *models.ScanResult, urlPrefix string) (
case err := <-errChan:
errs = append(errs, err)
case <-timeout:
return nil, fmt.Errorf("Timeout Fetching OVAL")
return nil, xerrors.New("Timeout Fetching OVAL")
}
}
if len(errs) != 0 {
return nil, fmt.Errorf("Failed to fetch OVAL. err: %v", errs)
return nil, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
}
return
}
@@ -176,8 +159,7 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
if count == retryMax {
return nil
}
return fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
errs, url, resp)
return xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %w", url, resp, errs)
}
return nil
}
@@ -186,11 +168,11 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
}
err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
if err != nil {
errChan <- fmt.Errorf("HTTP Error %s", err)
errChan <- xerrors.Errorf("HTTP Error %w", err)
return
}
if count == retryMax {
errChan <- fmt.Errorf("HRetry count exceeded")
errChan <- xerrors.New("Retry count exceeded")
return
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 297 KiB

33
libmanager/libManager.go Normal file
View File

@@ -0,0 +1,33 @@
package libmanager
import (
"github.com/aquasecurity/trivy/pkg/db"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/future-architect/vuls/models"
)
// FillLibrary fills LibraryScanner informations
func FillLibrary(r *models.ScanResult) (totalCnt int, err error) {
// initialize trivy's logger and db
err = log.InitLogger(false, false)
if err != nil {
return 0, err
}
if err := db.Init(); err != nil {
return 0, err
}
for _, lib := range r.LibraryScanners {
vinfos, err := lib.Scan()
if err != nil {
return 0, err
}
for _, vinfo := range vinfos {
r.ScannedCves[vinfo.CveID] = vinfo
}
totalCnt += len(vinfos)
}
db.Close()
return totalCnt, nil
}

17
main.go
View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
import (

View File

@@ -1,24 +1,9 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
import (
"time"
"github.com/aquasecurity/trivy/pkg/vulnsrc/vulnerability"
)
// CveContents has CveContent
@@ -68,6 +53,9 @@ func (v CveContents) SourceLinks(lang, myFamily, cveID string) (values []CveCont
order := CveContentTypes{Nvd, NvdXML, NewCveContentType(myFamily)}
for _, ctype := range order {
if cont, found := v[ctype]; found {
if cont.SourceLink == "" {
continue
}
values = append(values, CveContentStr{ctype, cont.SourceLink})
}
}
@@ -108,7 +96,7 @@ type CveContentCpes struct {
// Cpes returns affected CPEs of this Vulnerability
func (v CveContents) Cpes(myFamily string) (values []CveContentCpes) {
order := CveContentTypes{NewCveContentType(myFamily)}
order = append(order, AllCveContetTypes.Except(append(order)...)...)
order = append(order, AllCveContetTypes.Except(order...)...)
for _, ctype := range order {
if cont, found := v[ctype]; found && 0 < len(cont.Cpes) {
@@ -130,7 +118,7 @@ type CveContentRefs struct {
// References returns References
func (v CveContents) References(myFamily string) (values []CveContentRefs) {
order := CveContentTypes{NewCveContentType(myFamily)}
order = append(order, AllCveContetTypes.Except(append(order)...)...)
order = append(order, AllCveContetTypes.Except(order...)...)
for _, ctype := range order {
if cont, found := v[ctype]; found && 0 < len(cont.References) {
@@ -140,13 +128,14 @@ func (v CveContents) References(myFamily string) (values []CveContentRefs) {
})
}
}
return
}
// CweIDs returns related CweIDs of the vulnerability
func (v CveContents) CweIDs(myFamily string) (values []CveContentStr) {
order := CveContentTypes{NewCveContentType(myFamily)}
order = append(order, AllCveContetTypes.Except(append(order)...)...)
order = append(order, AllCveContetTypes.Except(order...)...)
for _, ctype := range order {
if cont, found := v[ctype]; found && 0 < len(cont.CweIDs) {
for _, cweID := range cont.CweIDs {
@@ -222,7 +211,7 @@ func NewCveContentType(name string) CveContentType {
return Oracle
case "ubuntu":
return Ubuntu
case "debian":
case "debian", vulnerability.DebianOVAL:
return Debian
case "redhat_api":
return RedHatAPI
@@ -230,6 +219,20 @@ func NewCveContentType(name string) CveContentType {
return DebianSecurityTracker
case "microsoft":
return Microsoft
case "wordpress":
return WPVulnDB
case "amazon":
return Amazon
case vulnerability.NodejsSecurityWg:
return NodeSec
case vulnerability.PythonSafetyDB:
return PythonSec
case vulnerability.RustSec:
return RustSec
case vulnerability.PhpSecurityAdvisories:
return PhpSec
case vulnerability.RubySec:
return RubySec
default:
return Unknown
}
@@ -263,12 +266,33 @@ const (
// Oracle is Oracle Linux
Oracle CveContentType = "oracle"
// Amazon is Amazon Linux
Amazon CveContentType = "amazon"
// SUSE is SUSE Linux
SUSE CveContentType = "suse"
// Microsoft is Microsoft
Microsoft CveContentType = "microsoft"
// WPVulnDB is WordPress
WPVulnDB CveContentType = "wpvulndb"
// NodeSec : for JS
NodeSec CveContentType = "node"
// PythonSec : for PHP
PythonSec CveContentType = "python"
// PhpSec : for PHP
PhpSec CveContentType = "php"
// RubySec : for Ruby
RubySec CveContentType = "ruby"
// RustSec : for Rust
RustSec CveContentType = "rust"
// Unknown is Unknown
Unknown CveContentType = "unknown"
)
@@ -282,10 +306,18 @@ var AllCveContetTypes = CveContentTypes{
NvdXML,
Jvn,
RedHat,
RedHatAPI,
Debian,
Ubuntu,
RedHatAPI,
Amazon,
SUSE,
DebianSecurityTracker,
WPVulnDB,
NodeSec,
PythonSec,
PhpSec,
RubySec,
RustSec,
}
// Except returns CveContentTypes except for given args

View File

@@ -1,19 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
import (

141
models/library.go Normal file
View File

@@ -0,0 +1,141 @@
package models
import (
"path/filepath"
"github.com/aquasecurity/trivy/pkg/scanner/library"
"github.com/aquasecurity/trivy/pkg/vulnsrc/vulnerability"
"github.com/future-architect/vuls/util"
"golang.org/x/xerrors"
"github.com/aquasecurity/go-dep-parser/pkg/types"
"github.com/knqyf263/go-version"
)
// LibraryScanner has libraries information
type LibraryScanner struct {
Path string
Libs []types.Library
}
// Scan : scan target library
func (s LibraryScanner) Scan() ([]VulnInfo, error) {
scanner := library.NewScanner(filepath.Base(string(s.Path)))
if scanner == nil {
return nil, xerrors.New("unknown file type")
}
util.Log.Info("Updating library db...")
err := scanner.UpdateDB()
if err != nil {
return nil, xerrors.Errorf("failed to update %s advisories: %w", scanner.Type(), err)
}
var vulnerabilities []VulnInfo
for _, pkg := range s.Libs {
v, err := version.NewVersion(pkg.Version)
if err != nil {
util.Log.Debugf("new version cant detected %s@%s", pkg.Name, pkg.Version)
continue
}
tvulns, err := scanner.Detect(pkg.Name, v)
if err != nil {
return nil, xerrors.Errorf("failed to detect %s vulnerabilities: %w", scanner.Type(), err)
}
vulns := s.convertFanalToVuln(tvulns)
vulnerabilities = append(vulnerabilities, vulns...)
}
return vulnerabilities, nil
}
func (s LibraryScanner) convertFanalToVuln(tvulns []vulnerability.DetectedVulnerability) (vulns []VulnInfo) {
for _, tvuln := range tvulns {
vinfo, _ := s.getVulnDetail(tvuln)
vulns = append(vulns, vinfo)
}
return vulns
}
func (s LibraryScanner) getVulnDetail(tvuln vulnerability.DetectedVulnerability) (vinfo VulnInfo, err error) {
details, err := vulnerability.Get(tvuln.VulnerabilityID)
if err != nil {
return vinfo, err
} else if len(details) == 0 {
return vinfo, xerrors.Errorf("Unknown vulnID : %s", tvuln.VulnerabilityID)
}
vinfo.CveID = tvuln.VulnerabilityID
vinfo.CveContents = getCveContents(details)
if tvuln.FixedVersion != "" {
vinfo.LibraryFixedIns = []LibraryFixedIn{
{
Key: s.GetLibraryKey(),
Name: tvuln.PkgName,
FixedIn: tvuln.FixedVersion,
},
}
}
return vinfo, nil
}
func getCveContents(details map[string]vulnerability.Vulnerability) (contents map[CveContentType]CveContent) {
contents = map[CveContentType]CveContent{}
for source, detail := range details {
refs := []Reference{}
for _, refURL := range detail.References {
refs = append(refs, Reference{Source: refURL, Link: refURL})
}
content := CveContent{
Type: NewCveContentType(source),
CveID: detail.ID,
Title: detail.Title,
Summary: detail.Description,
Cvss3Score: detail.CvssScoreV3,
Cvss3Severity: string(detail.SeverityV3),
Cvss2Score: detail.CvssScore,
Cvss2Severity: string(detail.Severity),
References: refs,
//SourceLink string `json:"sourceLink"`
//Cvss2Vector string `json:"cvss2Vector"`
//Cvss3Vector string `json:"cvss3Vector"`
//Cvss3Severity string `json:"cvss3Severity"`
//Cpes []Cpe `json:"cpes,omitempty"`
//CweIDs []string `json:"cweIDs,omitempty"`
//Published time.Time `json:"published"`
//LastModified time.Time `json:"lastModified"`
//Mitigation string `json:"mitigation"` // RedHat API
//Optional map[string]string `json:"optional,omitempty"`
}
contents[NewCveContentType(source)] = content
}
return contents
}
// LibraryMap is filename and library type
var LibraryMap = map[string]string{
"package-lock.json": "node",
"yarn.lock": "node",
"Gemfile.lock": "ruby",
"Cargo.lock": "rust",
"composer.json": "php",
"Pipfile.lock": "python",
"poetry.lock": "python",
}
// GetLibraryKey returns target library key
func (s LibraryScanner) GetLibraryKey() string {
fileName := filepath.Base(s.Path)
return LibraryMap[fileName]
}
// LibraryFixedIn has library fixed information
type LibraryFixedIn struct {
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
FixedIn string `json:"fixedIn,omitempty"`
}

52
models/library_test.go Normal file
View File

@@ -0,0 +1,52 @@
package models
import (
"testing"
godeptypes "github.com/aquasecurity/go-dep-parser/pkg/types"
"github.com/aquasecurity/trivy/pkg/db"
"github.com/aquasecurity/trivy/pkg/log"
)
func TestScan(t *testing.T) {
var tests = []struct {
path string
pkgs []godeptypes.Library
}{
{
path: "app/package-lock.json",
pkgs: []godeptypes.Library{
{
Name: "jquery",
Version: "2.2.4",
},
{
Name: "@babel/traverse",
Version: "7.4.4",
},
},
},
}
if err := log.InitLogger(false, false); err != nil {
t.Errorf("trivy logger failed")
}
if err := db.Init(); err != nil {
t.Errorf("trivy db.Init failed")
}
for _, v := range tests {
lib := LibraryScanner{
Path: v.path,
Libs: v.pkgs,
}
actual, err := lib.Scan()
if err != nil {
t.Errorf("error occurred")
}
if len(actual) == 0 {
t.Errorf("no vuln found : actual: %v\n", actual)
}
}
db.Close()
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
// JSONVersion is JSON Version

View File

@@ -1,18 +0,0 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models

View File

@@ -1,26 +1,11 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
import (
"bytes"
"fmt"
"strings"
"golang.org/x/xerrors"
)
// Packages is Map of Package
@@ -83,7 +68,7 @@ func (ps Packages) FindByFQPN(nameVerRelArc string) (*Package, error) {
return &p, nil
}
}
return nil, fmt.Errorf("Failed to find the package: %s", nameVerRelArc)
return nil, xerrors.Errorf("Failed to find the package: %s", nameVerRelArc)
}
// Package has installed binary packages.
@@ -135,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
@@ -183,8 +173,9 @@ type Changelog struct {
// AffectedProcess keep a processes information affected by software update
type AffectedProcess struct {
PID string `json:"pid"`
Name string `json:"name"`
PID string `json:"pid,omitempty"`
Name string `json:"name,omitempty"`
ListenPorts []string `json:"listenPorts,omitempty"`
}
// NeedRestartProcess keep a processes information affected by software update
@@ -204,6 +195,7 @@ type NeedRestartProcess struct {
type SrcPackage struct {
Name string `json:"name"`
Version string `json:"version"`
Arch string `json:"arch"`
BinaryNames []string `json:"binaryNames"`
}

View File

@@ -1,19 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
import (
@@ -191,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)
}
})
}
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
import (
@@ -24,8 +7,6 @@ import (
"strings"
"time"
"github.com/future-architect/vuls/alert"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/cwe"
"github.com/future-architect/vuls/util"
@@ -36,35 +17,42 @@ type ScanResults []ScanResult
// ScanResult has the result of scanned CVE information.
type ScanResult struct {
JSONVersion int `json:"jsonVersion"`
Lang string `json:"lang"`
ServerUUID string `json:"serverUUID"`
ServerName string `json:"serverName"` // TOML Section key
Family string `json:"family"`
Release string `json:"release"`
Container Container `json:"container"`
Platform Platform `json:"platform"`
IPv4Addrs []string `json:"ipv4Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast)
IPv6Addrs []string `json:"ipv6Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast)
ScannedAt time.Time `json:"scannedAt"`
ScanMode string `json:"scanMode"`
ScannedVersion string `json:"scannedVersion"`
ScannedRevision string `json:"scannedRevision"`
ScannedBy string `json:"scannedBy"`
ScannedIPv4Addrs []string `json:"scannedIpv4Addrs"`
ScannedIPv6Addrs []string `json:"scannedIpv6Addrs"`
ReportedAt time.Time `json:"reportedAt"`
ReportedVersion string `json:"reportedVersion"`
ReportedRevision string `json:"reportedRevision"`
ReportedBy string `json:"reportedBy"`
ScannedCves VulnInfos `json:"scannedCves"`
RunningKernel Kernel `json:"runningKernel"`
Packages Packages `json:"packages"`
CweDict CweDict `json:"cweDict"`
Optional map[string]interface{} `json:",omitempty"`
SrcPackages SrcPackages `json:",omitempty"`
Errors []string `json:"errors"`
Config struct {
JSONVersion int `json:"jsonVersion"`
Lang string `json:"lang"`
ServerUUID string `json:"serverUUID"`
ServerName string `json:"serverName"` // TOML Section key
Family string `json:"family"`
Release string `json:"release"`
Container Container `json:"container"`
Image Image `json:"image"`
Platform Platform `json:"platform"`
IPv4Addrs []string `json:"ipv4Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast)
IPv6Addrs []string `json:"ipv6Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast)
IPSIdentifiers map[config.IPS]string `json:"ipsIdentifiers,omitempty"`
ScannedAt time.Time `json:"scannedAt"`
ScanMode string `json:"scanMode"`
ScannedVersion string `json:"scannedVersion"`
ScannedRevision string `json:"scannedRevision"`
ScannedBy string `json:"scannedBy"`
ScannedVia string `json:"scannedVia"`
ScannedIPv4Addrs []string `json:"scannedIpv4Addrs,omitempty"`
ScannedIPv6Addrs []string `json:"scannedIpv6Addrs,omitempty"`
ReportedAt time.Time `json:"reportedAt"`
ReportedVersion string `json:"reportedVersion"`
ReportedRevision string `json:"reportedRevision"`
ReportedBy string `json:"reportedBy"`
Errors []string `json:"errors"`
Warnings []string `json:"warnings"`
ScannedCves VulnInfos `json:"scannedCves"`
RunningKernel Kernel `json:"runningKernel"`
Packages Packages `json:"packages"`
SrcPackages SrcPackages `json:",omitempty"`
WordPressPackages *WordPressPackages `json:",omitempty"`
LibraryScanners []LibraryScanner `json:"libScanners"`
CweDict CweDict `json:"cweDict,omitempty"`
Optional map[string]interface{} `json:",omitempty"`
Config struct {
Scan config.Config `json:"scan"`
Report config.Config `json:"report"`
} `json:"config"`
@@ -74,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":
@@ -82,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)
@@ -96,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
@@ -106,15 +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"`
}
// GetAlertsByCveID return alerts fetched by cveID
func GetAlertsByCveID(cveID string, lang string) (alerts []alert.Alert) {
alerts = alert.GenerateAlertDict(cveID, lang)
return alerts
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
@@ -153,8 +153,6 @@ func (r ScanResult) FilterIgnoreCves() ScanResult {
if con, ok := s.Containers[r.Container.Name]; ok {
ignoreCves = con.IgnoreCves
} else {
util.Log.Errorf("%s is not found in config.toml",
r.Container.Name)
return r
}
} else {
@@ -182,6 +180,7 @@ func (r ScanResult) FilterUnfixed() ScanResult {
return r
}
filtered := r.ScannedCves.Find(func(v VulnInfo) bool {
// Report cves detected by CPE because Vuls can't know 'fixed' or 'unfixed'
if len(v.CpeURIs) != 0 {
return true
}
@@ -205,8 +204,6 @@ func (r ScanResult) FilterIgnorePkgs() ScanResult {
if con, ok := s.Containers[r.Container.Name]; ok {
ignorePkgsRegexps = con.IgnorePkgsRegexp
} else {
util.Log.Errorf("%s is not found in config.toml",
r.Container.Name)
return r
}
} else {
@@ -220,7 +217,7 @@ func (r ScanResult) FilterIgnorePkgs() ScanResult {
for _, pkgRegexp := range ignorePkgsRegexps {
re, err := regexp.Compile(pkgRegexp)
if err != nil {
util.Log.Errorf("Faild to parse %s, %s", pkgRegexp, err)
util.Log.Errorf("Faild to parse %s. err: %+v", pkgRegexp, err)
continue
} else {
regexps = append(regexps, re)
@@ -252,7 +249,31 @@ func (r ScanResult) FilterIgnorePkgs() ScanResult {
return r
}
// ReportFileName returns the filename on localhost without extention
// FilterInactiveWordPressLibs is filter function.
func (r ScanResult) FilterInactiveWordPressLibs() ScanResult {
if !config.Conf.Servers[r.ServerName].WordPress.IgnoreInactive {
return r
}
filtered := r.ScannedCves.Find(func(v VulnInfo) bool {
if len(v.WpPackageFixStats) == 0 {
return true
}
// Ignore if all libs in this vulnInfo inactive
for _, wp := range v.WpPackageFixStats {
if p, ok := r.WordPressPackages.Find(wp.Name); ok {
if p.Status != Inactive {
return true
}
}
}
return false
})
r.ScannedCves = filtered
return r
}
// 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)
@@ -260,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 {
@@ -289,6 +310,9 @@ func (r ScanResult) ServerInfoTui() string {
if len(r.Container.ContainerID) == 0 {
line := fmt.Sprintf("%s (%s%s)",
r.ServerName, r.Family, r.Release)
if len(r.Warnings) != 0 {
line = "[Warn] " + line
}
if r.RunningKernel.RebootRequired {
return "[Reboot] " + line
}
@@ -411,6 +435,11 @@ func (r ScanResult) IsContainer() bool {
return 0 < len(r.Container.ContainerID)
}
// IsImage returns whether this ServerInfo is about container
func (r ScanResult) IsImage() bool {
return 0 < len(r.Image.Name)
}
// IsDeepScanMode checks if the scan mode is deep scan mode.
func (r ScanResult) IsDeepScanMode() bool {
for _, s := range r.Config.Scan.Servers {
@@ -432,6 +461,13 @@ type Container struct {
UUID string `json:"uuid"`
}
// Image has Container information
type Image struct {
Name string `json:"name"`
Tag string `json:"tag"`
Digest string `json:"digest"`
}
// Platform has platform information
type Platform struct {
Name string `json:"name"` // aws or azure or gcp or other...

View File

@@ -1,19 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
import (
@@ -348,7 +332,7 @@ func TestFilterUnfixed(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0001": {
CveID: "CVE-2017-0001",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{
Name: "a",
NotFixedYet: true,
@@ -357,7 +341,7 @@ func TestFilterUnfixed(t *testing.T) {
},
"CVE-2017-0002": {
CveID: "CVE-2017-0002",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{
Name: "b",
NotFixedYet: false,
@@ -366,7 +350,7 @@ func TestFilterUnfixed(t *testing.T) {
},
"CVE-2017-0003": {
CveID: "CVE-2017-0003",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{
Name: "c",
NotFixedYet: true,
@@ -383,7 +367,7 @@ func TestFilterUnfixed(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0002": {
CveID: "CVE-2017-0002",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{
Name: "b",
NotFixedYet: false,
@@ -392,7 +376,7 @@ func TestFilterUnfixed(t *testing.T) {
},
"CVE-2017-0003": {
CveID: "CVE-2017-0003",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{
Name: "c",
NotFixedYet: true,
@@ -435,7 +419,7 @@ func TestFilterIgnorePkgs(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0001": {
CveID: "CVE-2017-0001",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{Name: "kernel"},
},
},
@@ -462,7 +446,7 @@ func TestFilterIgnorePkgs(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0001": {
CveID: "CVE-2017-0001",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{Name: "kernel"},
{Name: "vim"},
},
@@ -475,7 +459,7 @@ func TestFilterIgnorePkgs(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0001": {
CveID: "CVE-2017-0001",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{Name: "kernel"},
{Name: "vim"},
},
@@ -491,7 +475,7 @@ func TestFilterIgnorePkgs(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0001": {
CveID: "CVE-2017-0001",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{Name: "kernel"},
{Name: "vim"},
},
@@ -545,7 +529,7 @@ func TestFilterIgnorePkgsContainer(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0001": {
CveID: "CVE-2017-0001",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{Name: "kernel"},
},
},
@@ -574,7 +558,7 @@ func TestFilterIgnorePkgsContainer(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0001": {
CveID: "CVE-2017-0001",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{Name: "kernel"},
{Name: "vim"},
},
@@ -588,7 +572,7 @@ func TestFilterIgnorePkgsContainer(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0001": {
CveID: "CVE-2017-0001",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{Name: "kernel"},
{Name: "vim"},
},
@@ -605,7 +589,7 @@ func TestFilterIgnorePkgsContainer(t *testing.T) {
ScannedCves: VulnInfos{
"CVE-2017-0001": {
CveID: "CVE-2017-0001",
AffectedPackages: PackageStatuses{
AffectedPackages: PackageFixStatuses{
{Name: "kernel"},
{Name: "vim"},
},

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
import (

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
import (
@@ -24,8 +7,6 @@ import (
"strings"
"time"
"github.com/future-architect/vuls/alert"
"github.com/future-architect/vuls/config"
exploitmodels "github.com/mozqnet/go-exploitdb/models"
)
@@ -115,27 +96,26 @@ func (v VulnInfos) FormatFixedStatus(packs Packages) string {
continue
}
total++
if vInfo.PatchStatus(packs) == "Fixed" {
if vInfo.PatchStatus(packs) == "fixed" {
fixed++
}
}
return fmt.Sprintf("%d/%d Fixed", fixed, total)
}
// PackageStatuses is a list of PackageStatus
type PackageStatuses []PackageStatus
// PackageFixStatuses is a list of PackageStatus
type PackageFixStatuses []PackageFixStatus
// FormatTuiSummary format packname to show TUI summary
func (ps PackageStatuses) FormatTuiSummary() string {
names := []string{}
// Names return a slice of package names
func (ps PackageFixStatuses) Names() (names []string) {
for _, p := range ps {
names = append(names, p.Name)
}
return strings.Join(names, ", ")
return names
}
// Store insert given pkg if missing, update pkg if exists
func (ps PackageStatuses) Store(pkg PackageStatus) PackageStatuses {
func (ps PackageFixStatuses) Store(pkg PackageFixStatus) PackageFixStatuses {
for i, p := range ps {
if p.Name == pkg.Name {
ps[i] = pkg
@@ -147,38 +127,49 @@ func (ps PackageStatuses) Store(pkg PackageStatus) PackageStatuses {
}
// Sort by Name
func (ps PackageStatuses) Sort() {
func (ps PackageFixStatuses) Sort() {
sort.Slice(ps, func(i, j int) bool {
return ps[i].Name < ps[j].Name
})
return
}
// PackageStatus has name and other status abount the package
type PackageStatus struct {
Name string `json:"name"`
NotFixedYet bool `json:"notFixedYet"`
FixState string `json:"fixState"`
// PackageFixStatus has name and other status abount the package
type PackageFixStatus struct {
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
type VulnInfo struct {
CveID string `json:"cveID,omitempty"`
Confidences Confidences `json:"confidences,omitempty"`
AffectedPackages PackageStatuses `json:"affectedPackages,omitempty"`
DistroAdvisories []DistroAdvisory `json:"distroAdvisories,omitempty"` // for Aamazon, RHEL, FreeBSD
CveContents CveContents `json:"cveContents,omitempty"`
Exploits []Exploit `json:"exploits,omitempty"`
AlertDict AlertDict `json:"alertDict,omitempty"`
CveID string `json:"cveID,omitempty"`
Confidences Confidences `json:"confidences,omitempty"`
AffectedPackages PackageFixStatuses `json:"affectedPackages,omitempty"`
DistroAdvisories DistroAdvisories `json:"distroAdvisories,omitempty"` // for Aamazon, RHEL, FreeBSD
CveContents CveContents `json:"cveContents,omitempty"`
Exploits []Exploit `json:"exploits,omitempty"`
AlertDict AlertDict `json:"alertDict,omitempty"`
CpeURIs []string `json:"cpeURIs,omitempty"` // CpeURIs related to this CVE defined in config.toml
GitHubSecurityAlerts GitHubSecurityAlerts `json:"gitHubSecurityAlerts,omitempty"`
WpPackageFixStats WpPackageFixStats `json:"wpPackageFixStats,omitempty"`
LibraryFixedIns LibraryFixedIns `json:"libraryFixedIns,omitempty"`
VulnType string `json:"vulnType,omitempty"`
}
// Alert has XCERT alert information
type Alert struct {
URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"`
Team string `json:"team,omitempty"`
}
// GitHubSecurityAlerts is a list of GitHubSecurityAlert
type GitHubSecurityAlerts []GitHubSecurityAlert
// Add adds given arg to the slice and return the slice (imutable)
// Add adds given arg to the slice and return the slice (immutable)
func (g GitHubSecurityAlerts) Add(alert GitHubSecurityAlert) GitHubSecurityAlerts {
for _, a := range g {
if a.PackageName == alert.PackageName {
@@ -188,12 +179,12 @@ func (g GitHubSecurityAlerts) Add(alert GitHubSecurityAlert) GitHubSecurityAlert
return append(g, alert)
}
func (g GitHubSecurityAlerts) String() string {
ss := []string{}
// Names return a slice of lib names
func (g GitHubSecurityAlerts) Names() (names []string) {
for _, a := range g {
ss = append(ss, a.PackageName)
names = append(names, a.PackageName)
}
return strings.Join(ss, ", ")
return names
}
// GitHubSecurityAlert has detected CVE-ID, PackageName, Status fetched via GitHub API
@@ -206,6 +197,33 @@ type GitHubSecurityAlert struct {
DismissReason string `json:"dismissReason"`
}
// LibraryFixedIns is a list of Library's FixedIn
type LibraryFixedIns []LibraryFixedIn
// WpPackageFixStats is a list of WpPackageFixStatus
type WpPackageFixStats []WpPackageFixStatus
// Names return a slice of names
func (ws WpPackageFixStats) Names() (names []string) {
for _, w := range ws {
names = append(names, w.Name)
}
return names
}
// WpPackages has a list of WpPackage
type WpPackages []WpPackage
// Add adds given arg to the slice and return the slice (immutable)
func (g WpPackages) Add(pkg WpPackage) WpPackages {
for _, a := range g {
if a.Name == pkg.Name {
return g
}
}
return append(g, pkg)
}
// Titles returns tilte (TUI)
func (v VulnInfo) Titles(lang, myFamily string) (values []CveContentStr) {
if lang == "ja" {
@@ -259,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) {
@@ -278,6 +296,13 @@ func (v VulnInfo) Summaries(lang, myFamily string) (values []CveContentStr) {
})
}
if v, ok := v.CveContents[WPVulnDB]; ok {
values = append(values, CveContentStr{
Type: "WPVDB",
Value: v.Title,
})
}
if len(values) == 0 {
return []CveContentStr{{
Type: Unknown,
@@ -317,7 +342,7 @@ func (v VulnInfo) Cvss2Scores(myFamily string) (values []CveContentCvss) {
}
for _, ctype := range order {
if cont, found := v.CveContents[ctype]; found {
if cont.Cvss2Score == 0 && cont.Cvss2Severity == "" {
if cont.Cvss2Score == 0 || cont.Cvss2Severity == "" {
continue
}
// https://nvd.nist.gov/vuln-metrics/cvss
@@ -510,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 "Network"
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 "Adjacent"
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 "Local"
} else if strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:P") {
return "Physical"
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 {
@@ -530,7 +556,7 @@ func (v VulnInfo) AttackVector() string {
return ""
}
// PatchStatus returns attack vector string
// PatchStatus returns fixed or unfixed string
func (v VulnInfo) PatchStatus(packs Packages) string {
// Vuls don't know patch status of the CPE
if len(v.CpeURIs) != 0 {
@@ -538,17 +564,24 @@ func (v VulnInfo) PatchStatus(packs Packages) string {
}
for _, p := range v.AffectedPackages {
if p.NotFixedYet {
return "Unfixed"
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 == "" {
return "Unknown"
return "unknown"
}
}
}
return "Fixed"
return "fixed"
}
// CveContentCvss has CVSS information
@@ -648,6 +681,12 @@ func (v VulnInfo) Cvss3CalcURL() string {
// VendorLinks returns links of vendor support's URL
func (v VulnInfo) VendorLinks(family string) map[string]string {
links := map[string]string{}
if strings.HasPrefix(v.CveID, "WPVDBID") {
links["WPVulnDB"] = fmt.Sprintf("https://wpvulndb.com/vulnerabilities/%s",
strings.TrimPrefix(v.CveID, "WPVDBID-"))
return links
}
switch family {
case config.RedHat, config.CentOS:
links["RHEL-CVE"] = "https://access.redhat.com/security/cve/" + v.CveID
@@ -666,8 +705,14 @@ func (v VulnInfo) VendorLinks(family string) map[string]string {
case config.Amazon:
links["RHEL-CVE"] = "https://access.redhat.com/security/cve/" + v.CveID
for _, advisory := range v.DistroAdvisories {
links[advisory.AdvisoryID] =
fmt.Sprintf("https://alas.aws.amazon.com/%s.html", advisory.AdvisoryID)
if strings.HasPrefix(advisory.AdvisoryID, "ALAS2") {
links[advisory.AdvisoryID] =
fmt.Sprintf("https://alas.aws.amazon.com/AL2/%s.html",
strings.Replace(advisory.AdvisoryID, "ALAS2", "ALAS", -1))
} else {
links[advisory.AdvisoryID] =
fmt.Sprintf("https://alas.aws.amazon.com/%s.html", advisory.AdvisoryID)
}
}
return links
case config.Ubuntu:
@@ -687,6 +732,20 @@ func (v VulnInfo) VendorLinks(family string) map[string]string {
return links
}
// DistroAdvisories is a list of DistroAdvisory
type DistroAdvisories []DistroAdvisory
// AppendIfMissing appends if missing
func (advs *DistroAdvisories) AppendIfMissing(adv *DistroAdvisory) bool {
for _, a := range *advs {
if a.AdvisoryID == adv.AdvisoryID {
return false
}
}
*advs = append(*advs, *adv)
return true
}
// DistroAdvisory has Amazon Linux, RHEL, FreeBSD Security Advisory information.
type DistroAdvisory struct {
AdvisoryID string `json:"advisoryID"`
@@ -723,13 +782,8 @@ type Exploit struct {
// AlertDict has target cve's JPCERT and USCERT alert data
type AlertDict struct {
Ja []alert.Alert `json:"ja"`
En []alert.Alert `json:"en"`
}
// HasAlert returns whether or not it has En or Ja entries.
func (a AlertDict) HasAlert() bool {
return len(a.En) != 0 || len(a.Ja) != 0
Ja []Alert `json:"ja"`
En []Alert `json:"en"`
}
// FormatSource returns which source has this alert
@@ -810,6 +864,9 @@ const (
// GitHubMatchStr is a String representation of GitHubMatch
GitHubMatchStr = "GitHubMatch"
// WPVulnDBMatchStr is a String representation of WordPress VulnDB scanning
WPVulnDBMatchStr = "WPVulnDBMatch"
// FailedToGetChangelog is a String representation of FailedToGetChangelog
FailedToGetChangelog = "FailedToGetChangelog"
@@ -844,4 +901,7 @@ var (
// GitHubMatch is a ranking how confident the CVE-ID was deteted correctly
GitHubMatch = Confidence{97, GitHubMatchStr, 2}
// WPVulnDBMatch is a ranking how confident the CVE-ID was deteted correctly
WPVulnDBMatch = Confidence{100, WPVulnDBMatchStr, 0}
)

View File

@@ -1,19 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package models
import (
@@ -159,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
@@ -193,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
@@ -916,15 +900,15 @@ func TestFormatMaxCvssScore(t *testing.T) {
func TestSortPackageStatues(t *testing.T) {
var tests = []struct {
in PackageStatuses
out PackageStatuses
in PackageFixStatuses
out PackageFixStatuses
}{
{
in: PackageStatuses{
in: PackageFixStatuses{
{Name: "b"},
{Name: "a"},
},
out: PackageStatuses{
out: PackageFixStatuses{
{Name: "a"},
{Name: "b"},
},
@@ -940,19 +924,19 @@ func TestSortPackageStatues(t *testing.T) {
func TestStorePackageStatueses(t *testing.T) {
var tests = []struct {
pkgstats PackageStatuses
in PackageStatus
out PackageStatuses
pkgstats PackageFixStatuses
in PackageFixStatus
out PackageFixStatuses
}{
{
pkgstats: PackageStatuses{
pkgstats: PackageFixStatuses{
{Name: "a"},
{Name: "b"},
},
in: PackageStatus{
in: PackageFixStatus{
Name: "c",
},
out: PackageStatuses{
out: PackageFixStatuses{
{Name: "a"},
{Name: "b"},
{Name: "c"},
@@ -1034,3 +1018,148 @@ func TestSortByConfiden(t *testing.T) {
}
}
}
func TestDistroAdvisories_AppendIfMissing(t *testing.T) {
type args struct {
adv *DistroAdvisory
}
tests := []struct {
name string
advs DistroAdvisories
args args
want bool
after DistroAdvisories
}{
{
name: "duplicate no append",
advs: DistroAdvisories{
DistroAdvisory{
AdvisoryID: "ALASs-2019-1214",
}},
args: args{
adv: &DistroAdvisory{
AdvisoryID: "ALASs-2019-1214",
},
},
want: false,
after: DistroAdvisories{
DistroAdvisory{
AdvisoryID: "ALASs-2019-1214",
}},
},
{
name: "append",
advs: DistroAdvisories{
DistroAdvisory{
AdvisoryID: "ALASs-2019-1214",
}},
args: args{
adv: &DistroAdvisory{
AdvisoryID: "ALASs-2019-1215",
},
},
want: true,
after: DistroAdvisories{
{
AdvisoryID: "ALASs-2019-1214",
},
{
AdvisoryID: "ALASs-2019-1215",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.advs.AppendIfMissing(tt.args.adv); got != tt.want {
t.Errorf("DistroAdvisories.AppendIfMissing() = %v, want %v", got, tt.want)
}
if !reflect.DeepEqual(tt.advs, tt.after) {
t.Errorf("\nexpected: %v\n actual: %v\n", tt.after, tt.advs)
}
})
}
}
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)
}
})
}
}

71
models/wordpress.go Normal file
View File

@@ -0,0 +1,71 @@
package models
// WordPressPackages has Core version, plugins and themes.
type WordPressPackages []WpPackage
// CoreVersion returns the core version of the installed WordPress
func (w WordPressPackages) CoreVersion() string {
for _, p := range w {
if p.Type == WPCore {
return p.Version
}
}
return ""
}
// Plugins returns a slice of plugins of the installed WordPress
func (w WordPressPackages) Plugins() (ps []WpPackage) {
for _, p := range w {
if p.Type == WPPlugin {
ps = append(ps, p)
}
}
return
}
// Themes returns a slice of themes of the installed WordPress
func (w WordPressPackages) Themes() (ps []WpPackage) {
for _, p := range w {
if p.Type == WPTheme {
ps = append(ps, p)
}
}
return
}
// Find searches by specified name
func (w WordPressPackages) Find(name string) (ps *WpPackage, found bool) {
for _, p := range w {
if p.Name == name {
return &p, true
}
}
return nil, false
}
const (
// WPCore is a type `core` in WPPackage struct
WPCore = "core"
// WPPlugin is a type `plugin` in WPPackage struct
WPPlugin = "plugin"
// WPTheme is a type `theme` in WPPackage struct
WPTheme = "theme"
// Inactive is a inactive status in WPPackage struct
Inactive = "inactive"
)
// WpPackage has a details of plugin and theme
type WpPackage struct {
Name string `json:"name,omitempty"`
Status string `json:"status,omitempty"` // active, inactive or must-use
Update string `json:"update,omitempty"` // available or none
Version string `json:"version,omitempty"`
Type string `json:"type,omitempty"` // core, plugin, theme
}
// WpPackageFixStatus is used in Vulninfo.WordPress
type WpPackageFixStatus struct {
Name string `json:"name,omitempty"`
FixedIn string `json:"fixedIn,omitempty"`
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package oval
import (

View File

@@ -1,23 +1,9 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package oval
import (
"fmt"
"strings"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
@@ -57,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,
}
}
}
}
@@ -93,6 +90,7 @@ func (o DebianBase) convertToModel(def *ovalmodels.Definition) *models.CveConten
Title: def.Title,
Summary: def.Description,
Cvss2Severity: def.Advisory.Severity,
Cvss3Severity: def.Advisory.Severity,
References: refs,
}
}
@@ -148,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
@@ -189,55 +187,177 @@ func NewUbuntu() Ubuntu {
// FillWithOval returns scan result after updating CVE info by OVAL
func (o Ubuntu) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
ovalKernelImageNames := []string{
"linux-aws",
"linux-azure",
"linux-flo",
"linux-gcp",
"linux-gke",
"linux-goldfish",
"linux-hwe",
"linux-hwe-edge",
"linux-kvm",
"linux-mako",
"linux-raspi2",
"linux-snapdragon",
switch major(r.Release) {
case "14":
kernelNamesInOval := []string{
"linux-aws",
"linux-azure",
"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-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-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)
}
linuxImage := "linux-image-" + r.RunningKernel.Release
return 0, fmt.Errorf("Ubuntu %s is not support for now", r.Release)
}
func (o Ubuntu) fillWithOval(driver db.DB, r *models.ScanResult, kernelNamesInOval []string) (nCVEs int, err error) {
linuxImage := "linux-image-" + r.RunningKernel.Release
runningKernelVersion := ""
kernelPkgInOVAL := ""
isOVALKernelPkgAdded := false
unusedKernels := []models.Package{}
copiedSourcePkgs := models.SrcPackages{}
found := false
if r.Container.ContainerID == "" {
for _, n := range ovalKernelImageNames {
if _, ok := r.Packages[n]; ok {
v, ok := r.Packages[linuxImage]
if ok {
// Set running kernel version
p := r.Packages[n]
p.Version = v.Version
p.NewVersion = v.NewVersion
r.Packages[n] = p
} else {
util.Log.Warnf("Running kernel image %s is not found: %s",
linuxImage, r.RunningKernel.Version)
}
found = true
if v, ok := r.Packages[linuxImage]; ok {
runningKernelVersion = v.Version
} else {
util.Log.Warnf("Unable to detect vulns of running kernel because the version of the runnning kernel is unknown. server: %s",
r.ServerName)
}
for _, n := range kernelNamesInOval {
if p, ok := r.Packages[n]; ok {
kernelPkgInOVAL = p.Name
break
}
}
if !found {
// linux-generic is described as "linux" in Ubuntu's oval.
// Add "linux" and set the version of running kernel to search OVAL.
v, ok := r.Packages[linuxImage]
if ok {
r.Packages["linux"] = models.Package{
Name: "linux",
Version: v.Version,
NewVersion: v.NewVersion,
// remove unused kernels from packages to prevent detecting vulns of unused kernel
for _, n := range kernelNamesInOval {
if v, ok := r.Packages[n]; ok {
unusedKernels = append(unusedKernels, v)
delete(r.Packages, n)
}
}
// 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)
}
} else {
util.Log.Warnf("%s is not found. Running: %s",
linuxImage, r.RunningKernel.Release)
}
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{
Name: kernelPkgInOVAL,
Version: runningKernelVersion,
}
}
}
@@ -253,24 +373,27 @@ func (o Ubuntu) FillWithOval(driver db.DB, r *models.ScanResult) (nCVEs int, err
}
}
if !found {
delete(r.Packages, "linux")
if isOVALKernelPkgAdded {
delete(r.Packages, kernelPkgInOVAL)
}
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 _, ok := defPacks.actuallyAffectedPackNames["linux"]; !found && ok {
defPacks.actuallyAffectedPackNames[linuxImage] = true
delete(defPacks.actuallyAffectedPackNames, "linux")
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 == "linux" {
if p.Name == kernelPkgInOVAL {
p.Name = linuxImage
defPacks.def.AffectedPacks[i] = p
}
}
}
o.update(r, defPacks)
}

View File

@@ -1,19 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package oval
import (
@@ -36,7 +20,7 @@ func TestPackNamesOfUpdateDebian(t *testing.T) {
in: models.ScanResult{
ScannedCves: models.VulnInfos{
"CVE-2000-1000": models.VulnInfo{
AffectedPackages: models.PackageStatuses{
AffectedPackages: models.PackageFixStatuses{
{Name: "packA"},
{Name: "packC"},
},
@@ -49,16 +33,19 @@ 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{
ScannedCves: models.VulnInfos{
"CVE-2000-1000": models.VulnInfo{
AffectedPackages: models.PackageStatuses{
AffectedPackages: models.PackageFixStatuses{
{Name: "packA"},
{Name: "packB", NotFixedYet: true},
{Name: "packB", NotFixedYet: true, FixedIn: "1.0.0"},
{Name: "packC"},
},
},
@@ -73,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)
}
}
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package oval
import (
@@ -28,6 +11,7 @@ import (
"github.com/future-architect/vuls/util"
"github.com/kotakanbe/goval-dictionary/db"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
// Client is the interface of OVAL client.
@@ -58,7 +42,7 @@ func (b Base) CheckHTTPHealth() error {
// 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 fmt.Errorf("Failed to request to OVAL server. url: %s, errs: %v",
return xerrors.Errorf("Failed to request to OVAL server. url: %s, errs: %w",
url, errs)
}
return nil
@@ -69,8 +53,7 @@ func (b Base) CheckIfOvalFetched(driver db.DB, osFamily, release string) (fetche
if !cnf.Conf.OvalDict.IsFetchViaHTTP() {
count, err := driver.CountDefs(osFamily, release)
if err != nil {
return false, fmt.Errorf("Failed to count OVAL defs: %s, %s, %v",
osFamily, release, err)
return false, xerrors.Errorf("Failed to count OVAL defs: %s, %s, %w", osFamily, release, err)
}
return 0 < count, nil
}
@@ -78,13 +61,11 @@ func (b Base) CheckIfOvalFetched(driver db.DB, osFamily, release string) (fetche
url, _ := util.URLPathJoin(cnf.Conf.OvalDict.URL, "count", osFamily, release)
resp, body, errs := gorequest.New().Get(url).End()
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
return false, fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
errs, url, resp)
return false, xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %w", url, resp, errs)
}
count := 0
if err := json.Unmarshal([]byte(body), &count); err != nil {
return false, fmt.Errorf("Failed to Unmarshall. body: %s, err: %s",
body, err)
return false, xerrors.Errorf("Failed to Unmarshall. body: %s, err: %w", body, err)
}
return 0 < count, nil
}
@@ -98,13 +79,11 @@ func (b Base) CheckIfOvalFresh(driver db.DB, osFamily, release string) (ok bool,
url, _ := util.URLPathJoin(cnf.Conf.OvalDict.URL, "lastmodified", osFamily, release)
resp, body, errs := gorequest.New().Get(url).End()
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
return false, fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
errs, url, resp)
return false, xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %w", url, resp, errs)
}
if err := json.Unmarshal([]byte(body), &lastModified); err != nil {
return false, fmt.Errorf("Failed to Unmarshall. body: %s, err: %s",
body, err)
return false, xerrors.Errorf("Failed to Unmarshall. body: %s, err: %w", body, err)
}
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package oval
import (
@@ -119,7 +102,6 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int)
if v.LastModified.After(ovalContent.LastModified) {
util.Log.Debugf("%s, OvalID: %d ignroed: ",
cve.CveID, defPacks.def.ID)
continue
} else {
util.Log.Debugf("%s OVAL will be overwritten", cve.CveID)
}
@@ -133,12 +115,21 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int)
vinfo.CveContents = cveContents
}
vinfo.DistroAdvisories.AppendIfMissing(
o.convertToDistroAdvisory(&defPacks.def))
// 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()
@@ -148,6 +139,21 @@ func (o RedHatBase) update(r *models.ScanResult, defPacks defPacks) (nCVEs int)
return
}
func (o RedHatBase) convertToDistroAdvisory(def *ovalmodels.Definition) *models.DistroAdvisory {
advisoryID := def.Title
if (o.family == config.RedHat || o.family == config.CentOS) && len(advisoryID) > 0 {
ss := strings.Fields(def.Title)
advisoryID = strings.TrimSuffix(ss[0], ":")
}
return &models.DistroAdvisory{
AdvisoryID: advisoryID,
Severity: def.Advisory.Severity,
Issued: def.Advisory.Issued,
Updated: def.Advisory.Updated,
Description: def.Description,
}
}
func (o RedHatBase) convertToModel(cveID string, def *ovalmodels.Definition) *models.CveContent {
for _, cve := range def.Advisory.Cves {
if cve.CveID != cveID {
@@ -171,10 +177,10 @@ func (o RedHatBase) convertToModel(cveID string, def *ovalmodels.Definition) *mo
}
sev2, sev3 := "", ""
if score2 != 0 {
if score2 == 0 {
sev2 = severity
}
if score3 != 0 {
if score3 == 0 {
sev3 = severity
}
@@ -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, ""
}
@@ -276,3 +287,20 @@ func NewOracle() Oracle {
},
}
}
// Amazon is the interface for RedhatBase OVAL
type Amazon struct {
// Base
RedHatBase
}
// NewAmazon creates OVAL client for Amazon Linux
func NewAmazon() Amazon {
return Amazon{
RedHatBase{
Base{
family: config.Amazon,
},
},
}
}

View File

@@ -1,19 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package oval
import (
@@ -75,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{
@@ -102,7 +93,7 @@ func TestPackNamesOfUpdate(t *testing.T) {
in: models.ScanResult{
ScannedCves: models.VulnInfos{
"CVE-2000-1000": models.VulnInfo{
AffectedPackages: models.PackageStatuses{
AffectedPackages: models.PackageFixStatuses{
{Name: "packA"},
{Name: "packB", NotFixedYet: false},
},
@@ -119,14 +110,17 @@ 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{
ScannedCves: models.VulnInfos{
"CVE-2000-1000": models.VulnInfo{
AffectedPackages: models.PackageStatuses{
AffectedPackages: models.PackageFixStatuses{
{Name: "packA"},
{Name: "packB", NotFixedYet: true},
},

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package oval
import (
@@ -92,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()

View File

@@ -1,25 +1,7 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package oval
import (
"encoding/json"
"fmt"
"net/http"
"regexp"
"strings"
@@ -34,6 +16,7 @@ import (
"github.com/kotakanbe/goval-dictionary/db"
ovalmodels "github.com/kotakanbe/goval-dictionary/models"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
type ovalResult struct {
@@ -44,32 +27,42 @@ type defPacks struct {
def ovalmodels.Definition
// BinaryPackageName : NotFixedYet
actuallyAffectedPackNames map[string]bool
binpkgFixstat map[string]fixStat
}
func (e defPacks) toPackStatuses() (ps models.PackageStatuses) {
for name, notFixedYet := range e.actuallyAffectedPackNames {
ps = append(ps, models.PackageStatus{
type fixStat struct {
notFixedYet bool
fixedIn string
isSrcPack bool
srcPackName string
}
func (e defPacks) toPackStatuses() (ps models.PackageFixStatuses) {
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
@@ -78,7 +71,8 @@ func (e *ovalResult) upsert(def ovalmodels.Definition, packName string, notFixed
type request struct {
packName string
versionRelease string
NewVersionRelease string
newVersionRelease string
arch string
binaryPackNames []string
isSrcPack bool
}
@@ -105,8 +99,9 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult) (
reqChan <- request{
packName: pack.Name,
versionRelease: pack.FormatVer(),
NewVersionRelease: pack.FormatVer(),
newVersionRelease: pack.FormatVer(),
isSrcPack: false,
arch: pack.Arch,
}
}
for _, pack := range r.SrcPackages {
@@ -115,6 +110,7 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult) (
binaryPackNames: pack.BinaryNames,
versionRelease: pack.Version,
isSrcPack: true,
// arch: pack.Arch,
}
}
}()
@@ -148,27 +144,37 @@ 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:
errs = append(errs, err)
case <-timeout:
return relatedDefs, fmt.Errorf("Timeout Fetching OVAL")
return relatedDefs, xerrors.New("Timeout Fetching OVAL")
}
}
if len(errs) != 0 {
return relatedDefs, fmt.Errorf("Failed to fetch OVAL. err: %v", errs)
return relatedDefs, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
}
return
}
@@ -186,8 +192,7 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
if count == retryMax {
return nil
}
return fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
errs, url, resp)
return xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %w", url, resp, errs)
}
return nil
}
@@ -196,18 +201,17 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
}
err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
if err != nil {
errChan <- fmt.Errorf("HTTP Error %s", err)
errChan <- xerrors.Errorf("HTTP Error %w", err)
return
}
if count == retryMax {
errChan <- fmt.Errorf("HRetry count exceeded")
errChan <- xerrors.New("HRetry count exceeded")
return
}
defs := []ovalmodels.Definition{}
if err := json.Unmarshal([]byte(body), &defs); err != nil {
errChan <- fmt.Errorf("Failed to Unmarshall. body: %s, err: %s",
body, err)
errChan <- xerrors.Errorf("Failed to Unmarshall. body: %s, err: %w", body, err)
return
}
resChan <- response{
@@ -222,7 +226,8 @@ func getDefsByPackNameFromOvalDB(driver db.DB, r *models.ScanResult) (relatedDef
requests = append(requests, request{
packName: pack.Name,
versionRelease: pack.FormatVer(),
NewVersionRelease: pack.FormatNewVer(),
newVersionRelease: pack.FormatNewVer(),
arch: pack.Arch,
isSrcPack: false,
})
}
@@ -231,27 +236,38 @@ func getDefsByPackNameFromOvalDB(driver db.DB, r *models.ScanResult) (relatedDef
packName: pack.Name,
binaryPackNames: pack.BinaryNames,
versionRelease: pack.Version,
arch: pack.Arch,
isSrcPack: true,
})
}
for _, req := range requests {
definitions, err := driver.GetByPackName(r.Release, req.packName)
definitions, err := driver.GetByPackName(r.Family, r.Release, req.packName, req.arch)
if err != nil {
return relatedDefs, fmt.Errorf("Failed to get %s OVAL info by package: %#v, err: %s", r.Family, req, err)
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)
}
}
}
@@ -269,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
@@ -288,45 +304,64 @@ 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
less, err := lessThan(family, req.versionRelease, ovalPack)
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
// 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,
config.Amazon,
config.SUSEEnterpriseServer,
config.Debian,
config.Ubuntu:
// Use fixed state in OVAL for these distros.
return true, false, ovalPack.Version
}
// But CentOS can't judge whether fixed or unfixed.
// Because fixed state in RHEL's OVAL is different.
// So, it have to be judged version comparison.
// `offline` or `fast` scan mode can't get a updatable version.
// In these mode, the blow field was set empty.
// Vuls can not judge fixed or unfixed.
if req.NewVersionRelease == "" {
return true, false
if req.newVersionRelease == "" {
return true, false, ovalPack.Version
}
// compare version: newVer vs oval
less, err := lessThan(family, req.NewVersionRelease, ovalPack)
less, err := lessThan(family, req.newVersionRelease, ovalPack)
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
err, req.newVersionRelease, ovalPack, def.DefinitionID)
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)?`)
var esVerPattern = regexp.MustCompile(`\.el(\d+)(?:_\d+)?`)
func lessThan(family, versionRelease string, packB ovalmodels.Package) (bool, error) {
switch family {
case config.Debian, config.Ubuntu:
case config.Debian,
config.Ubuntu:
vera, err := debver.NewVersion(versionRelease)
if err != nil {
return false, err
@@ -336,18 +371,23 @@ func lessThan(family, versionRelease string, packB ovalmodels.Package) (bool, er
return false, err
}
return vera.LessThan(verb), nil
case config.Oracle, config.SUSEEnterpriseServer, config.Alpine:
case config.Oracle,
config.SUSEEnterpriseServer,
config.Alpine,
config.Amazon:
vera := rpmver.NewVersion(versionRelease)
verb := rpmver.NewVersion(packB.Version)
return vera.LessThan(verb), nil
case config.RedHat, config.CentOS: // TODO: Suport config.Scientific
rea := regexp.MustCompile(`\.[es]l(\d+)(?:_\d+)?(?:\.centos)?`)
reb := regexp.MustCompile(`\.el(\d+)(?:_\d+)?`)
vera := rpmver.NewVersion(rea.ReplaceAllString(versionRelease, ".el$1"))
verb := rpmver.NewVersion(reb.ReplaceAllString(packB.Version, ".el$1"))
case config.RedHat,
config.CentOS:
vera := rpmver.NewVersion(centosVerPattern.ReplaceAllString(versionRelease, ".el$1"))
verb := rpmver.NewVersion(esVerPattern.ReplaceAllString(packB.Version, ".el$1"))
return vera.LessThan(verb), nil
default:
util.Log.Errorf("Not implemented yet: %s", family)
}
return false, fmt.Errorf("Package version comparison not supported: %s", family)
return false, xerrors.Errorf("Package version comparison not supported: %s", family)
}

View File

@@ -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)
}
@@ -110,7 +134,7 @@ func TestDefpacksToPackStatuses(t *testing.T) {
}
var tests = []struct {
in in
out models.PackageStatuses
out models.PackageFixStatuses
}{
// Ubuntu
{
@@ -121,32 +145,40 @@ 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",
},
},
},
},
out: models.PackageStatuses{
out: models.PackageFixStatuses{
{
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
@@ -281,11 +317,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "1.0.0-0",
NewVersionRelease: "1.0.0-2",
newVersionRelease: "1.0.0-2",
},
},
affected: true,
notFixedYet: true,
fixedIn: "1.0.0-3",
notFixedYet: false,
},
// 4. Ubuntu
// ovalpack.NotFixedYet == false
@@ -313,11 +350,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "1.0.0-0",
NewVersionRelease: "1.0.0-3",
newVersionRelease: "1.0.0-3",
},
},
affected: true,
notFixedYet: false,
fixedIn: "1.0.0-2",
},
// 5 RedHat
{
@@ -340,11 +378,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.7",
NewVersionRelease: "",
newVersionRelease: "",
},
},
affected: true,
notFixedYet: false,
fixedIn: "0:1.2.3-45.el6_7.8",
},
// 6 RedHat
{
@@ -367,11 +406,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.6",
NewVersionRelease: "0:1.2.3-45.el6_7.7",
newVersionRelease: "0:1.2.3-45.el6_7.7",
},
},
affected: true,
notFixedYet: true,
notFixedYet: false,
fixedIn: "0:1.2.3-45.el6_7.8",
},
// 7 RedHat
{
@@ -446,11 +486,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.6",
NewVersionRelease: "0:1.2.3-45.el6_7.7",
newVersionRelease: "0:1.2.3-45.el6_7.7",
},
},
affected: true,
notFixedYet: true,
notFixedYet: false,
fixedIn: "0:1.2.3-45.el6_7.8",
},
// 10 RedHat
{
@@ -473,11 +514,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.6",
NewVersionRelease: "0:1.2.3-45.el6_7.8",
newVersionRelease: "0:1.2.3-45.el6_7.8",
},
},
affected: true,
notFixedYet: false,
fixedIn: "0:1.2.3-45.el6_7.8",
},
// 11 RedHat
{
@@ -499,11 +541,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6_7.6",
NewVersionRelease: "0:1.2.3-45.el6_7.9",
newVersionRelease: "0:1.2.3-45.el6_7.9",
},
},
affected: true,
notFixedYet: false,
fixedIn: "0:1.2.3-45.el6_7.8",
},
// 12 RedHat
{
@@ -578,11 +621,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.7",
NewVersionRelease: "",
newVersionRelease: "",
},
},
affected: true,
notFixedYet: false,
fixedIn: "0:1.2.3-45.el6_7.8",
},
// 15
{
@@ -657,11 +701,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.6",
NewVersionRelease: "0:1.2.3-45.el6.centos.7",
newVersionRelease: "0:1.2.3-45.el6.centos.7",
},
},
affected: true,
notFixedYet: true,
fixedIn: "0:1.2.3-45.el6_7.8",
},
// 18
{
@@ -684,11 +729,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.6",
NewVersionRelease: "0:1.2.3-45.el6.centos.8",
newVersionRelease: "0:1.2.3-45.el6.centos.8",
},
},
affected: true,
notFixedYet: false,
fixedIn: "0:1.2.3-45.el6_7.8",
},
// 19
{
@@ -711,11 +757,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.el6.centos.6",
NewVersionRelease: "0:1.2.3-45.el6.centos.9",
newVersionRelease: "0:1.2.3-45.el6.centos.9",
},
},
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{
@@ -865,11 +913,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.sl6.6",
NewVersionRelease: "0:1.2.3-45.sl6.7",
newVersionRelease: "0:1.2.3-45.sl6.7",
},
},
affected: true,
notFixedYet: true,
fixedIn: "0:1.2.3-45.el6_7.8",
},
{
in: in{
@@ -891,11 +940,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.sl6.6",
NewVersionRelease: "0:1.2.3-45.sl6.8",
newVersionRelease: "0:1.2.3-45.sl6.8",
},
},
affected: true,
notFixedYet: false,
fixedIn: "0:1.2.3-45.el6_7.8",
},
{
in: in{
@@ -917,11 +967,12 @@ func TestIsOvalDefAffected(t *testing.T) {
packName: "b",
isSrcPack: false,
versionRelease: "0:1.2.3-45.sl6.6",
NewVersionRelease: "0:1.2.3-45.sl6.9",
newVersionRelease: "0:1.2.3-45.sl6.9",
},
},
affected: true,
notFixedYet: false,
fixedIn: "0:1.2.3-45.el6_7.8",
},
{
in: in{
@@ -989,7 +1040,7 @@ func TestIsOvalDefAffected(t *testing.T) {
req: request{
packName: "kernel",
versionRelease: "3.0.0",
NewVersionRelease: "3.2.0",
newVersionRelease: "3.2.0",
},
kernel: models.Kernel{
Release: "3.0.0",
@@ -1013,7 +1064,7 @@ func TestIsOvalDefAffected(t *testing.T) {
req: request{
packName: "kernel",
versionRelease: "3.0.0",
NewVersionRelease: "3.2.0",
newVersionRelease: "3.2.0",
},
kernel: models.Kernel{
Release: "3.0.0",
@@ -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)
}
}
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -25,6 +8,7 @@ import (
"time"
storage "github.com/Azure/azure-sdk-for-go/storage"
"golang.org/x/xerrors"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
@@ -60,7 +44,7 @@ func (w AzureBlobWriter) Write(rs ...models.ScanResult) (err error) {
k := key + ".json"
var b []byte
if b, err = json.Marshal(r); err != nil {
return fmt.Errorf("Failed to Marshal to JSON: %s", err)
return xerrors.Errorf("Failed to Marshal to JSON: %w", err)
}
if err := createBlockBlob(cli, k, b); err != nil {
return err
@@ -87,7 +71,7 @@ func (w AzureBlobWriter) Write(rs ...models.ScanResult) (err error) {
k := key + ".xml"
var b []byte
if b, err = xml.Marshal(r); err != nil {
return fmt.Errorf("Failed to Marshal to XML: %s", err)
return xerrors.Errorf("Failed to Marshal to XML: %w", err)
}
allBytes := bytes.Join([][]byte{[]byte(xml.Header + vulsOpenTag), b, []byte(vulsCloseTag)}, []byte{})
if err := createBlockBlob(cli, k, allBytes); err != nil {
@@ -117,7 +101,7 @@ func CheckIfAzureContainerExists() error {
}
}
if !found {
return fmt.Errorf("Container not found. Container: %s", c.Conf.Azure.ContainerName)
return xerrors.Errorf("Container not found. Container: %s", c.Conf.Azure.ContainerName)
}
return nil
}
@@ -142,7 +126,7 @@ func createBlockBlob(cli storage.BlobStorageClient, k string, b []byte) error {
ref := cli.GetContainerReference(c.Conf.Azure.ContainerName)
blob := ref.GetBlobReference(k)
if err := blob.CreateBlockBlobFromReader(bytes.NewReader(b), nil); err != nil {
return fmt.Errorf("Failed to upload data to %s/%s, %s",
return xerrors.Errorf("Failed to upload data to %s/%s, err: %w",
c.Conf.Azure.ContainerName, k, err)
}
return nil

View File

@@ -1 +0,0 @@
package report

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -25,11 +8,12 @@ import (
"github.com/cenkalti/backoff"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/util"
cvedb "github.com/kotakanbe/go-cve-dictionary/db"
cve "github.com/kotakanbe/go-cve-dictionary/models"
cvemodels "github.com/kotakanbe/go-cve-dictionary/models"
)
// CveClient is api client of CVE disctionary service.
@@ -57,7 +41,7 @@ func (api cvedictClient) CheckHealth() error {
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 fmt.Errorf("Failed to request to CVE server. url: %s, errs: %v",
return xerrors.Errorf("Failed to request to CVE server. url: %s, errs: %w",
url, errs)
}
return nil
@@ -65,18 +49,21 @@ func (api cvedictClient) CheckHealth() error {
type response struct {
Key string
CveDetail cve.CveDetail
CveDetail cvemodels.CveDetail
}
func (api cvedictClient) FetchCveDetails(driver cvedb.DB, cveIDs []string) (cveDetails []cve.CveDetail, err error) {
func (api cvedictClient) FetchCveDetails(driver cvedb.DB, cveIDs []string) (cveDetails []cvemodels.CveDetail, err error) {
if !config.Conf.CveDict.IsFetchViaHTTP() {
if driver == nil {
return
}
for _, cveID := range cveIDs {
cveDetail, err := driver.Get(cveID)
if err != nil {
return nil, fmt.Errorf("Failed to fetch CVE. err: %s", err)
return nil, xerrors.Errorf("Failed to fetch CVE. err: %w", err)
}
if len(cveDetail.CveID) == 0 {
cveDetails = append(cveDetails, cve.CveDetail{
cveDetails = append(cveDetails, cvemodels.CveDetail{
CveID: cveID,
})
} else {
@@ -123,7 +110,7 @@ func (api cvedictClient) FetchCveDetails(driver cvedb.DB, cveIDs []string) (cveD
select {
case res := <-resChan:
if len(res.CveDetail.CveID) == 0 {
cveDetails = append(cveDetails, cve.CveDetail{
cveDetails = append(cveDetails, cvemodels.CveDetail{
CveID: res.Key,
})
} else {
@@ -132,12 +119,12 @@ func (api cvedictClient) FetchCveDetails(driver cvedb.DB, cveIDs []string) (cveD
case err := <-errChan:
errs = append(errs, err)
case <-timeout:
return nil, fmt.Errorf("Timeout Fetching CVE")
return nil, xerrors.New("Timeout Fetching CVE")
}
}
if len(errs) != 0 {
return nil,
fmt.Errorf("Failed to fetch CVE. err: %v", errs)
xerrors.Errorf("Failed to fetch CVE. err: %w", errs)
}
return
}
@@ -150,8 +137,8 @@ func (api cvedictClient) httpGet(key, url string, resChan chan<- response, errCh
// resp, body, errs = gorequest.New().SetDebug(config.Conf.Debug).Get(url).End()
resp, body, errs = gorequest.New().Get(url).End()
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
return fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
errs, url, resp)
return xerrors.Errorf("HTTP GET Error, url: %s, resp: %v, err: %w",
url, resp, errs)
}
return nil
}
@@ -161,13 +148,12 @@ func (api cvedictClient) httpGet(key, url string, resChan chan<- response, errCh
}
err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
if err != nil {
errChan <- fmt.Errorf("HTTP Error %s", err)
errChan <- xerrors.Errorf("HTTP Error: %w", err)
return
}
cveDetail := cve.CveDetail{}
cveDetail := cvemodels.CveDetail{}
if err := json.Unmarshal([]byte(body), &cveDetail); err != nil {
errChan <- fmt.Errorf("Failed to Unmarshall. body: %s, err: %s",
body, err)
errChan <- xerrors.Errorf("Failed to Unmarshall. body: %s, err: %w", body, err)
return
}
resChan <- response{
@@ -176,7 +162,7 @@ func (api cvedictClient) httpGet(key, url string, resChan chan<- response, errCh
}
}
func (api cvedictClient) FetchCveDetailsByCpeName(driver cvedb.DB, cpeName string) ([]cve.CveDetail, error) {
func (api cvedictClient) FetchCveDetailsByCpeName(driver cvedb.DB, cpeName string) ([]cvemodels.CveDetail, error) {
if config.Conf.CveDict.IsFetchViaHTTP() {
api.baseURL = config.Conf.CveDict.URL
url, err := util.URLPathJoin(api.baseURL, "cpes")
@@ -191,7 +177,7 @@ func (api cvedictClient) FetchCveDetailsByCpeName(driver cvedb.DB, cpeName strin
return driver.GetByCpeURI(cpeName)
}
func (api cvedictClient) httpPost(key, url string, query map[string]string) ([]cve.CveDetail, error) {
func (api cvedictClient) httpPost(key, url string, query map[string]string) ([]cvemodels.CveDetail, error) {
var body string
var errs []error
var resp *http.Response
@@ -203,7 +189,7 @@ func (api cvedictClient) httpPost(key, url string, query map[string]string) ([]c
}
resp, body, errs = req.End()
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
return fmt.Errorf("HTTP POST error: %v, url: %s, resp: %v", errs, url, resp)
return xerrors.Errorf("HTTP POST error. url: %s, resp: %v, err: %w", url, resp, errs)
}
return nil
}
@@ -212,13 +198,13 @@ func (api cvedictClient) httpPost(key, url string, query map[string]string) ([]c
}
err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
if err != nil {
return nil, fmt.Errorf("HTTP Error %s", err)
return nil, xerrors.Errorf("HTTP Error: %w", err)
}
cveDetails := []cve.CveDetail{}
cveDetails := []cvemodels.CveDetail{}
if err := json.Unmarshal([]byte(body), &cveDetails); err != nil {
return nil,
fmt.Errorf("Failed to Unmarshall. body: %s, err: %s", body, err)
xerrors.Errorf("Failed to Unmarshall. body: %s, err: %w", body, err)
}
return cveDetails, nil
}

View File

@@ -1,7 +1,6 @@
package report
import (
"fmt"
"os"
"github.com/future-architect/vuls/config"
@@ -10,6 +9,7 @@ import (
cvedb "github.com/kotakanbe/go-cve-dictionary/db"
ovaldb "github.com/kotakanbe/goval-dictionary/db"
exploitdb "github.com/mozqnet/go-exploitdb/db"
"golang.org/x/xerrors"
)
// DBClient is a dictionarie's db client for reporting
@@ -33,7 +33,7 @@ type DBClientConf struct {
func NewDBClient(cnf DBClientConf) (dbclient *DBClient, locked bool, err error) {
cveDriver, locked, err := NewCveDB(cnf)
if locked {
return nil, true, fmt.Errorf("CveDB is locked: %s",
return nil, true, xerrors.Errorf("CveDB is locked: %s",
cnf.OvalDictCnf.SQLite3Path)
} else if err != nil {
return nil, locked, err
@@ -41,7 +41,7 @@ func NewDBClient(cnf DBClientConf) (dbclient *DBClient, locked bool, err error)
ovaldb, locked, err := NewOvalDB(cnf)
if locked {
return nil, true, fmt.Errorf("OvalDB is locked: %s",
return nil, true, xerrors.Errorf("OvalDB is locked: %s",
cnf.OvalDictCnf.SQLite3Path)
} else if err != nil {
util.Log.Warnf("Unable to use OvalDB: %s, err: %s",
@@ -50,7 +50,7 @@ func NewDBClient(cnf DBClientConf) (dbclient *DBClient, locked bool, err error)
gostdb, locked, err := NewGostDB(cnf)
if locked {
return nil, true, fmt.Errorf("gostDB is locked: %s",
return nil, true, xerrors.Errorf("gostDB is locked: %s",
cnf.GostCnf.SQLite3Path)
} else if err != nil {
util.Log.Warnf("Unable to use gostDB: %s, err: %s",
@@ -59,7 +59,7 @@ func NewDBClient(cnf DBClientConf) (dbclient *DBClient, locked bool, err error)
exploitdb, locked, err := NewExploitDB(cnf)
if locked {
return nil, true, fmt.Errorf("exploitDB is locked: %s",
return nil, true, xerrors.Errorf("exploitDB is locked: %s",
cnf.ExploitCnf.SQLite3Path)
} else if err != nil {
util.Log.Warnf("Unable to use exploitDB: %s, err: %s",
@@ -83,12 +83,16 @@ func NewCveDB(cnf DBClientConf) (driver cvedb.DB, locked bool, err error) {
path := cnf.CveDictCnf.URL
if cnf.CveDictCnf.Type == "sqlite3" {
path = cnf.CveDictCnf.SQLite3Path
if _, err := os.Stat(path); os.IsNotExist(err) {
util.Log.Warnf("--cvedb-path=%s file not found. [CPE-scan](https://vuls.io/docs/en/usage-scan-non-os-packages.html#cpe-scan) needs cve-dictionary. if you specify cpe in config.toml, fetch cve-dictionary before reporting. For details, see `https://github.com/kotakanbe/go-cve-dictionary#deploy-go-cve-dictionary`", path)
return nil, false, nil
}
}
util.Log.Debugf("Open cve-dictionary db (%s): %s", cnf.CveDictCnf.Type, path)
driver, locked, err = cvedb.NewDB(cnf.CveDictCnf.Type, path, cnf.DebugSQL)
if err != nil {
err = fmt.Errorf("Failed to init CVE DB. err: %s, path: %s", err, path)
err = xerrors.Errorf("Failed to init CVE DB. err: %w, path: %s", err, path)
return nil, locked, err
}
return driver, false, nil
@@ -104,7 +108,7 @@ func NewOvalDB(cnf DBClientConf) (driver ovaldb.DB, locked bool, err error) {
path = cnf.OvalDictCnf.SQLite3Path
if _, err := os.Stat(path); os.IsNotExist(err) {
util.Log.Warnf("--ovaldb-path=%s is not found. It's recommended to use OVAL to improve scanning accuracy. For details, see https://github.com/kotakanbe/goval-dictionary#usage", path)
util.Log.Warnf("--ovaldb-path=%s file not found", path)
return nil, false, nil
}
}
@@ -112,7 +116,7 @@ func NewOvalDB(cnf DBClientConf) (driver ovaldb.DB, locked bool, err error) {
util.Log.Debugf("Open oval-dictionary db (%s): %s", cnf.OvalDictCnf.Type, path)
driver, locked, err = ovaldb.NewDB("", cnf.OvalDictCnf.Type, path, cnf.DebugSQL)
if err != nil {
err = fmt.Errorf("Failed to new OVAL DB. err: %s", err)
err = xerrors.Errorf("Failed to new OVAL DB. err: %w", err)
if locked {
return nil, true, err
}
@@ -131,7 +135,7 @@ func NewGostDB(cnf DBClientConf) (driver gostdb.DB, locked bool, err error) {
path = cnf.GostCnf.SQLite3Path
if _, err := os.Stat(path); os.IsNotExist(err) {
util.Log.Warnf("--gostdb-path=%s is not found. If the scan target server is Debian, RHEL or CentOS, it's recommended to use gost to improve scanning accuracy. To use gost database, see https://github.com/knqyf263/gost#fetch-redhat", path)
util.Log.Warnf("--gostdb-path=%s file not found. Vuls can detect `patch-not-released-CVE-ID` using gost if the scan target server is Debian, RHEL or CentOS, For details, see `https://github.com/knqyf263/gost#fetch-redhat`", path)
return nil, false, nil
}
}
@@ -139,7 +143,7 @@ func NewGostDB(cnf DBClientConf) (driver gostdb.DB, locked bool, err error) {
util.Log.Debugf("Open gost db (%s): %s", cnf.GostCnf.Type, path)
if driver, locked, err = gostdb.NewDB(cnf.GostCnf.Type, path, cnf.DebugSQL); err != nil {
if locked {
util.Log.Errorf("gostDB is locked: %s", err)
util.Log.Errorf("gostDB is locked. err: %+v", err)
return nil, true, err
}
return nil, false, err
@@ -157,7 +161,7 @@ func NewExploitDB(cnf DBClientConf) (driver exploitdb.DB, locked bool, err error
path = cnf.ExploitCnf.SQLite3Path
if _, err := os.Stat(path); os.IsNotExist(err) {
util.Log.Warnf("--exploitdb-path=%s is not found. It's recommended to use exploit to improve scanning accuracy. To use exploit db database, see https://github.com/mozqnet/go-exploitdb", path)
util.Log.Warnf("--exploitdb-path=%s file not found. Fetch go-exploit-db before reporting if you want to display exploit codes of detected CVE-IDs. For details, see `https://github.com/mozqnet/go-exploitdb`", path)
return nil, false, nil
}
}
@@ -165,7 +169,7 @@ func NewExploitDB(cnf DBClientConf) (driver exploitdb.DB, locked bool, err error
util.Log.Debugf("Open exploit db (%s): %s", cnf.ExploitCnf.Type, path)
if driver, locked, err = exploitdb.NewDB(cnf.ExploitCnf.Type, path, cnf.DebugSQL); err != nil {
if locked {
util.Log.Errorf("exploitDB is locked: %s", err)
util.Log.Errorf("exploitDB is locked. err: %+v", err)
return nil, true, err
}
return nil, false, err
@@ -177,12 +181,12 @@ func NewExploitDB(cnf DBClientConf) (driver exploitdb.DB, locked bool, err error
func (d DBClient) CloseDB() {
if d.CveDB != nil {
if err := d.CveDB.CloseDB(); err != nil {
util.Log.Errorf("Failed to close DB: %s", err)
util.Log.Errorf("Failed to close DB. err: %+v", err)
}
}
if d.OvalDB != nil {
if err := d.OvalDB.CloseDB(); err != nil {
util.Log.Errorf("Failed to close DB: %s", err)
util.Log.Errorf("Failed to close DB. err: %+v", err)
}
}
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -27,6 +10,7 @@ import (
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"golang.org/x/xerrors"
)
// EMailWriter send mail
@@ -41,7 +25,6 @@ func (w EMailWriter) Write(rs ...models.ScanResult) (err error) {
for _, r := range rs {
if conf.FormatOneEMail {
message += formatFullPlainText(r) + "\r\n\r\n"
mm := r.ScannedCves.CountGroupBySeverity()
keys := []string{"High", "Medium", "Low", "Unknown"}
for _, k := range keys {
@@ -63,12 +46,14 @@ func (w EMailWriter) Write(rs ...models.ScanResult) (err error) {
} else {
message = formatFullPlainText(r)
}
if conf.FormatOneLineText {
message = fmt.Sprintf("One Line Summary\r\n================\r\n%s", formatOneLineSummary(r))
}
if err := sender.Send(subject, message); err != nil {
return err
}
}
}
summary := ""
if config.Conf.IgnoreUnscoredCves {
summary = fmt.Sprintf("Total: %d (High:%d Medium:%d Low:%d)",
@@ -77,17 +62,12 @@ func (w EMailWriter) Write(rs ...models.ScanResult) (err error) {
summary = fmt.Sprintf("Total: %d (High:%d Medium:%d Low:%d ?:%d)",
m["High"]+m["Medium"]+m["Low"]+m["Unknown"],
m["High"], m["Medium"], m["Low"], m["Unknown"])
origmessage := message
if conf.FormatOneEMail {
message = fmt.Sprintf(
`
One Line Summary
================
%s
%s`,
formatOneLineSummary(rs...), message)
message = fmt.Sprintf("One Line Summary\r\n================\r\n%s", formatOneLineSummary(rs...))
if !conf.FormatOneLineText {
message += fmt.Sprintf("\r\n\r\n%s", origmessage)
}
subject := fmt.Sprintf("%s %s",
conf.EMail.SubjectPrefix, summary)
@@ -112,7 +92,7 @@ func (e *emailSender) Send(subject, body string) (err error) {
cc := strings.Join(emailConf.Cc[:], ", ")
mailAddresses := append(emailConf.To, emailConf.Cc...)
if _, err := mail.ParseAddressList(strings.Join(mailAddresses[:], ", ")); err != nil {
return fmt.Errorf("Failed to parse email addresses: %s", err)
return xerrors.Errorf("Failed to parse email addresses: %w", err)
}
headers := make(map[string]string)
@@ -130,20 +110,34 @@ func (e *emailSender) Send(subject, body string) (err error) {
message := fmt.Sprintf("%s\r\n%s", header, body)
smtpServer := net.JoinHostPort(emailConf.SMTPAddr, emailConf.SMTPPort)
if emailConf.User != "" && emailConf.Password != "" {
err = e.send(
smtpServer,
smtp.PlainAuth(
"",
emailConf.User,
emailConf.Password,
emailConf.SMTPAddr,
),
emailConf.From,
mailAddresses,
[]byte(message),
)
if err != nil {
return xerrors.Errorf("Failed to send emails: %w", err)
}
return nil
}
err = e.send(
smtpServer,
smtp.PlainAuth(
"",
emailConf.User,
emailConf.Password,
emailConf.SMTPAddr,
),
nil,
emailConf.From,
mailAddresses,
[]byte(message),
)
if err != nil {
return fmt.Errorf("Failed to send emails: %s", err)
return xerrors.Errorf("Failed to send emails: %w", err)
}
return nil
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -100,7 +83,7 @@ func TestSend(t *testing.T) {
t.Errorf("#%d: wrong 'addr' field.\r\nexpected: %s\n got: %s", i, test.out.addr, r.addr)
}
if !reflect.DeepEqual(r.auth, test.out.auth) {
if !reflect.DeepEqual(r.auth, test.out.auth) && r.auth != nil {
t.Errorf("#%d: wrong 'auth' field.\r\nexpected: %v\n got: %v", i, test.out.auth, r.auth)
}

View File

@@ -1 +0,0 @@
package report

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Architect, Inc. Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -22,10 +5,9 @@ import (
"encoding/json"
"net/http"
"github.com/pkg/errors"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"golang.org/x/xerrors"
)
// HTTPRequestWriter writes results to HTTP request
@@ -53,7 +35,7 @@ type HTTPResponseWriter struct {
func (w HTTPResponseWriter) Write(rs ...models.ScanResult) (err error) {
res, err := json.Marshal(rs)
if err != nil {
return errors.Wrap(err, "Failed to marshal scah results")
return xerrors.Errorf("Failed to marshal scah results: %w", err)
}
w.Writer.Header().Set("Content-Type", "application/json")
_, err = w.Writer.Write(res)

View File

@@ -1,33 +1,16 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
"bytes"
"encoding/json"
"encoding/xml"
"fmt"
"io/ioutil"
"os"
"path/filepath"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"golang.org/x/xerrors"
)
// LocalFileWriter writes results to a local file.
@@ -40,8 +23,8 @@ func (w LocalFileWriter) Write(rs ...models.ScanResult) (err error) {
path := filepath.Join(w.CurrentDir, "summary.txt")
text := formatOneLineSummary(rs...)
if err := writeFile(path, []byte(text), 0600); err != nil {
return fmt.Errorf(
"Failed to write to file. path: %s, err: %s",
return xerrors.Errorf(
"Failed to write to file. path: %s, err: %w",
path, err)
}
}
@@ -60,15 +43,15 @@ 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 fmt.Errorf("Failed to Marshal to JSON: %s", err)
return xerrors.Errorf("Failed to Marshal to JSON: %w", err)
}
} else {
if b, err = json.Marshal(r); err != nil {
return fmt.Errorf("Failed to Marshal to JSON: %s", err)
return xerrors.Errorf("Failed to Marshal to JSON: %w", err)
}
}
if err := writeFile(p, b, 0600); err != nil {
return fmt.Errorf("Failed to write JSON. path: %s, err: %s", p, err)
return xerrors.Errorf("Failed to write JSON. path: %s, err: %w", p, err)
}
}
@@ -82,8 +65,8 @@ func (w LocalFileWriter) Write(rs ...models.ScanResult) (err error) {
if err := writeFile(
p, []byte(formatList(r)), 0600); err != nil {
return fmt.Errorf(
"Failed to write text files. path: %s, err: %s", p, err)
return xerrors.Errorf(
"Failed to write text files. path: %s, err: %w", p, err)
}
}
@@ -97,8 +80,8 @@ func (w LocalFileWriter) Write(rs ...models.ScanResult) (err error) {
if err := writeFile(
p, []byte(formatFullPlainText(r)), 0600); err != nil {
return fmt.Errorf(
"Failed to write text files. path: %s, err: %s", p, err)
return xerrors.Errorf(
"Failed to write text files. path: %s, err: %w", p, err)
}
}
@@ -112,11 +95,11 @@ func (w LocalFileWriter) Write(rs ...models.ScanResult) (err error) {
var b []byte
if b, err = xml.Marshal(r); err != nil {
return fmt.Errorf("Failed to Marshal to XML: %s", err)
return xerrors.Errorf("Failed to Marshal to XML: %w", err)
}
allBytes := bytes.Join([][]byte{[]byte(xml.Header + vulsOpenTag), b, []byte(vulsCloseTag)}, []byte{})
if err := writeFile(p, allBytes, 0600); err != nil {
return fmt.Errorf("Failed to write XML. path: %s, err: %s", p, err)
return xerrors.Errorf("Failed to write XML. path: %s, err: %w", p, err)
}
}
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -28,7 +11,10 @@ import (
"strings"
"time"
"github.com/future-architect/vuls/libmanager"
"github.com/BurntSushi/toml"
"github.com/future-architect/vuls/config"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/contrib/owasp-dependency-check/parser"
"github.com/future-architect/vuls/cwe"
@@ -38,11 +24,14 @@ import (
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/oval"
"github.com/future-architect/vuls/util"
"github.com/future-architect/vuls/wordpress"
"github.com/hashicorp/uuid"
gostdb "github.com/knqyf263/gost/db"
cvedb "github.com/kotakanbe/go-cve-dictionary/db"
cvemodels "github.com/kotakanbe/go-cve-dictionary/models"
ovaldb "github.com/kotakanbe/goval-dictionary/db"
exploitdb "github.com/mozqnet/go-exploitdb/db"
"golang.org/x/xerrors"
)
const (
@@ -61,18 +50,20 @@ func FillCveInfos(dbclient DBClient, rs []models.ScanResult, dir string) ([]mode
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, fmt.Errorf("Failed to read OWASP Dependency Check XML: %s, %s, %s",
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
@@ -80,7 +71,7 @@ func FillCveInfos(dbclient DBClient, rs []models.ScanResult, dir string) ([]mode
if owaspDCXMLPath != "" {
cpes, err := parser.Parse(owaspDCXMLPath)
if err != nil {
return nil, fmt.Errorf("Failed to read OWASP Dependency Check XML: %s, %s, %s",
return nil, xerrors.Errorf("Failed to read OWASP Dependency Check XML on %s, `%s`, err: %w",
r.ServerInfo(), owaspDCXMLPath, err)
}
cpeURIs = append(cpeURIs, cpes...)
@@ -89,7 +80,17 @@ func FillCveInfos(dbclient DBClient, rs []models.ScanResult, dir string) ([]mode
}
}
if err := FillCveInfo(dbclient, &r, cpeURIs); err != nil {
// Integrations
githubInts := GithubSecurityAlerts(c.Conf.Servers[r.ServerName].GitHubRepos)
wpOpt := WordPressOption{c.Conf.Servers[r.ServerName].WordPress.WPVulnDBToken}
if err := FillCveInfo(dbclient,
&r,
cpeURIs,
true,
githubInts,
wpOpt); err != nil {
return nil, err
}
r.Lang = c.Conf.Lang
@@ -102,7 +103,7 @@ func FillCveInfos(dbclient DBClient, rs []models.ScanResult, dir string) ([]mode
r.ServerName: c.Conf.Servers[r.ServerName],
}
if err := overwriteJSONFile(dir, r); err != nil {
return nil, fmt.Errorf("Failed to write JSON: %s", err)
return nil, xerrors.Errorf("Failed to write JSON: %w", err)
}
filledResults = append(filledResults, r)
} else {
@@ -136,6 +137,7 @@ func FillCveInfos(dbclient DBClient, rs []models.ScanResult, dir string) ([]mode
r = r.FilterIgnoreCves()
r = r.FilterUnfixed()
r = r.FilterIgnorePkgs()
r = r.FilterInactiveWordPressLibs()
if c.Conf.IgnoreUnscoredCves {
r.ScannedCves = r.ScannedCves.FindScoredVulns()
}
@@ -145,12 +147,19 @@ func FillCveInfos(dbclient DBClient, rs []models.ScanResult, dir string) ([]mode
}
// FillCveInfo fill scanResult with cve info.
func FillCveInfo(dbclient DBClient, r *models.ScanResult, cpeURIs []string, integrations ...c.IntegrationConf) error {
func FillCveInfo(dbclient DBClient, r *models.ScanResult, cpeURIs []string, ignoreWillNotFix bool, integrations ...Integration) error {
util.Log.Debugf("need to refresh")
nCVEs, err := FillWithOval(dbclient.OvalDB, r)
nCVEs, err := libmanager.FillLibrary(r)
if err != nil {
return fmt.Errorf("Failed to fill with OVAL: %s", err)
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)
if err != nil {
return xerrors.Errorf("Failed to fill with OVAL: %w", err)
}
util.Log.Infof("%s: %d CVEs are detected with OVAL",
r.FormatServerName(), nCVEs)
@@ -166,45 +175,38 @@ func FillCveInfo(dbclient DBClient, r *models.ScanResult, cpeURIs []string, inte
nCVEs, err = fillVulnByCpeURIs(dbclient.CveDB, r, cpeURIs)
if err != nil {
return fmt.Errorf("Failed to detect vulns of %s: %s", cpeURIs, err)
return xerrors.Errorf("Failed to detect vulns of `%s`: %w", cpeURIs, err)
}
util.Log.Infof("%s: %d CVEs are detected with CPE", r.FormatServerName(), nCVEs)
if len(integrations) != 0 {
for k, v := range integrations[0].GitHubConf {
c.Conf.Servers[r.ServerName].GitHubRepos[k] = v
ints := &integrationResults{}
for _, o := range integrations {
if err = o.apply(r, ints); err != nil {
return xerrors.Errorf("Failed to fill with integration: %w", err)
}
}
nCVEs, err = fillGitHubSecurityAlerts(r)
if err != nil {
return fmt.Errorf("Failed to access GitHub Security Alerts: %s", err)
}
util.Log.Infof("%s: %d CVEs are detected with GitHub Security Alerts", r.FormatServerName(), nCVEs)
util.Log.Infof("%s: %d CVEs are detected with GitHub Security Alerts", r.FormatServerName(), ints.GithubAlertsCveCounts)
nCVEs, err = FillWithGost(dbclient.GostDB, r)
nCVEs, err = FillWithGost(dbclient.GostDB, r, ignoreWillNotFix)
if err != nil {
return fmt.Errorf("Failed to fill with gost: %s", err)
return xerrors.Errorf("Failed to fill with gost: %w", err)
}
util.Log.Infof("%s: %d unfixed CVEs are detected with gost",
r.FormatServerName(), nCVEs)
util.Log.Infof("Fill CVE detailed information with CVE-DB")
if err := fillCveDetail(dbclient.CveDB, r); err != nil {
return fmt.Errorf("Failed to fill with CVE: %s", err)
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)
if err != nil {
return fmt.Errorf("Failed to fill with exploit: %s", err)
return xerrors.Errorf("Failed to fill with exploit: %w", err)
}
util.Log.Infof("%s: %d exploits are detected",
r.FormatServerName(), nExploitCve)
enAlertCnt, jaAlertCnt := fillAlerts(r)
util.Log.Infof("%s: en: %d, ja: %d alerts are detected",
r.FormatServerName(), enAlertCnt, jaAlertCnt)
fillCweDict(r)
return nil
}
@@ -227,6 +229,7 @@ func fillCveDetail(driver cvedb.DB, r *models.ScanResult) error {
}
jvn := models.ConvertJvnToModel(d.CveID, d.Jvn)
alerts := fillCertAlerts(&d)
for cveID, vinfo := range r.ScannedCves {
if vinfo.CveID == d.CveID {
if vinfo.CveContents == nil {
@@ -237,6 +240,7 @@ func fillCveDetail(driver cvedb.DB, r *models.ScanResult) error {
vinfo.CveContents[con.Type] = *con
}
}
vinfo.AlertDict = alerts
r.ScannedCves[cveID] = vinfo
break
}
@@ -245,6 +249,28 @@ func fillCveDetail(driver cvedb.DB, r *models.ScanResult) error {
return nil
}
func fillCertAlerts(cvedetail *cvemodels.CveDetail) (dict models.AlertDict) {
if cvedetail.NvdJSON != nil {
for _, cert := range cvedetail.NvdJSON.Certs {
dict.En = append(dict.En, models.Alert{
URL: cert.Link,
Title: cert.Title,
Team: "us",
})
}
}
if cvedetail.Jvn != nil {
for _, cert := range cvedetail.Jvn.Certs {
dict.Ja = append(dict.Ja, models.Alert{
URL: cert.Link,
Title: cert.Title,
Team: "jp",
})
}
}
return dict
}
// FillWithOval fetches OVAL database
func FillWithOval(driver ovaldb.DB, r *models.ScanResult) (nCVEs int, err error) {
var ovalClient oval.Client
@@ -274,23 +300,26 @@ func FillWithOval(driver ovaldb.DB, r *models.ScanResult) (nCVEs int, err error)
case c.Alpine:
ovalClient = oval.NewAlpine()
ovalFamily = c.Alpine
case c.Amazon, c.Raspbian, c.FreeBSD, c.Windows:
case c.Amazon:
ovalClient = oval.NewAmazon()
ovalFamily = c.Amazon
case c.Raspbian, c.FreeBSD, c.Windows:
return 0, nil
case c.ServerTypePseudo:
return 0, nil
default:
if r.Family == "" {
return 0, fmt.Errorf("Probably an error occurred during scanning. Check the error message")
return 0, xerrors.New("Probably an error occurred during scanning. Check the error message")
}
return 0, fmt.Errorf("OVAL for %s is not implemented yet", r.Family)
return 0, xerrors.Errorf("OVAL for %s is not implemented yet", r.Family)
}
if !c.Conf.OvalDict.IsFetchViaHTTP() {
if driver == nil {
return 0, nil
return 0, xerrors.Errorf("You have to fetch OVAL data for %s before reporting. For details, see `https://github.com/kotakanbe/goval-dictionary#usage`", r.Family)
}
if err = driver.NewOvalDB(ovalFamily); err != nil {
return 0, fmt.Errorf("Failed to New Oval DB. err: %s", err)
return 0, xerrors.Errorf("Failed to New Oval DB. err: %w", err)
}
}
@@ -300,8 +329,7 @@ func FillWithOval(driver ovaldb.DB, r *models.ScanResult) (nCVEs int, err error)
return 0, err
}
if !ok {
util.Log.Warnf("OVAL entries of %s %s are not found. It's recommended to use OVAL to improve scanning accuracy. For details, see https://github.com/kotakanbe/goval-dictionary#usage , Then report with --ovaldb-path or --ovaldb-url flag", ovalFamily, r.Release)
return 0, nil
return 0, xerrors.Errorf("OVAL entries of %s %s are not found. Fetch OVAL before reporting. For details, see `https://github.com/kotakanbe/goval-dictionary#usage`", ovalFamily, r.Release)
}
_, err = ovalClient.CheckIfOvalFresh(driver, ovalFamily, r.Release)
@@ -314,11 +342,14 @@ func FillWithOval(driver ovaldb.DB, r *models.ScanResult) (nCVEs int, err error)
// FillWithGost fills CVEs with gost dataabase
// https://github.com/knqyf263/gost
func FillWithGost(driver gostdb.DB, r *models.ScanResult) (nCVEs int, err error) {
func FillWithGost(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
return gostClient.FillWithGost(driver, r)
if nCVEs, err = gostClient.DetectUnfixed(driver, r, ignoreWillNotFix); err != nil {
return
}
return nCVEs, gostClient.FillCVEsWithRedHat(driver, r)
}
// FillWithExploit fills Exploits with exploit dataabase
@@ -330,6 +361,11 @@ func FillWithExploit(driver exploitdb.DB, r *models.ScanResult) (nExploitCve int
}
func fillVulnByCpeURIs(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`",
cpeURIs)
}
for _, name := range cpeURIs {
details, err := CveClient.FetchCveDetailsByCpeName(driver, name)
if err != nil {
@@ -356,19 +392,59 @@ func fillVulnByCpeURIs(driver cvedb.DB, r *models.ScanResult, cpeURIs []string)
return nCVEs, nil
}
type integrationResults struct {
GithubAlertsCveCounts int
WordPressCveCounts int
}
// Integration is integration of vuls report
type Integration interface {
apply(*models.ScanResult, *integrationResults) error
}
// GithubSecurityAlerts :
func GithubSecurityAlerts(githubConfs map[string]config.GitHubConf) Integration {
return GithubSecurityAlertOption{
GithubConfs: githubConfs,
}
}
// GithubSecurityAlertOption :
type GithubSecurityAlertOption struct {
GithubConfs map[string]config.GitHubConf
}
// https://help.github.com/articles/about-security-alerts-for-vulnerable-dependencies/
func fillGitHubSecurityAlerts(r *models.ScanResult) (nCVEs int, err error) {
repos := c.Conf.Servers[r.ServerName].GitHubRepos
for ownerRepo, setting := range repos {
func (g GithubSecurityAlertOption) apply(r *models.ScanResult, ints *integrationResults) (err error) {
var nCVEs int
for ownerRepo, setting := range g.GithubConfs {
ss := strings.Split(ownerRepo, "/")
owner, repo := ss[0], ss[1]
n, err := github.FillGitHubSecurityAlerts(r, owner, repo, setting.Token)
if err != nil {
return 0, err
return xerrors.Errorf("Failed to access GitHub Security Alerts: %w", err)
}
nCVEs += n
}
return nCVEs, nil
ints.GithubAlertsCveCounts = nCVEs
return nil
}
// WordPressOption :
type WordPressOption struct {
token string
}
func (g WordPressOption) apply(r *models.ScanResult, ints *integrationResults) (err error) {
if g.token == "" {
return nil
}
n, err := wordpress.FillWordPress(r, g.token)
if err != nil {
return xerrors.Errorf("Failed to fetch from WPVulnDB. Check the WPVulnDBToken in config.toml. err: %w", err)
}
ints.WordPressCveCounts = n
return nil
}
func fillCweDict(r *models.ScanResult) {
@@ -384,9 +460,6 @@ func fillCweDict(r *models.ScanResult) {
}
}
// TODO check the format of CWEID, clean CWEID
// JVN, NVD XML, JSON, OVALs
dict := map[string]models.CweDictEntry{}
for id := range uniqCweIDMap {
entry := models.CweDictEntry{}
@@ -394,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)
@@ -405,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)
@@ -417,22 +502,22 @@ func fillCweDict(r *models.ScanResult) {
return
}
func fillAlerts(r *models.ScanResult) (enCnt int, jaCnt int) {
for cveID, vuln := range r.ScannedCves {
enAs, jaAs := models.GetAlertsByCveID(cveID, "en"), models.GetAlertsByCveID(cveID, "ja")
vuln.AlertDict = models.AlertDict{
Ja: jaAs,
En: enAs,
}
r.ScannedCves[cveID] = vuln
enCnt += len(enAs)
jaCnt += len(jaAs)
}
return enCnt, jaCnt
}
const reUUID = "[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}"
// Scanning with the -containers-only, -images-only flag at scan time, the UUID of Container Host may not be generated,
// so check it. Otherwise create a UUID of the Container Host and set it.
func getOrCreateServerUUID(r models.ScanResult, server c.ServerInfo) (serverUUID string) {
if id, ok := server.UUIDs[r.ServerName]; !ok {
serverUUID = uuid.GenerateUUID()
} else {
matched, err := regexp.MatchString(reUUID, id)
if !matched || err != nil {
serverUUID = uuid.GenerateUUID()
}
}
return serverUUID
}
// EnsureUUIDs generate a new UUID of the scan target server if UUID is not assigned yet.
// And then set the generated UUID to config.toml and scan results.
func EnsureUUIDs(configPath string, results models.ScanResults) error {
@@ -453,20 +538,13 @@ func EnsureUUIDs(configPath string, results models.ScanResults) error {
name := ""
if r.IsContainer() {
name = fmt.Sprintf("%s@%s", r.Container.Name, r.ServerName)
// Scanning with the -containers-only flag at scan time, the UUID of Container Host may not be generated,
// so check it. Otherwise create a UUID of the Container Host and set it.
serverUUID := ""
if id, ok := server.UUIDs[r.ServerName]; !ok {
serverUUID = uuid.GenerateUUID()
} else {
matched, err := regexp.MatchString(reUUID, id)
if !matched || err != nil {
serverUUID = uuid.GenerateUUID()
}
if uuid := getOrCreateServerUUID(r, server); uuid != "" {
server.UUIDs[r.ServerName] = uuid
}
if serverUUID != "" {
server.UUIDs[r.ServerName] = serverUUID
} else if r.IsImage() {
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
}
} else {
name = r.ServerName
@@ -602,21 +680,21 @@ func EnsureUUIDs(configPath string, results models.ScanResults) error {
// rename the current config.toml to config.toml.bak
info, err := os.Lstat(configPath)
if err != nil {
return fmt.Errorf("Failed to lstat %s: %s", configPath, err)
return xerrors.Errorf("Failed to lstat %s: %w", configPath, err)
}
realPath := configPath
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
if realPath, err = os.Readlink(configPath); err != nil {
return fmt.Errorf("Failed to Read link %s: %s", configPath, err)
return xerrors.Errorf("Failed to Read link %s: %w", configPath, err)
}
}
if err := os.Rename(realPath, realPath+".bak"); err != nil {
return fmt.Errorf("Failed to rename %s: %s", configPath, err)
return xerrors.Errorf("Failed to rename %s: %w", configPath, err)
}
var buf bytes.Buffer
if err := toml.NewEncoder(&buf).Encode(c); err != nil {
return fmt.Errorf("Failed to encode to toml: %s", err)
return xerrors.Errorf("Failed to encode to toml: %w", err)
}
str := strings.Replace(buf.String(), "\n [", "\n\n [", -1)
str = fmt.Sprintf("%s\n\n%s",

View File

@@ -1 +1,51 @@
package report
import (
"testing"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
)
const defaultUUID = "11111111-1111-1111-1111-111111111111"
func TestGetOrCreateServerUUID(t *testing.T) {
cases := map[string]struct {
scanResult models.ScanResult
server config.ServerInfo
isDefault bool
}{
"baseServer": {
scanResult: models.ScanResult{
ServerName: "hoge",
},
server: config.ServerInfo{
UUIDs: map[string]string{
"hoge": defaultUUID,
},
},
isDefault: false,
},
"onlyContainers": {
scanResult: models.ScanResult{
ServerName: "hoge",
},
server: config.ServerInfo{
UUIDs: map[string]string{
"fuga": defaultUUID,
},
},
isDefault: false,
},
}
for testcase, v := range cases {
uuid := getOrCreateServerUUID(v.scanResult, v.server)
if (uuid == defaultUUID) != v.isDefault {
t.Errorf("%s : expected isDefault %t got %s", testcase, v.isDefault, uuid)
}
}
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -31,6 +14,7 @@ import (
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"golang.org/x/xerrors"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
@@ -75,7 +59,7 @@ func (w S3Writer) Write(rs ...models.ScanResult) (err error) {
k := key + ".json"
var b []byte
if b, err = json.Marshal(r); err != nil {
return fmt.Errorf("Failed to Marshal to JSON: %s", err)
return xerrors.Errorf("Failed to Marshal to JSON: %w", err)
}
if err := putObject(svc, k, b); err != nil {
return err
@@ -102,7 +86,7 @@ func (w S3Writer) Write(rs ...models.ScanResult) (err error) {
k := key + ".xml"
var b []byte
if b, err = xml.Marshal(r); err != nil {
return fmt.Errorf("Failed to Marshal to XML: %s", err)
return xerrors.Errorf("Failed to Marshal to XML: %w", err)
}
allBytes := bytes.Join([][]byte{[]byte(xml.Header + vulsOpenTag), b, []byte(vulsCloseTag)}, []byte{})
if err := putObject(svc, k, allBytes); err != nil {
@@ -118,8 +102,8 @@ func CheckIfBucketExists() error {
svc := getS3()
result, err := svc.ListBuckets(&s3.ListBucketsInput{})
if err != nil {
return fmt.Errorf(
"Failed to list buckets. err: %s, profile: %s, region: %s",
return xerrors.Errorf(
"Failed to list buckets. err: %w, profile: %s, region: %s",
err, c.Conf.AWS.Profile, c.Conf.AWS.Region)
}
@@ -131,7 +115,7 @@ func CheckIfBucketExists() error {
}
}
if !found {
return fmt.Errorf(
return xerrors.Errorf(
"Failed to find the buckets. profile: %s, region: %s, bucket: %s",
c.Conf.AWS.Profile, c.Conf.AWS.Region, c.Conf.AWS.S3Bucket)
}
@@ -158,7 +142,7 @@ func putObject(svc *s3.S3, k string, b []byte) error {
}
if _, err := svc.PutObject(putObjectInput); err != nil {
return fmt.Errorf("Failed to upload data to %s/%s, %s",
return xerrors.Errorf("Failed to upload data to %s/%s, err: %w",
c.Conf.AWS.S3Bucket, k, err)
}
return nil

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -24,7 +7,9 @@ import (
"io/ioutil"
"net/http"
"net/url"
"os"
"path"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
@@ -35,6 +20,7 @@ import (
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"golang.org/x/xerrors"
)
// SaasWriter writes results to SaaS
@@ -48,8 +34,11 @@ type TempCredential struct {
}
type payload struct {
GroupID int `json:"GroupID"`
Token string `json:"Token"`
GroupID int `json:"GroupID"`
Token string `json:"Token"`
ScannedBy string `json:"ScannedBy"`
ScannedIPv4s string `json:"ScannedIPv4s"`
ScannedIPv6s string `json:"ScannedIPv6s"`
}
// UploadSaas : UploadSaas
@@ -59,14 +48,23 @@ func (w SaasWriter) Write(rs ...models.ScanResult) (err error) {
return nil
}
ipv4s, ipv6s, err := util.IP()
if err != nil {
util.Log.Errorf("Failed to fetch scannedIPs. err: %+v", err)
}
hostname, _ := os.Hostname()
payload := payload{
GroupID: c.Conf.Saas.GroupID,
Token: c.Conf.Saas.Token,
GroupID: c.Conf.Saas.GroupID,
Token: c.Conf.Saas.Token,
ScannedBy: hostname,
ScannedIPv4s: strings.Join(ipv4s, ", "),
ScannedIPv6s: strings.Join(ipv6s, ", "),
}
var body []byte
if body, err = json.Marshal(payload); err != nil {
return fmt.Errorf("Failed to Marshal to JSON: %s", err)
return xerrors.Errorf("Failed to Marshal to JSON: %w", err)
}
var req *http.Request
@@ -95,7 +93,7 @@ func (w SaasWriter) Write(rs ...models.ScanResult) (err error) {
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("Failed to get Credential. Request JSON : %s,", string(body))
return xerrors.Errorf("Failed to get Credential. Request JSON : %s,", string(body))
}
var t []byte
@@ -105,7 +103,7 @@ func (w SaasWriter) Write(rs ...models.ScanResult) (err error) {
var tempCredential TempCredential
if err = json.Unmarshal(t, &tempCredential); err != nil {
return fmt.Errorf("Failed to unmarshal saas credential file. err : %s", err)
return xerrors.Errorf("Failed to unmarshal saas credential file. err : %s", err)
}
credential := credentials.NewStaticCredentialsFromCreds(credentials.Value{
@@ -119,7 +117,7 @@ func (w SaasWriter) Write(rs ...models.ScanResult) (err error) {
Credentials: credential,
Region: aws.String("ap-northeast-1"),
}); err != nil {
return fmt.Errorf("Failed to new aws session. err : %s", err)
return xerrors.Errorf("Failed to new aws session. err: %w", err)
}
svc := s3.New(sess)
@@ -127,7 +125,7 @@ func (w SaasWriter) Write(rs ...models.ScanResult) (err error) {
s3Key := renameKeyNameUTC(r.ScannedAt, r.ServerUUID, r.Container)
var b []byte
if b, err = json.Marshal(r); err != nil {
return fmt.Errorf("Failed to Marshal to JSON: %s", err)
return xerrors.Errorf("Failed to Marshal to JSON: %w", err)
}
util.Log.Infof("Uploading...: ServerName: %s, ", r.ServerName)
putObjectInput := &s3.PutObjectInput{
@@ -137,10 +135,11 @@ func (w SaasWriter) Write(rs ...models.ScanResult) (err error) {
}
if _, err := svc.PutObject(putObjectInput); err != nil {
return fmt.Errorf("Failed to upload data to %s/%s, %s",
return xerrors.Errorf("Failed to upload data to %s/%s, err: %w",
tempCredential.S3Bucket, s3Key, err)
}
}
util.Log.Infof("done")
return nil
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -30,6 +13,7 @@ import (
"github.com/nlopes/slack"
"github.com/parnurzeal/gorequest"
log "github.com/sirupsen/logrus"
"golang.org/x/xerrors"
)
type field struct {
@@ -59,19 +43,6 @@ func (w SlackWriter) Write(rs ...models.ScanResult) (err error) {
channel = fmt.Sprintf("#%s", r.ServerName)
}
if 0 < len(r.Errors) {
msg := message{
Text: msgText(r),
Username: conf.AuthUser,
IconEmoji: conf.IconEmoji,
Channel: channel,
}
if err = send(msg); err != nil {
return err
}
continue
}
// A maximum of 100 attachments are allowed on a message.
// Split into chunks with 100 elements
// https://api.slack.com/methods/chat.postMessage
@@ -86,38 +57,67 @@ func (w SlackWriter) Write(rs ...models.ScanResult) (err error) {
}
sort.Ints(chunkKeys)
summary := fmt.Sprintf("%s\n%s",
getNotifyUsers(config.Conf.Slack.NotifyUsers),
formatOneLineSummary(r))
// Send slack by API
if 0 < len(token) {
api := slack.New(token)
ParentMsg := slack.PostMessageParameters{
// Text: msgText(r),
msgPrms := slack.PostMessageParameters{
Username: conf.AuthUser,
IconEmoji: conf.IconEmoji,
}
var ts string
if _, ts, err = api.PostMessage(channel, msgText(r), ParentMsg); err != nil {
if _, ts, err = api.PostMessage(
channel,
slack.MsgOptionText(summary, true),
slack.MsgOptionPostMessageParameters(msgPrms),
); err != nil {
return err
}
if config.Conf.FormatOneLineText || 0 < len(r.Errors) {
continue
}
for _, k := range chunkKeys {
params := slack.PostMessageParameters{
// Text: msgText(r),
Username: conf.AuthUser,
IconEmoji: conf.IconEmoji,
Attachments: m[k],
ThreadTimestamp: ts,
}
if _, _, err = api.PostMessage(channel, msgText(r), params); err != nil {
if _, _, err = api.PostMessage(
channel,
slack.MsgOptionText("", false),
slack.MsgOptionPostMessageParameters(params),
slack.MsgOptionAttachments(m[k]...),
); err != nil {
return err
}
}
} else {
for i, k := range chunkKeys {
txt := ""
if i == 0 {
txt = msgText(r)
}
msg := message{
Text: summary,
Username: conf.AuthUser,
IconEmoji: conf.IconEmoji,
Channel: channel,
}
if err := send(msg); err != nil {
return err
}
if config.Conf.FormatOneLineText || 0 < len(r.Errors) {
continue
}
for _, k := range chunkKeys {
txt := fmt.Sprintf("%d/%d for %s",
k+1,
len(chunkKeys),
r.FormatServerName())
msg := message{
Text: txt,
Username: conf.AuthUser,
@@ -148,9 +148,9 @@ func send(msg message) error {
if count == retryMax {
return nil
}
return fmt.Errorf(
"HTTP POST error: %v, url: %s, resp: %v, body: %s",
errs, conf.HookURL, resp, body)
return xerrors.Errorf(
"HTTP POST error. url: %s, resp: %v, body: %s, err: %w",
conf.HookURL, resp, body, errs)
}
return nil
}
@@ -160,74 +160,55 @@ func send(msg message) error {
}
boff := backoff.NewExponentialBackOff()
if err := backoff.RetryNotify(f, boff, notify); err != nil {
return fmt.Errorf("HTTP error: %s", err)
return xerrors.Errorf("HTTP error: %w", err)
}
if count == retryMax {
return fmt.Errorf("Retry count exceeded")
return xerrors.New("Retry count exceeded")
}
return nil
}
func msgText(r models.ScanResult) string {
notifyUsers := ""
if 0 < len(r.ScannedCves) {
notifyUsers = getNotifyUsers(config.Conf.Slack.NotifyUsers)
}
serverInfo := fmt.Sprintf("*%s*", r.ServerInfo())
if 0 < len(r.Errors) {
return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\nError: %s",
notifyUsers,
serverInfo,
r.ScannedCves.FormatCveSummary(),
r.ScannedCves.FormatFixedStatus(r.Packages),
r.FormatUpdatablePacksSummary(),
r.Errors)
}
return fmt.Sprintf("%s\n%s\n%s\n%s\n%s",
notifyUsers,
serverInfo,
r.ScannedCves.FormatCveSummary(),
r.ScannedCves.FormatFixedStatus(r.Packages),
r.FormatUpdatablePacksSummary())
}
func toSlackAttachments(r models.ScanResult) (attaches []slack.Attachment) {
vinfos := r.ScannedCves.ToSortedSlice()
for _, vinfo := range vinfos {
curent := []string{}
installed, candidate := []string{}, []string{}
for _, affected := range vinfo.AffectedPackages {
if p, ok := r.Packages[affected.Name]; ok {
curent = append(curent,
installed = append(installed,
fmt.Sprintf("%s-%s", p.Name, p.FormatVer()))
} else {
curent = append(curent, affected.Name)
installed = append(installed, affected.Name)
}
}
for _, n := range vinfo.CpeURIs {
curent = append(curent, n)
}
for _, n := range vinfo.GitHubSecurityAlerts {
curent = append(curent, n.PackageName)
}
new := []string{}
for _, affected := range vinfo.AffectedPackages {
if p, ok := r.Packages[affected.Name]; ok {
if affected.NotFixedYet {
new = append(new, "Not Fixed Yet")
candidate = append(candidate, "Not Fixed Yet")
} else {
new = append(new, p.FormatNewVer())
candidate = append(candidate, p.FormatNewVer())
}
} else {
new = append(new, "?")
candidate = append(candidate, "?")
}
}
for range vinfo.CpeURIs {
new = append(new, "?")
for _, n := range vinfo.CpeURIs {
installed = append(installed, n)
candidate = append(candidate, "?")
}
for range vinfo.GitHubSecurityAlerts {
new = append(new, "?")
for _, n := range vinfo.GitHubSecurityAlerts {
installed = append(installed, n.PackageName)
candidate = append(candidate, "?")
}
for _, wp := range vinfo.WpPackageFixStats {
if p, ok := r.WordPressPackages.Find(wp.Name); ok {
installed = append(installed, fmt.Sprintf("%s-%s", wp.Name, p.Version))
candidate = append(candidate, wp.FixedIn)
} else {
installed = append(installed, wp.Name)
candidate = append(candidate, "?")
}
}
a := slack.Attachment{
@@ -239,12 +220,12 @@ func toSlackAttachments(r models.ScanResult) (attaches []slack.Attachment) {
{
// Title: "Current Package/CPE",
Title: "Installed",
Value: strings.Join(curent, "\n"),
Value: strings.Join(installed, "\n"),
Short: true,
},
{
Title: "Candidate",
Value: strings.Join(new, "\n"),
Value: strings.Join(candidate, "\n"),
Short: true,
},
},
@@ -262,7 +243,7 @@ func cvssColor(cvssScore float64) string {
return "danger"
case 4 <= cvssScore && cvssScore < 7:
return "warning"
case cvssScore < 0:
case cvssScore == 0:
return "#C0C0C0"
default:
return "good"
@@ -348,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")
}

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2016 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (

View File

@@ -1 +0,0 @@
package report

View File

@@ -1,20 +1,3 @@
/* Vuls - Vulnerability Scanner
Copyright (C) 2018 Future Corporation , Japan.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package report
import (
@@ -22,8 +5,7 @@ import (
"strings"
syslog "github.com/RackSec/srslog"
"github.com/pkg/errors"
"golang.org/x/xerrors"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
@@ -40,7 +22,7 @@ func (w SyslogWriter) Write(rs ...models.ScanResult) (err error) {
sysLog, err := syslog.Dial(conf.Protocol, raddr, severity|facility, conf.Tag)
if err != nil {
return errors.Wrap(err, "Failed to initialize syslog client")
return xerrors.Errorf("Failed to initialize syslog client: %w", err)
}
for _, r := range rs {

View File

@@ -22,15 +22,15 @@ func TestSyslogWriterEncodeSyslog(t *testing.T) {
IPv4Addrs: []string{"192.168.0.1", "10.0.2.15"},
ScannedCves: models.VulnInfos{
"CVE-2017-0001": models.VulnInfo{
AffectedPackages: models.PackageStatuses{
models.PackageStatus{Name: "pkg1"},
models.PackageStatus{Name: "pkg2"},
AffectedPackages: models.PackageFixStatuses{
models.PackageFixStatus{Name: "pkg1"},
models.PackageFixStatus{Name: "pkg2"},
},
},
"CVE-2017-0002": models.VulnInfo{
AffectedPackages: models.PackageStatuses{
models.PackageStatus{Name: "pkg3"},
models.PackageStatus{Name: "pkg4"},
AffectedPackages: models.PackageFixStatuses{
models.PackageFixStatus{Name: "pkg3"},
models.PackageFixStatus{Name: "pkg4"},
},
CveContents: models.CveContents{
models.NvdXML: models.CveContent{
@@ -57,8 +57,8 @@ func TestSyslogWriterEncodeSyslog(t *testing.T) {
IPv6Addrs: []string{"2001:0DB8::1"},
ScannedCves: models.VulnInfos{
"CVE-2017-0003": models.VulnInfo{
AffectedPackages: models.PackageStatuses{
models.PackageStatus{Name: "pkg5"},
AffectedPackages: models.PackageFixStatuses{
models.PackageFixStatus{Name: "pkg5"},
},
CveContents: models.CveContents{
models.RedHat: models.CveContent{

Some files were not shown because too many files have changed in this diff Show More