Compare commits

...

697 Commits

Author SHA1 Message Date
kazuminn
4c04acbd9e feat(report) : Differences between vulnerability patched items (#1157)
* add plusDiff() and minusDiff()
* add plusDiff minusDiff test

Co-authored-by: Kota Kanbe <kotakanbe@gmail.com>
2021-02-10 06:55:48 +09:00
Kota Kanbe
1c4f231572 fix(scan): ignore rpm -qf exit status (#1168) 2021-02-09 17:26:12 +09:00
Kota Kanbe
51b8e169d2 fix(scan): warning if lsof command not found (#1167) 2021-02-07 07:28:45 +09:00
Kota Kanbe
b4611ae9b7 fix(scan): fix yum-ps warning Failed to exec which -bash (#1166) 2021-02-07 07:23:12 +09:00
Kota Kanbe
cd6722017b fix(scan): yum-ps err Failed to find the package (#1165) 2021-02-06 08:42:06 +09:00
Kota Kanbe
290edffccf fix(log): output version to log for debugging purpose (#1163) 2021-02-04 07:47:56 +09:00
Kota Kanbe
64a6222bf9 fix(report): set created_at and updated_at of trivy to json (#1162) 2021-02-03 17:52:44 +09:00
Kota Kanbe
adb686b7c9 fix(report): set created_at and updated_at of wpscan.com to json (#1161) 2021-02-03 16:41:44 +09:00
Kota Kanbe
d4af341b0f fix(report): remove duplicated refreshing logic when report with -diff (#1160) 2021-02-03 07:37:19 +09:00
Kota Kanbe
fea7e93c8d chore: fix comment (#1158) 2021-02-02 06:06:49 +09:00
sadayuki-matsuno
8b6b8d0f2e feat(wordpress): define API limit exceed error for wpscan.com (#1155)
* feat(wordpress) specify wp err

* fix typo, chagne const name

Co-authored-by: Kota Kanbe <kotakanbe@gmail.com>
2021-01-30 09:53:41 +09:00
Kota Kanbe
4dcbd865cc fix(report): set http timeout 10 sec (#1154)
* fix(report): set http timeout 10 sec

* fix: add an error handling
2021-01-30 09:40:33 +09:00
Kota Kanbe
39b19444fe Merge branch 'master' of github.com:future-architect/vuls 2021-01-28 16:24:14 +09:00
Kota Kanbe
644d5a5462 fix(report): remove retry logic for wpscan.com (#1151)
* fix(saas) change saas upload s3 key (#1116)

* fix(report): remove retry logic for wpscan.com

Co-authored-by: sadayuki-matsuno <sadayuki.matsuno@gmail.com>
2021-01-28 16:21:33 +09:00
Kota Kanbe
8e18451e3f Merge branch 'master' of github.com:future-architect/vuls 2021-01-28 08:24:23 +09:00
Kota Kanbe
3dbdd01f97 fix(report): wordrpess scanning skipped when package is emtpy (#1150) 2021-01-28 08:24:03 +09:00
sadayuki-matsuno
a89079c005 fix(saas) change saas upload s3 key (#1116) 2021-01-28 08:20:13 +09:00
sadayuki-matsuno
a8c0926b4f fix(saas) change saas upload s3 key (#1116) 2021-01-27 14:43:09 +09:00
Kota Kanbe
dd2959a31b fix(eol): add eol for alpine 3.13 (#1149) 2021-01-27 12:52:07 +09:00
Kota Kanbe
51099f42c3 fix(tui): runtime panic when tui with docker-base-setup (#1148)
* fix(tui): runtime panic when tui with docker-base-setup

* pass test case
2021-01-26 09:40:26 +09:00
Kota Kanbe
63f170cc7a fix(report): set severity in Red Hat OVAL to both CVSS v3 and v2 #1146 (#1147) 2021-01-26 07:58:59 +09:00
Kota Kanbe
3c1489e588 feat(report): range notion calc by severity when no-cvss-score (#1145) 2021-01-25 13:22:55 +09:00
Kota Kanbe
e4f1e03f62 feat(github): display GitHub Security Advisory details (#1143) 2021-01-24 09:15:04 +09:00
Kota Kanbe
83d48ec990 Create codeql-analysis.yml 2021-01-24 09:06:13 +09:00
Kota Kanbe
b20d2b2684 fix(scan): skip wordpress scan for preudo servers (#1142) 2021-01-21 07:11:55 +09:00
Kota Kanbe
2b918c70ae fix(scan): config dump nocolor in debug mode. (#1141) 2021-01-21 06:38:37 +09:00
Kota Kanbe
1100c133ba feat(config): Default values for WordPress scanning to be set in config.toml (#1140)
* chore: update go mod

* fix(wordpress): set default if defined in config.toml
2021-01-21 06:22:25 +09:00
Kota Kanbe
88899f0e89 refactor: around CheckHTTPHealth (#1139) 2021-01-20 07:41:29 +09:00
Kota Kanbe
59dc0059bc fix(model): omit changelog from json if empty (#1137) 2021-01-19 09:01:35 +09:00
Kota Kanbe
986fb304c0 fix(scan): add --nogpgcheck to dnf mod list to avoid Error: Cache-only enabled but no cache for *** (#1136) 2021-01-19 08:05:20 +09:00
Kota Kanbe
d6435d2885 fix(xml): remove -format-xml #1068 (#1134) 2021-01-18 04:38:00 +09:00
shopper
affb456499 fix(email.go):Fix runtime error(invalid memory address) (#1133) 2021-01-18 04:08:14 +09:00
Kota Kanbe
705ed0a0ac fix(discover): change config.toml template (#1132) 2021-01-16 07:58:46 +09:00
Kota Kanbe
dfffe5b508 fix(config): err occurs when host not set in local-scan-mode (#1129)
If host is not set in local scan mode, an error occurs.
2021-01-14 09:22:04 +09:00
Shigechika AIKAWA
fca102edba fix dnf prompt and ssh user (#1126) 2021-01-14 08:22:06 +09:00
Kota Kanbe
554b6345a2 chore: go mod update (#1127) 2021-01-14 08:12:47 +09:00
Kota Kanbe
aa954dc84c fix(scan): kindness msg when no-cache err on dnf mod list (#1128) 2021-01-14 08:12:35 +09:00
Kota Kanbe
b5506a1368 chore: go mod update (#1125) 2021-01-13 11:56:35 +09:00
Kota Kanbe
0b55f94828 Improve implementation around config (#1122)
* refactor config

* fix saas config

* feat(config): scanmodule for each server in config.toml

* feat(config): enable to specify containersOnly in config.toml

* add new keys of config.toml to discover.go

* fix summary output, logging
2021-01-13 08:46:27 +09:00
Kota Kanbe
a67052f48c fix(scan): err detecting EOL for alpine Linux (#1124) 2021-01-12 20:10:22 +09:00
Kota Kanbe
6eff6a9329 feat(report): display EOL information to scan summary (#1120)
* feat(report): display EOL information to scan summary

* detect Amazon linux EOL
2021-01-09 07:58:55 +09:00
Kota Kanbe
69d32d4511 feat(report): add a err code to wpscan.com API error (#1119) 2021-01-07 14:57:49 +09:00
Kota Kanbe
d7a613b710 chore: go mod update (#1118) 2021-01-07 08:02:29 +09:00
sadayuki-matsuno
669c019287 fix(cvecontent) Fixed not to split empty string (#1117) 2021-01-06 15:52:55 +09:00
Shigechika AIKAWA
fcc4901a10 fix(scan): Failed to parse CentOS Stream (#1098) 2021-01-06 14:57:19 +09:00
Kota Kanbe
4359503484 fix(redhat): possibility of false positives on RHEL (#1115) 2021-01-06 13:33:08 +09:00
Kota Kanbe
b13f93a2d3 feat(scan): support dnf modules (#1114)
* feat(scan): support dnf modules

* change dnf module list --installed to --enabled

* chore: refactor

* feat(report): detect logic for dnf modularity label

* fix func name

* chore: update go mods
2021-01-06 11:36:41 +09:00
Kota Kanbe
8405e0fad6 refactor(gost): Duplicate code into function (#1110)
* refactor(gost): Duplicate code into function

* fix
2020-12-30 08:33:30 +09:00
Kota Kanbe
aceb3f1826 fix(scan): add an error case for rpm -qa (#1109) 2020-12-30 08:05:14 +09:00
Kota Kanbe
a206675f3e fix(wordpress): remove cache because not permitted. (#1107) 2020-12-29 07:25:58 +09:00
Kota Kanbe
f4253d74ae fix(wordpress): wpscan.com unmarshal error (#1106)
* refactor(report): remove Integration.apply

* add an err check

* fix(wordpress): wpscan.com unmarshal error

* fix warnings
2020-12-29 07:11:04 +09:00
Kota Kanbe
aaea15e516 refactor(report): remove Integration.apply (#1105)
* refactor(report): remove Integration.apply

* add an err check
2020-12-29 06:59:48 +09:00
Kota Kanbe
83d1f80959 chore(report): remove stride and hipchat support (#1104) 2020-12-26 08:52:45 +09:00
Kota Kanbe
a33cff8f13 fix(reprot): use SQLite3 in current dir if not specified (#1103) 2020-12-26 08:24:17 +09:00
Kota Kanbe
8679759f60 chore: fix typo (#1102) 2020-12-26 08:23:02 +09:00
Kota Kanbe
53deaee3d7 refactor(config): remove DependencyCheckXMLPath in config.toml (#1100) 2020-12-25 06:38:00 +09:00
Kota Kanbe
5a14a58fe4 refactor(nvdxml): Remove codes related to NVD xml(deprecated) (#1099) 2020-12-25 06:16:14 +09:00
Kota Kanbe
fb1fbf8f95 feat(report): Add NVD as a source for mitigations, primarySrc URL and Patch URL (#1097)
* feat(report): Add NVD as a src for mitigations.

* feat(report): display "Vendor Advisory" URL in NVD

* feat(report): display patch urls in report, tui
2020-12-24 08:37:10 +09:00
Kota Kanbe
cfbf779f9b feat(exploit): add exploit link in NVD as a source (#1096)
Added Refs information with NVD's Expoit tag as an information source
for Exploit.
2020-12-16 07:10:18 +09:00
Kota Kanbe
d576b6c6c1 refactor(report): around FillCveInfo (#1095)
* refactor(report): around FillCveInfo

* refacotr(report): around FillCveInfo
2020-12-15 15:48:23 +09:00
Kota Kanbe
514eb71482 fix(server): make config loading same as scan (#1091)
* fix(server): make config loading same as scan

* also remove from report, tui
2020-12-15 04:33:14 +09:00
Kota Kanbe
43ed904db1 fix(deps): update dependencies (#1094)
* fix(dpes): update dependencies

* update go ver

* update go ver

* update go

* update go
2020-12-15 04:32:23 +09:00
Kota Kanbe
0a440ca629 fix(saas): add saas subcmd (#1093) 2020-12-11 16:19:36 +09:00
Kota Kanbe
eff1dbf95b feat(scanner): vuls-scanner binary on release archive (#1092) 2020-12-11 11:05:48 +09:00
Kota Kanbe
9a32a94806 refactor: fix build warnings (#1090) 2020-12-11 06:45:39 +09:00
Shigechika AIKAWA
2534098509 fix(report): wpvulndb poor versioning(#1088) (#1089) 2020-12-11 05:53:41 +09:00
sadayuki-matsuno
9497365758 update pkg (#1087) 2020-12-04 15:57:02 +09:00
Kota Kanbe
101c44c9c0 Change .goreleaser to build binaries for arm, 386, amd64 at release. (#1082)
* fix go-releaser

* add vuls-scanner
2020-11-28 06:39:52 +09:00
Kota Kanbe
ffd745c004 fix a compile error #1083 (#1084) 2020-11-27 15:14:04 +09:00
Kota Kanbe
5fea4eaef8 feat(nocgo): enable to build with CGO_ENABLED=0 (#1080) 2020-11-27 09:55:09 +09:00
Kota Kanbe
1f610043cf feat(scan): IgnoredJSONKyes to clear values in result json #1071 (#1078) 2020-11-20 10:36:36 +09:00
Kota Kanbe
3f8de02683 fix(portscan): to keep backward compatibility before v0.13.0 (#1076) 2020-11-19 16:54:36 +09:00
Kota Kanbe
d02535d053 fix(debian): false negative of kernel cves with rdb backend (#1075)
* fix(debian): false negative of kernel cves with rdb backend

* update golangci.yml

* add --timeout=10m to golangci.yml
2020-11-18 10:32:37 +09:00
Kota Kanbe
75fceff5f7 refactor(report): format-csv (#1072) 2020-11-05 21:10:35 +09:00
gy741
ebd3834a35 add(report) -format-csv option (#1034) 2020-11-05 20:56:19 +09:00
Kota Kanbe
93059b74c3 feat(report): IgnoredJSONKyes to clear values in result json (#1071)
* feat(report): IgnoredJSONKyes to clear values in result json

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

* fix test case

* change append simple

* fix format

* set golangci-lint timeout

* Revert "set golangci-lint timeout"

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

* change parse to models.ListenPorts from string

* change support models.ListenPorts in TUI

* add scanPort template , detectScanDest

* add Test_detectScanDest

* change impl scanPorts template

* fix build error

* change collect scan success address

* add Test_matchListenPorts

* add Test_updatePortStatus

* change display port scan result on tui

* change display scan emoji on report

* Revert "change display scan emoji on report"

This reverts commit e281882cc6.

* add continue

* change display format

* change no use loop label

* remove comment code

* change display

* fix padding

* change refactoring var , fn name

* fix var name

* fix var name

* change eye icon

* change icon

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

Sure, that's better.

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

* fix test
2020-09-12 05:08:41 +09:00
Kota Kanbe
8a8ab8cb18 feat(libscan): enable to scan vulns of libs with pseudo #1035 (#1050) 2020-09-11 13:09:59 +09:00
Kota Kanbe
8146f5fd1b update readme (#1049) 2020-09-11 10:26:57 +09:00
shopper
425c585e47 Support for smtp LOGIN authentication (#1048)
* finished to implement new mail client

* delete email_test.go
2020-09-04 15:45:29 +09:00
Kota Kanbe
4f1578b2d6 [WIP]fix(scan): collect a running version of kernel-devel (#1044)
* fix(scan): collect a running kernel-devel version

* refactor
2020-09-01 14:37:40 +09:00
Norihiro NAKAOKA
7969b343b0 Raspberry Pi OS(Raspbian) scanning using OVAL DB (#1019)
* change: never refer to ChangeLog

* change raspberry pi os use debian oval at report

* change do not use r.Family

* change gost do not use r.Family

* change use r.Family because family has a large impact

* change replace MaineK00n/goval-dictionary@raspberrypi-oval

* note Raspbian Scan Policy

* add Raspbian Changelog support policy

* change grep Package for Raspbian at fast-scan mode

* add changelog preprocessing for Raspbian

* add take note of TODO

* change Changelog fetch part to function

* change error handling

* change solve one TODO

* change make ChangelogDir once

* add comment

* fix oval support Amazon Linux :refs #824

* change to useScannedCves from ovalSupproted

* change confidence for Raspbian

* change skip package for raspbian in OVAL DB

* change separate raspbian implementation from util

* change error, log format

* change print format

* change log format(delete newline)

* change support changelog.(Debian.)gz

* Revert "change support changelog.(Debian.)gz"

This reverts commit 2265a72c67.

* change test chnage.(Debian.)gz

* change support raspbian package(*raspberry*)

* change error format

* fix regexp pattern

* fix typo

* fix changelog cache

* change rename function name

* add TestParseChangelog

* change changelog lenient match for raspbian

* fix test case

* change clog dir support symbolic link, clog save dir name append suffix

* change remove more package for raspberry pi

* fix error handling

* change module update

* change refactoring around identifying raspbian package

* update go module

* update scan image

* update scan image

* change clarify scan mode

* change raspiPackNamePattern and add test case
2020-08-25 14:11:34 +09:00
Kota Kanbe
58cf1f4c8e refactor(typo): fix typos (#1041) 2020-08-24 16:34:32 +09:00
Norihiro NAKAOKA
a5b87af862 delete unnecessary images (#1036)
* delete unnecessary images

* Revert "delete unnecessary images"

This reverts commit 0967e1c522.

* delete unnecessary images
2020-08-21 17:07:20 +09:00
Kota Kanbe
a0e592b934 fix(report): fix segfault while uploading to s3 (#1033) 2020-08-07 10:31:43 +09:00
Kota Kanbe
7eccc538bb fix(msfdb): udpate go-msfdb-deps (#1032) 2020-08-06 16:54:14 +09:00
Kota Kanbe
59daa8570a fix(gost): suppress err logging when unsupported debian (#1031) 2020-08-05 20:05:50 +09:00
Kota Kanbe
3f52d318bc fix(log): suppress err msg if no access priv to logfile (#1029) 2020-07-31 16:55:12 +09:00
takuzoo
11a7a0c934 Display metasploit module information for each detected CVE-IDs (#1011)
* add metasploit

* fix go deps

* fix msf report

* fix msfdb server port number

* delete non-unique msfdb url from fulltext report

* fix(report): validate msfdb config on report (#1)

* fix(msfdb): update deps (go-msfdb)

* version up go-msfdb v0.1.0

Co-authored-by: Kota Kanbe <kotakanbe@gmail.com>
2020-07-03 14:05:07 +09:00
sadayuki-matsuno
89f49b0e29 Fix trivy parser test (#1014)
* fix trivy parser test

* fixed parser data
2020-06-24 17:14:43 +09:00
Kota Kanbe
72457cbf8e bump up version 2020-06-24 10:57:39 +09:00
Kota Kanbe
c11ba27509 fix(libscan): include a lockfile path of libs (#1012) 2020-06-24 10:46:00 +09:00
segatomo
8a611f9ba6 add diff-mode info (#1008) 2020-06-19 16:07:14 +09:00
Kota Kanbe
4a73875e4d bump up version (#1007) 2020-06-17 12:21:26 +09:00
shopper
d9d5e612ff Support ProxyJump option when using ssh command (#1004)
* Add proxyjump func

* Run go mod tidy

* Run make fmt
2020-06-17 12:15:12 +09:00
Kota Kanbe
4d8599e4fc update deps (#1006)
see https://github.com/knqyf263/go-apk-version/pull/1
2020-06-16 07:48:07 +09:00
Norihiro NAKAOKA
59c7061d29 Fix SSH failure due to .ssh/config owner (#1005)
* use -F option, success configtest and scan

* add sshConfigPath in config.toml

* Use sshConfigPath in config.toml when using ssh -F

* change -ssh-config to deprecated

* fix typo

* add sshConfigPath in tomltemplate
2020-06-16 05:48:31 +09:00
segatomo
996557c667 support alpine3.11 (#1002) 2020-06-12 13:42:11 +09:00
ahulab
519fb19a77 Added ReportedAt time for server mode reports (#996)
- Fixes #928
2020-06-11 11:42:04 +09:00
kazuminn
36456cb151 feat(wordpress): Cache WpVulnDB (#989)
* add wpVulnCache

* fix bug

* add test

* fmt

* fix bug

* refactor

* fix bug
2020-06-05 16:08:28 +09:00
sadayuki-matsuno
4ae87cc36c Fix releaser (#988)
* fix releaser

* fix releaser

* fix releaser

* fix releaser

* add 32 bit releaser and add exit code  in cmd

* delete 32 bit releaser

* fix
2020-06-05 15:04:06 +09:00
shopper
b37df89fb1 Support SMTPS when using report -to-email (#991)
* Add smtps func

* Add SMTPS implementation

* fix error message
2020-06-05 14:42:01 +09:00
sadayuki-matsuno
d18e7a751d add trivy parser (#981)
* add trivy parser

* fix test

* format

* add title and summary

* add trivy parse command

* add uploader

* set args by env

* add README

* add err check

* fix

* fix

* fix

* fix test

* update trivy

* refactor

* delete require uuid

* delete uuid from trivy parser

Co-authored-by: Kota Kanbe <kotakanbe@gmail.com>
2020-05-29 18:06:45 +09:00
kazuminn
8d5ea98e50 add -wp-ignore-inactive flag which ignores inactive plugin or themes (#974)
* command

* config

* ignore inactive

* fix

* add test

* fmt

* add unset test

* rename

* add test

* refactor

* fix

* refactor

* refactor

* fix golangci-lint error
2020-05-29 15:27:47 +09:00
Kota Kanbe
835dc08049 fix .golangci.yml 2020-05-27 20:33:57 +09:00
Kota Kanbe
62c9409fe9 add a github actions config (#985)
* add a github actions config

* fix(log): Don't create a log dir when testing

* remove a meaningless test case

* Thanks for everything, Mr, Travys.

* add golangci

* add goreleaser.yml

* add tidy.yml

* add golang-ci

* fix many lint warnings
2020-05-27 20:11:24 +09:00
Kota Kanbe
2374f578ed Bump up version 2020-05-26 09:32:10 +09:00
shopper
34e2f033d8 add kernelnames ubuntu20.04 (#982) 2020-05-22 12:19:07 +09:00
kazuminn
420825cacc remove append (#978) 2020-05-20 13:55:07 +09:00
Kota Kanbe
466ec93d8e bump up version 2020-05-08 17:15:25 +09:00
Kota Kanbe
3f5bb6ab29 fix(scan): alpine detection #965 (#966)
* fix(scan): alpine detection #965

* use knqyf263/go-apk-version
2020-05-08 16:12:01 +09:00
Kota Kanbe
ebe5f858c8 update trivy, and unsupport image scanning feature (#971)
* update trivy, fanal. unsupport image scanning

* Update models/library.go

Co-authored-by: Teppei Fukuda <teppei@elab.ic.i.u-tokyo.ac.jp>

* add -no-progress flag to report/tui cmd

* Display trivy vuln info to tui/report

* add detection method to vulninfo detected by trivy

* fix(uuid): change uuid lib to go-uuid #929 (#969)

* update trivy, fanal. unsupport image scanning

* Update models/library.go

Co-authored-by: Teppei Fukuda <teppei@elab.ic.i.u-tokyo.ac.jp>

* add -no-progress flag to report/tui cmd

* Display trivy vuln info to tui/report

* add detection method to vulninfo detected by trivy

* unique ref links in TUI

* download trivy DB only when lock file is specified in config.toml

Co-authored-by: Teppei Fukuda <teppei@elab.ic.i.u-tokyo.ac.jp>
2020-05-08 15:24:39 +09:00
Kota Kanbe
9dd025437b fix(uuid): change uuid lib to go-uuid #929 (#969) 2020-05-06 14:14:07 +09:00
Wagde Zabit
c0ebac305a composer.lock insteaad of composer.json (#973)
Co-authored-by: Wagde Zabit <wagde@orcasecurity.io>
2020-05-01 15:20:33 +09:00
Kota Kanbe
1f23ab7ba4 Bump up version 2020-04-28 14:27:46 +09:00
Kota Kanbe
ea3b63998d fix(report): GitHub Security Alerts Integration (#970) 2020-04-28 14:26:37 +09:00
Kota Kanbe
3093426458 fix(logging): panic if no write permission #949 (#968) 2020-04-27 17:37:30 +09:00
Kota Kanbe
37716feac7 refactor(lint): fix lint warnings (#967) 2020-04-27 17:02:27 +09:00
Kota Kanbe
56b12c38d2 fix(config): not working with empty config #962 (#963) 2020-04-23 10:50:35 +09:00
Kota Kanbe
749ead5d4a update go mod (#960) 2020-04-20 21:33:11 +09:00
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
Kota Kanbe
89d58d1abc bump up version 2019-02-20 14:58:49 +09:00
Kota Kanbe
d6b6969cb3 update README 2019-02-20 14:56:24 +09:00
kazuminn
e7bf6fa69d feat(README): contiruters shield (#778)
* add contiruters shield

* Update README.md

* Update README.md
2019-02-20 12:20:56 +09:00
Kota Kanbe
6e51970b91 fix(discovery): show the template of GitHub Security Alerts integration to discovery subcommand 2019-02-20 12:08:22 +09:00
Kota Kanbe
56d7d43768 feat(report): GitHub security alerts integration (#775)
feat(report): integrate to GitHub security alerts
2019-02-20 12:04:10 +09:00
Shota Ito
256c99ffa2 Delete tab from output in case of No CVE-IDs (#768) 2019-01-25 00:21:41 +09:00
Takayuki Ushida
9c0bc3b13b modify build time (#766) 2019-01-24 15:26:12 +09:00
Kota Kanbe
9b8a323d85 fix(report): detect 0 vulns for Amazon, FreeBSD, Raspbian (#765) 2019-01-24 11:49:33 +09:00
kota kanbe
3178c1e326 Merge branch 'master' of https://github.com/future-architect/vuls
* 'master' of https://github.com/future-architect/vuls:
  Add Telegram support (#762)
2019-01-23 00:25:54 +09:00
kota kanbe
321d68e03a Bump up version 2019-01-23 00:25:02 +09:00
Yao Ding
3d8753c621 Add Telegram support (#762)
* add telegram support

* format message

* remove debug print

* fix linting error

* add telegram to discover; group message by 10

* use chatID instead of channel

* apply refactor

* remove reduntant space
2019-01-23 00:19:16 +09:00
Tomoya Amachi
967c56909d add ScannedIPv4Addrs and ScannedIPv6Addrs (#764) 2019-01-19 22:19:06 +09:00
Takayuki Ushida
7c4831d2d1 add build time (#763) 2019-01-18 13:13:50 +09:00
Shigechika AIKAWA
4b49e11a33 add(report) -format-list option to -to-email (#761) 2019-01-17 16:31:04 +09:00
Kota Kanbe
d84a6a8627 fix(oracle): vuls report returns different result each time in the case of Oracle Linux (#759)
https://github.com/kotakanbe/goval-dictionary/pull/56
2019-01-12 23:11:06 +09:00
sadayuki-matsuno
63b7f4a8db delete paperr (#758) 2019-01-12 22:40:56 +09:00
yahharo
ca2160264a Remove ThreadTimeStamp from message struct (#756)
- If `thread_ts` valus sent as empty string ("") to Slack, it returns error `invalid_thread_ts`
- When API try to send, it use `slack.PostMessageParameters`, not use `message`
2018-12-25 12:27:53 +09:00
Kota Kanbe
7842594f53 fix(scan): OS detection ssh timeout in first run #699 (#753) 2018-12-20 13:59:54 +09:00
Kota Kanbe
7db056102c fix(report): overdetection for Red Hat/CentOS with redis backend (#748)
fix(report): miss detection for Red Hat/CentOS with redis backend
2018-12-06 15:29:28 +09:00
Tomoya Amachi
a5a800fa0a add alert data to result json (#747)
* add alert data to result json

* delete omitempty from AlertDict
2018-12-05 15:38:23 +09:00
Tomoya Amachi
9147ec148d Beautify alert (#746)
* update dep

* to make easy edit alert data manually

* fix alert data bug
2018-12-05 12:30:04 +09:00
sadayuki-matsuno
b3260588c6 fix(gost) update pkg to incorporate the latest gost (#745) 2018-12-04 17:33:31 +09:00
sadayuki-matsuno
7d31328271 export exploit func (#744) 2018-11-30 16:53:51 +09:00
Kota Kanbe
6e82981ee3 feat(report): Display CERT information to reports (#741)
* fix(tui): show JPCERT Alert URL in TUI

* feat(tui): show `!` when the CVE-ID corresponds to USCERT or JPCERT alert

* feat(report): display cert alert info to stdout report

* fix(report): Display CVEs detected by CPEs with -ignore-unfixed flag
2018-11-30 15:41:59 +09:00
Tomoya Amachi
9d7b115bb5 add JPCERT and USCERT alert dictionary (#740)
* add alert dictionary

* fix for sider review

* fix for sider review
2018-11-30 14:17:17 +09:00
Kota Kanbe
8eae5002a3 fix(report): return both scores of gost and oval (#739) 2018-11-29 12:17:19 +09:00
Kota Kanbe
31bd6c0371 feat(scan): get repository name of updatable pkgs for debian/ubuntu (#738) 2018-11-26 12:02:52 +09:00
Kota Kanbe
7585f9d537 fix(report): fix cvedb-url, add -cvedb-type=http (#734)
* fix(report): fix cvedb-url, add -cvedb-type=http

* feat(report): support go-exploitdb server mode

* update deps

* implement tui

* fix server mode

* fix(tui): default value of cvedb-type to ""

* update deps
2018-11-16 21:22:18 +09:00
sadayuki-matsuno
76037cdf72 fix new cve contents (#735) 2018-11-15 13:43:06 +09:00
sadayuki-matsuno
98c5421edc fix exploit db (#733) 2018-11-12 17:36:53 +09:00
Kota Kanbe
e63fc7e3f5 fix(report): nil pointer in deep scan mode #728 (#732) 2018-11-10 12:36:12 +09:00
sadayuki-matsuno
6ed9cf3fb4 add scan mode (#731) 2018-11-05 15:35:50 +09:00
sadayuki-matsuno
9865eab2c0 Display exploit codes information for each detected CVE-IDs (#729)
* add exploit

* bug fix while loading config in TUI, display in format-full-text

* fix readme
2018-11-03 16:36:59 +09:00
Kota Kanbe
678e72a8b6 fix(gost): a bug of parseCwe (#726) 2018-10-29 21:21:20 +09:00
sadayuki-matsuno
ec41899089 check cve_contents init (#725)
check cve_contents init to avoid nil pointer
2018-10-29 16:27:54 +09:00
Harald Nordgren
b2d913cc21 Bump Go versions and use '.x' to always get latest patch versions (#724) 2018-10-29 16:26:20 +09:00
sadayuki-matsuno
bc86c24e6a update pkg (#723)
* update pkg

* change lint url
2018-10-18 13:37:17 +09:00
sadayuki-matsuno
87a77dd95c update pkgs (#720) 2018-10-10 17:43:26 +09:00
sadayuki-matsuno
e8188f3432 add ms gost (#718)
* add ms gost

* change gost branch
2018-10-05 12:45:26 +09:00
Kota Kanbe
50506be546 [WIP] feat(report): show repository of affected pkgs (#713)
feat(report): show repository of affected pkgs
2018-10-04 16:01:55 +09:00
Iskander (Alex) Sharipov
4ded028258 config: remove commented-out code from tomlloader (#714)
Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>
2018-10-04 12:37:58 +09:00
Iskander (Alex) Sharipov
6da8b3c4a1 commands: simplify s[:] to s (#715)
If s is a slice, then `s[:]` is identical to just `s`.

Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>
2018-10-04 12:37:31 +09:00
Iskander (Alex) Sharipov
d5c92cbcb3 report: simplify x = x <op> y to x <op>= y (#716)
Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>
2018-10-04 12:35:02 +09:00
sadayuki-matsuno
ed5f98d6f0 change syslog pkg (#717) 2018-10-04 12:34:23 +09:00
Kota Kanbe
f854b8f908 fix(report): fix an error while loading cveDict.type in config.toml (#711) 2018-10-02 09:27:34 +09:00
Shigechika AIKAWA
de7a6159d4 remove table.SetHeaderColor codes (#709)
table.SetHeaderColor does not need in case of formatFullPlainText().
2018-09-25 10:31:22 +09:00
Kota Kanbe
6090a34037 fix(cpe): update deps to avoid parsing err of cpeNames (#708) 2018-09-13 13:42:04 +09:00
Kota Kanbe
f566745479 fix(config): a DB URL error 'does not validate as url' #705 (#706) 2018-09-11 09:19:24 +09:00
kota kanbe
153234b623 update readme 2018-08-29 22:39:05 +09:00
Kota Kanbe
ac510d21ff fix(scan): fix err msg when unable to connect via SSH (#702) 2018-08-29 10:48:32 +09:00
Kota Kanbe
44fa2c5800 v0.5.0 (no backwards compatibility) (#478)
* Change config.toml, Auto-generate UUIDs, change structure of optional field

* Detect processes affected by update using yum-ps (#482)

Detect processes affected by update using yum-ps

* Detect processes needs restart using checkrestart on Debian and Ubuntu.

* pass cpename by args when calling FillCveInfo (#513)

* fix new db (#502)

* Include Version,Revision in JSON

* Include hostname in JSON

* Update goval-dictionary's commit hash in Gopkg.lock

* Remove README.ja.md

* update packages (#596)

* fix: change ControlPath to .vuls of SSH option (#618)

* feat: checkrestart for Ubuntu and Debian (#622)

* feat: checkrestart for Ubuntu and Debian

* fix: dependencies check logic of configtest

* feat: need-restarting on RedHat

* refactor: Process.ProcName to Process.Name

* feat: detect a systemd service name of need-restarting-process

* feat: detect a systemd service name of need-restarting-process on Ubuntu

* feat: fill a service name of need-restarting-process, init-system

* Support NVD JSON and CVSS3 of JVN (#605)

* fix: compile errors

* fix: Show CVSS3 on TUI

* fix: test cases

* fix: Avoid null in JSON

* Fix maxCvssScore (#621)

* Fix maxCvssScore

* Update vulninfos.go

* fix(init): remove unnecessary log initialization

* refactor(nvd): use only json feed if exists json data. if not, use xml feed

* fix(scan): make Confidence slice

* feat(CWE): Display CWE name to TUI

* feat(cwe): import CWE defs in Japanese

* feat(cwe): add OWASP Top 10 ranking to CWE if applicable

* feat(scan): add -fast-root mode, implement scan/amazon.go

* refactor(const): change const name JVN to Jvn

* feat(scan): add -fast-root mode, implement scan/centos.go

* refactor(dep): update deps

* fix(amazon): deps check

* feat(scan): add -fast-root mode, implement scan/rhel.go

* feat(scan): add -fast-root mode, implement scan/oracle.go

* fix complile err

* feat(scan): add -fast-root mode, implement scan/debian.go

* fix testcase

* fix(amazon): scan using yum

* fix(configtest): change error message, status when no scannnable servers

* Fix(scan): detect init process logic

* fix(tui): display cvss as table format

* fix(scan): parse a output of reboot-notifier on CentOS6.9

* fix(tui): don't display score, vector when score is zero

* fix(scan): add -offline mode to suse scanner

* fix(scan): fix help message

* feat(scan): enable to define scan mode for each servers in config.toml #510

* refactor(config): chagne cpeNames to cpeURIs

* refactor(config): change dependencyCheckXMLPath to owaspDCXMLPath

* fix(config): containers -> containersIncluded, Excluded, containerType

* feature(report): enable to define cpeURIs for each contaner

* feature(report): enable to specify owasp dc xml path for each container

* fix(discover): fix a template displayed at the end of discover

* feature(report): add ignorePkgsRegexp #665

* feature(report): enable to define ignoreCves for each container #666

* fix(report): Displayed nothing in TUI detail area when CweID is nil

* Gopkg.toml diet

* feat(server): support server mode (#678)

* feat(server): support server mode

* Lock go version

* Use the latest kernel release among the installed release when the running kernel release is unknown

* Add TestViaHTTP

* Set logger to go-cve-dictionary client

* Add -to-localfile

* Add -to-http option to report

* Load -to-http conf from config.toml

* Support gost (#676)

* feat(gost): Support RedHat API

* feat(gost): Support Debian Security Tracker

* feat(db): display error msg when SQLite3 is locked at the beginning of reporting.

* feat(gost): TUI

* Only use RedHat information of installed packages

* feat(tui): show mitigation on TUI

* feat(gost): support redis backend

* fix test case

* fix nil pointer when db is nil

* fix(gost): detect vulns of src packages for Debian

* feat(gost): implement redis backend for gost redhat api

* feat(report): display fixState of unfixed pkgs

* fix(report): display distincted cweIDs

* feat(slack): display gost info

* feat(slack): display mitigation

* feat(report): display available patch state as fixed/total

* fix(tui): display - if source of reference is empty

* update deps

* fix(report): key in ScanResult JSON be lowerCamelcase.

* some keys to lower camel

* fix(configtest): dep check logic of yum-plugin-ps

* fix(tui): format

* feat(report): add -format-list option

* fix(report): -format-full-text

* fix(report): report -format-full-text

* fix(report): display v3 score detected by gost

* fix(scan): scan in fast mode if not defined in config.toml

* fix(gost): fetch RedHat data for fixed CVEs

* feat(report): show number of cves detected in each database

* fix(report): show new version as `Unknown` in offline and fast scan mode

* fix(report): fix num of upadtable and fixed

* fix(report): set `Not fixed yet` if packageStatus is empty

* refact(gost): make convertToModel public

* fix(test): fix test case

* update deps

* fix(report): include gost score in MaxCvssScore

* [WIP] feat(config): enable to set options in config.toml instead of cmd opt (#690)

* feat(config): enable to set options in config.toml instead of cmd opt

* fix(config): change Conf.Report.Slack to Conf.Slack

* fix(discover): change tempalte

* fix(report): fix config.toml auto-generate with -uuid

* Add endpoint for health check and change endpoint

* refact(cmd): refactor flag set

* fix(report): enable to specify opts with cmd arg and env value

* fix(scan): enable to parse the release version of amazon linux 2

* add(report) add -to-saas option (#695)

* add(report) add -to-saas option

* ignore other writer if -to-saas

* fix(saas) fix bug

* fix(scan): need-restarting needs internet connection

* fix(scan,configtest): check scan mode

* refactor(scan): change func name

* fix(suse): support offline mode, bug fix on AWS, zypper --no-color

* fix(tui): fix nil pointer when no vulns in tui

* feat(report): enable to define CPE FS format in config.toml

* fix(vet): fix warnings of go vet

* fix(travis): go version to 1.11

* update deps
2018-08-27 13:51:09 +09:00
Masayuki Matsuki
d785fc2a54 Lint (#700)
* adjust GNUmakefile by using ... wildcard

go command excludes vendored packages from ... wildcard Go1.9 or later

* fix vet warnings

* fmt
2018-08-26 21:22:37 +09:00
Kota Kanbe
ea800e04bc fix(report): generate report even if some scan-err-jsons are included #685 (#686) 2018-07-24 22:26:46 +09:00
kota kanbe
fe582ac635 Change GitHub templates 2018-07-19 10:04:31 +09:00
Takayuki Ushida
330edb3bce change copyright (#677) 2018-07-17 15:10:36 +09:00
Teppei Fukuda
212fec7115 Remove old Dockerfile (#684) 2018-07-12 21:02:59 +09:00
Teppei Fukuda
24d7021c47 Refactor Dockerfile (#683) 2018-07-12 20:28:18 +09:00
Kota Kanbe
e3a01ff6a8 fix(report): database is locked with SQLite3 backend #681 (#682) 2018-07-11 11:11:57 +09:00
Kota Kanbe
81f2ba8a46 fix(report): record not found on reporting with OVAL #679 (#680)
* fix(report): record not found on reporting with OVAL #679

* lock go version in .travis.yml
2018-07-10 15:14:35 +09:00
Kota Kanbe
9e9370b178 refactor(suse): add testcase for detectSUSE (#675)
* refactor(suse): add testcase for detectSUSE
2018-06-25 14:46:41 +09:00
jenningsloy318
ced6114a95 pull request to add SLES variant OS SLES_SAP support (#672)
* add SLES_SAP fix

* add SLES_SAP version regexp
2018-06-25 14:34:40 +09:00
Teppei Fukuda
3144faae5d feat(syslog): add all CVSS scores/vectors (#664) 2018-06-06 20:56:56 +09:00
Teppei Fukuda
8960c67a82 fix(report): use CVSS score not calculated from severity preferentially (#663) 2018-06-06 18:58:24 +09:00
Teppei Fukuda
f8ca924434 Add title to syslog (#662) 2018-06-06 10:36:59 +09:00
Kota Kanbe
399a08775e feat(scan): add -ssh-config option #417 (#660) 2018-05-31 12:39:46 +09:00
Zsolt
92f36ca558 Add missing ca-certificates, needed for slack webhook (#657) 2018-05-24 10:16:13 +09:00
Zsolt
3dcc58205a Move to alpine based docker images (#643) 2018-05-23 15:32:05 +09:00
Kota Kanbe
09779962cf Fix(reporting): NotFixedYet of SourcePackage in OVAL match on Debian and Ubuntu (#656)
* fix(refactoring): oval

* Fix(reporting): NotFixedYet of SourcePackage in OVAL match on Debian and Ubuntu #655
2018-05-22 18:53:08 +09:00
Kota Kanbe
9cc78770a3 fix(configtest): Only warning when reboot-notifier is not installed on Debian (#654) 2018-05-21 14:57:05 +09:00
Zsolt
f653ca9131 Don't check reboot-notifier package for debian containers (#642) 2018-05-21 14:11:59 +09:00
Teppei Fukuda
6f9fd91849 Send logs via syslog when no CVE-IDs found (#646) 2018-05-17 12:04:23 +09:00
Teppei Fukuda
cb1aec4fc0 Add scanned_at into syslog report (#641) 2018-05-11 11:17:45 +09:00
Kota Kanbe
7cebaf8a76 Use servername for SSH ControlPath filename (#640) 2018-05-09 16:45:03 +09:00
Kota Kanbe
241c943424 fix(tui): show CVSS severity on TUI for Ubuntu (#638)
* fix(tui): show CVSS severity on TUI for Ubuntu

* refactoring
2018-05-02 17:07:20 +09:00
kazuminn
d5d88d8cf0 Refactor stride (#637)
* refactor

* go fmt
2018-05-02 16:58:29 +09:00
nohararc
cf9d26068c Update README.md (#631)
fix typo.
2018-04-27 15:52:40 +09:00
Cyrille Hemidy
308a93dc72 misspell (#632)
* Update tomlloader.go

fix misspelling

* Update packages.go

fix misspelling

* Update scanresults.go

fix misspelling
2018-04-27 15:52:16 +09:00
kota kanbe
d6a7e65e4c [refactor]make fmt 2018-04-27 15:07:12 +09:00
kazuminn
e0a5c5d3b8 refactoring : hipchat (#635)
* refactoring
2018-04-27 15:04:35 +09:00
adachin
314f775243 Chatwork support (#634) 2018-04-27 14:59:58 +09:00
kazuminn
7a1644135a Stride support (#624) 2018-04-10 13:30:22 +09:00
Kota Kanbe
5076326589 Fix Amazon Linux 2 scanning (#630)
* fix(amazon2): fix OS version parse error
2018-04-10 11:53:11 +09:00
Kota Kanbe
ce56261b52 fix(redhat): fix detection method of changelog scan (#628)
fix(redhat, deepscan): fix detection method of changelog scan
2018-03-29 21:17:44 +09:00
Kota Kanbe
baa0e897b2 fix: a bug of diff logic when multiple oval defs found for a certain CVE-ID and same updated_at (#627)
* fix: a bug of diff logic when multiple oval-defs hav certain CVE-ID and same updated_at

Commented out beause a bug of diff logic when multiple oval defs has certain CVE-ID and same updated_at.
If these OVAL defs have different affected packages, this logic detects not-updated-CVE-ID as updated.
This logic will be uncommented after integration with ghost https://github.com/knqyf263/gost
2018-03-26 22:29:14 +09:00
Teppei Fukuda
1d49c0e1ce fix(scan): fix RHEL 5 (#626) 2018-03-26 17:40:39 +09:00
Teppei Fukuda
08755e446e fix(fmt): fix gofmt warn (#625) 2018-03-23 12:28:12 +09:00
Kota Kanbe
bb12d9dadb Add diff to TUI (#620)
* fix: change ControlPath to .vuls of SSH option (#618)

* feat: Add diff option to TUI
2018-03-16 15:18:10 +09:00
Kota Kanbe
fd1429fef0 Fix diff logic (#619)
* fix: change ControlPath to .vuls of SSH option (#618)

* fix: Bug of diff logic
2018-03-16 15:07:26 +09:00
kazuminn
d3c421a4a8 inform new release on diff option (#614)
inform new release on diff option (#614)
2018-03-15 13:30:33 +09:00
Kota Kanbe
0c919da4b1 fix: change ControlPath to .vuls of SSH option (#618) 2018-03-14 16:39:17 +09:00
Kota Kanbe
9afbf1255f feat: Add -vvv option to scan cmd (#617) 2018-03-14 12:18:03 +09:00
Kota Kanbe
50b105c4af fix: SSH session multiplexing (#616) 2018-03-13 22:35:25 +09:00
kazuminn
028508c1f7 fix link nvd on hipchat (#613) 2018-03-13 12:32:55 +09:00
Kota Kanbe
f0137a3695 feat: Display pkg information to slack notification #611 (#612) 2018-03-09 10:26:41 +09:00
Kota Kanbe
e6d3a1718c fix: validation for reporting (#610) 2018-03-07 14:01:52 +09:00
Kota Kanbe
86ba551e07 fix: remove a validation of hipchat (#609) 2018-03-07 05:21:57 +09:00
kazuminn
26418be937 hipchat support (#593)
* first commit

* hipchat conf

* hipchat conf
2018-03-06 17:40:21 +09:00
Kota Kanbe
092a19bdc1 fix: bug of report -diff option (#607) 2018-03-06 16:50:09 +09:00
Kota Kanbe
6d3398574c fix: support CentOS cloud image (#606)
https://bugzilla.redhat.com/show_bug.cgi?id=1332025
2018-03-06 14:10:21 +09:00
Teppei Fukuda
b08969ad89 Support a reporting via Syslog (#604)
* Support a reporting via syslog

* Update dependencies
2018-02-27 20:38:34 +09:00
Kota Kanbe
0653656526 fix: add some logging for goval-dictionary (#603) 2018-02-19 13:30:42 +09:00
Teppei Fukuda
7a5793c562 Add IP address to scan results (#602) 2018-02-19 12:50:00 +09:00
Emilien Kenler
562ff7807d Support AWS S3 Server-Side Encryption (#597)
* Support AWS S3 Server-Side Encryption

* Improve documentation for aws-s3-server-side-encryption
2018-02-12 11:26:23 +09:00
Kota Kanbe
7971bdf7f7 fix: Kindness error message in reporting (#601) 2018-02-12 10:57:09 +09:00
Kota Kanbe
d926b7fd6d Update deps (#592) 2018-01-24 01:02:02 +09:00
Kota Kanbe
c00404793a Add offline option to scan and configtest (#588)
Add offline option to scan and configtest
2018-01-19 01:07:44 +09:00
Kota Kanbe
a0e0ee6c1e Move README to Vulsdoc https://vuls.io (#586) 2018-01-17 18:03:37 +09:00
Kota Kanbe
4ccbee705b If the OWASP dc XML does not exist, continue reporting after warning #580 (#582) 2018-01-16 17:08:12 +09:00
Mai MISHIRO
db43d55b2c Fixed panic occurred when blank line continued in changelog (#569) 2018-01-05 10:23:44 +09:00
~Stack~
5a3a333eec Fixed Typo (#574) 2018-01-05 10:20:35 +09:00
nakamurakyo
039edf1616 fix typo(BackSpace) in README.ja.md (#576) 2018-01-05 10:20:06 +09:00
Kota Kanbe
47498bbf23 Fix a bug of sending to closed socket while oval access via HTTP #578 (#579) 2018-01-05 10:12:21 +09:00
Yoshikazu Aoyama
cc28bf4ae2 fix typo in reports/s3.go (#573) 2017-12-27 22:30:26 +09:00
Mai MISHIRO
0e8736045e LXC container support without LXD (#552)
* LXC container support without LXD

* Fix: LXC required root privilege

* Update README
2017-12-18 22:54:32 +09:00
Kota Kanbe
19b581edef Support Amazon Linux2 (#562) 2017-12-15 20:07:49 +09:00
Mai MISHIRO
295f6656d9 Fix #548 and #557 - RHEL's Fast Scan no longer required internet connection and root privilege (#559) 2017-12-15 19:34:10 +09:00
Mai MISHIRO
1214d8c14d Change error handling of "Reboot Required" detection (#556) 2017-12-12 17:03:42 +09:00
Mai MISHIRO
b4cd96fc9a Fix some RPM related commands failed in the container (#554) 2017-12-12 12:14:57 +09:00
Davor Kapsa
3238a9b898 travis: update go version (#555) 2017-12-11 14:35:13 +09:00
Mai MISHIRO
c0f66320f6 Add more kernel related packages (Fix #541) (#551) 2017-12-11 14:32:20 +09:00
Kota Kanbe
383220f384 Remove empty CveContent output to JSON with Alpine Linux scan (#550) 2017-12-04 12:52:32 +09:00
Takayuki Ushida
76a9c37e6b Update README (#547) 2017-12-02 00:47:49 +09:00
Kota Kanbe
e788e6a5ad Support Alpine Linux #194 (#545)
* Support Alpine Linux #194

* Fix testcase

* Fix README

* Fix dep files

* Fix changelog

* Bump up version
2017-12-01 23:17:28 +09:00
Flaviu
d00e912934 Replace strings.HasPrefix with strings.Index for SuSE scanner (#546) 2017-11-21 11:37:43 +09:00
Kota Kanbe
8ebb663368 Fix yum changelog option (#543) 2017-11-15 17:32:17 +09:00
nnao45
445ffc4123 Update README.md (#542) 2017-11-14 17:05:12 +09:00
Kota Kanbe
6af49f4d55 Fix false positive: ignore oval info when kernel major version is different. (#541) 2017-11-10 23:33:43 +09:00
Mai MISHIRO
1de9e8c086 Fix: Misdetection of OvalMatch for CentOS and Scientific in oval/util.go (#536)
* Fix: Misdecection of OvalMatch for CentOS in oval/util.go

* Remediation: Misdetection of OvalMatch for Scientific (currently treated as RHEL) oval/util.go

* The regular expression was changed because the release number of CentOS and Scientific's unchanged package is different from upstream.

* OvalMatch test of RedHat and CentOS has been added.
2017-11-09 11:20:23 +09:00
Mai MISHIRO
59b0812adf Fix: "Reboot Required" detection process in scan/redhat.go (#534) 2017-11-08 17:16:59 +09:00
kota kanbe
719785c1ed Remove README.fr.md because unable to maintenance.. 2017-11-08 16:11:03 +09:00
nakacya
8e5f627e59 README Typo Update (#538)
* Update README.ja.md

Typo Update

* Update README.md

Typo Update
2017-11-08 15:57:18 +09:00
Kota Kanbe
5ced3c72b8 Insert sudo only at the beginning of command in deep scan #495 (#539)
* Insert `sudo` only at the beginning of command in deep scan #495

* Fix testcase
2017-11-08 15:48:43 +09:00
Kota Kanbe
c002f0168c Fix config.toml validation (#537) 2017-11-06 09:56:18 +09:00
Kota Kanbe
00c690f516 Add pseudo server type for non-ssh scanning (only cpe scan) #512 (#531)
* Add pseudo server type for non-ssh scanning (only cpe scan) #512

* Don't check hostname for pseudo type

* Update README.md
2017-11-02 17:02:06 +09:00
nakacya
ab68ad5cc5 README Update (#530)
* README.ja.md Update

Add Update steps

* Update README.ja.md

* Update README.ja.md

* README.md update

Add Update steps
2017-10-30 13:24:46 +09:00
kota kanbe
5c84ebefab Update README 2017-10-26 14:54:15 +09:00
sadayuki-matsuno
eb2acaff22 send slack msg by api (#525) 2017-10-26 13:30:01 +09:00
shimojomasatsugummm
84d0655c52 fix typo Privious -> Previous (#523) 2017-10-25 18:51:29 +09:00
nashiox
e137ebb9c2 Fix package query fails on debian based container (#519) (#522)
* Fix package query fails on debian based container (#519)

* Fix executil test (#519)
2017-10-25 18:49:47 +09:00
atsu
10d690d929 fix typo from "enviroment" to "environment" (#518) 2017-10-21 18:28:53 +09:00
yuu26
14611d2fd9 Fix typo in config/jsonloader.go (#517) 2017-10-20 14:34:48 +09:00
x-blood
0665bfe15f Modified Spell Miss of "README.md". (#516)
* Modified spell miss of README.md. 1305:Calculator

* Revert "Modified spell miss of README.md. 1305:Calculator"

This reverts commit 0e0db1be8d.

* Modified spell miss of README.md. line:1305"Calculator"
2017-10-20 14:02:16 +09:00
kota kanbe
473096d35d Fix .goreleaser.yml 2017-10-19 14:31:35 +09:00
kota kanbe
0eae26e261 Merge branch 'master' of https://github.com/future-architect/vuls
* 'master' of https://github.com/future-architect/vuls:
  Fix a bug of making channels when fill oval information via HTTP (#514)
2017-10-17 13:37:06 +09:00
Kota Kanbe
a32845f652 Fix a bug of making channels when fill oval information via HTTP (#514)
* Fix a bug of making channels when fill oval information via HTTP
2017-10-17 13:36:49 +09:00
kota kanbe
15a0f7eadb Merge branch 'master' of https://github.com/future-architect/vuls
* 'master' of https://github.com/future-architect/vuls:
  Fix OVAL detection on Debian and Ubuntu (#509)
2017-10-16 14:13:40 +09:00
Kota Kanbe
5a0a6abf11 Fix OVAL detection on Debian and Ubuntu (#509)
* Add filter options to tui subcommand (#508)

* Capture version of source packages on Debian based linux

* Change makefile, gofmt -s

* Refactoring

* Implement OVAL detection of source packages for Debian, Ubuntu
2017-10-13 17:22:11 +09:00
kota kanbe
032b8d9572 Merge branch 'master' of https://github.com/future-architect/vuls
* 'master' of https://github.com/future-architect/vuls:
  Add filter options to tui subcommand (#508)
2017-09-29 08:41:31 +09:00
Kota Kanbe
5798e3af83 Add filter options to tui subcommand (#508) 2017-09-29 08:37:32 +09:00
Kota Kanbe
8e15b9ce1c Add filter options to tui subcommand (#508) 2017-09-28 18:31:09 +09:00
Kota Kanbe
7a1f132c1f Add -ignore-unfixed option to report subcommand #485 (#507) 2017-09-28 17:29:47 +09:00
Emilien Kenler
a8483b2195 Add goreleaser to distribute binaries (#460)
See https://github.com/future-architect/vuls/issues/459
2017-09-28 15:29:27 +09:00
kota kanbe
83bbbd0cb0 Add goreportcard to README 2017-09-28 15:23:51 +09:00
Kota Kanbe
132432dce6 Support SUSE Enterprise Linux (#487)
* Support SUSE Enterprise Linux

* Implement Reboot Required detection on SLES

* Fix query OVAL because SUSE provides OVAL data each major.minor version

* Update README

* Support SUSE Enterprise 11
2017-09-28 12:23:19 +09:00
Xiuming Chen
e5eb8e42f5 Debian: Use --showformat flag to get status of packages and ignore n(not-inst… (#484)
* Use --showformat flag to get status of packages and ignore n(not-installed) and c(removed, only has config files remaining) packages.

* Ignoring all packages that are not in 'Installed' status.

* Simplify char escaping in the command.

* Fix typo.
2017-09-27 09:43:59 +09:00
Takayuki Ushida
1095ebea24 fix vulsrepo dockerfile (#496) 2017-09-26 18:17:46 +09:00
328
1541a602b2 Update README.ja.md (#498) 2017-09-26 18:17:19 +09:00
~Stack~
03a141c252 Fix typos (#499)
* Update bolt.go

Fix typos

* Update util.go

Fix Typos
2017-09-26 18:16:54 +09:00
Kota Kanbe
5f2183fc8e Check repoquery with sudo nopasswd in deep scan mode on RedHat (#492) 2017-09-14 09:14:20 -07:00
Kota Kanbe
820831fa5d Fix sort order of servers on TUI (#481) 2017-09-05 15:54:13 +09:00
Kota Kanbe
6d2d767c52 Fix a arg of report subcommand (#479) 2017-09-04 14:47:25 +08:00
Kota Kanbe
e0c3a728ae Fix ping option of discover subcommand #471 (#472) 2017-08-30 14:13:53 +08:00
sadayuki-matsuno
ec92f7797f add windows type (#470) 2017-08-28 18:49:34 +08:00
Kota Kanbe
0ba490c6df Merge pull request #469 from usiusi360/use_vulsrepo-server
use_vulsrepo-server
2017-08-25 21:59:52 +09:00
usiusi360
cfd668e11d use_vulsrepo-server 2017-08-25 21:42:33 +09:00
kota kanbe
a8bc25321e Update Changelog.md 2017-08-25 11:21:31 +08:00
Kota Kanbe
fec13bcb86 Merge pull request #449 from future-architect/support_oval
v0.4.0
2017-08-25 11:20:02 +09:00
kota kanbe
cb1c07f998 Update README 2017-08-25 10:08:41 +08:00
Yasunari Momoi
6312b97faa fix typos in commands. (#464) 2017-08-23 19:29:31 +09:00
sadayuki-matsuno
21f13b55eb export fill cve info (#467) 2017-08-23 18:09:22 +09:00
kota kanbe
187598382b Update README 2017-08-23 17:38:23 +09:00
kota kanbe
551fdd5022 Display "Reboot Required" on report if the kernel has been updated but not restarted 2017-08-23 13:59:19 +09:00
kota kanbe
58b0d03e28 No escape on details view in TUI 2017-08-23 12:02:58 +09:00
kota kanbe
3790197699 Fix ignoreCves option 2017-08-22 20:28:24 +09:00
kota kanbe
579fff122c Merge branch 'support_oval' of https://github.com/future-architect/vuls into dev_v0.4.0
* 'support_oval' of https://github.com/future-architect/vuls:
  add oval docker (#466)
2017-08-22 18:14:43 +09:00
kota kanbe
feb3f79a13 Update Gopkg 2017-08-22 18:14:00 +09:00
kota kanbe
b5cb08ac43 Handle kernel's vulns using OVAL 2017-08-22 17:44:50 +09:00
sadayuki-matsuno
4ac5d9e0da add oval docker (#466)
* add oval docker

* Update README.md
2017-08-22 12:40:54 +09:00
kota kanbe
93f741da35 Show Not Fixed Yet in report, tui 2017-08-19 00:21:11 +09:00
kota kanbe
648a999514 Include config in json result 2017-08-18 22:39:45 +09:00
kota kanbe
71490aebd9 Fix sudo in deep scan of RHEL 2017-08-17 21:17:13 +09:00
kota kanbe
9e90c0f912 Implement NotFixedYet for CentOS 2017-08-17 20:07:39 +09:00
kota kanbe
de65073f61 Set NotFixedYet for Ubuntu Scan 2017-08-17 15:32:22 +09:00
kota kanbe
6129ac7bd4 Change model ScanResult.ScannedCves.AffectedPackages 2017-08-17 12:18:06 +09:00
kota kanbe
b5d4d27312 Fix "Vulnerable package: is not found" error on FreeBSD 2017-08-16 14:34:59 +09:00
kota kanbe
823fcd91f4 Merge branch 'support_oval' of https://github.com/future-architect/vuls into dev_v0.4.0
* 'support_oval' of https://github.com/future-architect/vuls:
  Update README.ja.md
2017-08-16 11:54:45 +09:00
kota kanbe
477e12d5cf Fix FreeBSD detection 2017-08-16 11:54:19 +09:00
Kota Kanbe
a36a226ae2 Update README.ja.md 2017-08-15 17:29:14 +09:00
kota kanbe
886a21c633 Bump up version to 0.4.0 2017-08-15 10:43:59 +09:00
kota kanbe
fd19fa2082 nosudo repoquery 2017-08-15 10:37:11 +09:00
kota kanbe
843f1a462f Fix checkDependencies for redhat.go 2017-08-14 15:53:11 +09:00
kota kanbe
5c5b8a361d Merge branch 'support_oval' of https://github.com/future-architect/vuls into dev_v0.4.0
* 'support_oval' of https://github.com/future-architect/vuls:
  Update README (#463)
2017-08-14 00:07:54 +09:00
Kota Kanbe
417df0582d Update README (#463) 2017-08-14 00:07:39 +09:00
kota kanbe
999d8f5866 Update README 2017-08-14 00:05:20 +09:00
kota kanbe
47a444e795 Use CVE>Impact as severity when it is not empty (RedHat OVAL) 2017-08-13 22:17:25 +09:00
kota kanbe
dbceca8780 Update Gopkg.lock 2017-08-13 21:51:43 +09:00
kota kanbe
c66898e608 Set actually affected package's name only to vulnInfo.PackageNames 2017-08-13 20:50:26 +09:00
kota kanbe
ee20cb59a5 Refactoring 2017-08-13 17:56:12 +09:00
kota kanbe
5c51d83573 Refactoring 2017-08-13 17:18:01 +09:00
kota kanbe
47b3b3848b Refactoring 2017-08-13 15:31:14 +09:00
sadayuki-matsuno
95eb980f58 export FillWithOval (#462) 2017-08-11 17:27:10 +09:00
kota kanbe
f738622c28 Update png in README.md 2017-08-11 13:31:02 +09:00
kota kanbe
577509bbf9 Fix MaxCvssScore logic 2017-08-09 16:18:09 +09:00
kota kanbe
774c78add0 Fix oval-db existence check on reporting 2017-08-09 16:18:09 +09:00
kota kanbe
b14406e329 Fix check logic of dependent packages in redhat.go 2017-08-09 16:18:09 +09:00
kota kanbe
29cf4bb517 Setup changelog cache only when necessary 2017-08-09 16:18:09 +09:00
kota kanbe
a233e08929 When scanning raspbian, always scan with deep scan mode 2017-08-09 16:18:09 +09:00
sadayuki-matsuno
cbd1c12773 add s3 dirctory option (#457) 2017-08-09 16:18:08 +09:00
sadayuki-matsuno
0a3f0f9ffc add serveruuid field (#458) 2017-08-09 16:18:08 +09:00
kota kanbe
d3014025b0 Update README 2017-08-09 16:18:08 +09:00
kota kanbe
2887dc0d36 Fix configtest to match fast and deep scan mode 2017-08-09 16:15:25 +09:00
kota kanbe
5f49e7da8e Refactoring 2017-08-09 16:15:25 +09:00
kota kanbe
9e0032b258 Fix cvss link in slack notification 2017-08-09 16:15:25 +09:00
kota kanbe
008da49b83 Imlement OVAL scan on Oracle Linux 2017-08-09 16:15:25 +09:00
kota kanbe
9899cba816 Display summary of advisory when no entry in NVD, OVAL 2017-08-09 16:15:25 +09:00
kota kanbe
27724a2faf Use CVSS seveirty of distro advisory when no entiry in NVD and OVAL 2017-08-09 16:15:25 +09:00
kota kanbe
8b6a283114 Add a deep flag to scan 2017-08-09 16:15:25 +09:00
kota kanbe
4379b8bacf Use version comparison logic when parsing change log (Ubuntu, Debian) 2017-08-09 16:15:25 +09:00
kota kanbe
56603dcfae Fix a bug of lower limit of cursor movement in TUI 2017-08-09 16:15:25 +09:00
kota kanbe
1752736714 Fix nil pointer 2017-08-09 16:15:25 +09:00
kota kanbe
b1428b6758 Fix a bug of fill oval information of Ubuntu 2017-08-09 16:15:25 +09:00
kota kanbe
9b6d84def6 Fix false positive detection on RHEL, Amazon and Oracle 2017-08-09 16:15:25 +09:00
kota kanbe
ed162d7d6e Display the information of yum updateinfo on TUI (for RHEL, Amazon, Oracle) 2017-08-09 16:15:25 +09:00
kota kanbe
1aae425945 Undisplay the number of CVEs at the end of 'scan --package-list-only' 2017-08-09 16:15:25 +09:00
kota kanbe
26e447f11a Check existence and last modified time of local OVAL database when reporting 2017-08-09 16:15:25 +09:00
Kota Kanbe
ffbaa0a508 Extract Advisory.Description on RHEL, Amazon, Oracle (#450) 2017-08-09 16:15:25 +09:00
Kota Kanbe
a9ebac3818 nosudo on CentOS and Fetch Changelogs on Amazon, RHEL (#448)
* Use repoquery for no sudo and avoid unintended line feed of yum or rpm. #444

* Change data type of enablerepo in config.toml. string to array

* Fetch yum changelogs at once then grep CVE-IDs

* Fix changelog parse logic and Update Gopkg
2017-08-09 16:15:25 +09:00
sadayuki-matsuno
738e9fb119 change logrus package to lowercase and update other packages (#446) 2017-08-09 16:15:25 +09:00
sadayuki-matsuno
7778783dd8 add db backend redis (#445) 2017-08-09 16:15:25 +09:00
Kota Kanbe
c442a433b0 Add OVAL HTTP health check 2017-08-09 16:15:24 +09:00
Kota Kanbe
f7aa85746d Add retry-max to HTTP access 2017-08-09 16:15:24 +09:00
Kota Kanbe
1883da3b2a Implement HTTP access to oval-dictionary 2017-08-09 16:15:24 +09:00
Kota Kanbe
997dd6022f Kind error message when SSH connection fails 2017-08-09 16:15:24 +09:00
Kota Kanbe
63394a2400 Fix error handling while loading JSON in reporting 2017-08-09 16:15:24 +09:00
Kota Kanbe
a662b038dc Fix CVSS2 in TUI 2017-08-09 16:15:24 +09:00
Kota Kanbe
e9df2bfa01 Convert null to empty in JSON 2017-08-09 16:15:24 +09:00
Kota Kanbe
a7951b727c Remove commented out code 2017-08-09 16:15:24 +09:00
Kota Kanbe
c6ad9ea57a Fix tui 2017-08-09 16:15:24 +09:00
Kota Kanbe
a14810bbd4 Fix -to-slack 2017-08-09 16:15:24 +09:00
Kota Kanbe
bc5a95ebb3 Fix -to-email 2017-08-09 16:15:24 +09:00
Kota Kanbe
306182e2ae Fix test cases 2017-08-09 16:15:24 +09:00
Kota Kanbe
ad096196ee Add vendor links to -format-shor-text 2017-08-09 16:15:24 +09:00
Kota Kanbe
af66e44427 SHow Vendor Links in text report 2017-08-09 16:15:24 +09:00
Kota Kanbe
0a012273ec Fix -ignore-unscored-cves 2017-08-09 16:15:24 +09:00
Kota Kanbe
73b011eba7 Sort results order by CVSS score, CVE-ID 2017-08-09 16:15:24 +09:00
Kota Kanbe
a31974a3c0 Use Severity ranking in OVAL when the CVSS scores are empty. 2017-08-09 16:15:24 +09:00
Kota Kanbe
eb02bdd95a Add test cases of models.Packages 2017-08-09 16:15:24 +09:00
Kota Kanbe
74805c6be8 Add test cases of CveContents 2017-08-09 16:15:24 +09:00
Kota Kanbe
d9bc4499a4 Refactoring 2017-08-09 16:15:24 +09:00
Kota Kanbe
9128e2748b Refactoring 2017-08-09 16:15:24 +09:00
Kota Kanbe
7f8c975bd7 Avoid concurrent Map writes 2017-08-09 16:15:24 +09:00
Kota Kanbe
8b6c841b1e Fix TestCase 2017-08-09 16:15:24 +09:00
Kota Kanbe
4fcdea3ccb Implement -format-full-text 2017-08-09 16:15:24 +09:00
Kota Kanbe
3be11cf52f Implement format-short-text 2017-08-09 16:15:24 +09:00
Kota Kanbe
b285cb0e57 Remove CRUD funcs of CveContents 2017-08-09 16:15:24 +09:00
Kota Kanbe
dd5a7920e5 Add JSON Version 2017-08-09 16:15:24 +09:00
Kota Kanbe
cfb848918f Change structure of ScanResult.[]VulnInfo to Map 2017-08-09 16:15:24 +09:00
Kota Kanbe
b977558f38 Change structure of VulnInfo.Pacakges to []string 2017-08-09 16:15:24 +09:00
Kota Kanbe
210e3dc990 Change ScanResult.Packages structure to Map 2017-08-09 16:15:24 +09:00
Kota Kanbe
f36671784e Fix testcase 2017-08-09 16:15:24 +09:00
Kota Kanbe
d626cc8a8b Rename PackageInfoList to Packages 2017-08-09 16:15:24 +09:00
Kota Kanbe
f26b61d773 Change CveContents data type to map 2017-08-09 16:15:24 +09:00
Kota Kanbe
12c2d3cbc6 Fix test cases 2017-08-09 16:15:24 +09:00
Kota Kanbe
209ca704de Fixed a bug caused by capturing epoch number on RedHat.go 2017-08-09 16:15:24 +09:00
Kota Kanbe
2e37d3adc1 Improve sort logics 2017-08-09 16:15:24 +09:00
Kota Kanbe
509fb045b6 Refactoring diff logic 2017-08-09 16:15:24 +09:00
Kota Kanbe
a2c364f9eb Refacotring 2017-08-09 16:15:23 +09:00
Kota Kanbe
17a4e532c1 Fix testcase 2017-08-09 16:15:23 +09:00
Kota Kanbe
c103b79ec2 Change models structure 2017-08-09 16:15:23 +09:00
Kota Kanbe
b545b5d0a3 Unify the models of NVD, JVN, OVAL 2017-08-09 16:15:23 +09:00
Kota Kanbe
342a1c6cff Refactoring 2017-08-09 16:15:23 +09:00
Kota Kanbe
aafbdcd34d Fix testcase 2017-08-09 16:15:23 +09:00
Kota Kanbe
ec092501c3 [BreakingChange]Remove models.ScanHistory 2017-08-09 16:15:23 +09:00
Kota Kanbe
bb708db89f Make it work on FreeBSD 2017-08-09 16:15:23 +09:00
Kota Kanbe
085a9dcb79 Fix Test Case 2017-08-09 16:15:23 +09:00
Kota Kanbe
037e12b0bd Add Ubuntu Support 2017-08-09 16:15:23 +09:00
Kota Kanbe
c9ab956f8f Make it work on Amazon Linux 2017-08-09 16:15:23 +09:00
Kota Kanbe
587c87b3a0 Fix RHEL oval scan 2017-08-09 16:15:23 +09:00
Kota Kanbe
1a319859eb Include RHEL, CentOS epoch number in version 2017-08-09 16:15:23 +09:00
knqyf263
c989c31aeb Support RHEL 2017-08-09 16:15:23 +09:00
Kota Kanbe
e5d32c8764 Debian Report using OVAL 2017-08-09 16:15:23 +09:00
Kota Kanbe
23c177ed4a -package-list-only for Debian 2017-08-09 16:15:23 +09:00
knqyf263
10a27042b5 Support Debian 2017-08-09 16:15:23 +09:00
Takayuki Ushida
2cec20c7ee Fix when reading tui config.toml (#441) 2017-08-08 20:35:04 +09:00
sadayuki-matsuno
7ecd09f497 fast go test (#435) 2017-06-24 00:51:48 +09:00
sadayuki-matsuno
8bf7f6cac5 fix typo (#433) 2017-06-24 00:51:12 +09:00
sadayuki-matsuno
067a2315df Add support for PostgreSQL as a DB storage back-end (#431) 2017-06-20 17:29:44 +09:00
ryurock
fecd1ad464 typo README.js.md (#426) 2017-04-24 23:30:05 +09:00
Kota Kanbe
a3f2555bc1 Add TOC to README (#425)
Add TOC to README
2017-04-22 21:02:26 +09:00
Teppei Fukuda
5bf4cd46ff Enable -timeout option when detecting OS (#410) 2017-04-22 18:39:13 +09:00
elfgoh
f878e225cc Fixing #420 where lock and manifest have moved to TOML (#421)
https://github.com/golang/dep/pull/342
2017-04-14 15:06:37 +09:00
Ján Koščo
eb2598f3b3 Define timeout for vulnerabilities scan and platform detection (#414) 2017-04-09 16:25:45 +09:00
Kota Kanbe
e20a59b991 SSH Hostkey check (#417)
* Add Hostkey check as default behavior when SSH
2017-04-06 18:08:55 +09:00
Kota Kanbe
703c142659 Change NVD URL to new one (#419) 2017-04-06 18:08:24 +09:00
Kota Kanbe
8335b40368 Add some testcases (#418) 2017-04-06 13:09:51 +09:00
Kota Kanbe
05884c2d29 Change default ssh method from go library to external command (#416)
* Change default ssh method from go library to external command
2017-04-06 12:00:09 +09:00
Teppei Fukuda
33b2aa2d52 Add containers-only option to configtest (#411) 2017-04-04 14:34:56 +09:00
Kota Kanbe
9ab0622886 Fix SSH dial error (#413)
Error message:
[Apr  2 13:36:49] DEBUG [localhost] Failed to Dial to u16, err: ssh: must specify HostKeyCallback, Retrying in 552.330144ms...

It is caused by breaking changes of Go library.
https://go-review.googlesource.com/c/38701/
2017-04-02 14:01:30 +09:00
Kota Kanbe
b33cd54916 Update deps, Change deps tool from glide to dep (#412) 2017-04-01 20:06:28 +09:00
Paul Furtado
d4bec0dd9a Add --user root to docker exec command (#389)
* Add --user root to docker exec command

If containers were run with their user set to something other than root,
docker exec will exec the command in the container as that user by
default. Unfortunately, this causes many package manager commands to
fail. This commit adds --user root to the docker exec command so that
commands executed inside the container will always run as root.

* Use numerical id for root rather than name
2017-03-31 18:58:00 +09:00
Teppei Fukuda
bdf6efeaac Merge pull request #401 from knqyf263/fix_readme
Remove duplicate command in README
2017-03-31 12:13:53 +09:00
hogehogehugahuga
74431ca63f fix report option Loaded error-info (#406) 2017-03-30 23:45:18 +09:00
knqyf263
c90be385ef Remove duplicate command 2017-03-24 16:50:32 +09:00
Kota Kanbe
b0d9c0b550 Update Changelog 2017-03-24 14:55:28 +09:00
Kota Kanbe
9255132f9b Bump up version 2017-03-24 14:37:48 +09:00
大沼
d5c0092fa3 fix typo (#394) 2017-03-24 00:25:23 +09:00
Teppei Fukuda
c7019debb9 Notify the difference from the previous scan result (#392)
add diff option
2017-03-23 23:58:05 +09:00
Kota Kanbe
7131270cad Add timeout option to configtest (#400) 2017-03-23 20:52:25 +09:00
Kota Kanbe
af5a1204bc Update README (#387)
Update Tutorial in README
2017-03-21 10:47:19 +09:00
Kota Kanbe
58afcfc49a Fix nil-ponter in TUI (#388) 2017-03-17 16:46:42 +09:00
Avi Miller
986762ca85 Add Oracle Linux support (#386)
Adding support for Oracle Linux
2017-03-16 17:07:43 +09:00
Kota Kanbe
6342cf79f5 Merge pull request #383 from usiusi360/Fix_README
Fix README
2017-03-15 17:47:36 +09:00
Kota Kanbe
5fbf67f971 Merge pull request #384 from future-architect/mysql
Fix Bug of Mysql Backend
2017-03-15 16:51:25 +09:00
Kota Kanbe
e441e5a696 Fix Bug of Mysql Backend 2017-03-15 16:44:49 +09:00
usiusi360
d201efb029 Fix README 2017-03-15 13:53:42 +09:00
Kota Kanbe
25960126c7 Fix README 2017-03-15 12:35:50 +09:00
Kota Kanbe
63d5a6f584 Merge pull request #382 from beuno/patch-1
s/dictinary/dictionary typo
2017-03-15 10:32:36 +09:00
Martin Albisetti
2030951a8f s/dictinary/dictionary typo 2017-03-14 16:50:36 -03:00
Kota Kanbe
cd841462cd Merge pull request #381 from future-architect/container-excluded
Change container scan format in config.toml
2017-03-14 20:32:22 +09:00
Kota Kanbe
735aa835a6 Change container scan setting in config.toml 2017-03-14 20:07:51 +09:00
Kota Kanbe
92e213ca32 Merge pull request #379 from future-architect/fix-scan-confidence-on-debian
Fix scan confidence on Ubuntu/Debian/Raspbian #362
2017-03-13 21:03:12 +09:00
Kota Kanbe
d077c29716 Fix scan confidence on Ubuntu/Debian/Raspbian #362 2017-03-13 20:55:23 +09:00
Kota Kanbe
d6eba48a50 Merge pull request #377 from IMAI-Yuji/IMAI-Yuji-patch-1
Fix Japanese typo
2017-03-13 17:27:11 +09:00
Kota Kanbe
2a1608d1d2 Merge pull request #378 from future-architect/obsolete-centos5
Obsolete CentOS5 support
2017-03-13 17:04:36 +09:00
Kota Kanbe
cc7d3dc2aa Obsolete CentOS5 2017-03-13 16:57:43 +09:00
Kota Kanbe
a5c4c682f5 Merge pull request #375 from future-architect/deprecate-prepare
Deprecate prepare subcommand to minimize the root authority defined by /etc/sudoers
2017-03-13 15:59:35 +09:00
Kota Kanbe
688cfd6872 Deprecate prepare subcommand to minimize the root authority #375 2017-03-13 13:21:01 +09:00
Yuji IMAI
7e268dbae1 Fix Japanese typo 2017-03-10 11:34:53 +09:00
Kota Kanbe
ce6a4231ef Deprecate prepare subcommand to minimize the root authority defined by /etc/sudoers 2017-03-07 18:09:10 +09:00
Kota Kanbe
e1de8ab626 Merge pull request #370 from ohsawa0515/support_iam_role
Support IAM role for report to S3.
2017-03-07 14:07:32 +09:00
Kota Kanbe
0058eaf357 Merge pull request #374 from future-architect/package-count
Fix updatalbe packages count #373
2017-03-07 14:03:19 +09:00
Kota Kanbe
732d95098a Fix updatalbe packages count #373 2017-03-07 13:49:25 +09:00
Shuichi Ohsawa
52f0943207 Add ec2 roles credentials. 2017-03-07 12:37:31 +09:00
Kota Kanbe
41f99f2b65 Merge pull request #372 from future-architect/sudo-check-update-rhel
sudo yum check-update on RHEL
2017-03-06 15:16:38 +09:00
Kota Kanbe
1f9e5c6263 sudo yum check-update on RHEL 2017-03-06 14:43:02 +09:00
Kota Kanbe
2f3eddd2ab Merge pull request #369 from knqyf263/change_option
Change ssh option from -t to -tt
2017-03-06 14:37:29 +09:00
knqyf263
619a0ee700 Change ssh option from -t to -tt 2017-03-03 11:20:57 +09:00
Kota Kanbe
b1b5c2c9a0 Merge pull request #356 from future-architect/changelog
Output changelog in report, TUI and JSON for Ubuntu/Debian/CentOS
2017-03-02 22:28:29 +09:00
Kota Kanbe
a86035c0bf Output changelog in report, TUI and JSON for Ubuntu/Debian/CentOS 2017-03-02 22:22:35 +09:00
Kota Kanbe
c66b0f4db4 Merge pull request #364 from knqyf263/increase_width
Increase the width of RequestPty
2017-03-01 12:15:23 +09:00
knqyf263
a4cf4bd314 Increase the width of RequestPty 2017-02-28 14:29:12 +09:00
Kota Kanbe
f1cd9383c1 Merge pull request #358 from ymomoi/remove-unused-import
remove unused import line.
2017-02-28 14:23:55 +09:00
Kota Kanbe
6fa57abe10 Merge pull request #363 from knqyf263/support_travis
Add .travis.yml
2017-02-28 13:08:42 +09:00
knqyf263
6e77c714b5 Add .travis.yml 2017-02-27 21:42:22 +09:00
Yasunari Momoi
fbab020e6e remove unused import line. 2017-02-25 04:48:28 +09:00
Kota Kanbe
5581a5cce7 Merge pull request #354 from future-architect/mistook-english
Fix candidate to confidence.
2017-02-23 12:07:44 +09:00
Kota Kanbe
b4be11775e Fix candidate to confidence. 2017-02-23 12:05:13 +09:00
Kota Kanbe
b079f5e52e Update README.ja.md 2017-02-22 21:15:01 +09:00
Kota Kanbe
f9bf470a37 Update README.md 2017-02-22 21:13:54 +09:00
Kota Kanbe
9d783dd2ab Merge pull request #350 from future-architect/show-false-positive
Output confidence score of detection accuracy and detection method to JSON or Reporting
2017-02-22 20:57:39 +09:00
Kota Kanbe
1b9aafbbaf Output confidence ranking of detection accuracy to JSON or Reporting 2017-02-22 20:51:58 +09:00
Kota Kanbe
1d3ee6a241 Merge pull request #328 from federacy/leniant_changelog_parsing_for_debian
Add leniancy to the version matching for debian to account for versio…
2017-02-22 20:43:46 +09:00
Kota Kanbe
2f9c3071a6 Merge pull request #351 from hasegawa-tomoki/patch-1
Improve kanji character
2017-02-21 15:48:24 +09:00
HASEGAWA Tomoki
4b0be4f115 Fix typo(?) 2017-02-21 15:45:17 +09:00
Kota Kanbe
1419c7c8c6 Merge pull request #348 from knqyf263/add_template
Add PULL_REQUEST_TEMPLATE.md
2017-02-20 15:37:44 +09:00
knqyf263
851cecdd73 Add PULL_REQUEST_TEMPLATE.md 2017-02-19 23:36:22 +09:00
Kota Kanbe
753da3aad7 Merge pull request #347 from knqyf263/update_readme
Update README
2017-02-19 09:57:28 +09:00
Kota Kanbe
65c10d6d8e Merge pull request #346 from knqyf263/send_cc
Bug fix: not send e-mail to cc address
2017-02-19 09:56:20 +09:00
Kota Kanbe
1b8b423131 Merge pull request #345 from future-architect/avoid-null
Avoid null slice being null in JSON
2017-02-19 09:37:36 +09:00
Kota Kanbe
55b1264c7d Avoid null slice being null in JSON 2017-02-19 09:34:24 +09:00
knqyf263
902a1888d4 Update README 2017-02-17 18:33:11 +09:00
knqyf263
98151f7d0e Bug fix: not send e-mail to cc address 2017-02-16 22:25:04 +09:00
Kota Kanbe
a6f0c559f8 Merge pull request #332 from kazuminn/add-err-handling
add error handling
2017-02-16 18:06:59 +09:00
kazuminn
e7ec5b841d due to miss error handling
I fixed it according to the review
2017-02-16 12:49:13 +09:00
Kota Kanbe
d6f72ac0f3 Merge pull request #343 from knqyf263/fix_typo
Fix typo
2017-02-16 12:01:03 +09:00
Kota Kanbe
7e3a10025a Merge pull request #344 from future-architect/fix-testcase
Fix test case
2017-02-16 11:33:07 +09:00
Kota Kanbe
e16ec15226 Fix test case 2017-02-16 11:32:18 +09:00
Kota Kanbe
6935b56c9d Merge pull request #308 from lapthorn/update-readme
Update readme
2017-02-16 07:54:51 +09:00
Alan Lapthorn
0e3a0b64e7 Update READMEs
Fix typo

Fix typo in comment
2017-02-15 22:53:03 +00:00
knqyf263
74e6aee236 Fix typo 2017-02-15 23:51:46 +09:00
Kota Kanbe
db0602b7b8 Merge pull request #296 from galigalikun/update-readme
update readme
2017-02-15 22:08:51 +09:00
Kota Kanbe
c9b7c3f179 Merge pull request #331 from knqyf263/add_one-email
Add -format-one-email option
2017-02-15 21:58:14 +09:00
knqyf263
5bd9f4afb4 Add -format-one-email option 2017-02-15 18:31:51 +09:00
Kota Kanbe
9d2ba5912e Merge pull request #340 from future-architect/freebsd-version
Change the command used for os detection from uname to freebsd-version
2017-02-15 14:39:31 +09:00
Kota Kanbe
9986c4a6f3 Change the command used for os detection from uname to freebsd-version 2017-02-15 14:34:53 +09:00
Kota Kanbe
df2c9697ef Merge pull request #339 from future-architect/gnu-makefile
Rename Makefile to GNUmakefile #313
2017-02-15 14:13:45 +09:00
Kota Kanbe
ab0388e882 Rename Makefile to GNUmakefile #313 2017-02-15 14:07:43 +09:00
Kota Kanbe
c05d8a36eb Merge pull request #338 from future-architect/update-readme
Update README
2017-02-14 12:47:33 +09:00
Kota Kanbe
492753d905 Update README 2017-02-14 12:45:28 +09:00
Kota Kanbe
6e08bd23f4 Merge pull request #330 from knqyf263/support_raspbian
Support Raspbian
2017-02-14 12:15:28 +09:00
Kota Kanbe
a687c97808 Merge pull request #337 from future-architect/fix-error-handling
Fix error handling of detectOS
2017-02-14 11:58:43 +09:00
Kota Kanbe
c6864289cb Fix error handling of detectOS 2017-02-14 11:54:06 +09:00
Kota Kanbe
97d85258c5 Merge pull request #309 from future-architect/continue_scan_on_error
Continue scanning even when some hosts have tech issues
2017-02-14 11:10:13 +09:00
knqyf263
bee25f5aa2 Support Raspbian 2017-02-13 22:15:09 +09:00
Kota Kanbe
386b97d2be Continue scanning even when some hosts have tech issues
see #264
2017-02-13 21:55:55 +09:00
Kota Kanbe
00660485b7 Merge pull request #324 from federacy/aptitude_changelog_more_to_cat
aptitude changelog defaults to using more, which is not interactive a…
2017-02-13 14:54:12 +09:00
Kota Kanbe
1e8f24dedb Merge pull request #326 from federacy/add_image_info_for_docker
Add image information for docker containers
2017-02-13 13:48:11 +09:00
Kota Kanbe
2be190f863 Merge pull request #322 from knqyf263/delete_sudo_echo
Do not use sudo when echo
2017-02-13 12:19:16 +09:00
Kota Kanbe
ec7c6e6c85 Merge pull request #317 from federacy/fix_cve_dictionary_url_conditional
Don't check for a CVE DB when CVE Dictionary URL is defined
2017-02-13 10:49:36 +09:00
Kota Kanbe
c52bc53fd8 Merge pull request #314 from justyns/fixcontainertypo
Fix typo contianer -> container
2017-02-13 10:43:47 +09:00
James Sulinski
981631503a Add leniancy to the version matching for debian to account for versions without the "+" when package maintainers aren't using them. 2017-02-10 11:38:46 -08:00
Kota Kanbe
48de3a6a4f Merge pull request #319 from federacy/nosudo_for_debian_scans
Reduce privilege requirements for commands that don't need sudo on Ubuntu/Debian
2017-02-10 19:40:34 +09:00
Kota Kanbe
d1983a6978 Merge pull request #329 from future-architect/retry-exceeded-slack
Fix infinite retry at size overrun error in Slack report
2017-02-10 18:41:22 +09:00
Kota Kanbe
f821a26aec Fix infinite retry at size overrun error in Slack report 2017-02-10 18:40:29 +09:00
James Sulinski
3380e905de Add image information for docker containers 2017-02-09 01:05:12 -08:00
James Sulinski
b5c2718756 aptitude changelog defaults to using more, which is not interactive and breaks docker scans. Set PAGER=cat before running to default to cat. 2017-02-09 00:54:47 -08:00
James Sulinski
a03a803b89 Reduce privilege requirements for commands that don't need sudo 2017-02-09 00:47:08 -08:00
knqyf263
e743177ae6 Do not use sudo when echo 2017-02-09 17:43:15 +09:00
James Sulinski
6e12c69953 Don't check for a CVE DB when CVE Dictionary URL is defined 2017-02-09 00:36:23 -08:00
Justyn Shull
019ab77466 Fix typo contianer -> container 2017-02-08 17:17:12 -06:00
Kota Kanbe
1730caf124 Merge pull request #306 from knqyf263/update_lock
Update glide.lock to fix import error
2017-01-30 17:50:03 +09:00
knqyf263
59d1533795 Update glide.lock to fix import error 2017-01-30 17:49:23 +09:00
Kota Kanbe
a6278ab7ea Merge pull request #305 from future-architect/fix-changelog-cache
Fix the changelog cache logic for ubuntu/debian
2017-01-28 04:16:04 +09:00
Kota Kanbe
42a6004c7d Fix the changelog cache logic for ubuntu/debian 2017-01-28 04:08:57 +09:00
Kota Kanbe
6084c1b1d3 Merge pull request #304 from future-architect/fix-yum-updateinfo-opts
Fix yum updateinfo options
2017-01-27 18:50:17 +09:00
Kota Kanbe
c96fbc1dba Fix yum updateinfo options
see #281
2017-01-27 18:42:14 +09:00
Kota Kanbe
5546a8b093 Merge pull request #303 from future-architect/glide
Update glide.lock to fix create-log-dir error.
2017-01-26 21:37:23 +09:00
Kota Kanbe
6b76b38dcd Update glide.lock to fix create-log-dir error.
see https://github.com/kotakanbe/go-cve-dictionary/pull/40
2017-01-26 21:34:44 +09:00
Kota Kanbe
941e50b460 Merge pull request #302 from future-architect/log-dir
Fix a bug in logging (file output) at scan command
2017-01-26 17:22:45 +09:00
Kota Kanbe
5a10e5c9ff Fix a bug in logging (file output) at scan command
Log of localhost was not output to file. #301
2017-01-26 17:21:03 +09:00
Kota Kanbe
883fe13756 Merge pull request #301 from knqyf263/add_logdir
Add -log-dir option
2017-01-26 16:51:31 +09:00
knqyf263
2e7c34cf9f Add -log-dir option 2017-01-26 15:36:30 +09:00
Kota Kanbe
9216efbd2f Merge pull request #300 from knqyf263/use_assumeno
Use --assumeno option
2017-01-24 15:07:58 +09:00
teppei-fukuda
6c8100e5b6 Use --assumeno option 2017-01-24 12:28:39 +09:00
Kota Kanbe
e7ef50bedf Update README.md 2017-01-24 01:17:05 +09:00
Kota Kanbe
386ca3565a Merge pull request #299 from future-architect/fix-pipe-problem
Add -pipe flag #294
2017-01-24 01:13:48 +09:00
Kota Kanbe
2d854cd64d Add -pipe flag #294
Solved the problem of trying to read from STDIN and stopping on the way when running from CRON or AWS Lambda.
2017-01-24 01:06:22 +09:00
Kota Kanbe
49b4b8be22 Update README.md 2017-01-23 18:47:42 +09:00
Kota Kanbe
db975ebfee Merge pull request #297 from knqyf263/update_readme
Update docker README
2017-01-23 18:36:31 +09:00
Kota Kanbe
d60a41139b Merge pull request #298 from knqyf263/check_echo
Check whether echo is executable with nopasswd
2017-01-23 17:42:17 +09:00
knqyf263
f62d869d27 Check whether echo is executable with nopasswd 2017-01-22 23:15:25 +09:00
knqyf263
6cbe3cdb93 Update docker README 2017-01-21 22:04:57 +09:00
akaishi takeshi
b13e7b9da4 update readme 2017-01-18 14:34:23 +09:00
Kota Kanbe
8fe34c8474 Fix architecture image file 2017-01-17 00:32:53 +09:00
Kota Kanbe
bef29be50f Merge pull request #291 from future-architect/localscan
Add local scan mode(Scan without SSH when target server is localhost)
2017-01-17 00:22:09 +09:00
Kota Kanbe
20275a1063 Add local scan mode.
If the scan target server is localhost, Don't use SSH. #210
2017-01-17 00:16:46 +09:00
Kota Kanbe
910385b084 Merge pull request #288 from jiazio/add-lxd-support
Add LXD support
2017-01-16 16:43:51 +09:00
Kota Kanbe
8e779374a7 Merge pull request #293 from future-architect/fix-rhel5
Fix RHEL5 scan stopped halfway
2017-01-13 06:41:26 +09:00
Kota Kanbe
44fc6f728e Fix RHEL5 scan stopped halfway 2017-01-13 06:40:03 +09:00
Kota Kanbe
1f62dcf22a Merge pull request #292 from future-architect/fix-bug-amazon-linux
Fix amazon linux scan stopped halfway
2017-01-13 04:59:34 +09:00
Kota Kanbe
0416c3b561 Fix amazon linux scan stopped halfway 2017-01-13 04:56:59 +09:00
Kota Kanbe
a6912cae76 Merge pull request #289 from future-architect/rhel5
Support RHEL5
2017-01-10 16:34:37 +09:00
Kota Kanbe
63dfe8a952 Support RHEL5 2017-01-10 16:32:06 +09:00
Kota Kanbe
62d1b761bd Update CHANGELOG 2017-01-10 16:24:02 +09:00
Kota Kanbe
082b10a15b Merge pull request #270 from future-architect/report-subcommand
Add report subcommand, change scan options. #239
2017-01-10 16:15:01 +09:00
Kota Kanbe
1a6bcd82b0 Merge pull request #287 from jiazio/fix-container-os-dectecion
Fix container os detection
2017-01-10 14:35:07 +09:00
jiazio
6ecd70220b Add LXD support 2017-01-06 22:11:13 +09:00
jiazio
e9f55f5772 Fix container os detection 2017-01-06 16:32:42 +09:00
Kota Kanbe
155cadf901 Add report subcommand, change scan options. Bump up ver #239 2017-01-05 13:40:25 +09:00
Kota Kanbe
cb29289167 Merge pull request #283 from ymomoi/add-date-header
Add date header to report mail.
2017-01-02 09:13:33 +09:00
Yasunari Momoi
e4db9d1d91 Add date header to report mail. 2016-12-16 11:22:09 +09:00
Kota Kanbe
7b2e2cb817 Merge pull request #280 from hogehogehugahuga/add-mail-header
Add Content-Type header to report/mail.go .
2016-12-15 10:53:25 +09:00
hogehogehugahuga
c717f8d15d Add Content-Type header to report/mail.go .
(fix pull request, "utf8" to "utf-8".)

I did the following test.
- compile vuls with this fix.
- I executed the following command and confirmed that garbled display is not done.
  + vuls scan -lang=en -report-mail -cve-dictionary...
  + vuls scan -lang=ja -report-mail -cve-dictionary...

Mail header is as follows.
Message-Id: <...>
Subject: <...>
Content-Type: text/plain; charset=utf8
From: <...>
To: <...>
Cc: <...>
2016-12-15 10:27:34 +09:00
Kota Kanbe
8db147acab Merge pull request #272 from yoheimuta/sort-CveInfo-PackageInfo
Keep output of "vuls scan -report-*" to be same every times
2016-11-29 12:15:19 +09:00
yoheimuta
e6de7aa9ca Sorted PackageInfos by Name to keep report texts same every times 2016-11-22 01:11:42 +09:00
Kota Kanbe
46f96740a2 Merge pull request #271 from future-architect/json-dir-regex
Fix JSON-dir regex pattern #265
2016-11-17 22:17:40 +09:00
Kota Kanbe
8f9fb5c262 Fix JSON-dir regex pattern #265 2016-11-17 22:14:41 +09:00
Kota Kanbe
171d6d6684 Merge pull request #263 from Code0x58/ssh-external-tidy
Stop quietly ignoring `--ssh-external` on Windows
2016-11-16 16:31:58 +09:00
Oliver Bristow
f648b5ad0a Refactor SSHExternal flag so it isn't quietly ignored on Windows 2016-11-16 06:42:34 +00:00
Kota Kanbe
ef21376f0a Merge pull request #265 from Code0x58/rfc3339-timestamps
Use RFC3339 timestamps in the results
2016-11-16 11:13:02 +09:00
Kota Kanbe
58958d68d8 Merge pull request #266 from Code0x58/260-prepare-confirm-flag
Add --assume-yes to prepare #260
2016-11-16 10:36:33 +09:00
Kota Kanbe
a06b565ee9 Merge pull request #262 from Code0x58/261-fix-gocui-signature-change
Fix gocui.NewGui after signature change #261
2016-11-16 09:49:24 +09:00
Oliver Bristow
a7db27ce5a Add --assume-yes to prepare #260 2016-11-14 20:44:19 +00:00
Oliver Bristow
cda69dc7f0 Use RFC3339 timestamps in the results 2016-11-14 19:10:58 +00:00
Oliver Bristow
39f9594548 Update glide.lock and fix gocui.NewGui after signature change #261 2016-11-14 18:05:28 +00:00
Kota Kanbe
6d82ad32a9 Merge pull request #254 from Code0x58/patch-2
Replace inconsistent tabs with spaces
2016-11-14 04:53:52 +09:00
Kota Kanbe
cfcd8bf223 Merge pull request #253 from Code0x58/patch-1
Fix non-interactive `apt-get install` #251
2016-11-14 04:49:12 +09:00
Oliver Bristow
8149ad00b5 Replace inconsistent tabs with spaces 2016-11-11 19:26:41 +00:00
Oliver Bristow
2310522806 Fix non-interactive apt-get install #251 2016-11-11 19:13:51 +00:00
Kota Kanbe
e40ef656d6 Merge pull request #249 from usiusi360/Fix-README
Fix README
2016-11-08 22:54:24 +09:00
Takayuki Ushida
e060d40a32 Fix README 2016-11-08 22:27:57 +09:00
208 changed files with 39619 additions and 13909 deletions

7
.dockerignore Normal file
View File

@@ -0,0 +1,7 @@
.dockerignore
Dockerfile
vendor/
cve.sqlite3*
oval.sqlite3*
setup/
img/

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

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

43
.github/ISSUE_TEMPLATE/BUG_REPORT.md vendored Normal file
View File

@@ -0,0 +1,43 @@
---
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.)
# What did you expect to happen?
# What happened instead?
* Current Output
Please re-run the command using ```-debug``` and provide the output below.
# Steps to reproduce the behaviour
# Configuration (**MUST** fill this out):
* Go version (`go version`):
* Go environment (`go env`):
* Vuls environment:
Hash : ____
To check the commit hash of HEAD
$ vuls -v
or
$ cd $GOPATH/src/github.com/future-architect/vuls
$ git rev-parse --short HEAD
* config.toml:
* command:

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.
---

40
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,40 @@
If this Pull Request is work in progress, Add a prefix of “[WIP]” in the title.
# What did you implement:
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context.
Fixes # (issue)
## Type of change
Please delete options that are not relevant.
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
# How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce.
# Checklist:
You don't have to satisfy all of the following.
- [ ] Write tests
- [ ] Write documentation
- [ ] Check that there aren't other open pull requests for the same issue/feature
- [ ] Format your source code by `make fmt`
- [ ] Pass the test by `make test`
- [ ] Provide verification config / commands
- [ ] Enable "Allow edits from maintainers" for this PR
- [ ] Update the messages below
***Is this ready for review?:*** NO
# Reference
* https://blog.github.com/2015-01-21-how-to-write-the-perfect-pull-request/

67
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,67 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '32 20 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

29
.github/workflows/golangci.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: golangci-lint
on:
push:
tags:
- v*
branches:
- master
pull_request:
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.32
args: --timeout=10m
# Optional: working directory, useful for monorepos
# working-directory: somedir
# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0
# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

31
.github/workflows/goreleaser.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: goreleaser
on:
push:
tags:
- '*'
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Unshallow
run: git fetch --prune --unshallow
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.15
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

21
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Test
on: [pull_request]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: 1.15.x
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Test
run: make test

22
.github/workflows/tidy.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: go-mod-tidy-pr
on:
schedule:
- cron: "0 0 * * 1" # Weekly build
jobs:
go-mod-tidy-pr:
name: go-mod-tidy-pr
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run go-mod-tidy-pr
uses: sue445/go-mod-tidy-pr@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
git_user_name: kotakanbe
git_user_email: kotakanbe@gmail.com
go_version: 1.15.6

4
.gitignore vendored
View File

@@ -1,4 +1,3 @@
vuls
.vscode
*.txt
*.json
@@ -13,3 +12,6 @@ log/
results/
*config.toml
!setup/docker/*
.DS_Store
dist/
.idea

17
.golangci.yml Normal file
View File

@@ -0,0 +1,17 @@
name: golang-ci
linters-settings:
errcheck:
#exclude: /path/to/file.txt
linters:
disable-all: true
enable:
- goimports
- golint
- govet
- misspell
- errcheck
- staticcheck
- prealloc
- ineffassign

114
.goreleaser.yml Normal file
View File

@@ -0,0 +1,114 @@
project_name: vuls
env:
- GO111MODULE=on
release:
github:
owner: future-architect
name: vuls
builds:
- id: vuls
goos:
- linux
goarch:
- amd64
main: ./cmd/vuls/main.go
flags:
- -a
ldflags:
- -s -w -X github.com/future-architect/vuls/config.Version={{.Version}} -X github.com/future-architect/vuls/config.Revision={{.Commit}}-{{ .CommitDate }}
binary: vuls
- id: vuls-scanner
env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- 386
- amd64
- arm
- arm64
main: ./cmd/scanner/main.go
flags:
- -a
- -tags=scanner
ldflags:
- -s -w -X github.com/future-architect/vuls/config.Version={{.Version}} -X github.com/future-architect/vuls/config.Revision={{.Commit}}-{{ .CommitDate }}
binary: vuls-scanner
- id: trivy-to-vuls
env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- 386
- amd64
- arm
- arm64
main: ./contrib/trivy/cmd/main.go
binary: trivy-to-vuls
- id: future-vuls
env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- 386
- amd64
- arm
- arm64
flags:
- -a
- -tags=scanner
main: ./contrib/future-vuls/cmd/main.go
binary: future-vuls
archives:
- id: vuls
name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
builds:
- vuls
format: tar.gz
files:
- LICENSE
- NOTICE
- README*
- CHANGELOG.md
- id: vuls-scanner
name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
builds:
- vuls-scanner
format: tar.gz
files:
- LICENSE
- NOTICE
- README*
- CHANGELOG.md
- id: trivy-to-vuls
name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
builds:
- trivy-to-vuls
format: tar.gz
files:
- LICENSE
- NOTICE
- README*
- CHANGELOG.md
- id: future-vuls
name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
builds:
- future-vuls
format: tar.gz
files:
- LICENSE
- NOTICE
- README*
- CHANGELOG.md
snapshot:
name_template: SNAPSHOT-{{ .Commit }}

View File

@@ -1,5 +1,230 @@
# Change Log
## v0.4.1 and later, see [GitHub release](https://github.com/future-architect/vuls/releases)
## [v0.4.0](https://github.com/future-architect/vuls/tree/v0.4.0) (2017-08-25)
[Full Changelog](https://github.com/future-architect/vuls/compare/v0.3.0...v0.4.0)
**Implemented enhancements:**
- Output changelog in report, TUI and JSON for RHEL [\#367](https://github.com/future-architect/vuls/issues/367)
- Output changelog in report, TUI and JSON for Amazon Linux [\#366](https://github.com/future-architect/vuls/issues/366)
- Improve scanning accuracy by checking package versions [\#256](https://github.com/future-architect/vuls/issues/256)
- Improve SSH [\#415](https://github.com/future-architect/vuls/issues/415)
- Enable to scan even if target server can not connect to the Internet [\#258](https://github.com/future-architect/vuls/issues/258)
- SSH Hostkey check [\#417](https://github.com/future-architect/vuls/pull/417) ([kotakanbe](https://github.com/kotakanbe))
- v0.4.0 [\#449](https://github.com/future-architect/vuls/pull/449) ([kotakanbe](https://github.com/kotakanbe))
- Change default ssh method from go library to external command [\#416](https://github.com/future-architect/vuls/pull/416) ([kotakanbe](https://github.com/kotakanbe))
- Add containers-only option to configtest [\#411](https://github.com/future-architect/vuls/pull/411) ([knqyf263](https://github.com/knqyf263))
**Fixed bugs:**
- Running Vuls tui before vuls report does not show vulnerabilities checked by CPE [\#396](https://github.com/future-architect/vuls/issues/396)
- With a long package name, Local shell mode \(stty dont' work\) [\#444](https://github.com/future-architect/vuls/issues/444)
- Improve SSH [\#415](https://github.com/future-architect/vuls/issues/415)
- Report that a vulnerability exists in the wrong package [\#408](https://github.com/future-architect/vuls/issues/408)
- With a long package name, a parse error occurs. [\#391](https://github.com/future-architect/vuls/issues/391)
- Ubuntu failed to scan vulnerable packages [\#205](https://github.com/future-architect/vuls/issues/205)
- CVE-ID in changelog can't be picked up. [\#154](https://github.com/future-architect/vuls/issues/154)
- v0.4.0 [\#449](https://github.com/future-architect/vuls/pull/449) ([kotakanbe](https://github.com/kotakanbe))
- Fix SSH dial error [\#413](https://github.com/future-architect/vuls/pull/413) ([kotakanbe](https://github.com/kotakanbe))
- Update deps, Change deps tool from glide to dep [\#412](https://github.com/future-architect/vuls/pull/412) ([kotakanbe](https://github.com/kotakanbe))
- fix report option Loaded error-info [\#406](https://github.com/future-architect/vuls/pull/406) ([hogehogehugahuga](https://github.com/hogehogehugahuga))
- Add --user root to docker exec command [\#389](https://github.com/future-architect/vuls/pull/389) ([PaulFurtado](https://github.com/PaulFurtado))
**Closed issues:**
- README.md.ja not include "Oracle Linux, FreeBSD" [\#465](https://github.com/future-architect/vuls/issues/465)
- Can't scan remote server - \(centos 7 - updated\) [\#451](https://github.com/future-architect/vuls/issues/451)
- An abnormality in the result of vuls tui [\#439](https://github.com/future-architect/vuls/issues/439)
- compile faild [\#436](https://github.com/future-architect/vuls/issues/436)
- Can't install vuls on CentOS 7 [\#432](https://github.com/future-architect/vuls/issues/432)
- Vuls scan doesn't show severity score in any of the vulnerable packages [\#430](https://github.com/future-architect/vuls/issues/430)
- Load config failedtoml: cannot load TOML value of type string into a Go slice [\#429](https://github.com/future-architect/vuls/issues/429)
- vuls scan not running check-update with sudo for Centos 7 [\#428](https://github.com/future-architect/vuls/issues/428)
- options for configtest not being activated [\#422](https://github.com/future-architect/vuls/issues/422)
- "could not find project Gopkg.toml, use dep init to initiate a manifest" when installing vuls [\#420](https://github.com/future-architect/vuls/issues/420)
- go get not get [\#407](https://github.com/future-architect/vuls/issues/407)
- Failed to scan via docker. err: Unknown format [\#404](https://github.com/future-architect/vuls/issues/404)
- Failed to scan - kernel-xxx is an installed security update [\#403](https://github.com/future-architect/vuls/issues/403)
- 169.254.169.254 port 80: Connection refused [\#402](https://github.com/future-architect/vuls/issues/402)
- vuls scan --debug cause `invalid memory address` error [\#397](https://github.com/future-architect/vuls/issues/397)
- Provide a command line flag that will automatically install aptitude on debian? [\#390](https://github.com/future-architect/vuls/issues/390)
**Merged pull requests:**
- export fill cve info [\#467](https://github.com/future-architect/vuls/pull/467) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- add oval docker [\#466](https://github.com/future-architect/vuls/pull/466) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- fix typos in commands. [\#464](https://github.com/future-architect/vuls/pull/464) ([ymomoi](https://github.com/ymomoi))
- Update README [\#463](https://github.com/future-architect/vuls/pull/463) ([kotakanbe](https://github.com/kotakanbe))
- export FillWithOval [\#462](https://github.com/future-architect/vuls/pull/462) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- add serveruuid field [\#458](https://github.com/future-architect/vuls/pull/458) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- add s3 dirctory option [\#457](https://github.com/future-architect/vuls/pull/457) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- Extract Advisory.Description on RHEL, Amazon, Oracle [\#450](https://github.com/future-architect/vuls/pull/450) ([kotakanbe](https://github.com/kotakanbe))
- nosudo on CentOS and Fetch Changelogs on Amazon, RHEL [\#448](https://github.com/future-architect/vuls/pull/448) ([kotakanbe](https://github.com/kotakanbe))
- change logrus package to lowercase and update other packages [\#446](https://github.com/future-architect/vuls/pull/446) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- add db backend redis [\#445](https://github.com/future-architect/vuls/pull/445) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- fast test [\#435](https://github.com/future-architect/vuls/pull/435) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- fix typo [\#433](https://github.com/future-architect/vuls/pull/433) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- Add support for PostgreSQL as a DB storage back-end [\#431](https://github.com/future-architect/vuls/pull/431) ([sadayuki-matsuno](https://github.com/sadayuki-matsuno))
- typo README.js.md [\#426](https://github.com/future-architect/vuls/pull/426) ([ryurock](https://github.com/ryurock))
- Add TOC to README [\#425](https://github.com/future-architect/vuls/pull/425) ([kotakanbe](https://github.com/kotakanbe))
- Fixing \#420 where lock and manifest have moved to TOML [\#421](https://github.com/future-architect/vuls/pull/421) ([elfgoh](https://github.com/elfgoh))
- Define timeout for vulnerabilities scan and platform detection [\#414](https://github.com/future-architect/vuls/pull/414) ([s7anley](https://github.com/s7anley))
- Enable -timeout option when detecting OS [\#410](https://github.com/future-architect/vuls/pull/410) ([knqyf263](https://github.com/knqyf263))
- Remove duplicate command in README [\#401](https://github.com/future-architect/vuls/pull/401) ([knqyf263](https://github.com/knqyf263))
- Fix to read config.toml at tui [\#441](https://github.com/future-architect/vuls/pull/441) ([usiusi360](https://github.com/usiusi360))
- Change NVD URL to new one [\#419](https://github.com/future-architect/vuls/pull/419) ([kotakanbe](https://github.com/kotakanbe))
- Add some testcases [\#418](https://github.com/future-architect/vuls/pull/418) ([kotakanbe](https://github.com/kotakanbe))
## [v0.3.0](https://github.com/future-architect/vuls/tree/v0.3.0) (2017-03-24)
[Full Changelog](https://github.com/future-architect/vuls/compare/v0.2.0...v0.3.0)
**Implemented enhancements:**
- Changelog parsing fails when package maintainers aren't consistent regarding versions [\#327](https://github.com/future-architect/vuls/issues/327)
- Docker scan doesn't report image name [\#325](https://github.com/future-architect/vuls/issues/325)
- vuls report -to-email only one E-Mail [\#295](https://github.com/future-architect/vuls/issues/295)
- Support RHEL5 [\#286](https://github.com/future-architect/vuls/issues/286)
- Continue scanning even when some hosts have tech issues? [\#264](https://github.com/future-architect/vuls/issues/264)
- Normalization of JSON output [\#259](https://github.com/future-architect/vuls/issues/259)
- Add report subcommand, change scan subcommand options [\#239](https://github.com/future-architect/vuls/issues/239)
- scan localhost? [\#210](https://github.com/future-architect/vuls/issues/210)
- Can Vuls show details about updateable packages [\#341](https://github.com/future-architect/vuls/issues/341)
- Scan all containers except [\#285](https://github.com/future-architect/vuls/issues/285)
- Notify the difference from the previous scan result [\#255](https://github.com/future-architect/vuls/issues/255)
- EC2RoleCreds support? [\#250](https://github.com/future-architect/vuls/issues/250)
- Output confidence score of detection accuracy and detection method to JSON or Reporting [\#350](https://github.com/future-architect/vuls/pull/350) ([kotakanbe](https://github.com/kotakanbe))
- Avoid null slice being null in JSON [\#345](https://github.com/future-architect/vuls/pull/345) ([kotakanbe](https://github.com/kotakanbe))
- Add -format-one-email option [\#331](https://github.com/future-architect/vuls/pull/331) ([knqyf263](https://github.com/knqyf263))
- Support Raspbian [\#330](https://github.com/future-architect/vuls/pull/330) ([knqyf263](https://github.com/knqyf263))
- Add leniancy to the version matching for debian to account for versio… [\#328](https://github.com/future-architect/vuls/pull/328) ([jsulinski](https://github.com/jsulinski))
- Add image information for docker containers [\#326](https://github.com/future-architect/vuls/pull/326) ([jsulinski](https://github.com/jsulinski))
- Continue scanning even when some hosts have tech issues [\#309](https://github.com/future-architect/vuls/pull/309) ([kotakanbe](https://github.com/kotakanbe))
- Add -log-dir option [\#301](https://github.com/future-architect/vuls/pull/301) ([knqyf263](https://github.com/knqyf263))
- Use --assumeno option [\#300](https://github.com/future-architect/vuls/pull/300) ([knqyf263](https://github.com/knqyf263))
- Add local scan mode\(Scan without SSH when target server is localhost\) [\#291](https://github.com/future-architect/vuls/pull/291) ([kotakanbe](https://github.com/kotakanbe))
- Support RHEL5 [\#289](https://github.com/future-architect/vuls/pull/289) ([kotakanbe](https://github.com/kotakanbe))
- Add LXD support [\#288](https://github.com/future-architect/vuls/pull/288) ([jiazio](https://github.com/jiazio))
- Add timeout option to configtest [\#400](https://github.com/future-architect/vuls/pull/400) ([kotakanbe](https://github.com/kotakanbe))
- Notify the difference from the previous scan result [\#392](https://github.com/future-architect/vuls/pull/392) ([knqyf263](https://github.com/knqyf263))
- Add Oracle Linux support [\#386](https://github.com/future-architect/vuls/pull/386) ([Djelibeybi](https://github.com/Djelibeybi))
- Change container scan format in config.toml [\#381](https://github.com/future-architect/vuls/pull/381) ([kotakanbe](https://github.com/kotakanbe))
- Obsolete CentOS5 support [\#378](https://github.com/future-architect/vuls/pull/378) ([kotakanbe](https://github.com/kotakanbe))
- Deprecate prepare subcommand to minimize the root authority defined by /etc/sudoers [\#375](https://github.com/future-architect/vuls/pull/375) ([kotakanbe](https://github.com/kotakanbe))
- Support IAM role for report to S3. [\#370](https://github.com/future-architect/vuls/pull/370) ([ohsawa0515](https://github.com/ohsawa0515))
- Add .travis.yml [\#363](https://github.com/future-architect/vuls/pull/363) ([knqyf263](https://github.com/knqyf263))
- Output changelog in report, TUI and JSON for Ubuntu/Debian/CentOS [\#356](https://github.com/future-architect/vuls/pull/356) ([kotakanbe](https://github.com/kotakanbe))
**Fixed bugs:**
- Debian scans failing in docker [\#323](https://github.com/future-architect/vuls/issues/323)
- Local CVE DB is still checked, even if a CVE Dictionary URL is defined [\#316](https://github.com/future-architect/vuls/issues/316)
- vuls needs gmake. [\#313](https://github.com/future-architect/vuls/issues/313)
- patch request for FreeBSD [\#312](https://github.com/future-architect/vuls/issues/312)
- Report: failed to read from json \(Docker\) [\#294](https://github.com/future-architect/vuls/issues/294)
- -report-mail option does not output required mail header [\#282](https://github.com/future-architect/vuls/issues/282)
- PackInfo not found error when vuls scan. [\#281](https://github.com/future-architect/vuls/issues/281)
- Normalize character set [\#279](https://github.com/future-architect/vuls/issues/279)
- The number of Updatable Packages is different from the number of yum check-update [\#373](https://github.com/future-architect/vuls/issues/373)
- sudo is needed when exec yum check-update on RHEL7 [\#371](https://github.com/future-architect/vuls/issues/371)
- `123-3ubuntu4` should be marked as ChangelogLenientMatch [\#362](https://github.com/future-architect/vuls/issues/362)
- CentOS multi package invalid result [\#360](https://github.com/future-architect/vuls/issues/360)
- Parse error after check-update. \(Unknown format\) [\#359](https://github.com/future-architect/vuls/issues/359)
- Fix candidate to confidence. [\#354](https://github.com/future-architect/vuls/pull/354) ([kotakanbe](https://github.com/kotakanbe))
- Bug fix: not send e-mail to cc address [\#346](https://github.com/future-architect/vuls/pull/346) ([knqyf263](https://github.com/knqyf263))
- Change the command used for os detection from uname to freebsd-version [\#340](https://github.com/future-architect/vuls/pull/340) ([kotakanbe](https://github.com/kotakanbe))
- Fix error handling of detectOS [\#337](https://github.com/future-architect/vuls/pull/337) ([kotakanbe](https://github.com/kotakanbe))
- Fix infinite retry at size overrun error in Slack report [\#329](https://github.com/future-architect/vuls/pull/329) ([kotakanbe](https://github.com/kotakanbe))
- aptitude changelog defaults to using more, which is not interactive a… [\#324](https://github.com/future-architect/vuls/pull/324) ([jsulinski](https://github.com/jsulinski))
- Do not use sudo when echo [\#322](https://github.com/future-architect/vuls/pull/322) ([knqyf263](https://github.com/knqyf263))
- Reduce privilege requirements for commands that don't need sudo on Ubuntu/Debian [\#319](https://github.com/future-architect/vuls/pull/319) ([jsulinski](https://github.com/jsulinski))
- Don't check for a CVE DB when CVE Dictionary URL is defined [\#317](https://github.com/future-architect/vuls/pull/317) ([jsulinski](https://github.com/jsulinski))
- Fix typo contianer -\> container [\#314](https://github.com/future-architect/vuls/pull/314) ([justyns](https://github.com/justyns))
- Fix the changelog cache logic for ubuntu/debian [\#305](https://github.com/future-architect/vuls/pull/305) ([kotakanbe](https://github.com/kotakanbe))
- Fix yum updateinfo options [\#304](https://github.com/future-architect/vuls/pull/304) ([kotakanbe](https://github.com/kotakanbe))
- Update glide.lock to fix create-log-dir error. [\#303](https://github.com/future-architect/vuls/pull/303) ([kotakanbe](https://github.com/kotakanbe))
- Fix a bug in logging \(file output\) at scan command [\#302](https://github.com/future-architect/vuls/pull/302) ([kotakanbe](https://github.com/kotakanbe))
- Add -pipe flag \#294 [\#299](https://github.com/future-architect/vuls/pull/299) ([kotakanbe](https://github.com/kotakanbe))
- Fix RHEL5 scan stopped halfway [\#293](https://github.com/future-architect/vuls/pull/293) ([kotakanbe](https://github.com/kotakanbe))
- Fix amazon linux scan stopped halfway [\#292](https://github.com/future-architect/vuls/pull/292) ([kotakanbe](https://github.com/kotakanbe))
- Fix nil-ponter in TUI [\#388](https://github.com/future-architect/vuls/pull/388) ([kotakanbe](https://github.com/kotakanbe))
- Fix Bug of Mysql Backend [\#384](https://github.com/future-architect/vuls/pull/384) ([kotakanbe](https://github.com/kotakanbe))
- Fix scan confidence on Ubuntu/Debian/Raspbian \#362 [\#379](https://github.com/future-architect/vuls/pull/379) ([kotakanbe](https://github.com/kotakanbe))
- Fix updatalbe packages count \#373 [\#374](https://github.com/future-architect/vuls/pull/374) ([kotakanbe](https://github.com/kotakanbe))
- sudo yum check-update on RHEL [\#372](https://github.com/future-architect/vuls/pull/372) ([kotakanbe](https://github.com/kotakanbe))
- Change ssh option from -t to -tt [\#369](https://github.com/future-architect/vuls/pull/369) ([knqyf263](https://github.com/knqyf263))
- Increase the width of RequestPty [\#364](https://github.com/future-architect/vuls/pull/364) ([knqyf263](https://github.com/knqyf263))
**Closed issues:**
- vuls configtest --debugがsudoのチェックで止まってしまう [\#395](https://github.com/future-architect/vuls/issues/395)
- Add support for Oracle Linux [\#385](https://github.com/future-architect/vuls/issues/385)
- error on install - Ubuntu 16.04 [\#376](https://github.com/future-architect/vuls/issues/376)
- Unknown OS Type [\#335](https://github.com/future-architect/vuls/issues/335)
- mac os 10.12.3 make install error [\#334](https://github.com/future-architect/vuls/issues/334)
- assumeYes doesn't work because there is no else condition [\#320](https://github.com/future-architect/vuls/issues/320)
- Debian scan uses sudo where unnecessary [\#318](https://github.com/future-architect/vuls/issues/318)
- Add FreeBSD 11 to supported OS on documents. [\#311](https://github.com/future-architect/vuls/issues/311)
- docker fetchnvd failing [\#274](https://github.com/future-architect/vuls/issues/274)
- Latest version of labstack echo breaks installation [\#268](https://github.com/future-architect/vuls/issues/268)
- fetchnvd Fails using example loop [\#267](https://github.com/future-architect/vuls/issues/267)
**Merged pull requests:**
- fix typo in README.ja.md [\#394](https://github.com/future-architect/vuls/pull/394) ([lv7777](https://github.com/lv7777))
- Update Tutorial in README [\#387](https://github.com/future-architect/vuls/pull/387) ([kotakanbe](https://github.com/kotakanbe))
- Fix README [\#383](https://github.com/future-architect/vuls/pull/383) ([usiusi360](https://github.com/usiusi360))
- s/dictinary/dictionary typo [\#382](https://github.com/future-architect/vuls/pull/382) ([beuno](https://github.com/beuno))
- Fix Japanese typo [\#377](https://github.com/future-architect/vuls/pull/377) ([IMAI-Yuji](https://github.com/IMAI-Yuji))
- Improve kanji character [\#351](https://github.com/future-architect/vuls/pull/351) ([hasegawa-tomoki](https://github.com/hasegawa-tomoki))
- Add PULL\_REQUEST\_TEMPLATE.md [\#348](https://github.com/future-architect/vuls/pull/348) ([knqyf263](https://github.com/knqyf263))
- Update README [\#347](https://github.com/future-architect/vuls/pull/347) ([knqyf263](https://github.com/knqyf263))
- Fix test case [\#344](https://github.com/future-architect/vuls/pull/344) ([kotakanbe](https://github.com/kotakanbe))
- Fix typo [\#343](https://github.com/future-architect/vuls/pull/343) ([knqyf263](https://github.com/knqyf263))
- Rename Makefile to GNUmakefile \#313 [\#339](https://github.com/future-architect/vuls/pull/339) ([kotakanbe](https://github.com/kotakanbe))
- Update README [\#338](https://github.com/future-architect/vuls/pull/338) ([kotakanbe](https://github.com/kotakanbe))
- add error handling [\#332](https://github.com/future-architect/vuls/pull/332) ([kazuminn](https://github.com/kazuminn))
- Update readme [\#308](https://github.com/future-architect/vuls/pull/308) ([lapthorn](https://github.com/lapthorn))
- Update glide.lock to fix import error [\#306](https://github.com/future-architect/vuls/pull/306) ([knqyf263](https://github.com/knqyf263))
- Check whether echo is executable with nopasswd [\#298](https://github.com/future-architect/vuls/pull/298) ([knqyf263](https://github.com/knqyf263))
- Update docker README [\#297](https://github.com/future-architect/vuls/pull/297) ([knqyf263](https://github.com/knqyf263))
- update readme [\#296](https://github.com/future-architect/vuls/pull/296) ([galigalikun](https://github.com/galigalikun))
- remove unused import line. [\#358](https://github.com/future-architect/vuls/pull/358) ([ymomoi](https://github.com/ymomoi))
## [v0.2.0](https://github.com/future-architect/vuls/tree/v0.2.0) (2017-01-10)
[Full Changelog](https://github.com/future-architect/vuls/compare/v0.1.7...v0.2.0)
**Implemented enhancements:**
- Add report subcommand, change scan options. \#239 [\#270](https://github.com/future-architect/vuls/pull/270) ([kotakanbe](https://github.com/kotakanbe))
- Add --assume-yes to prepare \#260 [\#266](https://github.com/future-architect/vuls/pull/266) ([Code0x58](https://github.com/Code0x58))
- Use RFC3339 timestamps in the results [\#265](https://github.com/future-architect/vuls/pull/265) ([Code0x58](https://github.com/Code0x58))
**Fixed bugs:**
- vuls prepare failed to centos7 [\#275](https://github.com/future-architect/vuls/issues/275)
- Failed to scan on RHEL5 [\#94](https://github.com/future-architect/vuls/issues/94)
- Fix container os detection [\#287](https://github.com/future-architect/vuls/pull/287) ([jiazio](https://github.com/jiazio))
- Add date header to report mail. [\#283](https://github.com/future-architect/vuls/pull/283) ([ymomoi](https://github.com/ymomoi))
- Add Content-Type header to report/mail.go . [\#280](https://github.com/future-architect/vuls/pull/280) ([hogehogehugahuga](https://github.com/hogehogehugahuga))
- Keep output of "vuls scan -report-\*" to be same every times [\#272](https://github.com/future-architect/vuls/pull/272) ([yoheimuta](https://github.com/yoheimuta))
- Fix JSON-dir regex pattern \#265 [\#271](https://github.com/future-architect/vuls/pull/271) ([kotakanbe](https://github.com/kotakanbe))
- Stop quietly ignoring `--ssh-external` on Windows [\#263](https://github.com/future-architect/vuls/pull/263) ([Code0x58](https://github.com/Code0x58))
- Fix non-interactive `apt-get install` \#251 [\#253](https://github.com/future-architect/vuls/pull/253) ([Code0x58](https://github.com/Code0x58))
**Closed issues:**
- gocui.NewGui now takes a parameter [\#261](https://github.com/future-architect/vuls/issues/261)
- Add a `--yes` flag to bypass interactive prompt for `vuls prepare` [\#260](https://github.com/future-architect/vuls/issues/260)
- `vuls prepare` doesn't work on Debian host due to apt-get confirmation prompt [\#251](https://github.com/future-architect/vuls/issues/251)
**Merged pull requests:**
- Fix gocui.NewGui after signature change \#261 [\#262](https://github.com/future-architect/vuls/pull/262) ([Code0x58](https://github.com/Code0x58))
- Replace inconsistent tabs with spaces [\#254](https://github.com/future-architect/vuls/pull/254) ([Code0x58](https://github.com/Code0x58))
- Fix README [\#249](https://github.com/future-architect/vuls/pull/249) ([usiusi360](https://github.com/usiusi360))
## [v0.1.7](https://github.com/future-architect/vuls/tree/v0.1.7) (2016-11-08)
[Full Changelog](https://github.com/future-architect/vuls/compare/v0.1.6...v0.1.7)
@@ -48,6 +273,8 @@
**Closed issues:**
- --enable-repos of yum option [\#246](https://github.com/future-architect/vuls/issues/246)
- --skip-broken at yum option [\#245](https://github.com/future-architect/vuls/issues/245)
- Recent changes to gobui cause build failures [\#228](https://github.com/future-architect/vuls/issues/228)
- https://hub.docker.com/r/vuls/go-cve-dictionary/ is empty [\#208](https://github.com/future-architect/vuls/issues/208)
- Not able to install gomail fails [\#202](https://github.com/future-architect/vuls/issues/202)
@@ -59,6 +286,7 @@
- vuls configtest -ssh-external doesnt work [\#178](https://github.com/future-architect/vuls/issues/178)
- apt-get update: time out [\#175](https://github.com/future-architect/vuls/issues/175)
- scanning on Centos6, but vuls recognizes debian. [\#174](https://github.com/future-architect/vuls/issues/174)
- Fix READMEja \#164 [\#173](https://github.com/future-architect/vuls/issues/173)
**Merged pull requests:**
@@ -258,7 +486,7 @@
- Maximum 6 nodes available to scan [\#12](https://github.com/future-architect/vuls/issues/12)
- panic: runtime error: index out of range [\#5](https://github.com/future-architect/vuls/issues/5)
- Fix sudo option on RedHat like Linux and change some messages. [\#20](https://github.com/future-architect/vuls/pull/20) ([kotakanbe](https://github.com/kotakanbe))
- Typo fix and updated readme [\#19](https://github.com/future-architect/vuls/pull/19) ([Euan-Kerr](https://github.com/Euan-Kerr))
- Typo fix and updated readme [\#19](https://github.com/future-architect/vuls/pull/19) ([EuanKerr](https://github.com/EuanKerr))
- remove a period at the end of error messages. [\#18](https://github.com/future-architect/vuls/pull/18) ([kotakanbe](https://github.com/kotakanbe))
- fix error while yum updateinfo --security update on rhel@aws [\#17](https://github.com/future-architect/vuls/pull/17) ([kotakanbe](https://github.com/kotakanbe))
- Fixed typos [\#15](https://github.com/future-architect/vuls/pull/15) ([radarhere](https://github.com/radarhere))
@@ -283,4 +511,4 @@
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*

34
Dockerfile Normal file
View File

@@ -0,0 +1,34 @@
FROM golang:alpine as builder
RUN apk add --no-cache \
git \
make \
gcc \
musl-dev
ENV REPOSITORY github.com/future-architect/vuls
COPY . $GOPATH/src/$REPOSITORY
RUN cd $GOPATH/src/$REPOSITORY && make install
FROM alpine:3.11
MAINTAINER hikachan sadayuki-matsuno
ENV LOGDIR /var/log/vuls
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"]
WORKDIR $WORKDIR
ENV PWD $WORKDIR
ENTRYPOINT ["vuls"]
CMD ["--help"]

82
GNUmakefile Normal file
View File

@@ -0,0 +1,82 @@
.PHONY: \
build \
install \
all \
vendor \
lint \
vet \
fmt \
fmtcheck \
pretest \
test \
cov \
clean
SRCS = $(shell git ls-files '*.go')
PKGS = $(shell go list ./...)
VERSION := $(shell git describe --tags --abbrev=0)
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
CGO_UNABLED := CGO_ENABLED=0 go
GO_OFF := GO111MODULE=off go
all: build
build: ./cmd/vuls/main.go pretest fmt
$(GO) build -a -ldflags "$(LDFLAGS)" -o vuls ./cmd/vuls
b: ./cmd/vuls/main.go
$(GO) build -a -ldflags "$(LDFLAGS)" -o vuls ./cmd/vuls
install: ./cmd/vuls/main.go pretest fmt
$(GO) install -ldflags "$(LDFLAGS)" ./cmd/vuls
build-scanner: ./cmd/scanner/main.go pretest fmt
$(CGO_UNABLED) build -tags=scanner -a -ldflags "$(LDFLAGS)" -o vuls ./cmd/scanner
install-scanner: ./cmd/scanner/main.go pretest fmt
$(CGO_UNABLED) install -tags=scanner -ldflags "$(LDFLAGS)" ./cmd/scanner
lint:
$(GO_OFF) get -u golang.org/x/lint/golint
golint $(PKGS)
vet:
echo $(PKGS) | xargs env $(GO) vet || exit;
fmt:
gofmt -s -w $(SRCS)
mlint:
$(foreach file,$(SRCS),gometalinter $(file) || exit;)
fmtcheck:
$(foreach file,$(SRCS),gofmt -s -d $(file);)
pretest: lint vet fmtcheck
test:
$(GO) test -cover -v ./... || exit;
unused:
$(foreach pkg,$(PKGS),unused $(pkg);)
cov:
@ go get -v github.com/axw/gocov/gocov
@ go get golang.org/x/tools/cmd/cover
gocov test | gocov report
clean:
echo $(PKGS) | xargs go clean || exit;
# trivy-to-vuls
build-trivy-to-vuls: pretest fmt
$(GO) build -o trivy-to-vuls contrib/trivy/cmd/*.go
# future-vuls
build-future-vuls: pretest fmt
$(GO) build -o future-vuls contrib/future-vuls/cmd/*.go

View File

@@ -1,36 +0,0 @@
# Environment
## Vuls
Hash : ____
To check the commit hash of HEAD
$ vuls -v
or
$ cd $GOPATH/src/github.com/future-architect/vuls
$ git rev-parse --short HEAD
## OS
- Target Server: Write here
- Vuls Server: Write here
## Go
- Go version: here
# Current Output
Please re-run the command using ```-debug``` and provide the output below.
# Addition Details
Can you also please fill in each of the remaining sections.
## Expected Behavior
## Actual Behavior
## Steps to reproduce the behaviour

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 Architect, Inc. 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 Architect, Inc. 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/>.

View File

@@ -1,71 +0,0 @@
.PHONY: \
glide \
deps \
update \
build \
install \
all \
vendor \
lint \
vet \
fmt \
fmtcheck \
pretest \
test \
cov \
clean
SRCS = $(shell git ls-files '*.go')
PKGS = ./. ./config ./models ./report ./cveapi ./scan ./util ./commands ./cache
VERSION := $(shell git describe --tags --abbrev=0)
REVISION := $(shell git rev-parse --short HEAD)
LDFLAGS := -X 'main.version=$(VERSION)' \
-X 'main.revision=$(REVISION)'
glide:
go get github.com/Masterminds/glide
deps: glide
glide install
update: glide
glide update
build: main.go deps
go build -ldflags "$(LDFLAGS)" -o vuls $<
install: main.go deps
go install -ldflags "$(LDFLAGS)"
all: test
lint:
@ go get -v github.com/golang/lint/golint
$(foreach file,$(SRCS),golint $(file) || exit;)
vet:
# @-go get -v golang.org/x/tools/cmd/vet
$(foreach pkg,$(PKGS),go vet $(pkg);)
fmt:
gofmt -w $(SRCS)
fmtcheck:
$(foreach file,$(SRCS),gofmt -d $(file);)
pretest: lint vet fmtcheck
test: pretest
$(foreach pkg,$(PKGS),go test -v $(pkg) || exit;)
unused :
$(foreach pkg,$(PKGS),unused $(pkg);)
cov:
@ go get -v github.com/axw/gocov/gocov
@ go get golang.org/x/tools/cmd/cover
gocov test | gocov report
clean:
$(foreach pkg,$(PKGS),go clean $(pkg) || exit;)

2
NOTICE
View File

@@ -1,2 +1,2 @@
Vuls Copyright (C) 2016 Future Architect, Inc. Japan.
Vuls Copyright (C) 2016 Future Corporation , Japan.

View File

@@ -1,224 +0,0 @@
# Vuls: VULnerability Scanner
[![Slack](https://img.shields.io/badge/slack-join-blue.svg)](http://goo.gl/forms/xm5KFo35tu)
Scanneur de vulnérabilité Linux, sans agent, écrit en golang
Nous avons une équipe Slack. [Rejoignez notre Slack Team](http://goo.gl/forms/xm5KFo35tu)
[README en English](https://github.com/future-architect/vuls/blob/master/README.md)
[README en Japonais](https://github.com/future-architect/vuls/blob/master/README.ja.md)
[![asciicast](https://asciinema.org/a/3y9zrf950agiko7klg8abvyck.png)](https://asciinema.org/a/3y9zrf950agiko7klg8abvyck)
![Vuls-slack](img/vuls-slack-en.png)
----
# Résumé
Effectuer des recherches de vulnérabilités et des mises à jour quotidiennes peut etre un fardeau pour un administrateur système.
Afin d'éviter des interruptions systèmes dans un environnement de production, il est fréquent pour un administrateur système de choisir de ne pas utiliser la fonction de mise à jour automatique proposée par le gestionnaire de paquets et d'effecter ces mises à jour manuellement.
Ce qui implique les problèmes suivants :
- L'administrateur système devra surveiller constamment toutes les nouvelles vulnérabilités dans NVD (National Vulnerability Database) etc.
- Il pourrait être impossible pour un administrateur système de surveiller tous les logiciels installés sur un serveur.
- Il est coûteux d'effectuer une analyse pour déterminer quels sont les serveurs affectés par de nouvelles vulnérabilités. La possibilité de négliger un serveur ou deux est bien présente.
Vuls est un outil crée pour palier aux problèmes listés ci-dessus. Voici ses caractéristiques.
- Informer les utilisateurs des vulnérabilités système.
- Informer les utilisateurs des systèmes concernés.
- La détection de vulnérabilités est effectuée automatiquement pour éviter toute négligence.
- Les rapports sont générés régulièrement via CRON pour mieux gérer ces vulnérabilités.
![Vuls-Motivation](img/vuls-motivation.png)
----
# Caractéristiques principales
- Recherche de vulnérabilités sur des serveurs Linux
- Supporte Ubuntu, Debian, CentOS, Amazon Linux, RHEL
- Cloud, auto-hébergement, Docker
- Scan d'intergiciels non inclus dans le gestionnaire de paquets de l'OS
- Scan d'intergiciels, de libraries de language de programmation et framework pour des vulnérabilités
- Supporte les logiciels inscrits au CPE
- Architecture sans agent
- L'utilisateur doit seulement mettre en place VULS sur une seule machine qui se connectera aux autres via SSH
- Génération automatique des fichiers de configuration
- Auto detection de serveurs via CIDR et génération de configuration
- Email et notification Slack possibles (supporte le Japonais)
- Les résultats d'un scan sont accessibles dans un shell via TUI Viewer terminal.
----
# Ce que Vuls ne fait pas
- Vuls ne met pas à jour les programmes affectés par les vulnérabilités découvertes.
----
# Hello Vuls
Ce tutoriel décrit la recherche de vulnérabilités sur une machine locale avec Vuls.
Voici les étapes à suivre.
1. Démrarrage d'Amazon Linux
1. Autoriser les connexions SSH depuis localhost
1. Installation des prérequis
1. Déploiement de go-cve-dictionary
1. Deploiement de Vuls
1. Configuration
1. Préparation
1. Scan
1. TUI(Terminal-Based User Interface)
## Step1. Démrarrage d'Amazon Linux
- Nous utilisons dans cette exemple une vieille AMI (amzn-ami-hvm-2015.09.1.x86_64-gp2 - ami-383c1956)
- Taille de l'instance : t2.medium
- La première fois, t2.medium et plus sont requis pour la récupération des CVE depuis NVD (2.3GB de mémoire utilisé)
- Une fois la récupération initiale des données NVD terminée vous pouvez passer sur une instance t2.nano.
- Ajoutez la configuration suivante au cloud-init, afin d'éviter une mise à jour automatique lors du premier démarrage.
- [Q: How do I disable the automatic installation of critical and important security updates on initial launch?](https://aws.amazon.com/amazon-linux-ami/faqs/?nc1=h_ls)
```
#cloud-config
repo_upgrade: none
```
## Step2. Paramètres SSH
Il est obligatoire que le serveur puisse se connecter à son propre serveur SSH
Générez une paire de clés SSH et ajoutez la clé publique dans le fichier authorized_keys
```bash
$ ssh-keygen -t rsa
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
```
## Step3. Installation des prérequis
Vuls requiert l'installation des paquets suivants :
- sqlite
- git
- gcc
- go v1.7.1 or later
- https://golang.org/doc/install
```bash
$ ssh ec2-user@52.100.100.100 -i ~/.ssh/private.pem
$ sudo yum -y install sqlite git gcc
$ wget https://storage.googleapis.com/golang/go1.7.1.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.7.1.linux-amd64.tar.gz
$ mkdir $HOME/go
```
Ajoutez les lignes suivantes dans /etc/profile.d/goenv.sh
```bash
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
```
Ajoutons ces nouvelles variables denvironnement au shell
```bash
$ source /etc/profile.d/goenv.sh
```
## Step4. Déploiement de [go-cve-dictionary](https://github.com/kotakanbe/go-cve-dictionary)
go get
```bash
$ sudo mkdir /var/log/vuls
$ sudo chown ec2-user /var/log/vuls
$ sudo chmod 700 /var/log/vuls
$ go get github.com/kotakanbe/go-cve-dictionary
```
Démarrez go-cve-dictionary en mode serveur.
Lors de son premier démarrage go-cve-dictionary récupère la liste des vulnérabilités depuis NVD
Cette opération prend environ 10 minutes (sur AWS).
## Step5. Déploiement de Vuls
Ouvrez un second terminal, connectez vous à l'instance ec2 via SSH
go get
```
$ go get github.com/future-architect/vuls
```
## Step6. Configuration
Créez un fichier de configuration (TOML format).
```
$ cat config.toml
[servers]
[servers.172-31-4-82]
host = "172.31.4.82"
port = "22"
user = "ec2-user"
keyPath = "/home/ec2-user/.ssh/id_rsa"
```
## Step7. Configuration des serveurs cibles vuls
```
$ vuls prepare
```
## Step8. Scan
```
$ vuls scan -cve-dictionary-dbpath=$PWD/cve.sqlite3
INFO[0000] Begin scanning (config: /home/ec2-user/config.toml)
... snip ...
172-31-4-82 (amazon 2015.09)
============================
CVE-2016-0494 10.0 Unspecified vulnerability in the Java SE and Java SE Embedded components in Oracle
Java SE 6u105, 7u91, and 8u66 and Java SE Embedded 8u65 allows remote attackers to
affect confidentiality, integrity, and availability via unknown vectors related to
2D.
... snip ...
CVE-2016-0494
-------------
Score 10.0 (High)
Vector (AV:N/AC:L/Au:N/C:C/I:C/A:C)
Summary Unspecified vulnerability in the Java SE and Java SE Embedded components in Oracle Java SE 6u105,
7u91, and 8u66 and Java SE Embedded 8u65 allows remote attackers to affect confidentiality,
integrity, and availability via unknown vectors related to 2D.
NVD https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-0494
MITRE https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0494
CVE Details http://www.cvedetails.com/cve/CVE-2016-0494
CVSS Calculator https://nvd.nist.gov/cvss/v2-calculator?name=CVE-2016-0494&vector=(AV:N/AC:L/Au:N/C:C/I:C/A:C)
RHEL-CVE https://access.redhat.com/security/cve/CVE-2016-0494
ALAS-2016-643 https://alas.aws.amazon.com/ALAS-2016-643.html
Package/CPE java-1.7.0-openjdk-1.7.0.91-2.6.2.2.63.amzn1 -> java-1.7.0-openjdk-1:1.7.0.95-2.6.4.0.65.amzn1
```
## Step9. TUI
Les résultats de Vuls peuvent etre affichés dans un Shell via TUI (Terminal-Based User Interface).
```
$ vuls tui
```
![Vuls-TUI](img/hello-vuls-tui.png)
----
For more information see [README in English](https://github.com/future-architect/vuls/blob/master/README.md)

File diff suppressed because it is too large Load Diff

1247
README.md

File diff suppressed because it is too large Load Diff

58
cache/bolt.go vendored
View File

@@ -1,29 +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 cache
import (
"encoding/json"
"fmt"
"time"
"github.com/Sirupsen/logrus"
"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
@@ -68,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
})
@@ -92,11 +76,28 @@ func (b Bolt) GetMeta(serverName string) (meta Meta, found bool, err error) {
return
}
// RefreshMeta gets a Meta Information os the servername to boltdb.
func (b Bolt) RefreshMeta(meta Meta) error {
meta.CreatedAt = time.Now()
jsonBytes, err := json.Marshal(meta)
if err != nil {
return xerrors.Errorf("Failed to marshal to JSON: %w", err)
}
return b.db.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(metabucket))
if err := bkt.Put([]byte(meta.Name), jsonBytes); err != nil {
return err
}
b.Log.Debugf("Refreshed Meta: %s", meta.Name)
return nil
})
}
// EnsureBuckets puts a Meta information and create a buket that holds changelogs.
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)
@@ -123,12 +124,12 @@ func (b Bolt) EnsureBuckets(meta Meta) error {
})
}
// PrettyPrint is for debuging
// PrettyPrint is for debug
func (b Bolt) PrettyPrint(meta Meta) error {
return b.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(metabucket))
v := bkt.Get([]byte(meta.Name))
b.Log.Debugf("key:%s, value:%s", meta.Name, v)
b.Log.Debugf("Meta: key:%s, value:%s", meta.Name, v)
bkt = tx.Bucket([]byte(meta.Name))
c := bkt.Cursor()
@@ -140,12 +141,12 @@ func (b Bolt) PrettyPrint(meta Meta) error {
})
}
// GetChangelog get the changelgo of specified packName from the Bucket
// GetChangelog get the changelog of specified packName from the Bucket
func (b Bolt) GetChangelog(servername, packName string) (changelog string, err error) {
err = b.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(servername))
if bkt == nil {
return fmt.Errorf("Faild to get Bucket: %s", servername)
return xerrors.Errorf("Failed to get Bucket: %s", servername)
}
v := bkt.Get([]byte(packName))
if v == nil {
@@ -163,11 +164,8 @@ 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("Faild to get Bucket: %s", servername)
return xerrors.Errorf("Failed to get Bucket: %s", servername)
}
if err := bkt.Put([]byte(packName), []byte(changelog)); err != nil {
return err
}
return nil
return bkt.Put([]byte(packName), []byte(changelog))
})
}

32
cache/bolt_test.go vendored
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 cache
import (
@@ -22,10 +5,10 @@ import (
"reflect"
"testing"
"github.com/Sirupsen/logrus"
"github.com/boltdb/bolt"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/sirupsen/logrus"
)
const path = "/tmp/vuls-test-cache-11111111.db"
@@ -37,8 +20,8 @@ var meta = Meta{
Family: "ubuntu",
Release: "16.04",
},
Packs: []models.PackageInfo{
{
Packs: models.Packages{
"apt": {
Name: "apt",
Version: "1",
},
@@ -63,7 +46,7 @@ func TestSetupBolt(t *testing.T) {
t.Errorf("Failed to open bolt: %s", err)
}
db.View(func(tx *bolt.Tx) error {
_ = db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(metabucket))
if bkt == nil {
t.Errorf("Meta bucket nof found")
@@ -90,9 +73,12 @@ func TestEnsureBuckets(t *testing.T) {
if !found {
t.Errorf("Not Found in meta")
}
if !reflect.DeepEqual(meta, m) {
if meta.Name != m.Name || meta.Distro != m.Distro {
t.Errorf("expected %v, actual %v", meta, m)
}
if !reflect.DeepEqual(meta.Packs, m.Packs) {
t.Errorf("expected %v, actual %v", meta.Packs, m.Packs)
}
if err := DB.Close(); err != nil {
t.Errorf("Failed to close bolt: %s", err)
}
@@ -101,7 +87,7 @@ func TestEnsureBuckets(t *testing.T) {
if err != nil {
t.Errorf("Failed to open bolt: %s", err)
}
db.View(func(tx *bolt.Tx) error {
_ = db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(servername))
if bkt == nil {
t.Errorf("Meta bucket nof found")

37
cache/db.go vendored
View File

@@ -1,23 +1,8 @@
/* 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 cache
import (
"time"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
)
@@ -31,6 +16,7 @@ const metabucket = "changelog-meta"
type Cache interface {
Close() error
GetMeta(string) (Meta, bool, error)
RefreshMeta(Meta) error
EnsureBuckets(Meta) error
PrettyPrint(Meta) error
GetChangelog(string, string) (string, error)
@@ -40,17 +26,8 @@ type Cache interface {
// Meta holds a server name, distro information of the scanned server and
// package information that was collected at the last scan.
type Meta struct {
Name string
Distro config.Distro
Packs []models.PackageInfo
}
// FindPack search a PackageInfo
func (m Meta) FindPack(name string) (pack models.PackageInfo, found bool) {
for _, p := range m.Packs {
if name == p.Name {
return p, true
}
}
return pack, false
Name string
Distro config.Distro
Packs models.Packages
CreatedAt time.Time
}

36
cmd/scanner/main.go Normal file
View File

@@ -0,0 +1,36 @@
package main
import (
"flag"
"fmt"
"os"
"context"
"github.com/future-architect/vuls/config"
commands "github.com/future-architect/vuls/subcmds"
"github.com/google/subcommands"
)
func main() {
subcommands.Register(subcommands.HelpCommand(), "")
subcommands.Register(subcommands.FlagsCommand(), "")
subcommands.Register(subcommands.CommandsCommand(), "")
subcommands.Register(&commands.DiscoverCmd{}, "discover")
subcommands.Register(&commands.ScanCmd{}, "scan")
subcommands.Register(&commands.HistoryCmd{}, "history")
subcommands.Register(&commands.ConfigtestCmd{}, "configtest")
subcommands.Register(&commands.SaaSCmd{}, "saas")
var v = flag.Bool("v", false, "Show version")
flag.Parse()
if *v {
fmt.Printf("vuls %s %s\n", config.Version, config.Revision)
os.Exit(int(subcommands.ExitSuccess))
}
ctx := context.Background()
os.Exit(int(subcommands.Execute(ctx)))
}

38
cmd/vuls/main.go Normal file
View File

@@ -0,0 +1,38 @@
package main
import (
"flag"
"fmt"
"os"
"context"
"github.com/future-architect/vuls/config"
commands "github.com/future-architect/vuls/subcmds"
"github.com/google/subcommands"
)
func main() {
subcommands.Register(subcommands.HelpCommand(), "")
subcommands.Register(subcommands.FlagsCommand(), "")
subcommands.Register(subcommands.CommandsCommand(), "")
subcommands.Register(&commands.DiscoverCmd{}, "discover")
subcommands.Register(&commands.TuiCmd{}, "tui")
subcommands.Register(&commands.ScanCmd{}, "scan")
subcommands.Register(&commands.HistoryCmd{}, "history")
subcommands.Register(&commands.ReportCmd{}, "report")
subcommands.Register(&commands.ConfigtestCmd{}, "configtest")
subcommands.Register(&commands.ServerCmd{}, "server")
var v = flag.Bool("v", false, "Show version")
flag.Parse()
if *v {
fmt.Printf("vuls-%s-%s\n", config.Version, config.Revision)
os.Exit(int(subcommands.ExitSuccess))
}
ctx := context.Background()
os.Exit(int(subcommands.Execute(ctx)))
}

View File

@@ -1,21 +0,0 @@
package commands
import (
"fmt"
"github.com/howeyc/gopass"
)
func getPasswd(prompt string) (string, error) {
for {
fmt.Print(prompt)
pass, err := gopass.GetPasswdMasked()
if err != nil {
return "", fmt.Errorf("Failed to read password")
}
if 0 < len(pass) {
return string(pass[:]), nil
}
}
}

View File

@@ -1,166 +0,0 @@
/* 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 (
"context"
"flag"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/Sirupsen/logrus"
"github.com/google/subcommands"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/scan"
"github.com/future-architect/vuls/util"
)
// ConfigtestCmd is Subcommand
type ConfigtestCmd struct {
configPath string
askKeyPassword bool
sshExternal bool
debug bool
}
// Name return subcommand name
func (*ConfigtestCmd) Name() string { return "configtest" }
// Synopsis return synopsis
func (*ConfigtestCmd) Synopsis() string { return "Test configuration" }
// Usage return usage
func (*ConfigtestCmd) Usage() string {
return `configtest:
configtest
[-config=/path/to/config.toml]
[-ask-key-password]
[-ssh-external]
[-debug]
[SERVER]...
`
}
// SetFlags set flag
func (p *ConfigtestCmd) SetFlags(f *flag.FlagSet) {
wd, _ := os.Getwd()
defaultConfPath := filepath.Join(wd, "config.toml")
f.StringVar(&p.configPath, "config", defaultConfPath, "/path/to/toml")
f.BoolVar(&p.debug, "debug", false, "debug mode")
f.BoolVar(
&p.askKeyPassword,
"ask-key-password",
false,
"Ask ssh privatekey password before scanning",
)
f.BoolVar(
&p.sshExternal,
"ssh-external",
false,
"Use external ssh command. Default: Use the Go native implementation")
}
// Execute execute
func (p *ConfigtestCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
var keyPass string
var err error
if p.askKeyPassword {
prompt := "SSH key password: "
if keyPass, err = getPasswd(prompt); err != nil {
logrus.Error(err)
return subcommands.ExitFailure
}
}
c.Conf.Debug = p.debug
c.Conf.SSHExternal = p.sshExternal
err = c.Load(p.configPath, keyPass)
if err != nil {
logrus.Errorf("Error loading %s, %s", p.configPath, err)
return subcommands.ExitUsageError
}
var servernames []string
if 0 < len(f.Args()) {
servernames = f.Args()
} else {
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
bytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
logrus.Errorf("Failed to read stdin: %s", err)
return subcommands.ExitFailure
}
fields := strings.Fields(string(bytes))
if 0 < len(fields) {
servernames = fields
}
}
}
target := make(map[string]c.ServerInfo)
for _, arg := range servernames {
found := false
for servername, info := range c.Conf.Servers {
if servername == arg {
target[servername] = info
found = true
break
}
}
if !found {
logrus.Errorf("%s is not in config", arg)
return subcommands.ExitUsageError
}
}
if 0 < len(servernames) {
c.Conf.Servers = target
}
// logger
Log := util.NewCustomLogger(c.ServerInfo{})
Log.Info("Validating Config...")
if !c.Conf.Validate() {
return subcommands.ExitUsageError
}
Log.Info("Detecting Server/Contianer OS... ")
if err := scan.InitServers(Log); err != nil {
Log.Errorf("Failed to init servers: %s", err)
return subcommands.ExitFailure
}
Log.Info("Checking sudo configuration... ")
if err := scan.CheckIfSudoNoPasswd(Log); err != nil {
Log.Errorf("Failed to sudo with nopassword via SSH. Define NOPASSWD in /etc/sudoers on target servers. err: %s", err)
return subcommands.ExitFailure
}
scan.PrintSSHableServerNames()
return subcommands.ExitSuccess
}

View File

@@ -1,169 +0,0 @@
/* 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 (
"context"
"flag"
"fmt"
"os"
"strings"
"text/template"
"github.com/google/subcommands"
"github.com/Sirupsen/logrus"
ps "github.com/kotakanbe/go-pingscanner"
)
// DiscoverCmd is Subcommand of host discovery mode
type DiscoverCmd struct {
}
// Name return subcommand name
func (*DiscoverCmd) Name() string { return "discover" }
// Synopsis return synopsis
func (*DiscoverCmd) Synopsis() string { return "Host discovery in the CIDR" }
// Usage return usage
func (*DiscoverCmd) Usage() string {
return `discover:
discover 192.168.0.0/24
`
}
// SetFlags set flag
func (p *DiscoverCmd) SetFlags(f *flag.FlagSet) {
}
// Execute execute
func (p *DiscoverCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
// validate
if len(f.Args()) == 0 {
return subcommands.ExitUsageError
}
for _, cidr := range f.Args() {
scanner := ps.PingScanner{
CIDR: cidr,
PingOptions: []string{
"-c1",
"-t1",
},
NumOfConcurrency: 100,
}
hosts, err := scanner.Scan()
if err != nil {
logrus.Errorf("Host Discovery failed. err: %s", err)
return subcommands.ExitFailure
}
if len(hosts) < 1 {
logrus.Errorf("Active hosts not found in %s", cidr)
return subcommands.ExitSuccess
} else if err := printConfigToml(hosts); err != nil {
logrus.Errorf("Failed to parse template. err: %s", err)
return subcommands.ExitFailure
}
}
return subcommands.ExitSuccess
}
// Output the tmeplate of config.toml
func printConfigToml(ips []string) (err error) {
const tomlTempale = `
[slack]
hookURL = "https://hooks.slack.com/services/abc123/defghijklmnopqrstuvwxyz"
channel = "#channel-name"
#channel = "${servername}"
iconEmoji = ":ghost:"
authUser = "username"
notifyUsers = ["@username"]
[mail]
smtpAddr = "smtp.gmail.com"
smtpPort = "587"
user = "username"
password = "password"
from = "from@address.com"
to = ["to@address.com"]
cc = ["cc@address.com"]
subjectPrefix = "[vuls]"
[default]
#port = "22"
#user = "username"
#keyPath = "/home/username/.ssh/id_rsa"
#cpeNames = [
# "cpe:/a:rubyonrails:ruby_on_rails:4.2.1",
#]
#dependencyCheckXMLPath = "/tmp/dependency-check-report.xml"
#containers = ["${running}"]
#ignoreCves = ["CVE-2014-6271"]
#optional = [
# ["key", "value"],
#]
[servers]
{{- $names:= .Names}}
{{range $i, $ip := .IPs}}
[servers.{{index $names $i}}]
host = "{{$ip}}"
#port = "22"
#user = "root"
#keyPath = "/home/username/.ssh/id_rsa"
#cpeNames = [
# "cpe:/a:rubyonrails:ruby_on_rails:4.2.1",
#]
#dependencyCheckXMLPath = "/tmp/dependency-check-report.xml"
#containers = ["${running}"]
#ignoreCves = ["CVE-2014-0160"]
#optional = [
# ["key", "value"],
#]
{{end}}
`
var tpl *template.Template
if tpl, err = template.New("tempalte").Parse(tomlTempale); err != nil {
return
}
type activeHosts struct {
IPs []string
Names []string
}
a := activeHosts{IPs: ips}
names := []string{}
for _, ip := range ips {
// TOML section header must not contain "."
name := strings.Replace(ip, ".", "-", -1)
names = append(names, name)
}
a.Names = names
fmt.Println("# Create config.toml using below and then ./vuls --config=/path/to/config.toml")
if err = tpl.Execute(os.Stdout, a); err != nil {
return
}
return
}

View File

@@ -1,171 +0,0 @@
/* 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 (
"context"
"flag"
"os"
"path/filepath"
"github.com/Sirupsen/logrus"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/scan"
"github.com/future-architect/vuls/util"
"github.com/google/subcommands"
)
// PrepareCmd is Subcommand of host discovery mode
type PrepareCmd struct {
debug bool
configPath string
askSudoPassword bool
askKeyPassword bool
sshExternal bool
}
// Name return subcommand name
func (*PrepareCmd) Name() string { return "prepare" }
// Synopsis return synopsis
func (*PrepareCmd) Synopsis() string {
return `Install required packages to scan.
CentOS: yum-plugin-security, yum-plugin-changelog
Amazon: None
RHEL: TODO
Ubuntu: None
`
}
// Usage return usage
func (*PrepareCmd) Usage() string {
return `prepare:
prepare
[-config=/path/to/config.toml]
[-ask-key-password]
[-debug]
[-ssh-external]
[SERVER]...
`
}
// SetFlags set flag
func (p *PrepareCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&p.debug, "debug", false, "debug mode")
wd, _ := os.Getwd()
defaultConfPath := filepath.Join(wd, "config.toml")
f.StringVar(&p.configPath, "config", defaultConfPath, "/path/to/toml")
f.BoolVar(
&p.askKeyPassword,
"ask-key-password",
false,
"Ask ssh privatekey password before scanning",
)
f.BoolVar(
&p.askSudoPassword,
"ask-sudo-password",
false,
"[Deprecated] THIS OPTION WAS REMOVED FOR SECURITY REASONS. Define NOPASSWD in /etc/sudoers on target servers and use SSH key-based authentication",
)
f.BoolVar(
&p.sshExternal,
"ssh-external",
false,
"Use external ssh command. Default: Use the Go native implementation")
}
// Execute execute
func (p *PrepareCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
var keyPass string
var err error
if p.askKeyPassword {
prompt := "SSH key password: "
if keyPass, err = getPasswd(prompt); err != nil {
logrus.Error(err)
return subcommands.ExitFailure
}
}
if p.askSudoPassword {
logrus.Errorf("[Deprecated] -ask-sudo-password WAS REMOVED FOR SECURITY REASONS. Define NOPASSWD in /etc/sudoers on target servers and use SSH key-based authentication")
return subcommands.ExitFailure
}
err = c.Load(p.configPath, keyPass)
if err != nil {
logrus.Errorf("Error loading %s, %s", p.configPath, err)
return subcommands.ExitUsageError
}
logrus.Infof("Start Preparing (config: %s)", p.configPath)
target := make(map[string]c.ServerInfo)
for _, arg := range f.Args() {
found := false
for servername, info := range c.Conf.Servers {
if servername == arg {
target[servername] = info
found = true
break
}
}
if !found {
logrus.Errorf("%s is not in config", arg)
return subcommands.ExitUsageError
}
}
if 0 < len(f.Args()) {
c.Conf.Servers = target
}
c.Conf.Debug = p.debug
c.Conf.SSHExternal = p.sshExternal
// Set up custom logger
logger := util.NewCustomLogger(c.ServerInfo{})
logger.Info("Detecting OS... ")
if err := scan.InitServers(logger); err != nil {
logger.Errorf("Failed to init servers: %s", err)
return subcommands.ExitFailure
}
logger.Info("Checking sudo configuration... ")
if err := scan.CheckIfSudoNoPasswd(logger); err != nil {
logger.Errorf("Failed to sudo with nopassword via SSH. Define NOPASSWD in /etc/sudoers on target servers")
return subcommands.ExitFailure
}
if errs := scan.Prepare(); 0 < len(errs) {
for _, e := range errs {
logger.Errorf("Failed to prepare: %s", e)
}
return subcommands.ExitFailure
}
return subcommands.ExitSuccess
}

View File

@@ -1,451 +0,0 @@
/* 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 (
"context"
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
"github.com/Sirupsen/logrus"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/cveapi"
"github.com/future-architect/vuls/report"
"github.com/future-architect/vuls/scan"
"github.com/future-architect/vuls/util"
"github.com/google/subcommands"
"github.com/k0kubun/pp"
)
// ScanCmd is Subcommand of host discovery mode
type ScanCmd struct {
lang string
debug bool
debugSQL bool
configPath string
resultsDir string
cvedbtype string
cvedbpath string
cveDictionaryURL string
cacheDBPath string
cvssScoreOver float64
ignoreUnscoredCves bool
httpProxy string
askSudoPassword bool
askKeyPassword bool
containersOnly bool
skipBroken bool
// reporting
reportSlack bool
reportMail bool
reportJSON bool
reportText bool
reportS3 bool
reportAzureBlob bool
reportXML bool
awsProfile string
awsS3Bucket string
awsRegion string
azureAccount string
azureKey string
azureContainer string
sshExternal bool
}
// Name return subcommand name
func (*ScanCmd) Name() string { return "scan" }
// Synopsis return synopsis
func (*ScanCmd) Synopsis() string { return "Scan vulnerabilities" }
// Usage return usage
func (*ScanCmd) Usage() string {
return `scan:
scan
[-lang=en|ja]
[-config=/path/to/config.toml]
[-results-dir=/path/to/results]
[-cve-dictionary-dbtype=sqlite3|mysql]
[-cve-dictionary-dbpath=/path/to/cve.sqlite3 or mysql connection string]
[-cve-dictionary-url=http://127.0.0.1:1323]
[-cache-dbpath=/path/to/cache.db]
[-cvss-over=7]
[-ignore-unscored-cves]
[-ssh-external]
[-containers-only]
[-skip-broken]
[-report-azure-blob]
[-report-json]
[-report-mail]
[-report-s3]
[-report-slack]
[-report-text]
[-report-xml]
[-http-proxy=http://192.168.0.1:8080]
[-ask-key-password]
[-debug]
[-debug-sql]
[-aws-profile=default]
[-aws-region=us-west-2]
[-aws-s3-bucket=bucket_name]
[-azure-account=accout]
[-azure-key=key]
[-azure-container=container]
[SERVER]...
`
}
// SetFlags set flag
func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
f.StringVar(&p.lang, "lang", "en", "[en|ja]")
f.BoolVar(&p.debug, "debug", false, "debug mode")
f.BoolVar(&p.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")
defaultResultsDir := filepath.Join(wd, "results")
f.StringVar(&p.resultsDir, "results-dir", defaultResultsDir, "/path/to/results")
f.StringVar(
&p.cvedbtype,
"cve-dictionary-dbtype",
"sqlite3",
"DB type for fetching CVE dictionary (sqlite3 or mysql)")
f.StringVar(
&p.cvedbpath,
"cve-dictionary-dbpath",
"",
"/path/to/sqlite3 (For get cve detail from cve.sqlite3)")
defaultURL := "http://127.0.0.1:1323"
f.StringVar(
&p.cveDictionaryURL,
"cve-dictionary-url",
defaultURL,
"http://CVE.Dictionary")
defaultCacheDBPath := filepath.Join(wd, "cache.db")
f.StringVar(
&p.cacheDBPath,
"cache-dbpath",
defaultCacheDBPath,
"/path/to/cache.db (local cache of changelog for Ubuntu/Debian)")
f.Float64Var(
&p.cvssScoreOver,
"cvss-over",
0,
"-cvss-over=6.5 means reporting CVSS Score 6.5 and over (default: 0 (means report all))")
f.BoolVar(
&p.ignoreUnscoredCves,
"ignore-unscored-cves",
false,
"Don't report the unscored CVEs")
f.BoolVar(
&p.sshExternal,
"ssh-external",
false,
"Use external ssh command. Default: Use the Go native implementation")
f.BoolVar(
&p.containersOnly,
"containers-only",
false,
"Scan containers only. Default: Scan both of hosts and containers")
f.BoolVar(
&p.skipBroken,
"skip-broken",
false,
"[For CentOS] yum update changelog with --skip-broken option")
f.StringVar(
&p.httpProxy,
"http-proxy",
"",
"http://proxy-url:port (default: empty)",
)
f.BoolVar(&p.reportSlack, "report-slack", false, "Send report via Slack")
f.BoolVar(&p.reportMail, "report-mail", false, "Send report via Email")
f.BoolVar(&p.reportJSON,
"report-json",
false,
fmt.Sprintf("Write report to JSON files (%s/results/current)", wd),
)
f.BoolVar(&p.reportText,
"report-text",
false,
fmt.Sprintf("Write report to text files (%s/results/current)", wd),
)
f.BoolVar(&p.reportXML,
"report-xml",
false,
fmt.Sprintf("Write report to XML files (%s/results/current)", wd),
)
f.BoolVar(&p.reportS3,
"report-s3",
false,
"Write report to S3 (bucket/yyyyMMdd_HHmm/servername.json)",
)
f.StringVar(&p.awsProfile, "aws-profile", "default", "AWS profile to use")
f.StringVar(&p.awsRegion, "aws-region", "us-east-1", "AWS region to use")
f.StringVar(&p.awsS3Bucket, "aws-s3-bucket", "", "S3 bucket name")
f.BoolVar(&p.reportAzureBlob,
"report-azure-blob",
false,
"Write report to Azure Storage blob (container/yyyyMMdd_HHmm/servername.json)",
)
f.StringVar(&p.azureAccount, "azure-account", "", "Azure account name to use. AZURE_STORAGE_ACCOUNT environment variable is used if not specified")
f.StringVar(&p.azureKey, "azure-key", "", "Azure account key to use. AZURE_STORAGE_ACCESS_KEY environment variable is used if not specified")
f.StringVar(&p.azureContainer, "azure-container", "", "Azure storage container name")
f.BoolVar(
&p.askKeyPassword,
"ask-key-password",
false,
"Ask ssh privatekey password before scanning",
)
f.BoolVar(
&p.askSudoPassword,
"ask-sudo-password",
false,
"[Deprecated] THIS OPTION WAS REMOVED FOR SECURITY REASONS. Define NOPASSWD in /etc/sudoers on target servers and use SSH key-based authentication",
)
}
// Execute execute
func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
var keyPass string
var err error
if p.askKeyPassword {
prompt := "SSH key password: "
if keyPass, err = getPasswd(prompt); err != nil {
logrus.Error(err)
return subcommands.ExitFailure
}
}
if p.askSudoPassword {
logrus.Errorf("[Deprecated] -ask-sudo-password WAS REMOVED FOR SECURITY REASONS. Define NOPASSWD in /etc/sudoers on target servers and use SSH key-based authentication")
return subcommands.ExitFailure
}
c.Conf.Debug = p.debug
err = c.Load(p.configPath, keyPass)
if err != nil {
logrus.Errorf("Error loading %s, %s", p.configPath, err)
return subcommands.ExitUsageError
}
logrus.Info("Start scanning")
logrus.Infof("config: %s", p.configPath)
if p.cvedbpath != "" {
if p.cvedbtype == "sqlite3" {
logrus.Infof("cve-dictionary: %s", p.cvedbpath)
}
} else {
logrus.Infof("cve-dictionary: %s", p.cveDictionaryURL)
}
var servernames []string
if 0 < len(f.Args()) {
servernames = f.Args()
} else {
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
bytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
logrus.Errorf("Failed to read stdin: %s", err)
return subcommands.ExitFailure
}
fields := strings.Fields(string(bytes))
if 0 < len(fields) {
servernames = fields
}
}
}
target := make(map[string]c.ServerInfo)
for _, arg := range servernames {
found := false
for servername, info := range c.Conf.Servers {
if servername == arg {
target[servername] = info
found = true
break
}
}
if !found {
logrus.Errorf("%s is not in config", arg)
return subcommands.ExitUsageError
}
}
if 0 < len(servernames) {
c.Conf.Servers = target
}
logrus.Debugf("%s", pp.Sprintf("%v", target))
c.Conf.Lang = p.lang
c.Conf.DebugSQL = p.debugSQL
// logger
Log := util.NewCustomLogger(c.ServerInfo{})
scannedAt := time.Now()
// report
reports := []report.ResultWriter{
report.StdoutWriter{},
report.LogrusWriter{},
}
if p.reportSlack {
reports = append(reports, report.SlackWriter{})
}
if p.reportMail {
reports = append(reports, report.MailWriter{})
}
if p.reportJSON {
reports = append(reports, report.JSONWriter{ScannedAt: scannedAt})
}
if p.reportText {
reports = append(reports, report.TextFileWriter{ScannedAt: scannedAt})
}
if p.reportXML {
reports = append(reports, report.XMLWriter{ScannedAt: scannedAt})
}
if p.reportS3 {
c.Conf.AwsRegion = p.awsRegion
c.Conf.AwsProfile = p.awsProfile
c.Conf.S3Bucket = p.awsS3Bucket
if err := report.CheckIfBucketExists(); err != nil {
Log.Errorf("Failed to access to the S3 bucket. err: %s", err)
Log.Error("Ensure the bucket or check AWS config before scanning")
return subcommands.ExitUsageError
}
reports = append(reports, report.S3Writer{})
}
if p.reportAzureBlob {
c.Conf.AzureAccount = p.azureAccount
if len(c.Conf.AzureAccount) == 0 {
c.Conf.AzureAccount = os.Getenv("AZURE_STORAGE_ACCOUNT")
}
c.Conf.AzureKey = p.azureKey
if len(c.Conf.AzureKey) == 0 {
c.Conf.AzureKey = os.Getenv("AZURE_STORAGE_ACCESS_KEY")
}
c.Conf.AzureContainer = p.azureContainer
if len(c.Conf.AzureContainer) == 0 {
Log.Error("Azure storage container name is requied with --azure-container option")
return subcommands.ExitUsageError
}
if err := report.CheckIfAzureContainerExists(); err != nil {
Log.Errorf("Failed to access to the Azure Blob container. err: %s", err)
Log.Error("Ensure the container or check Azure config before scanning")
return subcommands.ExitUsageError
}
reports = append(reports, report.AzureBlobWriter{})
}
c.Conf.ResultsDir = p.resultsDir
c.Conf.CveDBType = p.cvedbtype
c.Conf.CveDBPath = p.cvedbpath
c.Conf.CveDictionaryURL = p.cveDictionaryURL
c.Conf.CacheDBPath = p.cacheDBPath
c.Conf.CvssScoreOver = p.cvssScoreOver
c.Conf.IgnoreUnscoredCves = p.ignoreUnscoredCves
c.Conf.SSHExternal = p.sshExternal
c.Conf.HTTPProxy = p.httpProxy
c.Conf.ContainersOnly = p.containersOnly
c.Conf.SkipBroken = p.skipBroken
Log.Info("Validating Config...")
if !c.Conf.Validate() {
return subcommands.ExitUsageError
}
if ok, err := cveapi.CveClient.CheckHealth(); !ok {
Log.Errorf("CVE HTTP server is not running. err: %s", err)
Log.Errorf("Run go-cve-dictionary as server mode or specify -cve-dictionary-dbpath option")
return subcommands.ExitFailure
}
Log.Info("Detecting Server/Contianer OS... ")
if err := scan.InitServers(Log); err != nil {
Log.Errorf("Failed to init servers: %s", err)
return subcommands.ExitFailure
}
Log.Info("Checking sudo configuration... ")
if err := scan.CheckIfSudoNoPasswd(Log); err != nil {
Log.Errorf("Failed to sudo with nopassword via SSH. Define NOPASSWD in /etc/sudoers on target servers")
return subcommands.ExitFailure
}
Log.Info("Detecting Platforms... ")
scan.DetectPlatforms(Log)
Log.Info("Scanning vulnerabilities... ")
if errs := scan.Scan(); 0 < len(errs) {
for _, e := range errs {
Log.Errorf("Failed to scan. err: %s", e)
}
return subcommands.ExitFailure
}
scanResults, err := scan.GetScanResults()
if err != nil {
Log.Fatal(err)
return subcommands.ExitFailure
}
Log.Info("Reporting...")
filtered := scanResults.FilterByCvssOver()
for _, w := range reports {
if err := w.Write(filtered); err != nil {
Log.Fatalf("Failed to report, err: %s", err)
return subcommands.ExitFailure
}
}
return subcommands.ExitSuccess
}

View File

@@ -1,105 +0,0 @@
/* 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 (
"context"
"flag"
"io/ioutil"
"os"
"path/filepath"
"strings"
log "github.com/Sirupsen/logrus"
c "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/report"
"github.com/google/subcommands"
)
// TuiCmd is Subcommand of host discovery mode
type TuiCmd struct {
lang string
debugSQL bool
resultsDir string
}
// Name return subcommand name
func (*TuiCmd) Name() string { return "tui" }
// Synopsis return synopsis
func (*TuiCmd) Synopsis() string { return "Run Tui view to anayze vulnerabilites" }
// Usage return usage
func (*TuiCmd) Usage() string {
return `tui:
tui [-results-dir=/path/to/results]
`
}
// SetFlags set flag
func (p *TuiCmd) SetFlags(f *flag.FlagSet) {
// f.StringVar(&p.lang, "lang", "en", "[en|ja]")
f.BoolVar(&p.debugSQL, "debug-sql", false, "debug SQL")
wd, _ := os.Getwd()
defaultResultsDir := filepath.Join(wd, "results")
f.StringVar(&p.resultsDir, "results-dir", defaultResultsDir, "/path/to/results")
}
// Execute execute
func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
c.Conf.Lang = "en"
c.Conf.DebugSQL = p.debugSQL
c.Conf.ResultsDir = p.resultsDir
var jsonDirName string
var err error
if 0 < len(f.Args()) {
var jsonDirs report.JSONDirs
if jsonDirs, err = report.GetValidJSONDirs(); err != nil {
return subcommands.ExitFailure
}
for _, d := range jsonDirs {
splitPath := strings.Split(d, string(os.PathSeparator))
if splitPath[len(splitPath)-1] == f.Args()[0] {
jsonDirName = f.Args()[0]
break
}
}
if len(jsonDirName) == 0 {
log.Errorf("First Argument have to be JSON directory name : %s", err)
return subcommands.ExitFailure
}
} else {
stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) == 0 {
bytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Errorf("Failed to read stdin: %s", err)
return subcommands.ExitFailure
}
fields := strings.Fields(string(bytes))
if 0 < len(fields) {
jsonDirName = fields[0]
}
}
}
return report.RunTui(jsonDirName)
}

32
config/chatworkconf.go Normal file
View File

@@ -0,0 +1,32 @@
package config
import (
"github.com/asaskevich/govalidator"
"golang.org/x/xerrors"
)
// ChatWorkConf is ChatWork config
type ChatWorkConf struct {
APIToken string `json:"-"`
Room string `json:"-"`
}
// Validate validates configuration
func (c *ChatWorkConf) Validate() (errs []error) {
if !Conf.ToChatWork {
return
}
if len(c.Room) == 0 {
errs = append(errs, xerrors.New("chatWorkConf.room must not be empty"))
}
if len(c.APIToken) == 0 {
errs = append(errs, xerrors.New("chatWorkConf.ApiToken must not be empty"))
}
_, err := govalidator.ValidateStruct(c)
if err != nil {
errs = append(errs, err)
}
return
}

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 config
var (

View File

@@ -1,121 +1,106 @@
/* 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 config
import (
"fmt"
"os"
"runtime"
"strconv"
"strings"
log "github.com/Sirupsen/logrus"
valid "github.com/asaskevich/govalidator"
"github.com/asaskevich/govalidator"
log "github.com/sirupsen/logrus"
"golang.org/x/xerrors"
)
// Version of Vuls
var Version = "`make build` or `make install` will show the version"
// Revision of Git
var Revision string
// Conf has Configuration
var Conf Config
//Config is struct of Configuration
type Config struct {
Debug bool
DebugSQL bool
Lang string
Debug bool `json:"debug,omitempty"`
DebugSQL bool `json:"debugSQL,omitempty"`
Lang string `json:"lang,omitempty"`
HTTPProxy string `valid:"url" json:"httpProxy,omitempty"`
LogDir string `json:"logDir,omitempty"`
ResultsDir string `json:"resultsDir,omitempty"`
Pipe bool `json:"pipe,omitempty"`
Quiet bool `json:"quiet,omitempty"`
NoProgress bool `json:"noProgress,omitempty"`
SSHNative bool `json:"sshNative,omitempty"`
Vvv bool `json:"vvv,omitempty"`
Mail smtpConf
Slack SlackConf
Default ServerInfo
Servers map[string]ServerInfo
Default ServerInfo `json:"default,omitempty"`
Servers map[string]ServerInfo `json:"servers,omitempty"`
CvssScoreOver float64 `json:"cvssScoreOver,omitempty"`
CveDictionaryURL string `valid:"url"`
IgnoreUnscoredCves bool `json:"ignoreUnscoredCves,omitempty"`
IgnoreUnfixed bool `json:"ignoreUnfixed,omitempty"`
IgnoreGitHubDismissed bool `json:"ignore_git_hub_dismissed,omitempty"`
CvssScoreOver float64
IgnoreUnscoredCves bool
CacheDBPath string `json:"cacheDBPath,omitempty"`
TrivyCacheDBDir string `json:"trivyCacheDBDir,omitempty"`
SSHExternal bool
ContainersOnly bool
SkipBroken bool
CveDict GoCveDictConf `json:"cveDict,omitempty"`
OvalDict GovalDictConf `json:"ovalDict,omitempty"`
Gost GostConf `json:"gost,omitempty"`
Exploit ExploitConf `json:"exploit,omitempty"`
Metasploit MetasploitConf `json:"metasploit,omitempty"`
HTTPProxy string `valid:"url"`
ResultsDir string
CveDBType string
CveDBPath string
CacheDBPath string
Slack SlackConf `json:"-"`
EMail SMTPConf `json:"-"`
HTTP HTTPConf `json:"-"`
Syslog SyslogConf `json:"-"`
AWS AWSConf `json:"-"`
Azure AzureConf `json:"-"`
ChatWork ChatWorkConf `json:"-"`
Telegram TelegramConf `json:"-"`
AwsProfile string
AwsRegion string
S3Bucket string
WpScan WpScanConf `json:"WpScan,omitempty"`
AzureAccount string
AzureKey string
AzureContainer string
Saas SaasConf `json:"-"`
DetectIPS bool `json:"detectIps,omitempty"`
// CpeNames []string
// SummaryMode bool
RefreshCve bool `json:"refreshCve,omitempty"`
ToSlack bool `json:"toSlack,omitempty"`
ToChatWork bool `json:"toChatWork,omitempty"`
ToTelegram bool `json:"ToTelegram,omitempty"`
ToEmail bool `json:"toEmail,omitempty"`
ToSyslog bool `json:"toSyslog,omitempty"`
ToLocalFile bool `json:"toLocalFile,omitempty"`
ToS3 bool `json:"toS3,omitempty"`
ToAzureBlob bool `json:"toAzureBlob,omitempty"`
ToHTTP bool `json:"toHTTP,omitempty"`
FormatJSON bool `json:"formatJSON,omitempty"`
FormatOneEMail bool `json:"formatOneEMail,omitempty"`
FormatOneLineText bool `json:"formatOneLineText,omitempty"`
FormatList bool `json:"formatList,omitempty"`
FormatFullText bool `json:"formatFullText,omitempty"`
FormatCsvList bool `json:"formatCsvList,omitempty"`
GZIP bool `json:"gzip,omitempty"`
DiffPlus bool `json:"diffPlus,omitempty"`
DiffMinus bool `json:"diffMinus,omitempty"`
Diff bool `json:"diff,omitempty"`
}
// Validate configuration
func (c Config) Validate() bool {
errs := []error{}
// ValidateOnConfigtest validates
func (c Config) ValidateOnConfigtest() bool {
errs := c.checkSSHKeyExist()
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))
}
if runtime.GOOS == "windows" && !c.SSHNative {
errs = append(errs, xerrors.New("-ssh-native-insecure is needed on windows"))
}
// If no valid DB type is set, default to sqlite3
if c.CveDBType == "" {
c.CveDBType = "sqlite3"
}
if c.CveDBType != "sqlite3" && c.CveDBType != "mysql" {
errs = append(errs, fmt.Errorf(
"CVE DB type must be either 'sqlite3' or 'mysql'. -cve-dictionary-dbtype: %s", c.CveDBType))
}
if c.CveDBType == "sqlite3" {
if len(c.CveDBPath) != 0 {
if ok, _ := valid.IsFilePath(c.CveDBPath); !ok {
errs = append(errs, fmt.Errorf(
"SQLite3 DB(Cve Dictionary) path must be a *Absolute* file path. -cve-dictionary-dbpath: %s", c.CveDBPath))
}
}
}
if len(c.CacheDBPath) != 0 {
if ok, _ := valid.IsFilePath(c.CacheDBPath); !ok {
errs = append(errs, fmt.Errorf(
"Cache DB path must be a *Absolute* file path. -cache-dbpath: %s", c.CacheDBPath))
}
}
_, err := valid.ValidateStruct(c)
_, err := govalidator.ValidateStruct(c)
if err != nil {
errs = append(errs, err)
}
if mailerrs := c.Mail.Validate(); 0 < len(mailerrs) {
errs = append(errs, mailerrs...)
}
if slackerrs := c.Slack.Validate(); 0 < len(slackerrs) {
errs = append(errs, slackerrs...)
}
for _, err := range errs {
log.Error(err)
}
@@ -123,151 +108,318 @@ func (c Config) Validate() bool {
return len(errs) == 0
}
// smtpConf is smtp config
type smtpConf struct {
SMTPAddr string
SMTPPort string `valid:"port"`
// ValidateOnScan validates configuration
func (c Config) ValidateOnScan() bool {
errs := c.checkSSHKeyExist()
User string
Password string
From string
To []string
Cc []string
SubjectPrefix string
UseThisTime bool
}
func checkEmails(emails []string) (errs []error) {
for _, addr := range emails {
if len(addr) == 0 {
return
}
if ok := valid.IsEmail(addr); !ok {
errs = append(errs, fmt.Errorf("Invalid email address. email: %s", addr))
}
}
return
}
// Validate SMTP configuration
func (c *smtpConf) Validate() (errs []error) {
if !c.UseThisTime {
return
if runtime.GOOS == "windows" && !c.SSHNative {
errs = append(errs, xerrors.New("-ssh-native-insecure is needed on windows"))
}
// Check Emails fromat
emails := []string{}
emails = append(emails, c.From)
emails = append(emails, c.To...)
emails = append(emails, c.Cc...)
if emailErrs := checkEmails(emails); 0 < len(emailErrs) {
errs = append(errs, emailErrs...)
}
if len(c.SMTPAddr) == 0 {
errs = append(errs, fmt.Errorf("smtpAddr must not be empty"))
}
if len(c.SMTPPort) == 0 {
errs = append(errs, fmt.Errorf("smtpPort must not be empty"))
}
if len(c.To) == 0 {
errs = append(errs, fmt.Errorf("To required at least one address"))
}
if len(c.From) == 0 {
errs = append(errs, fmt.Errorf("From required at least one address"))
}
_, err := valid.ValidateStruct(c)
if err != nil {
errs = append(errs, err)
}
return
}
// SlackConf is slack config
type SlackConf struct {
HookURL string `valid:"url"`
Channel string `json:"channel"`
IconEmoji string `json:"icon_emoji"`
AuthUser string `json:"username"`
NotifyUsers []string
Text string `json:"text"`
UseThisTime bool
}
// Validate validates configuration
func (c *SlackConf) Validate() (errs []error) {
if !c.UseThisTime {
return
}
if len(c.HookURL) == 0 {
errs = append(errs, fmt.Errorf("hookURL must not be empty"))
}
if len(c.Channel) == 0 {
errs = append(errs, fmt.Errorf("channel must not be empty"))
} else {
if !(strings.HasPrefix(c.Channel, "#") ||
c.Channel == "${servername}") {
errs = append(errs, fmt.Errorf(
"channel's prefix must be '#', channel: %s", c.Channel))
if len(c.ResultsDir) != 0 {
if ok, _ := govalidator.IsFilePath(c.ResultsDir); !ok {
errs = append(errs, xerrors.Errorf(
"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
}
}
if len(c.AuthUser) == 0 {
errs = append(errs, fmt.Errorf("authUser must not be empty"))
if len(c.CacheDBPath) != 0 {
if ok, _ := govalidator.IsFilePath(c.CacheDBPath); !ok {
errs = append(errs, xerrors.Errorf(
"Cache DB path must be a *Absolute* file path. -cache-dbpath: %s",
c.CacheDBPath))
}
}
_, err := valid.ValidateStruct(c)
_, err := govalidator.ValidateStruct(c)
if err != nil {
errs = append(errs, err)
}
return
for _, err := range errs {
log.Error(err)
}
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{}
if err := validateDB("cvedb", c.CveDict.Type, c.CveDict.SQLite3Path, c.CveDict.URL); err != nil {
errs = append(errs, err)
}
if err := validateDB("ovaldb", c.OvalDict.Type, c.OvalDict.SQLite3Path, c.OvalDict.URL); err != nil {
errs = append(errs, err)
}
if err := validateDB("gostdb", c.Gost.Type, c.Gost.SQLite3Path, c.Gost.URL); err != nil {
errs = append(errs, err)
}
if err := validateDB("exploitdb", c.Exploit.Type, c.Exploit.SQLite3Path, c.Exploit.URL); err != nil {
errs = append(errs, err)
}
if err := validateDB("msfdb", c.Metasploit.Type, c.Metasploit.SQLite3Path, c.Metasploit.URL); err != nil {
errs = append(errs, err)
}
for _, err := range errs {
log.Error(err)
}
return len(errs) == 0
}
// ValidateOnReport validates configuration
func (c Config) ValidateOnReport() bool {
errs := []error{}
if len(c.ResultsDir) != 0 {
if ok, _ := govalidator.IsFilePath(c.ResultsDir); !ok {
errs = append(errs, xerrors.Errorf(
"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
}
}
_, err := govalidator.ValidateStruct(c)
if err != nil {
errs = append(errs, err)
}
if mailerrs := c.EMail.Validate(); 0 < len(mailerrs) {
errs = append(errs, mailerrs...)
}
if slackerrs := c.Slack.Validate(); 0 < len(slackerrs) {
errs = append(errs, slackerrs...)
}
if chatworkerrs := c.ChatWork.Validate(); 0 < len(chatworkerrs) {
errs = append(errs, chatworkerrs...)
}
if telegramerrs := c.Telegram.Validate(); 0 < len(telegramerrs) {
errs = append(errs, telegramerrs...)
}
if syslogerrs := c.Syslog.Validate(); 0 < len(syslogerrs) {
errs = append(errs, syslogerrs...)
}
if httperrs := c.HTTP.Validate(); 0 < len(httperrs) {
errs = append(errs, httperrs...)
}
for _, err := range errs {
log.Error(err)
}
return len(errs) == 0
}
// ValidateOnTui validates configuration
func (c Config) ValidateOnTui() bool {
errs := []error{}
if len(c.ResultsDir) != 0 {
if ok, _ := govalidator.IsFilePath(c.ResultsDir); !ok {
errs = append(errs, xerrors.Errorf(
"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
}
}
if err := validateDB("cvedb", c.CveDict.Type, c.CveDict.SQLite3Path, c.CveDict.URL); err != nil {
errs = append(errs, err)
}
for _, err := range errs {
log.Error(err)
}
return len(errs) == 0
}
// ValidateOnSaaS validates configuration
func (c Config) ValidateOnSaaS() bool {
saaserrs := c.Saas.Validate()
for _, err := range saaserrs {
log.Error("Failed to validate SaaS conf: %+w", err)
}
return len(saaserrs) == 0
}
// validateDB validates configuration
func validateDB(dictionaryDBName, dbType, dbPath, dbURL string) error {
log.Infof("-%s-type: %s, -%s-url: %s, -%s-path: %s",
dictionaryDBName, dbType, dictionaryDBName, dbURL, dictionaryDBName, dbPath)
switch dbType {
case "sqlite3":
if dbURL != "" {
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, _ := govalidator.IsFilePath(dbPath); !ok {
return xerrors.Errorf("SQLite3 path must be a *Absolute* file path. -%s-path: %s",
dictionaryDBName, dbPath)
}
case "mysql":
if dbURL == "" {
return xerrors.Errorf(`MySQL connection string is needed. -%s-url="user:pass@tcp(localhost:3306)/dbname"`,
dictionaryDBName)
}
case "postgres":
if dbURL == "" {
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 xerrors.Errorf(`Redis connection string is needed. -%s-url="redis://localhost/0"`,
dictionaryDBName)
}
case "http":
if dbURL == "" {
return xerrors.Errorf(`URL is needed. -%s-url="http://localhost:1323"`,
dictionaryDBName)
}
default:
return xerrors.Errorf("%s type must be either 'sqlite3', 'mysql', 'postgres', 'redis' or 'http'. -%s-type: %s",
dictionaryDBName, dictionaryDBName, dbType)
}
return nil
}
// AWSConf is aws config
type AWSConf struct {
// AWS profile to use
Profile string `json:"profile"`
// AWS region to use
Region string `json:"region"`
// S3 bucket name
S3Bucket string `json:"s3Bucket"`
// /bucket/path/to/results
S3ResultsDir string `json:"s3ResultsDir"`
// The Server-side encryption algorithm used when storing the reports in S3 (e.g., AES256, aws:kms).
S3ServerSideEncryption string `json:"s3ServerSideEncryption"`
}
// AzureConf is azure config
type AzureConf struct {
// Azure account name to use. AZURE_STORAGE_ACCOUNT environment variable is used if not specified
AccountName string `json:"accountName"`
// Azure account key to use. AZURE_STORAGE_ACCESS_KEY environment variable is used if not specified
AccountKey string `json:"-"`
// Azure storage container name
ContainerName string `json:"containerName"`
}
// WpScanConf is wpscan.com config
type WpScanConf struct {
Token string `toml:"token,omitempty" json:"-"`
DetectInactive bool `toml:"detectInactive,omitempty" json:"detectInactive,omitempty"`
}
// ServerInfo has SSH Info, additional CPE packages to scan.
type ServerInfo struct {
ServerName string
User string
Host string
Port string
KeyPath string
KeyPassword string
ServerName string `toml:"-" json:"serverName,omitempty"`
User string `toml:"user,omitempty" json:"user,omitempty"`
Host string `toml:"host,omitempty" json:"host,omitempty"`
JumpServer []string `toml:"jumpServer,omitempty" json:"jumpServer,omitempty"`
Port string `toml:"port,omitempty" json:"port,omitempty"`
SSHConfigPath string `toml:"sshConfigPath,omitempty" json:"sshConfigPath,omitempty"`
KeyPath string `toml:"keyPath,omitempty" json:"keyPath,omitempty"`
KeyPassword string `json:"-" toml:"-"`
CpeNames []string `toml:"cpeNames,omitempty" json:"cpeNames,omitempty"`
ScanMode []string `toml:"scanMode,omitempty" json:"scanMode,omitempty"`
ScanModules []string `toml:"scanModules,omitempty" json:"scanModules,omitempty"`
OwaspDCXMLPath string `toml:"owaspDCXMLPath,omitempty" json:"owaspDCXMLPath,omitempty"`
ContainersOnly bool `toml:"containersOnly,omitempty" json:"containersOnly,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"`
Containers map[string]ContainerSetting `toml:"containers,omitempty" json:"containers,omitempty"`
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
UUIDs map[string]string `toml:"uuids,omitempty" json:"uuids,omitempty"`
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
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 ""
IgnoredJSONKeys []string `toml:"ignoredJSONKeys,omitempty" json:"ignoredJSONKeys,omitempty"`
IPv4Addrs []string `toml:"-" json:"ipv4Addrs,omitempty"`
IPv6Addrs []string `toml:"-" json:"ipv6Addrs,omitempty"`
IPSIdentifiers map[IPS]string `toml:"-" json:"ipsIdentifiers,omitempty"`
WordPress *WordPressConf `toml:"wordpress,omitempty" json:"wordpress,omitempty"`
CpeNames []string
DependencyCheckXMLPath string
// internal use
LogMsgAnsiColor string `toml:"-" json:"-"` // DebugLog Color
Container Container `toml:"-" json:"-"`
Distro Distro `toml:"-" json:"-"`
Mode ScanMode `toml:"-" json:"-"`
Module ScanModule `toml:"-" json:"-"`
}
// Container Names or IDs
Containers []string
// ContainerSetting is used for loading container setting in config.toml
type ContainerSetting struct {
Cpes []string `json:"cpes,omitempty"`
OwaspDCXMLPath string `json:"owaspDCXMLPath,omitempty"`
IgnorePkgsRegexp []string `json:"ignorePkgsRegexp,omitempty"`
IgnoreCves []string `json:"ignoreCves,omitempty"`
}
IgnoreCves []string
// WordPressConf used for WordPress Scanning
type WordPressConf struct {
OSUser string `toml:"osUser,omitempty" json:"osUser,omitempty"`
DocRoot string `toml:"docRoot,omitempty" json:"docRoot,omitempty"`
CmdPath string `toml:"cmdPath,omitempty" json:"cmdPath,omitempty"`
}
// Optional key-value set that will be outputted to JSON
Optional [][]interface{}
// IsZero return whether this struct is not specified in config.toml
func (cnf WordPressConf) IsZero() bool {
return cnf.OSUser == "" && cnf.DocRoot == "" && cnf.CmdPath == ""
}
// For CentOS, RHEL, Amazon
Enablerepo string
// used internal
LogMsgAnsiColor string // DebugLog Color
Container Container
Distro Distro
// GitHubConf is used for GitHub Security Alerts
type GitHubConf struct {
Token string `json:"-"`
}
// GetServerName returns ServerName if this serverInfo is about host.
// If this serverInfo is abount a container, returns containerID@ServerName
// If this serverInfo is about a container, returns containerID@ServerName
func (s ServerInfo) GetServerName() string {
if len(s.Container.ContainerID) == 0 {
return s.ServerName
}
return fmt.Sprintf("%s@%s", s.Container.ContainerID, s.ServerName)
return fmt.Sprintf("%s@%s", s.Container.Name, s.ServerName)
}
// Distro has distribution info
@@ -280,6 +432,20 @@ func (l Distro) String() string {
return fmt.Sprintf("%s %s", l.Family, l.Release)
}
// MajorVersion returns Major version
func (l Distro) MajorVersion() (int, error) {
if l.Family == Amazon {
if isAmazonLinux1(l.Release) {
return 1, nil
}
return 2, nil
}
if 0 < len(l.Release) {
return strconv.Atoi(strings.Split(l.Release, ".")[0])
}
return 0, xerrors.New("Release is empty")
}
// IsContainer returns whether this ServerInfo is about container
func (s ServerInfo) IsContainer() bool {
return 0 < len(s.Container.ContainerID)
@@ -294,5 +460,10 @@ func (s *ServerInfo) SetContainer(d Container) {
type Container struct {
ContainerID string
Name string
Type string
Image string
}
// VulnSrcConf is an interface of vulnsrc
type VulnSrcConf interface {
CheckHTTPHealth() error
}

103
config/config_test.go Normal file
View File

@@ -0,0 +1,103 @@
package config
import (
"testing"
)
func TestSyslogConfValidate(t *testing.T) {
var tests = []struct {
conf SyslogConf
expectedErrLength int
}{
{
conf: SyslogConf{},
expectedErrLength: 0,
},
{
conf: SyslogConf{
Protocol: "tcp",
Port: "5140",
},
expectedErrLength: 0,
},
{
conf: SyslogConf{
Protocol: "udp",
Port: "12345",
Severity: "emerg",
Facility: "user",
},
expectedErrLength: 0,
},
{
conf: SyslogConf{
Protocol: "foo",
Port: "514",
},
expectedErrLength: 1,
},
{
conf: SyslogConf{
Protocol: "invalid",
Port: "-1",
},
expectedErrLength: 2,
},
{
conf: SyslogConf{
Protocol: "invalid",
Port: "invalid",
Severity: "invalid",
Facility: "invalid",
},
expectedErrLength: 4,
},
}
for i, tt := range tests {
Conf.ToSyslog = true
errs := tt.conf.Validate()
if len(errs) != tt.expectedErrLength {
t.Errorf("test: %d, expected %d, actual %d", i, tt.expectedErrLength, len(errs))
}
}
}
func TestDistro_MajorVersion(t *testing.T) {
var tests = []struct {
in Distro
out int
}{
{
in: Distro{
Family: Amazon,
Release: "2 (2017.12)",
},
out: 2,
},
{
in: Distro{
Family: Amazon,
Release: "2017.12",
},
out: 1,
},
{
in: Distro{
Family: CentOS,
Release: "7.10",
},
out: 7,
},
}
for i, tt := range tests {
ver, err := tt.in.MajorVersion()
if err != nil {
t.Errorf("[%d] err occurred: %s", i, err)
}
if tt.out != ver {
t.Errorf("[%d] expected %d, actual %d", i, tt.out, ver)
}
}
}

74
config/exploitconf.go Normal file
View File

@@ -0,0 +1,74 @@
package config
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
// ExploitConf is exploit config
type ExploitConf struct {
// DB type for exploit dictionary (sqlite3, mysql, postgres or redis)
Type string
// http://exploit-dictionary.com:1324 or DB connection string
URL string `json:"-"`
// /path/to/exploit.sqlite3
SQLite3Path string `json:"-"`
}
func (cnf *ExploitConf) setDefault() {
if cnf.Type == "" {
cnf.Type = "sqlite3"
}
if cnf.URL == "" && cnf.SQLite3Path == "" {
wd, _ := os.Getwd()
cnf.SQLite3Path = filepath.Join(wd, "go-exploitdb.sqlite3")
}
}
const exploitDBType = "EXPLOITDB_TYPE"
const exploitDBURL = "EXPLOITDB_URL"
const exploitDBPATH = "EXPLOITDB_SQLITE3_PATH"
// Init set options with the following priority.
// 1. Environment variable
// 2. config.toml
func (cnf *ExploitConf) Init() {
if os.Getenv(exploitDBType) != "" {
cnf.Type = os.Getenv(exploitDBType)
}
if os.Getenv(exploitDBURL) != "" {
cnf.URL = os.Getenv(exploitDBURL)
}
if os.Getenv(exploitDBPATH) != "" {
cnf.SQLite3Path = os.Getenv(exploitDBPATH)
}
cnf.setDefault()
}
// IsFetchViaHTTP returns wether fetch via http
func (cnf *ExploitConf) IsFetchViaHTTP() bool {
return Conf.Exploit.Type == "http"
}
// CheckHTTPHealth do health check
func (cnf *ExploitConf) CheckHTTPHealth() error {
if !cnf.IsFetchViaHTTP() {
return nil
}
url := fmt.Sprintf("%s/health", cnf.URL)
resp, _, errs := gorequest.New().Timeout(10 * time.Second).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 exploit server. url: %s, errs: %s", url, errs)
}
return nil
}

74
config/gocvedictconf.go Normal file
View File

@@ -0,0 +1,74 @@
package config
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
// GoCveDictConf is go-cve-dictionary config
type GoCveDictConf struct {
// DB type of CVE dictionary (sqlite3, mysql, postgres or redis)
Type string
// http://cve-dictionary.com:1323 or DB connection string
URL string `json:"-"`
// /path/to/cve.sqlite3
SQLite3Path string `json:"-"`
}
func (cnf *GoCveDictConf) setDefault() {
if cnf.Type == "" {
cnf.Type = "sqlite3"
}
if cnf.URL == "" && cnf.SQLite3Path == "" {
wd, _ := os.Getwd()
cnf.SQLite3Path = filepath.Join(wd, "cve.sqlite3")
}
}
const cveDBType = "CVEDB_TYPE"
const cveDBURL = "CVEDB_URL"
const cveDBPATH = "CVEDB_SQLITE3_PATH"
// Init set options with the following priority.
// 1. Environment variable
// 2. config.toml
func (cnf *GoCveDictConf) Init() {
if os.Getenv(cveDBType) != "" {
cnf.Type = os.Getenv(cveDBType)
}
if os.Getenv(cveDBURL) != "" {
cnf.URL = os.Getenv(cveDBURL)
}
if os.Getenv(cveDBPATH) != "" {
cnf.SQLite3Path = os.Getenv(cveDBPATH)
}
cnf.setDefault()
}
// IsFetchViaHTTP returns wether fetch via http
func (cnf *GoCveDictConf) IsFetchViaHTTP() bool {
return Conf.CveDict.Type == "http"
}
// CheckHTTPHealth checks http server status
func (cnf *GoCveDictConf) CheckHTTPHealth() error {
if !cnf.IsFetchViaHTTP() {
return nil
}
url := fmt.Sprintf("%s/health", cnf.URL)
resp, _, errs := gorequest.New().Timeout(10 * time.Second).SetDebug(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 request to CVE server. url: %s, errs: %s",
url, errs)
}
return nil
}

74
config/gostconf.go Normal file
View File

@@ -0,0 +1,74 @@
package config
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
// GostConf is gost config
type GostConf struct {
// DB type for gost dictionary (sqlite3, mysql, postgres or redis)
Type string
// http://gost-dictionary.com:1324 or DB connection string
URL string `json:"-"`
// /path/to/gost.sqlite3
SQLite3Path string `json:"-"`
}
func (cnf *GostConf) setDefault() {
if cnf.Type == "" {
cnf.Type = "sqlite3"
}
if cnf.URL == "" && cnf.SQLite3Path == "" {
wd, _ := os.Getwd()
cnf.SQLite3Path = filepath.Join(wd, "gost.sqlite3")
}
}
const gostDBType = "GOSTDB_TYPE"
const gostDBURL = "GOSTDB_URL"
const gostDBPATH = "GOSTDB_SQLITE3_PATH"
// Init set options with the following priority.
// 1. Environment variable
// 2. config.toml
func (cnf *GostConf) Init() {
if os.Getenv(gostDBType) != "" {
cnf.Type = os.Getenv(gostDBType)
}
if os.Getenv(gostDBURL) != "" {
cnf.URL = os.Getenv(gostDBURL)
}
if os.Getenv(gostDBPATH) != "" {
cnf.SQLite3Path = os.Getenv(gostDBPATH)
}
cnf.setDefault()
}
// IsFetchViaHTTP returns wether fetch via http
func (cnf *GostConf) IsFetchViaHTTP() bool {
return Conf.Gost.Type == "http"
}
// CheckHTTPHealth do health check
func (cnf *GostConf) CheckHTTPHealth() error {
if !cnf.IsFetchViaHTTP() {
return nil
}
url := fmt.Sprintf("%s/health", cnf.URL)
resp, _, errs := gorequest.New().Timeout(10 * time.Second).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: %s", url, errs)
}
return nil
}

76
config/govaldictconf.go Normal file
View File

@@ -0,0 +1,76 @@
package config
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
// GovalDictConf is goval-dictionary config
type GovalDictConf struct {
// DB type of OVAL dictionary (sqlite3, mysql, postgres or redis)
Type string
// http://goval-dictionary.com:1324 or DB connection string
URL string `json:"-"`
// /path/to/oval.sqlite3
SQLite3Path string `json:"-"`
}
func (cnf *GovalDictConf) setDefault() {
if cnf.Type == "" {
cnf.Type = "sqlite3"
}
if cnf.URL == "" && cnf.SQLite3Path == "" {
wd, _ := os.Getwd()
cnf.SQLite3Path = filepath.Join(wd, "oval.sqlite3")
}
}
const govalType = "OVALDB_TYPE"
const govalURL = "OVALDB_URL"
const govalPATH = "OVALDB_SQLITE3_PATH"
// Init set options with the following priority.
// 1. Environment variable
// 2. config.toml
func (cnf *GovalDictConf) Init() {
if os.Getenv(govalType) != "" {
cnf.Type = os.Getenv(govalType)
}
if os.Getenv(govalURL) != "" {
cnf.URL = os.Getenv(govalURL)
}
if os.Getenv(govalPATH) != "" {
cnf.SQLite3Path = os.Getenv(govalPATH)
}
cnf.setDefault()
}
// IsFetchViaHTTP returns wether fetch via http
func (cnf *GovalDictConf) IsFetchViaHTTP() bool {
return Conf.OvalDict.Type == "http"
}
// CheckHTTPHealth do health check
func (cnf *GovalDictConf) CheckHTTPHealth() error {
if !cnf.IsFetchViaHTTP() {
return nil
}
url := fmt.Sprintf("%s/health", cnf.URL)
resp, _, errs := gorequest.New().Timeout(10 * time.Second).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 request to OVAL server. url: %s, errs: %s",
url, errs)
}
return nil
}

38
config/httpconf.go Normal file
View File

@@ -0,0 +1,38 @@
package config
import (
"os"
"github.com/asaskevich/govalidator"
)
// HTTPConf is HTTP config
type HTTPConf struct {
URL string `valid:"url" json:"-"`
}
// Validate validates configuration
func (c *HTTPConf) Validate() (errs []error) {
if !Conf.ToHTTP {
return nil
}
if _, err := govalidator.ValidateStruct(c); err != nil {
errs = append(errs, err)
}
return errs
}
const httpKey = "VULS_HTTP_URL"
// Init set options with the following priority.
// 1. Environment variable
// 2. config.toml
func (c *HTTPConf) Init(toml HTTPConf) {
if os.Getenv(httpKey) != "" {
c.URL = os.Getenv(httpKey)
}
if toml.URL != "" {
c.URL = toml.URL
}
}

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,29 +1,12 @@
/* 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 config
import "fmt"
import "golang.org/x/xerrors"
// JSONLoader loads configuration
type JSONLoader struct {
}
// Load load the configuraiton JSON file specified by path arg.
// 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 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 config
// Load loads configuration

73
config/metasploitconf.go Normal file
View File

@@ -0,0 +1,73 @@
package config
import (
"fmt"
"os"
"path/filepath"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
// MetasploitConf is metasploit config
type MetasploitConf struct {
// DB type for metasploit dictionary (sqlite3, mysql, postgres or redis)
Type string
// http://metasploit-dictionary.com:1324 or DB connection string
URL string `json:"-"`
// /path/to/metasploit.sqlite3
SQLite3Path string `json:"-"`
}
func (cnf *MetasploitConf) setDefault() {
if cnf.Type == "" {
cnf.Type = "sqlite3"
}
if cnf.URL == "" && cnf.SQLite3Path == "" {
wd, _ := os.Getwd()
cnf.SQLite3Path = filepath.Join(wd, "go-msfdb.sqlite3")
}
}
const metasploitDBType = "METASPLOITDB_TYPE"
const metasploitDBURL = "METASPLOITDB_URL"
const metasploitDBPATH = "METASPLOITDB_SQLITE3_PATH"
// Init set options with the following priority.
// 1. Environment variable
// 2. config.toml
func (cnf *MetasploitConf) Init() {
if os.Getenv(metasploitDBType) != "" {
cnf.Type = os.Getenv(metasploitDBType)
}
if os.Getenv(metasploitDBURL) != "" {
cnf.URL = os.Getenv(metasploitDBURL)
}
if os.Getenv(metasploitDBPATH) != "" {
cnf.SQLite3Path = os.Getenv(metasploitDBPATH)
}
cnf.setDefault()
}
// IsFetchViaHTTP returns wether fetch via http
func (cnf *MetasploitConf) IsFetchViaHTTP() bool {
return Conf.Metasploit.Type == "http"
}
// CheckHTTPHealth do health check
func (cnf *MetasploitConf) CheckHTTPHealth() error {
if !cnf.IsFetchViaHTTP() {
return nil
}
url := fmt.Sprintf("%s/health", cnf.URL)
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 metasploit server. url: %s, errs: %s", url, errs)
}
return nil
}

249
config/os.go Normal file
View File

@@ -0,0 +1,249 @@
package config
import (
"fmt"
"strings"
"time"
)
const (
// RedHat is
RedHat = "redhat"
// Debian is
Debian = "debian"
// Ubuntu is
Ubuntu = "ubuntu"
// CentOS is
CentOS = "centos"
// Fedora is
// Fedora = "fedora"
// Amazon is
Amazon = "amazon"
// Oracle is
Oracle = "oracle"
// FreeBSD is
FreeBSD = "freebsd"
// Raspbian is
Raspbian = "raspbian"
// Windows is
Windows = "windows"
// OpenSUSE is
OpenSUSE = "opensuse"
// OpenSUSELeap is
OpenSUSELeap = "opensuse.leap"
// SUSEEnterpriseServer is
SUSEEnterpriseServer = "suse.linux.enterprise.server"
// SUSEEnterpriseDesktop is
SUSEEnterpriseDesktop = "suse.linux.enterprise.desktop"
// SUSEOpenstackCloud is
SUSEOpenstackCloud = "suse.openstack.cloud"
// Alpine is
Alpine = "alpine"
// ServerTypePseudo is used for ServerInfo.Type, r.Family
ServerTypePseudo = "pseudo"
)
// EOL has End-of-Life information
type EOL struct {
StandardSupportUntil time.Time
ExtendedSupportUntil time.Time
Ended bool
}
// IsStandardSupportEnded checks now is under standard support
func (e EOL) IsStandardSupportEnded(now time.Time) bool {
return e.Ended ||
!e.ExtendedSupportUntil.IsZero() && e.StandardSupportUntil.IsZero() ||
!e.StandardSupportUntil.IsZero() && now.After(e.StandardSupportUntil)
}
// IsExtendedSuppportEnded checks now is under extended support
func (e EOL) IsExtendedSuppportEnded(now time.Time) bool {
if e.Ended {
return true
}
if e.StandardSupportUntil.IsZero() && e.ExtendedSupportUntil.IsZero() {
return false
}
return !e.ExtendedSupportUntil.IsZero() && now.After(e.ExtendedSupportUntil) ||
e.ExtendedSupportUntil.IsZero() && now.After(e.StandardSupportUntil)
}
// GetEOL return EOL information for the OS-release passed by args
// https://github.com/aquasecurity/trivy/blob/master/pkg/detector/ospkg/redhat/redhat.go#L20
func GetEOL(family, release string) (eol EOL, found bool) {
switch family {
case Amazon:
rel := "2"
if isAmazonLinux1(release) {
rel = "1"
}
eol, found = map[string]EOL{
"1": {StandardSupportUntil: time.Date(2023, 6, 30, 23, 59, 59, 0, time.UTC)},
"2": {},
}[rel]
case RedHat:
// https://access.redhat.com/support/policy/updates/errata
eol, found = map[string]EOL{
"3": {Ended: true},
"4": {Ended: true},
"5": {Ended: true},
"6": {
StandardSupportUntil: time.Date(2020, 11, 30, 23, 59, 59, 0, time.UTC),
ExtendedSupportUntil: time.Date(2024, 6, 30, 23, 59, 59, 0, time.UTC),
},
"7": {
StandardSupportUntil: time.Date(2024, 6, 30, 23, 59, 59, 0, time.UTC),
},
"8": {
StandardSupportUntil: time.Date(2029, 5, 31, 23, 59, 59, 0, time.UTC),
},
}[major(release)]
case CentOS:
// https://en.wikipedia.org/wiki/CentOS#End-of-support_schedule
// TODO Stream
eol, found = map[string]EOL{
"3": {Ended: true},
"4": {Ended: true},
"5": {Ended: true},
"6": {Ended: true},
"7": {StandardSupportUntil: time.Date(2024, 6, 30, 23, 59, 59, 0, time.UTC)},
"8": {StandardSupportUntil: time.Date(2021, 12, 31, 23, 59, 59, 0, time.UTC)},
}[major(release)]
case Oracle:
eol, found = map[string]EOL{
// Source:
// https://www.oracle.com/a/ocom/docs/elsp-lifetime-069338.pdf
// https://community.oracle.com/docs/DOC-917964
"3": {Ended: true},
"4": {Ended: true},
"5": {Ended: true},
"6": {
StandardSupportUntil: time.Date(2021, 3, 1, 23, 59, 59, 0, time.UTC),
ExtendedSupportUntil: time.Date(2024, 3, 1, 23, 59, 59, 0, time.UTC),
},
"7": {
StandardSupportUntil: time.Date(2024, 7, 1, 23, 59, 59, 0, time.UTC),
},
"8": {
StandardSupportUntil: time.Date(2029, 7, 1, 23, 59, 59, 0, time.UTC),
},
}[major(release)]
case Debian:
eol, found = map[string]EOL{
// https://wiki.debian.org/LTS
"6": {Ended: true},
"7": {Ended: true},
"8": {Ended: true},
"9": {StandardSupportUntil: time.Date(2022, 6, 30, 23, 59, 59, 0, time.UTC)},
"10": {StandardSupportUntil: time.Date(2024, 6, 30, 23, 59, 59, 0, time.UTC)},
}[major(release)]
case Raspbian:
// Not found
eol, found = map[string]EOL{}[major(release)]
case Ubuntu:
// https://wiki.ubuntu.com/Releases
eol, found = map[string]EOL{
"14.10": {Ended: true},
"14.04": {
ExtendedSupportUntil: time.Date(2022, 4, 1, 23, 59, 59, 0, time.UTC),
},
"15.04": {Ended: true},
"16.10": {Ended: true},
"17.04": {Ended: true},
"17.10": {Ended: true},
"16.04": {
StandardSupportUntil: time.Date(2021, 4, 1, 23, 59, 59, 0, time.UTC),
ExtendedSupportUntil: time.Date(2024, 4, 1, 23, 59, 59, 0, time.UTC),
},
"18.04": {
StandardSupportUntil: time.Date(2023, 4, 1, 23, 59, 59, 0, time.UTC),
ExtendedSupportUntil: time.Date(2028, 4, 1, 23, 59, 59, 0, time.UTC),
},
"18.10": {Ended: true},
"19.04": {Ended: true},
"19.10": {Ended: true},
"20.04": {
StandardSupportUntil: time.Date(2025, 4, 1, 23, 59, 59, 0, time.UTC),
},
"21.04": {
StandardSupportUntil: time.Date(2022, 1, 1, 23, 59, 59, 0, time.UTC),
},
"21.10": {
StandardSupportUntil: time.Date(2022, 7, 1, 23, 59, 59, 0, time.UTC),
},
}[release]
case SUSEEnterpriseServer:
//TODO
case Alpine:
// https://github.com/aquasecurity/trivy/blob/master/pkg/detector/ospkg/alpine/alpine.go#L19
// https://wiki.alpinelinux.org/wiki/Alpine_Linux:Releases
eol, found = map[string]EOL{
"2.0": {Ended: true},
"2.1": {Ended: true},
"2.2": {Ended: true},
"2.3": {Ended: true},
"2.4": {Ended: true},
"2.5": {Ended: true},
"2.6": {Ended: true},
"2.7": {Ended: true},
"3.0": {Ended: true},
"3.1": {Ended: true},
"3.2": {Ended: true},
"3.3": {Ended: true},
"3.4": {Ended: true},
"3.5": {Ended: true},
"3.6": {Ended: true},
"3.7": {Ended: true},
"3.8": {Ended: true},
"3.9": {Ended: true},
"3.10": {StandardSupportUntil: time.Date(2021, 5, 1, 23, 59, 59, 0, time.UTC)},
"3.11": {StandardSupportUntil: time.Date(2021, 11, 1, 23, 59, 59, 0, time.UTC)},
"3.12": {StandardSupportUntil: time.Date(2022, 5, 1, 23, 59, 59, 0, time.UTC)},
"3.13": {StandardSupportUntil: time.Date(2022, 11, 1, 23, 59, 59, 0, time.UTC)},
}[majorDotMinor(release)]
case FreeBSD:
// https://www.freebsd.org/security/
eol, found = map[string]EOL{
"7": {Ended: true},
"8": {Ended: true},
"9": {Ended: true},
"10": {Ended: true},
"11": {StandardSupportUntil: time.Date(2021, 9, 30, 23, 59, 59, 0, time.UTC)},
"12": {StandardSupportUntil: time.Date(2024, 6, 30, 23, 59, 59, 0, time.UTC)},
}[major(release)]
}
return
}
func major(osVer string) (majorVersion string) {
return strings.Split(osVer, ".")[0]
}
func majorDotMinor(osVer string) (majorDotMinor string) {
ss := strings.SplitN(osVer, ".", 3)
if len(ss) == 1 {
return osVer
}
return fmt.Sprintf("%s.%s", ss[0], ss[1])
}
func isAmazonLinux1(osRelease string) bool {
return len(strings.Fields(osRelease)) == 1
}

373
config/os_test.go Normal file
View File

@@ -0,0 +1,373 @@
package config
import (
"testing"
"time"
)
func TestEOL_IsStandardSupportEnded(t *testing.T) {
type fields struct {
family string
release string
}
tests := []struct {
name string
fields fields
now time.Time
found bool
stdEnded bool
extEnded bool
}{
// Amazon Linux
{
name: "amazon linux 1 supported",
fields: fields{family: Amazon, release: "2018.03"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "amazon linux 1 eol on 2023-6-30",
fields: fields{family: Amazon, release: "2018.03"},
now: time.Date(2023, 7, 1, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: true,
found: true,
},
{
name: "amazon linux 2 supported",
fields: fields{family: Amazon, release: "2 (Karoo)"},
now: time.Date(2023, 7, 1, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
//RHEL
{
name: "RHEL7 supported",
fields: fields{family: RedHat, release: "7"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "RHEL8 supported",
fields: fields{family: RedHat, release: "8"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "RHEL6 eol",
fields: fields{family: RedHat, release: "6"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: false,
found: true,
},
{
name: "RHEL9 not found",
fields: fields{family: RedHat, release: "9"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: false,
},
//CentOS
{
name: "CentOS 7 supported",
fields: fields{family: CentOS, release: "7"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "CentOS 8 supported",
fields: fields{family: CentOS, release: "8"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "CentOS 6 eol",
fields: fields{family: CentOS, release: "6"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: true,
found: true,
},
{
name: "CentOS 9 not found",
fields: fields{family: CentOS, release: "9"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: false,
},
//Oracle
{
name: "Oracle Linux 7 supported",
fields: fields{family: Oracle, release: "7"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Oracle Linux 8 supported",
fields: fields{family: Oracle, release: "8"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Oracle Linux 6 eol",
fields: fields{family: Oracle, release: "6"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Oracle Linux 9 not found",
fields: fields{family: Oracle, release: "9"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: false,
},
//Ubuntu
{
name: "Ubuntu 18.04 supported",
fields: fields{family: Ubuntu, release: "18.04"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Ubuntu 18.04 ext supported",
fields: fields{family: Ubuntu, release: "18.04"},
now: time.Date(2025, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: false,
found: true,
},
{
name: "Ubuntu 16.04 supported",
fields: fields{family: Ubuntu, release: "18.04"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Ubuntu 14.04 eol",
fields: fields{family: Ubuntu, release: "14.04"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: false,
found: true,
},
{
name: "Ubuntu 14.10 eol",
fields: fields{family: Ubuntu, release: "14.10"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: true,
found: true,
},
{
name: "Ubuntu 12.10 not found",
fields: fields{family: Ubuntu, release: "12.10"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
found: false,
stdEnded: false,
extEnded: false,
},
{
name: "Ubuntu 21.04 supported",
fields: fields{family: Ubuntu, release: "21.04"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
found: true,
stdEnded: false,
extEnded: false,
},
//Debian
{
name: "Debian 9 supported",
fields: fields{family: Debian, release: "9"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Debian 10 supported",
fields: fields{family: Debian, release: "10"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Debian 8 supported",
fields: fields{family: Debian, release: "8"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: true,
found: true,
},
{
name: "Debian 11 supported",
fields: fields{family: Debian, release: "11"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: false,
},
//alpine
{
name: "alpine 3.10 supported",
fields: fields{family: Alpine, release: "3.10"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Alpine 3.11 supported",
fields: fields{family: Alpine, release: "3.11"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Alpine 3.12 supported",
fields: fields{family: Alpine, release: "3.12"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "Alpine 3.9 eol",
fields: fields{family: Alpine, release: "3.9"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: true,
found: true,
},
{
name: "Alpine 3.14 not found",
fields: fields{family: Alpine, release: "3.14"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: false,
},
// freebsd
{
name: "freebsd 11 supported",
fields: fields{family: FreeBSD, release: "11"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "freebsd 11 eol on 2021-9-30",
fields: fields{family: FreeBSD, release: "11"},
now: time.Date(2021, 10, 1, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: true,
found: true,
},
{
name: "freebsd 12 supported",
fields: fields{family: FreeBSD, release: "12"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: false,
extEnded: false,
found: true,
},
{
name: "freebsd 10 eol",
fields: fields{family: FreeBSD, release: "10"},
now: time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
stdEnded: true,
extEnded: true,
found: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
eol, found := GetEOL(tt.fields.family, tt.fields.release)
if found != tt.found {
t.Errorf("GetEOL.found = %v, want %v", found, tt.found)
}
if found {
if got := eol.IsStandardSupportEnded(tt.now); got != tt.stdEnded {
t.Errorf("EOL.IsStandardSupportEnded() = %v, want %v", got, tt.stdEnded)
}
if got := eol.IsExtendedSuppportEnded(tt.now); got != tt.extEnded {
t.Errorf("EOL.IsExtendedSupportEnded() = %v, want %v", got, tt.extEnded)
}
}
})
}
}
func Test_majorDotMinor(t *testing.T) {
type args struct {
osVer string
}
tests := []struct {
name string
args args
wantMajorDotMinor string
}{
{
name: "empty",
args: args{
osVer: "",
},
wantMajorDotMinor: "",
},
{
name: "major",
args: args{
osVer: "3",
},
wantMajorDotMinor: "3",
},
{
name: "major dot minor",
args: args{
osVer: "3.1",
},
wantMajorDotMinor: "3.1",
},
{
name: "major dot minor dot release",
args: args{
osVer: "3.1.4",
},
wantMajorDotMinor: "3.1",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotMajorDotMinor := majorDotMinor(tt.args.osVer); gotMajorDotMinor != tt.wantMajorDotMinor {
t.Errorf("majorDotMinor() = %v, want %v", gotMajorDotMinor, tt.wantMajorDotMinor)
}
})
}
}

34
config/saasconf.go Normal file
View File

@@ -0,0 +1,34 @@
package config
import (
"github.com/asaskevich/govalidator"
"golang.org/x/xerrors"
)
// SaasConf is FutureVuls config
type SaasConf struct {
GroupID int64 `json:"-"`
Token string `json:"-"`
URL string `json:"-"`
}
// Validate validates configuration
func (c *SaasConf) Validate() (errs []error) {
if c.GroupID == 0 {
errs = append(errs, xerrors.New("GroupID must not be empty"))
}
if len(c.Token) == 0 {
errs = append(errs, xerrors.New("Token must not be empty"))
}
if len(c.URL) == 0 {
errs = append(errs, xerrors.New("URL must not be empty"))
}
_, err := govalidator.ValidateStruct(c)
if err != nil {
errs = append(errs, err)
}
return
}

110
config/scanmode.go Normal file
View File

@@ -0,0 +1,110 @@
package config
import (
"strings"
"golang.org/x/xerrors"
)
// ScanMode has a type of scan mode. fast, fast-root, deep and offline
type ScanMode struct {
flag byte
}
const (
// Fast is fast scan mode
Fast = byte(1 << iota)
// FastRoot is scanmode
FastRoot
// Deep is scanmode
Deep
// Offline is scanmode
Offline
fastStr = "fast"
fastRootStr = "fast-root"
deepStr = "deep"
offlineStr = "offline"
)
// Set mode
func (s *ScanMode) Set(f byte) {
s.flag |= f
}
// IsFast return whether scan mode is fast
func (s ScanMode) IsFast() bool {
return s.flag&Fast == Fast
}
// IsFastRoot return whether scan mode is fastroot
func (s ScanMode) IsFastRoot() bool {
return s.flag&FastRoot == FastRoot
}
// IsDeep return whether scan mode is deep
func (s ScanMode) IsDeep() bool {
return s.flag&Deep == Deep
}
// IsOffline return whether scan mode is offline
func (s ScanMode) IsOffline() bool {
return s.flag&Offline == Offline
}
func (s *ScanMode) ensure() error {
numTrue := 0
for _, b := range []bool{s.IsFast(), s.IsFastRoot(), s.IsDeep()} {
if b {
numTrue++
}
}
if numTrue == 0 {
s.Set(Fast)
} else if s.IsDeep() && s.IsOffline() {
return xerrors.New("Don't specify both of deep and offline")
} else if numTrue != 1 {
return xerrors.New("Specify only one of offline, fast, fast-root or deep")
}
return nil
}
func (s ScanMode) String() string {
ss := ""
if s.IsFast() {
ss = fastStr
} else if s.IsFastRoot() {
ss = fastRootStr
} else if s.IsDeep() {
ss = deepStr
}
if s.IsOffline() {
ss += " " + offlineStr
}
return ss + " mode"
}
func setScanMode(server *ServerInfo, d ServerInfo) error {
if len(server.ScanMode) == 0 {
server.ScanMode = Conf.Default.ScanMode
}
for _, m := range server.ScanMode {
switch strings.ToLower(m) {
case fastStr:
server.Mode.Set(Fast)
case fastRootStr:
server.Mode.Set(FastRoot)
case deepStr:
server.Mode.Set(Deep)
case offlineStr:
server.Mode.Set(Offline)
default:
return xerrors.Errorf("scanMode: %s of %s is invalid. Specify -fast, -fast-root, -deep or offline",
m, server.ServerName)
}
}
if err := server.Mode.ensure(); err != nil {
return xerrors.Errorf("%s in %s", err, server.ServerName)
}
return nil
}

97
config/scanmodule.go Normal file
View File

@@ -0,0 +1,97 @@
package config
import (
"strings"
"golang.org/x/xerrors"
)
// ScanModule has a type of scan module
type ScanModule struct {
flag byte
}
const (
// OSPkg is scanmodule
OSPkg = byte(1 << iota)
// WordPress is scanmodule
WordPress
// Lockfile is scanmodule
Lockfile
// Port is scanmodule
Port
osPkgStr = "ospkg"
wordPressStr = "wordpress"
lockfileStr = "lockfile"
portStr = "port"
)
var allModules = []string{osPkgStr, wordPressStr, lockfileStr, portStr}
// Set module
func (s *ScanModule) Set(f byte) {
s.flag |= f
}
// IsScanOSPkg return whether scanning os pkg
func (s ScanModule) IsScanOSPkg() bool {
return s.flag&OSPkg == OSPkg
}
// IsScanWordPress return whether scanning wordpress
func (s ScanModule) IsScanWordPress() bool {
return s.flag&WordPress == WordPress
}
// IsScanLockFile whether scanning lock file
func (s ScanModule) IsScanLockFile() bool {
return s.flag&Lockfile == Lockfile
}
// IsScanPort whether scanning listening ports
func (s ScanModule) IsScanPort() bool {
return s.flag&Port == Port
}
// IsZero return the struct value are all false
func (s ScanModule) IsZero() bool {
return !(s.IsScanOSPkg() || s.IsScanWordPress() || s.IsScanLockFile() || s.IsScanPort())
}
func (s *ScanModule) ensure() error {
if s.IsZero() {
s.Set(OSPkg)
s.Set(WordPress)
s.Set(Lockfile)
s.Set(Port)
} else if !s.IsScanOSPkg() && s.IsScanPort() {
return xerrors.New("When specifying the Port, Specify OSPkg as well")
}
return nil
}
func setScanModules(server *ServerInfo, d ServerInfo) error {
if len(server.ScanModules) == 0 {
server.ScanModules = d.ScanModules
}
for _, m := range server.ScanModules {
switch strings.ToLower(m) {
case osPkgStr:
server.Module.Set(OSPkg)
case wordPressStr:
server.Module.Set(WordPress)
case lockfileStr:
server.Module.Set(Lockfile)
case portStr:
server.Module.Set(Port)
default:
return xerrors.Errorf("scanMode: %s of %s is invalid. Specify %s",
m, server.ServerName, allModules)
}
}
if err := server.Module.ensure(); err != nil {
return xerrors.Errorf("%s in %s", err, server.ServerName)
}
return nil
}

65
config/scanmodule_test.go Normal file
View File

@@ -0,0 +1,65 @@
package config
import (
"testing"
)
func TestScanModule_IsZero(t *testing.T) {
tests := []struct {
name string
modes []byte
want bool
}{
{
name: "not zero",
modes: []byte{OSPkg},
want: false,
},
{
name: "zero",
modes: []byte{},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := ScanModule{}
for _, b := range tt.modes {
s.Set(b)
}
if got := s.IsZero(); got != tt.want {
t.Errorf("ScanModule.IsZero() = %v, want %v", got, tt.want)
}
})
}
}
func TestScanModule_validate(t *testing.T) {
tests := []struct {
name string
modes []byte
wantErr bool
}{
{
name: "valid",
modes: []byte{},
wantErr: false,
},
{
name: "err",
modes: []byte{WordPress, Lockfile, Port},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := ScanModule{}
for _, b := range tt.modes {
s.Set(b)
}
if err := s.ensure(); (err != nil) != tt.wantErr {
t.Errorf("ScanModule.validate() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

51
config/slackconf.go Normal file
View File

@@ -0,0 +1,51 @@
package config
import (
"strings"
"github.com/asaskevich/govalidator"
"golang.org/x/xerrors"
)
// SlackConf is slack config
type SlackConf struct {
HookURL string `valid:"url" json:"-" toml:"hookURL,omitempty"`
LegacyToken string `json:"-" toml:"legacyToken,omitempty"`
Channel string `json:"-" toml:"channel,omitempty"`
IconEmoji string `json:"-" toml:"iconEmoji,omitempty"`
AuthUser string `json:"-" toml:"authUser,omitempty"`
NotifyUsers []string `toml:"notifyUsers,omitempty" json:"-"`
Text string `json:"-"`
}
// Validate validates configuration
func (c *SlackConf) Validate() (errs []error) {
if !Conf.ToSlack {
return
}
if len(c.HookURL) == 0 && len(c.LegacyToken) == 0 {
errs = append(errs, xerrors.New("slack.hookURL or slack.LegacyToken must not be empty"))
}
if len(c.Channel) == 0 {
errs = append(errs, xerrors.New("slack.channel must not be empty"))
} else {
if !(strings.HasPrefix(c.Channel, "#") ||
c.Channel == "${servername}") {
errs = append(errs, xerrors.Errorf(
"channel's prefix must be '#', channel: %s", c.Channel))
}
}
if len(c.AuthUser) == 0 {
errs = append(errs, xerrors.New("slack.authUser must not be empty"))
}
_, err := govalidator.ValidateStruct(c)
if err != nil {
errs = append(errs, err)
}
return
}

65
config/smtpconf.go Normal file
View File

@@ -0,0 +1,65 @@
package config
import (
"github.com/asaskevich/govalidator"
"golang.org/x/xerrors"
)
// SMTPConf is smtp config
type SMTPConf struct {
SMTPAddr string `toml:"smtpAddr,omitempty" json:"-"`
SMTPPort string `toml:"smtpPort,omitempty" valid:"port" json:"-"`
User string `toml:"user,omitempty" json:"-"`
Password string `toml:"password,omitempty" json:"-"`
From string `toml:"from,omitempty" json:"-"`
To []string `toml:"to,omitempty" json:"-"`
Cc []string `toml:"cc,omitempty" json:"-"`
SubjectPrefix string `toml:"subjectPrefix,omitempty" json:"-"`
}
func checkEmails(emails []string) (errs []error) {
for _, addr := range emails {
if len(addr) == 0 {
return
}
if ok := govalidator.IsEmail(addr); !ok {
errs = append(errs, xerrors.Errorf("Invalid email address. email: %s", addr))
}
}
return
}
// Validate SMTP configuration
func (c *SMTPConf) Validate() (errs []error) {
if !Conf.ToEmail {
return
}
// Check Emails fromat
emails := []string{}
emails = append(emails, c.From)
emails = append(emails, c.To...)
emails = append(emails, c.Cc...)
if emailErrs := checkEmails(emails); 0 < len(emailErrs) {
errs = append(errs, emailErrs...)
}
if len(c.SMTPAddr) == 0 {
errs = append(errs, xerrors.New("email.smtpAddr must not be empty"))
}
if len(c.SMTPPort) == 0 {
errs = append(errs, xerrors.New("email.smtpPort must not be empty"))
}
if len(c.To) == 0 {
errs = append(errs, xerrors.New("email.To required at least one address"))
}
if len(c.From) == 0 {
errs = append(errs, xerrors.New("email.From required at least one address"))
}
_, err := govalidator.ValidateStruct(c)
if err != nil {
errs = append(errs, err)
}
return
}

129
config/syslogconf.go Normal file
View File

@@ -0,0 +1,129 @@
package config
import (
"errors"
"log/syslog"
"github.com/asaskevich/govalidator"
"golang.org/x/xerrors"
)
// SyslogConf is syslog config
type SyslogConf struct {
Protocol string `json:"-"`
Host string `valid:"host" json:"-"`
Port string `valid:"port" json:"-"`
Severity string `json:"-"`
Facility string `json:"-"`
Tag string `json:"-"`
Verbose bool `json:"-"`
}
// Validate validates configuration
func (c *SyslogConf) Validate() (errs []error) {
if !Conf.ToSyslog {
return nil
}
// If protocol is empty, it will connect to the local syslog server.
if len(c.Protocol) > 0 && c.Protocol != "tcp" && c.Protocol != "udp" {
errs = append(errs, errors.New(`syslog.protocol must be "tcp" or "udp"`))
}
// Default port: 514
if c.Port == "" {
c.Port = "514"
}
if _, err := c.GetSeverity(); err != nil {
errs = append(errs, err)
}
if _, err := c.GetFacility(); err != nil {
errs = append(errs, err)
}
if _, err := govalidator.ValidateStruct(c); err != nil {
errs = append(errs, err)
}
return errs
}
// GetSeverity gets severity
func (c *SyslogConf) GetSeverity() (syslog.Priority, error) {
if c.Severity == "" {
return syslog.LOG_INFO, nil
}
switch c.Severity {
case "emerg":
return syslog.LOG_EMERG, nil
case "alert":
return syslog.LOG_ALERT, nil
case "crit":
return syslog.LOG_CRIT, nil
case "err":
return syslog.LOG_ERR, nil
case "warning":
return syslog.LOG_WARNING, nil
case "notice":
return syslog.LOG_NOTICE, nil
case "info":
return syslog.LOG_INFO, nil
case "debug":
return syslog.LOG_DEBUG, nil
default:
return -1, xerrors.Errorf("Invalid severity: %s", c.Severity)
}
}
// GetFacility gets facility
func (c *SyslogConf) GetFacility() (syslog.Priority, error) {
if c.Facility == "" {
return syslog.LOG_AUTH, nil
}
switch c.Facility {
case "kern":
return syslog.LOG_KERN, nil
case "user":
return syslog.LOG_USER, nil
case "mail":
return syslog.LOG_MAIL, nil
case "daemon":
return syslog.LOG_DAEMON, nil
case "auth":
return syslog.LOG_AUTH, nil
case "syslog":
return syslog.LOG_SYSLOG, nil
case "lpr":
return syslog.LOG_LPR, nil
case "news":
return syslog.LOG_NEWS, nil
case "uucp":
return syslog.LOG_UUCP, nil
case "cron":
return syslog.LOG_CRON, nil
case "authpriv":
return syslog.LOG_AUTHPRIV, nil
case "ftp":
return syslog.LOG_FTP, nil
case "local0":
return syslog.LOG_LOCAL0, nil
case "local1":
return syslog.LOG_LOCAL1, nil
case "local2":
return syslog.LOG_LOCAL2, nil
case "local3":
return syslog.LOG_LOCAL3, nil
case "local4":
return syslog.LOG_LOCAL4, nil
case "local5":
return syslog.LOG_LOCAL5, nil
case "local6":
return syslog.LOG_LOCAL6, nil
case "local7":
return syslog.LOG_LOCAL7, nil
default:
return -1, xerrors.Errorf("Invalid facility: %s", c.Facility)
}
}

32
config/telegramconf.go Normal file
View File

@@ -0,0 +1,32 @@
package config
import (
"github.com/asaskevich/govalidator"
"golang.org/x/xerrors"
)
// TelegramConf is Telegram config
type TelegramConf struct {
Token string `json:"-"`
ChatID string `json:"-"`
}
// Validate validates configuration
func (c *TelegramConf) Validate() (errs []error) {
if !Conf.ToTelegram {
return
}
if len(c.ChatID) == 0 {
errs = append(errs, xerrors.New("TelegramConf.ChatID must not be empty"))
}
if len(c.Token) == 0 {
errs = append(errs, xerrors.New("TelegramConf.Token must not be empty"))
}
_, err := govalidator.ValidateStruct(c)
if err != nil {
errs = append(errs, err)
}
return
}

View File

@@ -1,184 +1,242 @@
/* 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 config
import (
"fmt"
"os"
"regexp"
"strings"
"github.com/BurntSushi/toml"
log "github.com/Sirupsen/logrus"
"github.com/future-architect/vuls/contrib/owasp-dependency-check/parser"
"github.com/knqyf263/go-cpe/naming"
"golang.org/x/xerrors"
)
// TOMLLoader loads config
type TOMLLoader struct {
}
// Load load the configuraiton TOML file specified by path arg.
// Load load the configuration TOML file specified by path arg.
func (c TOMLLoader) Load(pathToToml, keyPass string) error {
if Conf.Debug {
log.SetLevel(log.DebugLevel)
}
var conf Config
if _, err := toml.DecodeFile(pathToToml, &conf); err != nil {
log.Error("Load config failed", err)
if _, err := toml.DecodeFile(pathToToml, &Conf); err != nil {
return err
}
Conf.Mail = conf.Mail
Conf.Slack = conf.Slack
d := conf.Default
Conf.Default = d
servers := make(map[string]ServerInfo)
if keyPass != "" {
d.KeyPassword = keyPass
Conf.Default.KeyPassword = keyPass
}
i := 0
for name, v := range conf.Servers {
if 0 < len(v.KeyPassword) {
log.Warn("[Deprecated] KEYPASSWORD IN CONFIG FILE ARE UNSECURE. REMOVE THEM IMMEDIATELY FOR A SECURITY REASONS. THEY WILL BE REMOVED IN A FUTURE RELEASE.")
Conf.CveDict.Init()
Conf.OvalDict.Init()
Conf.Gost.Init()
Conf.Exploit.Init()
Conf.Metasploit.Init()
index := 0
for name, server := range Conf.Servers {
server.ServerName = name
if 0 < len(server.KeyPassword) {
return xerrors.Errorf("[Deprecated] KEYPASSWORD IN CONFIG FILE ARE UNSECURE. REMOVE THEM IMMEDIATELY FOR A SECURITY REASONS. THEY WILL BE REMOVED IN A FUTURE RELEASE: %s", name)
}
s := ServerInfo{ServerName: name}
switch {
case v.User != "":
s.User = v.User
case d.User != "":
s.User = d.User
default:
return fmt.Errorf("%s is invalid. User is empty", name)
if err := setDefaultIfEmpty(&server, Conf.Default); err != nil {
return xerrors.Errorf("Failed to set default value to config. server: %s, err: %w", name, err)
}
s.Host = v.Host
if len(s.Host) == 0 {
return fmt.Errorf("%s is invalid. host is empty", name)
if err := setScanMode(&server, Conf.Default); err != nil {
return xerrors.Errorf("Failed to set ScanMode: %w", err)
}
switch {
case v.Port != "":
s.Port = v.Port
case d.Port != "":
s.Port = d.Port
default:
s.Port = "22"
if err := setScanModules(&server, Conf.Default); err != nil {
return xerrors.Errorf("Failed to set ScanModule: %w", err)
}
s.KeyPath = v.KeyPath
if len(s.KeyPath) == 0 {
s.KeyPath = d.KeyPath
if len(server.CpeNames) == 0 {
server.CpeNames = Conf.Default.CpeNames
}
if s.KeyPath != "" {
if _, err := os.Stat(s.KeyPath); err != nil {
return fmt.Errorf(
"%s is invalid. keypath: %s not exists", name, s.KeyPath)
}
}
// s.KeyPassword = keyPass
s.KeyPassword = v.KeyPassword
if len(s.KeyPassword) == 0 {
s.KeyPassword = d.KeyPassword
}
s.CpeNames = v.CpeNames
if len(s.CpeNames) == 0 {
s.CpeNames = d.CpeNames
}
s.DependencyCheckXMLPath = v.DependencyCheckXMLPath
if len(s.DependencyCheckXMLPath) == 0 {
s.DependencyCheckXMLPath = d.DependencyCheckXMLPath
}
// Load CPEs from OWASP Dependency Check XML
if len(s.DependencyCheckXMLPath) != 0 {
cpes, err := parser.Parse(s.DependencyCheckXMLPath)
for i, n := range server.CpeNames {
uri, err := toCpeURI(n)
if err != nil {
return fmt.Errorf(
"Failed to read OWASP Dependency Check XML: %s", err)
return xerrors.Errorf("Failed to parse CPENames %s in %s, err: %w", n, name, err)
}
log.Infof("Loaded from OWASP Dependency Check XML: %s",
s.ServerName)
s.CpeNames = append(s.CpeNames, cpes...)
server.CpeNames[i] = uri
}
s.Containers = v.Containers
if len(s.Containers) == 0 {
s.Containers = d.Containers
}
s.IgnoreCves = v.IgnoreCves
for _, cve := range d.IgnoreCves {
for _, cve := range Conf.Default.IgnoreCves {
found := false
for _, c := range s.IgnoreCves {
for _, c := range server.IgnoreCves {
if cve == c {
found = true
break
}
}
if !found {
s.IgnoreCves = append(s.IgnoreCves, cve)
server.IgnoreCves = append(server.IgnoreCves, cve)
}
}
s.Optional = v.Optional
for _, dkv := range d.Optional {
for _, pkg := range Conf.Default.IgnorePkgsRegexp {
found := false
for _, kv := range s.Optional {
if dkv[0] == kv[0] {
for _, p := range server.IgnorePkgsRegexp {
if pkg == p {
found = true
break
}
}
if !found {
s.Optional = append(s.Optional, dkv)
server.IgnorePkgsRegexp = append(server.IgnorePkgsRegexp, pkg)
}
}
s.Enablerepo = v.Enablerepo
if len(s.Enablerepo) == 0 {
s.Enablerepo = d.Enablerepo
for _, reg := range server.IgnorePkgsRegexp {
_, err := regexp.Compile(reg)
if err != nil {
return xerrors.Errorf("Failed to parse %s in %s. err: %w", reg, name, err)
}
}
if len(s.Enablerepo) != 0 {
for _, repo := range strings.Split(s.Enablerepo, ",") {
switch repo {
case "base", "updates":
// nop
default:
return fmt.Errorf(
"For now, enablerepo have to be base or updates: %s, servername: %s",
s.Enablerepo, name)
for contName, cont := range server.Containers {
for _, reg := range cont.IgnorePkgsRegexp {
_, err := regexp.Compile(reg)
if err != nil {
return xerrors.Errorf("Failed to parse %s in %s@%s. err: %w",
reg, contName, name, err)
}
}
}
s.LogMsgAnsiColor = Colors[i%len(Colors)]
i++
for ownerRepo, githubSetting := range server.GitHubRepos {
if ss := strings.Split(ownerRepo, "/"); len(ss) != 2 {
return xerrors.Errorf("Failed to parse GitHub owner/repo: %s in %s",
ownerRepo, name)
}
if githubSetting.Token == "" {
return xerrors.Errorf("GitHub owner/repo: %s in %s token is empty",
ownerRepo, name)
}
}
servers[name] = s
if len(server.Enablerepo) == 0 {
server.Enablerepo = Conf.Default.Enablerepo
}
if len(server.Enablerepo) != 0 {
for _, repo := range server.Enablerepo {
switch repo {
case "base", "updates":
// nop
default:
return xerrors.Errorf(
"For now, enablerepo have to be base or updates: %s",
server.Enablerepo)
}
}
}
server.LogMsgAnsiColor = Colors[index%len(Colors)]
index++
Conf.Servers[name] = server
}
Conf.Servers = servers
return nil
}
func setDefaultIfEmpty(server *ServerInfo, d ServerInfo) error {
if server.Type != ServerTypePseudo {
if len(server.Host) == 0 {
return xerrors.Errorf("server.host is empty")
}
if len(server.JumpServer) == 0 {
server.JumpServer = Conf.Default.JumpServer
}
if server.Port == "" {
if Conf.Default.Port != "" {
server.Port = Conf.Default.Port
} else {
server.Port = "22"
}
}
if server.User == "" {
server.User = Conf.Default.User
if server.User == "" && server.Port != "local" {
return xerrors.Errorf("server.user is empty")
}
}
if server.SSHConfigPath == "" {
server.SSHConfigPath = Conf.Default.SSHConfigPath
}
if server.KeyPath == "" {
server.KeyPath = Conf.Default.KeyPath
}
if server.KeyPassword == "" {
server.KeyPassword = Conf.Default.KeyPassword
}
}
if len(server.Lockfiles) == 0 {
server.Lockfiles = Conf.Default.Lockfiles
}
if len(server.ContainersIncluded) == 0 {
server.ContainersIncluded = Conf.Default.ContainersIncluded
}
if len(server.ContainersExcluded) == 0 {
server.ContainersExcluded = Conf.Default.ContainersExcluded
}
if server.ContainerType == "" {
server.ContainerType = Conf.Default.ContainerType
}
for contName, cont := range server.Containers {
cont.IgnoreCves = append(cont.IgnoreCves, Conf.Default.IgnoreCves...)
server.Containers[contName] = cont
}
if server.OwaspDCXMLPath == "" {
server.OwaspDCXMLPath = Conf.Default.OwaspDCXMLPath
}
if server.Memo == "" {
server.Memo = Conf.Default.Memo
}
if server.WordPress == nil {
server.WordPress = Conf.Default.WordPress
if server.WordPress == nil {
server.WordPress = &WordPressConf{}
}
}
if len(server.IgnoredJSONKeys) == 0 {
server.IgnoredJSONKeys = Conf.Default.IgnoredJSONKeys
}
opt := map[string]interface{}{}
for k, v := range Conf.Default.Optional {
opt[k] = v
}
for k, v := range server.Optional {
opt[k] = v
}
server.Optional = opt
return nil
}
func toCpeURI(cpename string) (string, error) {
if strings.HasPrefix(cpename, "cpe:2.3:") {
wfn, err := naming.UnbindFS(cpename)
if err != nil {
return "", err
}
return naming.BindToURI(wfn), nil
} else if strings.HasPrefix(cpename, "cpe:/") {
wfn, err := naming.UnbindURI(cpename)
if err != nil {
return "", err
}
return naming.BindToURI(wfn), nil
}
return "", xerrors.Errorf("Unknown CPE format: %s", cpename)
}

44
config/tomlloader_test.go Normal file
View File

@@ -0,0 +1,44 @@
package config
import (
"testing"
)
func TestToCpeURI(t *testing.T) {
var tests = []struct {
in string
expected string
err bool
}{
{
in: "",
expected: "",
err: true,
},
{
in: "cpe:/a:microsoft:internet_explorer:10",
expected: "cpe:/a:microsoft:internet_explorer:10",
err: false,
},
{
in: "cpe:2.3:a:microsoft:internet_explorer:10:*:*:*:*:*:*:*",
expected: "cpe:/a:microsoft:internet_explorer:10",
err: false,
},
}
for i, tt := range tests {
actual, err := toCpeURI(tt.in)
if err != nil && !tt.err {
t.Errorf("[%d] unexpected error occurred, in: %s act: %s, exp: %s",
i, tt.in, actual, tt.expected)
} else if err == nil && tt.err {
t.Errorf("[%d] expected error is not occurred, in: %s act: %s, exp: %s",
i, tt.in, actual, tt.expected)
}
if actual != tt.expected {
t.Errorf("[%d] in: %s, actual: %s, expected: %s",
i, tt.in, actual, tt.expected)
}
}
}

View File

@@ -0,0 +1,38 @@
# future-vuls
## Main Features
- upload vuls results json to future-vuls
## Installation
```
git clone https://github.com/future-architect/vuls.git
make build-future-vuls
```
## Command Reference
```
Upload to FutureVuls
Usage:
future-vuls upload [flags]
Flags:
--config string config file (default is $HOME/.cobra.yaml)
-g, --group-id int future vuls group id, ENV: VULS_GROUP_ID
-h, --help help for upload
-s, --stdin input from stdin. ENV: VULS_STDIN
-t, --token string future vuls token
--url string future vuls upload url
--uuid string server uuid. ENV: VULS_SERVER_UUID
```
## Usage
- update results json
```
cat results.json | future-vuls upload --stdin --token xxxx --url https://xxxx --group-id 1 --uuid xxxx
```

View File

@@ -0,0 +1,98 @@
package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"os"
"strconv"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/saas"
"github.com/spf13/cobra"
)
var (
configFile string
stdIn bool
jsonDir string
serverUUID string
groupID int64
token string
url string
)
func main() {
var err error
var cmdFvulsUploader = &cobra.Command{
Use: "upload",
Short: "Upload to FutureVuls",
Long: `Upload to FutureVuls`,
Run: func(cmd *cobra.Command, args []string) {
if len(serverUUID) == 0 {
serverUUID = os.Getenv("VULS_SERVER_UUID")
}
if groupID == 0 {
envGroupID := os.Getenv("VULS_GROUP_ID")
if groupID, err = strconv.ParseInt(envGroupID, 10, 64); err != nil {
fmt.Printf("Invalid GroupID: %s\n", envGroupID)
return
}
}
if len(url) == 0 {
url = os.Getenv("VULS_URL")
}
if len(token) == 0 {
token = os.Getenv("VULS_TOKEN")
}
var scanResultJSON []byte
if stdIn {
reader := bufio.NewReader(os.Stdin)
buf := new(bytes.Buffer)
if _, err = buf.ReadFrom(reader); err != nil {
return
}
scanResultJSON = buf.Bytes()
} else {
fmt.Println("use --stdin option")
os.Exit(1)
return
}
var scanResult models.ScanResult
if err = json.Unmarshal(scanResultJSON, &scanResult); err != nil {
fmt.Println("Failed to parse json", err)
os.Exit(1)
return
}
scanResult.ServerUUID = serverUUID
config.Conf.Saas.GroupID = groupID
config.Conf.Saas.Token = token
config.Conf.Saas.URL = url
if err = (saas.Writer{}).Write(scanResult); err != nil {
fmt.Println(err)
os.Exit(1)
return
}
return
},
}
cmdFvulsUploader.PersistentFlags().StringVar(&serverUUID, "uuid", "", "server uuid. ENV: VULS_SERVER_UUID")
cmdFvulsUploader.PersistentFlags().StringVar(&configFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
cmdFvulsUploader.PersistentFlags().BoolVarP(&stdIn, "stdin", "s", false, "input from stdin. ENV: VULS_STDIN")
// TODO Read JSON file from directory
// cmdFvulsUploader.Flags().StringVarP(&jsonDir, "results-dir", "d", "./", "vuls scan results json dir")
cmdFvulsUploader.PersistentFlags().Int64VarP(&groupID, "group-id", "g", 0, "future vuls group id, ENV: VULS_GROUP_ID")
cmdFvulsUploader.PersistentFlags().StringVarP(&token, "token", "t", "", "future vuls token")
cmdFvulsUploader.PersistentFlags().StringVar(&url, "url", "", "future vuls upload url")
var rootCmd = &cobra.Command{Use: "future-vuls"}
rootCmd.AddCommand(cmdFvulsUploader)
if err = rootCmd.Execute(); err != nil {
fmt.Println("Failed to execute command", err)
}
}

View File

@@ -2,11 +2,13 @@ package parser
import (
"encoding/xml"
"fmt"
"io/ioutil"
"os"
"sort"
"strings"
"github.com/knqyf263/go-cpe/naming"
log "github.com/sirupsen/logrus"
"golang.org/x/xerrors"
)
type analysis struct {
@@ -14,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 {
@@ -31,34 +32,40 @@ func appendIfMissing(slice []string, str string) []string {
return append(slice, str)
}
// Parse parses XML and collect list of cpe
// Parse parses OWASP dependency check XML and collect list of cpe
func Parse(path string) ([]string, error) {
file, err := os.Open(path)
if err != nil {
return []string{}, fmt.Errorf("Failed to open: %s", err)
log.Warnf("OWASP Dependency Check XML is not found: %s", path)
return []string{}, nil
}
defer file.Close()
b, err := ioutil.ReadAll(file)
if err != nil {
return []string{}, fmt.Errorf("Failed to read: %s", err)
log.Warnf("Failed to read OWASP Dependency Check XML: %s", path)
return []string{}, nil
}
var anal analysis
if err := xml.Unmarshal(b, &anal); err != 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)
}
}
sort.Strings(cpes)
return cpes, nil
}

35
contrib/trivy/README.md Normal file
View File

@@ -0,0 +1,35 @@
# trivy-to-vuls
## Main Features
- convert trivy's results json to vuls's report json
## Installation
```
git clone https://github.com/future-architect/vuls.git
make build-trivy-to-vuls
```
## Command Reference
```
Parse trivy json to vuls results
Usage:
trivy-to-vuls parse [flags]
Flags:
-h, --help help for parse
-s, --stdin input from stdin
-d, --trivy-json-dir string trivy json dir (default "./")
-f, --trivy-json-file-name string trivy json file name (default "results.json")
```
## Usage
- use trivy output
```
trivy -q image -f=json python:3.4-alpine | trivy-to-vuls parse --stdin
```

78
contrib/trivy/cmd/main.go Normal file
View File

@@ -0,0 +1,78 @@
package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/future-architect/vuls/contrib/trivy/parser"
"github.com/future-architect/vuls/models"
"github.com/spf13/cobra"
)
var (
serverUUID string
stdIn bool
jsonDir string
jsonFileName string
)
func main() {
var err error
var cmdTrivyToVuls = &cobra.Command{
Use: "parse",
Short: "Parse trivy json to vuls results",
Long: `Parse trivy json to vuls results`,
Run: func(cmd *cobra.Command, args []string) {
jsonFilePath := filepath.Join(jsonDir, jsonFileName)
var trivyJSON []byte
if stdIn {
reader := bufio.NewReader(os.Stdin)
buf := new(bytes.Buffer)
if _, err = buf.ReadFrom(reader); err != nil {
os.Exit(1)
return
}
trivyJSON = buf.Bytes()
} else {
if trivyJSON, err = ioutil.ReadFile(jsonFilePath); err != nil {
fmt.Println("Failed to read file", err)
os.Exit(1)
return
}
}
scanResult := &models.ScanResult{
JSONVersion: models.JSONVersion,
ScannedCves: models.VulnInfos{},
}
if scanResult, err = parser.Parse(trivyJSON, scanResult); err != nil {
fmt.Println("Failed to execute command", err)
os.Exit(1)
return
}
var resultJSON []byte
if resultJSON, err = json.MarshalIndent(scanResult, "", " "); err != nil {
fmt.Println("Failed to create json", err)
os.Exit(1)
return
}
fmt.Println(string(resultJSON))
return
},
}
cmdTrivyToVuls.Flags().BoolVarP(&stdIn, "stdin", "s", false, "input from stdin")
cmdTrivyToVuls.Flags().StringVarP(&jsonDir, "trivy-json-dir", "d", "./", "trivy json dir")
cmdTrivyToVuls.Flags().StringVarP(&jsonFileName, "trivy-json-file-name", "f", "results.json", "trivy json file name")
var rootCmd = &cobra.Command{Use: "trivy-to-vuls"}
rootCmd.AddCommand(cmdTrivyToVuls)
if err = rootCmd.Execute(); err != nil {
fmt.Println("Failed to execute command", err)
os.Exit(1)
}
}

View File

@@ -0,0 +1,176 @@
package parser
import (
"encoding/json"
"sort"
"time"
"github.com/aquasecurity/fanal/analyzer/os"
"github.com/aquasecurity/trivy/pkg/report"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/future-architect/vuls/models"
)
// Parse :
func Parse(vulnJSON []byte, scanResult *models.ScanResult) (result *models.ScanResult, err error) {
var trivyResults report.Results
if err = json.Unmarshal(vulnJSON, &trivyResults); err != nil {
return nil, err
}
pkgs := models.Packages{}
vulnInfos := models.VulnInfos{}
uniqueLibraryScannerPaths := map[string]models.LibraryScanner{}
for _, trivyResult := range trivyResults {
for _, vuln := range trivyResult.Vulnerabilities {
if _, ok := vulnInfos[vuln.VulnerabilityID]; !ok {
vulnInfos[vuln.VulnerabilityID] = models.VulnInfo{
CveID: vuln.VulnerabilityID,
Confidences: models.Confidences{
{
Score: 100,
DetectionMethod: models.TrivyMatchStr,
},
},
AffectedPackages: models.PackageFixStatuses{},
CveContents: models.CveContents{},
LibraryFixedIns: models.LibraryFixedIns{},
// VulnType : "",
}
}
vulnInfo := vulnInfos[vuln.VulnerabilityID]
var notFixedYet bool
fixState := ""
if len(vuln.FixedVersion) == 0 {
notFixedYet = true
fixState = "Affected"
}
var references models.References
for _, reference := range vuln.References {
references = append(references, models.Reference{
Source: "trivy",
Link: reference,
})
}
sort.Slice(references, func(i, j int) bool {
return references[i].Link < references[j].Link
})
var published time.Time
if vuln.PublishedDate != nil {
published = *vuln.PublishedDate
}
var lastModified time.Time
if vuln.LastModifiedDate != nil {
lastModified = *vuln.LastModifiedDate
}
vulnInfo.CveContents = models.CveContents{
models.Trivy: models.CveContent{
Cvss3Severity: vuln.Severity,
References: references,
Title: vuln.Title,
Summary: vuln.Description,
Published: published,
LastModified: lastModified,
},
}
// do only if image type is Vuln
if IsTrivySupportedOS(trivyResult.Type) {
pkgs[vuln.PkgName] = models.Package{
Name: vuln.PkgName,
Version: vuln.InstalledVersion,
}
vulnInfo.AffectedPackages = append(vulnInfo.AffectedPackages, models.PackageFixStatus{
Name: vuln.PkgName,
NotFixedYet: notFixedYet,
FixState: fixState,
FixedIn: vuln.FixedVersion,
})
// overwrite every time if os package
scanResult.Family = trivyResult.Type
scanResult.ServerName = trivyResult.Target
scanResult.Optional = map[string]interface{}{
"trivy-target": trivyResult.Target,
}
scanResult.ScannedAt = time.Now()
scanResult.ScannedBy = "trivy"
scanResult.ScannedVia = "trivy"
} else {
// LibraryScanの結果
vulnInfo.LibraryFixedIns = append(vulnInfo.LibraryFixedIns, models.LibraryFixedIn{
Key: trivyResult.Type,
Name: vuln.PkgName,
Path: trivyResult.Target,
FixedIn: vuln.FixedVersion,
})
libScanner := uniqueLibraryScannerPaths[trivyResult.Target]
libScanner.Libs = append(libScanner.Libs, types.Library{
Name: vuln.PkgName,
Version: vuln.InstalledVersion,
})
uniqueLibraryScannerPaths[trivyResult.Target] = libScanner
}
vulnInfos[vuln.VulnerabilityID] = vulnInfo
}
}
// flatten and unique libraries
libraryScanners := make([]models.LibraryScanner, 0, len(uniqueLibraryScannerPaths))
for path, v := range uniqueLibraryScannerPaths {
uniqueLibrary := map[string]types.Library{}
for _, lib := range v.Libs {
uniqueLibrary[lib.Name+lib.Version] = lib
}
var libraries []types.Library
for _, library := range uniqueLibrary {
libraries = append(libraries, library)
}
sort.Slice(libraries, func(i, j int) bool {
return libraries[i].Name < libraries[j].Name
})
libscanner := models.LibraryScanner{
Path: path,
Libs: libraries,
}
libraryScanners = append(libraryScanners, libscanner)
}
sort.Slice(libraryScanners, func(i, j int) bool {
return libraryScanners[i].Path < libraryScanners[j].Path
})
scanResult.ScannedCves = vulnInfos
scanResult.Packages = pkgs
scanResult.LibraryScanners = libraryScanners
return scanResult, nil
}
// IsTrivySupportedOS :
func IsTrivySupportedOS(family string) bool {
supportedFamilies := []string{
os.RedHat,
os.Debian,
os.Ubuntu,
os.CentOS,
os.Fedora,
os.Amazon,
os.Oracle,
os.Windows,
os.OpenSUSE,
os.OpenSUSELeap,
os.OpenSUSETumbleweed,
os.SLES,
os.Photon,
os.Alpine,
}
for _, supportedFamily := range supportedFamilies {
if family == supportedFamily {
return true
}
}
return false
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,254 +0,0 @@
/* 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 cveapi
import (
"encoding/json"
"fmt"
"net/http"
"sort"
"time"
"github.com/cenkalti/backoff"
"github.com/parnurzeal/gorequest"
log "github.com/Sirupsen/logrus"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/util"
cveconfig "github.com/kotakanbe/go-cve-dictionary/config"
cvedb "github.com/kotakanbe/go-cve-dictionary/db"
cve "github.com/kotakanbe/go-cve-dictionary/models"
)
// CveClient is api client of CVE disctionary service.
var CveClient cvedictClient
type cvedictClient struct {
// httpProxy string
baseURL string
}
func (api *cvedictClient) initialize() {
api.baseURL = config.Conf.CveDictionaryURL
}
func (api cvedictClient) CheckHealth() (ok bool, err error) {
if config.Conf.CveDBPath != "" {
log.Debugf("get cve-dictionary from %s", config.Conf.CveDBType)
return true, nil
}
api.initialize()
url := fmt.Sprintf("%s/health", api.baseURL)
var errs []error
var resp *http.Response
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 false, fmt.Errorf("Failed to request to CVE server. url: %s, errs: %v", url, errs)
}
return true, nil
}
type response struct {
Key string
CveDetail cve.CveDetail
}
func (api cvedictClient) FetchCveDetails(cveIDs []string) (cveDetails cve.CveDetails, err error) {
if config.Conf.CveDBPath != "" {
return api.FetchCveDetailsFromCveDB(cveIDs)
}
api.baseURL = config.Conf.CveDictionaryURL
reqChan := make(chan string, len(cveIDs))
resChan := make(chan response, len(cveIDs))
errChan := make(chan error, len(cveIDs))
defer close(reqChan)
defer close(resChan)
defer close(errChan)
go func() {
for _, cveID := range cveIDs {
reqChan <- cveID
}
}()
concurrency := 10
tasks := util.GenWorkers(concurrency)
for range cveIDs {
tasks <- func() {
select {
case cveID := <-reqChan:
url, err := util.URLPathJoin(api.baseURL, "cves", cveID)
if err != nil {
errChan <- err
} else {
log.Debugf("HTTP Request to %s", url)
api.httpGet(cveID, url, resChan, errChan)
}
}
}
}
timeout := time.After(2 * 60 * time.Second)
var errs []error
for range cveIDs {
select {
case res := <-resChan:
if len(res.CveDetail.CveID) == 0 {
cveDetails = append(cveDetails, cve.CveDetail{
CveID: res.Key,
})
} else {
cveDetails = append(cveDetails, res.CveDetail)
}
case err := <-errChan:
errs = append(errs, err)
case <-timeout:
return []cve.CveDetail{}, fmt.Errorf("Timeout Fetching CVE")
}
}
if len(errs) != 0 {
return []cve.CveDetail{},
fmt.Errorf("Failed to fetch CVE. err: %v", errs)
}
// order by CVE ID desc
sort.Sort(cveDetails)
return
}
func (api cvedictClient) FetchCveDetailsFromCveDB(cveIDs []string) (cveDetails cve.CveDetails, err error) {
log.Debugf("open cve-dictionary db (%s)", config.Conf.CveDBType)
cveconfig.Conf.DBType = config.Conf.CveDBType
cveconfig.Conf.DBPath = config.Conf.CveDBPath
cveconfig.Conf.DebugSQL = config.Conf.DebugSQL
if err := cvedb.OpenDB(); err != nil {
return []cve.CveDetail{},
fmt.Errorf("Failed to open DB. err: %s", err)
}
for _, cveID := range cveIDs {
cveDetail := cvedb.Get(cveID)
if len(cveDetail.CveID) == 0 {
cveDetails = append(cveDetails, cve.CveDetail{
CveID: cveID,
})
} else {
cveDetails = append(cveDetails, cveDetail)
}
}
// order by CVE ID desc
sort.Sort(cveDetails)
return
}
func (api cvedictClient) httpGet(key, url string, resChan chan<- response, errChan chan<- error) {
var body string
var errs []error
var resp *http.Response
f := func() (err error) {
// 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 nil
}
notify := func(err error, t time.Duration) {
log.Warnf("Failed to HTTP GET. retrying in %s seconds. err: %s", t, err)
}
err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
if err != nil {
errChan <- fmt.Errorf("HTTP Error %s", err)
}
cveDetail := cve.CveDetail{}
if err := json.Unmarshal([]byte(body), &cveDetail); err != nil {
errChan <- fmt.Errorf("Failed to Unmarshall. body: %s, err: %s", body, err)
}
resChan <- response{
key,
cveDetail,
}
}
type responseGetCveDetailByCpeName struct {
CpeName string
CveDetails []cve.CveDetail
}
func (api cvedictClient) FetchCveDetailsByCpeName(cpeName string) ([]cve.CveDetail, error) {
if config.Conf.CveDBPath != "" {
return api.FetchCveDetailsByCpeNameFromDB(cpeName)
}
api.baseURL = config.Conf.CveDictionaryURL
url, err := util.URLPathJoin(api.baseURL, "cpes")
if err != nil {
return []cve.CveDetail{}, err
}
query := map[string]string{"name": cpeName}
log.Debugf("HTTP Request to %s, query: %#v", url, query)
return api.httpPost(cpeName, url, query)
}
func (api cvedictClient) httpPost(key, url string, query map[string]string) ([]cve.CveDetail, error) {
var body string
var errs []error
var resp *http.Response
f := func() (err error) {
req := gorequest.New().SetDebug(config.Conf.Debug).Post(url)
for key := range query {
req = req.Send(fmt.Sprintf("%s=%s", key, query[key])).Type("json")
}
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 nil
}
notify := func(err error, t time.Duration) {
log.Warnf("Failed to HTTP POST. retrying in %s seconds. err: %s", t, err)
}
err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
if err != nil {
return []cve.CveDetail{}, fmt.Errorf("HTTP Error %s", err)
}
cveDetails := []cve.CveDetail{}
if err := json.Unmarshal([]byte(body), &cveDetails); err != nil {
return []cve.CveDetail{},
fmt.Errorf("Failed to Unmarshall. body: %s, err: %s", body, err)
}
return cveDetails, nil
}
func (api cvedictClient) FetchCveDetailsByCpeNameFromDB(cpeName string) ([]cve.CveDetail, error) {
log.Debugf("open cve-dictionary db (%s)", config.Conf.CveDBType)
cveconfig.Conf.DBType = config.Conf.CveDBType
cveconfig.Conf.DBPath = config.Conf.CveDBPath
cveconfig.Conf.DebugSQL = config.Conf.DebugSQL
if err := cvedb.OpenDB(); err != nil {
return []cve.CveDetail{},
fmt.Errorf("Failed to open DB. err: %s", err)
}
return cvedb.GetByCpeName(cpeName), 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"

5145
cwe/en.go Normal file

File diff suppressed because it is too large Load Diff

1027
cwe/ja.go Normal file

File diff suppressed because it is too large Load Diff

65
cwe/owasp.go Normal file
View File

@@ -0,0 +1,65 @@
package cwe
// OwaspTopTen2017 has CWE-ID in OWSP Top 10
var OwaspTopTen2017 = map[string]string{
"77": "1",
"89": "1",
"564": "1",
"917": "1",
"287": "2",
"384": "2",
"220": "3",
"310": "3",
"312": "3",
"319": "3",
"326": "3",
"359": "3",
"611": "4",
"22": "5",
"284": "5",
"285": "5",
"639": "5",
"2": "6",
"16": "6",
"388": "6",
"79": "7",
"502": "8",
"223": "10",
"778": "10",
}
// OwaspTopTen2017GitHubURLEn has GitHub links
var OwaspTopTen2017GitHubURLEn = map[string]string{
"1": "https://github.com/OWASP/Top10/blob/master/2017/en/0xa1-injection.md",
"2": "https://github.com/OWASP/Top10/blob/master/2017/en/0xa2-broken-authentication.md",
"3": "https://github.com/OWASP/Top10/blob/master/2017/en/0xa3-sensitive-data-disclosure.md",
"4": "https://github.com/OWASP/Top10/blob/master/2017/en/0xa4-xxe.md",
"5": "https://github.com/OWASP/Top10/blob/master/2017/en/0xa5-broken-access-control.md",
"6": "https://github.com/OWASP/Top10/blob/master/2017/en/0xa6-security-misconfiguration.md",
"7": "https://github.com/OWASP/Top10/blob/master/2017/en/0xa7-xss.md",
"8": "https://github.com/OWASP/Top10/blob/master/2017/en/0xa8-insecure-deserialization.md",
"9": "https://github.com/OWASP/Top10/blob/master/2017/en/0xa9-known-vulns.md<Paste>",
"10": "https://github.com/OWASP/Top10/blob/master/2017/en/0xaa-logging-detection-response.md",
}
// OwaspTopTen2017GitHubURLJa has GitHub links
var OwaspTopTen2017GitHubURLJa = map[string]string{
"1": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xa1-injection.md",
"2": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xa2-broken-authentication.md",
"3": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xa3-sensitive-data-disclosure.md",
"4": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xa4-xxe.md",
"5": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xa5-broken-access-control.md",
"6": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xa6-security-misconfiguration.md",
"7": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xa7-xss.md",
"8": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xa8-insecure-deserialization.md",
"9": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xa9-known-vulns.md<Paste>",
"10": "https://github.com/OWASP/Top10/blob/master/2017/ja/0xaa-logging-detection-response.md",
}

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 is a URL of sans 25
var SansTopTwentyfiveURL = "https://www.sans.org/top25-software-errors/"

33
errof/errof.go Normal file
View File

@@ -0,0 +1,33 @@
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"
// ErrFailedToAccessWpScan is error of wpscan.com api access
ErrFailedToAccessWpScan ErrorCode = "ErrFailedToAccessWpScan"
// ErrWpScanAPILimitExceeded is error of wpscan.com api limit exceeded
ErrWpScanAPILimitExceeded ErrorCode = "ErrWpScanAPILimitExceeded"
)
// New :
func New(code ErrorCode, msg string) Error {
return Error{
Code: code,
Message: msg,
}
}

85
exploit/exploit.go Normal file
View File

@@ -0,0 +1,85 @@
// +build !scanner
package exploit
import (
"encoding/json"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/vulsio/go-exploitdb/db"
exploitmodels "github.com/vulsio/go-exploitdb/models"
)
// FillWithExploit fills exploit information that has in Exploit
func FillWithExploit(driver db.DB, r *models.ScanResult, cnf *config.ExploitConf) (nExploitCve int, err error) {
if cnf.IsFetchViaHTTP() {
var cveIDs []string
for cveID := range r.ScannedCves {
cveIDs = append(cveIDs, cveID)
}
prefix, _ := util.URLPathJoin(cnf.URL, "cves")
responses, err := getCvesViaHTTP(cveIDs, prefix)
if err != nil {
return 0, err
}
for _, res := range responses {
exps := []*exploitmodels.Exploit{}
if err := json.Unmarshal([]byte(res.json), &exps); err != nil {
return 0, err
}
exploits := ConvertToModels(exps)
v, ok := r.ScannedCves[res.request.cveID]
if ok {
v.Exploits = exploits
}
r.ScannedCves[res.request.cveID] = v
nExploitCve++
}
} else {
if driver == nil {
return 0, nil
}
for cveID, vuln := range r.ScannedCves {
if cveID == "" {
continue
}
es := driver.GetExploitByCveID(cveID)
if len(es) == 0 {
continue
}
exploits := ConvertToModels(es)
vuln.Exploits = exploits
r.ScannedCves[cveID] = vuln
nExploitCve++
}
}
return nExploitCve, nil
}
// ConvertToModels converts gost model to vuls model
func ConvertToModels(es []*exploitmodels.Exploit) (exploits []models.Exploit) {
for _, e := range es {
var documentURL, shellURL *string
if e.OffensiveSecurity != nil {
os := e.OffensiveSecurity
if os.Document != nil {
documentURL = &os.Document.DocumentURL
}
if os.ShellCode != nil {
shellURL = &os.ShellCode.ShellCodeURL
}
}
exploit := models.Exploit{
ExploitType: e.ExploitType,
ID: e.ExploitUniqueID,
URL: e.URL,
Description: e.Description,
DocumentURL: documentURL,
ShellCodeURL: shellURL,
}
exploits = append(exploits, exploit)
}
return exploits
}

115
exploit/util.go Normal file
View File

@@ -0,0 +1,115 @@
package exploit
import (
"net/http"
"time"
"github.com/cenkalti/backoff"
"github.com/future-architect/vuls/util"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
type response struct {
request request
json string
}
func getCvesViaHTTP(cveIDs []string, urlPrefix string) (
responses []response, err error) {
nReq := len(cveIDs)
reqChan := make(chan request, nReq)
resChan := make(chan response, nReq)
errChan := make(chan error, nReq)
defer close(reqChan)
defer close(resChan)
defer close(errChan)
go func() {
for _, cveID := range cveIDs {
reqChan <- request{
cveID: cveID,
}
}
}()
concurrency := 10
tasks := util.GenWorkers(concurrency)
for i := 0; i < nReq; i++ {
tasks <- func() {
select {
case req := <-reqChan:
url, err := util.URLPathJoin(
urlPrefix,
req.cveID,
)
if err != nil {
errChan <- err
} else {
util.Log.Debugf("HTTP Request to %s", url)
httpGet(url, req, resChan, errChan)
}
}
}
}
timeout := time.After(2 * 60 * time.Second)
var errs []error
for i := 0; i < nReq; i++ {
select {
case res := <-resChan:
responses = append(responses, res)
case err := <-errChan:
errs = append(errs, err)
case <-timeout:
return nil, xerrors.New("Timeout Fetching OVAL")
}
}
if len(errs) != 0 {
return nil, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
}
return
}
type request struct {
osMajorVersion string
packName string
isSrcPack bool
cveID string
}
func httpGet(url string, req request, resChan chan<- response, errChan chan<- error) {
var body string
var errs []error
var resp *http.Response
count, retryMax := 0, 3
f := func() (err error) {
// resp, body, errs = gorequest.New().SetDebug(config.Conf.Debug).Get(url).End()
resp, body, errs = gorequest.New().Timeout(10 * time.Second).Get(url).End()
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
count++
if count == retryMax {
return nil
}
return xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %s", url, resp, errs)
}
return nil
}
notify := func(err error, t time.Duration) {
util.Log.Warnf("Failed to HTTP GET. retrying in %s seconds. err: %s", t, err)
}
err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
if err != nil {
errChan <- xerrors.Errorf("HTTP Error %w", err)
return
}
if count == retryMax {
errChan <- xerrors.New("Retry count exceeded")
return
}
resChan <- response{
request: req,
json: body,
}
}

200
github/github.go Normal file
View File

@@ -0,0 +1,200 @@
package github
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/errof"
"github.com/future-architect/vuls/models"
"golang.org/x/oauth2"
)
// DetectGitHubSecurityAlerts access to owner/repo on GitHub and fetch security alerts of the repository via GitHub API v4 GraphQL and then set to the given ScanResult.
// https://help.github.com/articles/about-security-alerts-for-vulnerable-dependencies/
//TODO move to report
func DetectGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string) (nCVEs int, err error) {
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
//TODO Proxy
httpClient := oauth2.NewClient(context.Background(), src)
// TODO Use `https://github.com/shurcooL/githubv4` if the tool supports vulnerabilityAlerts Endpoint
// Memo : https://developer.github.com/v4/explorer/
const jsonfmt = `{"query":
"query { repository(owner:\"%s\", name:\"%s\") { url vulnerabilityAlerts(first: %d, %s) { pageInfo { endCursor hasNextPage startCursor } edges { node { id dismissReason dismissedAt securityVulnerability{ package { name ecosystem } severity vulnerableVersionRange firstPatchedVersion { identifier } } securityAdvisory { description ghsaId permalink publishedAt summary updatedAt withdrawnAt origin severity references { url } identifiers { type value } } } } } } } "}`
after := ""
for {
jsonStr := fmt.Sprintf(jsonfmt, owner, repo, 100, after)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
req, err := http.NewRequestWithContext(ctx, http.MethodPost,
"https://api.github.com/graphql",
bytes.NewBuffer([]byte(jsonStr)),
)
defer cancel()
if err != nil {
return 0, err
}
// https://developer.github.com/v4/previews/#repository-vulnerability-alerts
// To toggle this preview and access data, need to provide a custom media type in the Accept header:
// MEMO: I tried to get the affected version via GitHub API. Bit it seems difficult to determin the affected version if there are multiple dependency files such as package.json.
// TODO remove this header if it is no longer preview status in the future.
req.Header.Set("Accept", "application/vnd.github.package-deletes-preview+json")
req.Header.Set("Content-Type", "application/json")
resp, err := httpClient.Do(req)
if err != nil {
return 0, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return 0, err
}
alerts := SecurityAlerts{}
if err := json.Unmarshal(body, &alerts); err != nil {
return 0, err
}
// util.Log.Debugf("%s", pp.Sprint(alerts))
// util.Log.Debugf("%s", string(body))
if alerts.Data.Repository.URL == "" {
return 0, errof.New(errof.ErrFailedToAccessGithubAPI,
fmt.Sprintf("Failed to access to GitHub API. Response: %s", string(body)))
}
for _, v := range alerts.Data.Repository.VulnerabilityAlerts.Edges {
if config.Conf.IgnoreGitHubDismissed && v.Node.DismissReason != "" {
continue
}
pkgName := fmt.Sprintf("%s %s",
alerts.Data.Repository.URL, v.Node.SecurityVulnerability.Package.Name)
m := models.GitHubSecurityAlert{
PackageName: pkgName,
FixedIn: v.Node.SecurityVulnerability.FirstPatchedVersion.Identifier,
AffectedRange: v.Node.SecurityVulnerability.VulnerableVersionRange,
Dismissed: len(v.Node.DismissReason) != 0,
DismissedAt: v.Node.DismissedAt,
DismissReason: v.Node.DismissReason,
}
cveIDs, other := []string{}, []string{}
for _, identifier := range v.Node.SecurityAdvisory.Identifiers {
if identifier.Type == "CVE" {
cveIDs = append(cveIDs, identifier.Value)
} else {
other = append(other, identifier.Value)
}
}
// If CVE-ID has not been assigned, use the GHSA ID etc as a ID.
if len(cveIDs) == 0 {
cveIDs = other
}
refs := []models.Reference{}
for _, r := range v.Node.SecurityAdvisory.References {
refs = append(refs, models.Reference{Link: r.URL})
}
for _, cveID := range cveIDs {
cveContent := models.CveContent{
Type: models.GitHub,
CveID: cveID,
Title: v.Node.SecurityAdvisory.Summary,
Summary: v.Node.SecurityAdvisory.Description,
Cvss2Severity: v.Node.SecurityVulnerability.Severity,
Cvss3Severity: v.Node.SecurityVulnerability.Severity,
SourceLink: v.Node.SecurityAdvisory.Permalink,
References: refs,
Published: v.Node.SecurityAdvisory.PublishedAt,
LastModified: v.Node.SecurityAdvisory.UpdatedAt,
}
if val, ok := r.ScannedCves[cveID]; ok {
val.GitHubSecurityAlerts = val.GitHubSecurityAlerts.Add(m)
val.CveContents[models.GitHub] = cveContent
r.ScannedCves[cveID] = val
} else {
v := models.VulnInfo{
CveID: cveID,
Confidences: models.Confidences{models.GitHubMatch},
GitHubSecurityAlerts: models.GitHubSecurityAlerts{m},
CveContents: models.NewCveContents(cveContent),
}
r.ScannedCves[cveID] = v
}
nCVEs++
}
}
if !alerts.Data.Repository.VulnerabilityAlerts.PageInfo.HasNextPage {
break
}
after = fmt.Sprintf(`after: \"%s\"`, alerts.Data.Repository.VulnerabilityAlerts.PageInfo.EndCursor)
}
return nCVEs, err
}
//SecurityAlerts has detected CVE-IDs, PackageNames, Refs
type SecurityAlerts struct {
Data struct {
Repository struct {
URL string `json:"url"`
VulnerabilityAlerts struct {
PageInfo struct {
EndCursor string `json:"endCursor"`
HasNextPage bool `json:"hasNextPage"`
StartCursor string `json:"startCursor"`
} `json:"pageInfo"`
Edges []struct {
Node struct {
ID string `json:"id"`
DismissReason string `json:"dismissReason"`
DismissedAt time.Time `json:"dismissedAt"`
SecurityVulnerability struct {
Package struct {
Name string `json:"name"`
Ecosystem string `json:"ecosystem"`
} `json:"package"`
Severity string `json:"severity"`
VulnerableVersionRange string `json:"vulnerableVersionRange"`
FirstPatchedVersion struct {
Identifier string `json:"identifier"`
} `json:"firstPatchedVersion"`
} `json:"securityVulnerability"`
SecurityAdvisory struct {
Description string `json:"description"`
GhsaID string `json:"ghsaId"`
Permalink string `json:"permalink"`
PublishedAt time.Time `json:"publishedAt"`
Summary string `json:"summary"`
UpdatedAt time.Time `json:"updatedAt"`
WithdrawnAt time.Time `json:"withdrawnAt"`
Origin string `json:"origin"`
Severity string `json:"severity"`
References []struct {
URL string `json:"url"`
} `json:"references"`
Identifiers []struct {
Type string `json:"type"`
Value string `json:"value"`
} `json:"identifiers"`
} `json:"securityAdvisory"`
} `json:"node"`
} `json:"edges"`
} `json:"vulnerabilityAlerts"`
} `json:"repository"`
} `json:"data"`
}

123
glide.lock generated
View File

@@ -1,123 +0,0 @@
hash: ca64aef6e9e94c7be91f79b88edb847363c8a5bd48da4ad27784e9342c8db6e2
updated: 2016-11-01T15:05:15.23083077+09:00
imports:
- name: github.com/asaskevich/govalidator
version: 7b3beb6df3c42abd3509abfc3bcacc0fbfb7c877
- name: github.com/aws/aws-sdk-go
version: 9e5bedb97b1cd85e53fd99209f93fd1a8a9f1df7
subpackages:
- aws
- aws/awserr
- aws/awsutil
- aws/client
- aws/client/metadata
- aws/corehandlers
- aws/credentials
- aws/credentials/ec2rolecreds
- aws/credentials/endpointcreds
- aws/credentials/stscreds
- aws/defaults
- aws/ec2metadata
- aws/request
- aws/session
- aws/signer/v4
- private/endpoints
- private/protocol
- private/protocol/query
- private/protocol/query/queryutil
- private/protocol/rest
- private/protocol/restxml
- private/protocol/xml/xmlutil
- private/waiter
- service/s3
- service/sts
- name: github.com/Azure/azure-sdk-for-go
version: 9016164015faa51e549605e7b4b117f7de2aa6f9
subpackages:
- storage
- name: github.com/boltdb/bolt
version: 074dffcc83e9f421e261526d297cd93f22a34080
- name: github.com/BurntSushi/toml
version: 99064174e013895bbd9b025c31100bd1d9b590ca
- name: github.com/cenkalti/backoff
version: b02f2bbce11d7ea6b97f282ef1771b0fe2f65ef3
- name: github.com/cheggaaa/pb
version: ad4efe000aa550bb54918c06ebbadc0ff17687b9
- name: github.com/go-ini/ini
version: 6e4869b434bd001f6983749881c7ead3545887d8
- name: github.com/go-sql-driver/mysql
version: 2a6c6079c7eff49a7e9d641e109d922f124a3e4c
- name: github.com/google/subcommands
version: a71b91e238406bd68766ee52db63bebedce0e9f6
- name: github.com/gosuri/uitable
version: 36ee7e946282a3fb1cfecd476ddc9b35d8847e42
subpackages:
- util/strutil
- util/wordwrap
- name: github.com/howeyc/gopass
version: f5387c492211eb133053880d23dfae62aa14123d
- name: github.com/jinzhu/gorm
version: c1b9cf186e4bcd8e5d566ef43f2ae2dfe22dc34e
subpackages:
- dialects/mysql
- name: github.com/jinzhu/inflection
version: 74387dc39a75e970e7a3ae6a3386b5bd2e5c5cff
- name: github.com/jmespath/go-jmespath
version: bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d
- name: github.com/jroimartin/gocui
version: 357a541add9e311f7b67dfbaf92e28c71680a6b7
- name: github.com/k0kubun/pp
version: f5dce6ed0ccf6c350f1679964ff6b61f3d6d2033
- name: github.com/kotakanbe/go-cve-dictionary
version: 70989b6709c3102924ad8c8483e9bdc99bcb598b
subpackages:
- config
- db
- jvn
- log
- models
- nvd
- util
- name: github.com/kotakanbe/go-pingscanner
version: 58e188a3e4f6ab1a6371e33421e4502e26fa1e80
- name: github.com/kotakanbe/logrus-prefixed-formatter
version: f4f7d41649cf1e75e736884da8d05324aa76ea25
- name: github.com/mattn/go-colorable
version: 6c903ff4aa50920ca86087a280590b36b3152b9c
- name: github.com/mattn/go-isatty
version: 66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8
- name: github.com/mattn/go-runewidth
version: 737072b4e32b7a5018b4a7125da8d12de90e8045
- name: github.com/mattn/go-sqlite3
version: e5a3c16c5c1d80b24f633e68aecd6b0702786d3d
- name: github.com/mgutz/ansi
version: c286dcecd19ff979eeb73ea444e479b903f2cfcb
- name: github.com/moul/http2curl
version: c984a4ec331f8ef0e5cd782975a97c92bd8ab40c
- name: github.com/nsf/termbox-go
version: b6acae516ace002cb8105a89024544a1480655a5
- name: github.com/parnurzeal/gorequest
version: e37b9d1efacf7c94820b29b75dd7d0c2996b3fb1
- name: github.com/rifflock/lfshook
version: 3f9d976bd7402de39b46357069fb6325a974572e
- name: github.com/Sirupsen/logrus
version: 3ec0642a7fb6488f65b06f9040adc67e3990296a
- name: golang.org/x/crypto
version: 1150b8bd09e53aea1d415621adae9bad665061a1
subpackages:
- curve25519
- ed25519
- ed25519/internal/edwards25519
- ssh
- ssh/agent
- ssh/terminal
- name: golang.org/x/net
version: 65dfc08770ce66f74becfdff5f8ab01caef4e946
subpackages:
- context
- publicsuffix
- name: golang.org/x/sys
version: c200b10b5d5e122be351b67af224adc6128af5bf
subpackages:
- unix
testImports: []

View File

@@ -1,39 +0,0 @@
package: github.com/future-architect/vuls
import:
- package: github.com/Azure/azure-sdk-for-go
subpackages:
- storage
- package: github.com/BurntSushi/toml
- package: github.com/Sirupsen/logrus
- package: github.com/asaskevich/govalidator
- package: github.com/aws/aws-sdk-go
subpackages:
- aws
- aws/credentials
- aws/session
- service/s3
- package: github.com/boltdb/bolt
- package: github.com/cenkalti/backoff
- package: github.com/google/subcommands
- package: github.com/gosuri/uitable
- package: github.com/howeyc/gopass
- package: github.com/jinzhu/gorm
- package: github.com/jroimartin/gocui
- package: github.com/k0kubun/pp
- package: github.com/kotakanbe/go-cve-dictionary
subpackages:
- config
- db
- models
- package: github.com/kotakanbe/go-pingscanner
- package: github.com/kotakanbe/logrus-prefixed-formatter
- package: github.com/mattn/go-sqlite3
- package: github.com/parnurzeal/gorequest
- package: github.com/rifflock/lfshook
- package: golang.org/x/crypto
subpackages:
- ssh
- ssh/agent
- package: golang.org/x/net
subpackages:
- context

50
go.mod Normal file
View File

@@ -0,0 +1,50 @@
module github.com/future-architect/vuls
go 1.15
require (
github.com/Azure/azure-sdk-for-go v50.2.0+incompatible
github.com/BurntSushi/toml v0.3.1
github.com/aquasecurity/fanal v0.0.0-20210119051230-28c249da7cfd
github.com/aquasecurity/trivy v0.15.0
github.com/aquasecurity/trivy-db v0.0.0-20210121143430-2a5c54036a86
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef
github.com/aws/aws-sdk-go v1.36.31
github.com/boltdb/bolt v1.3.1
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/d4l3k/messagediff v1.2.2-0.20190829033028-7e0a312ae40b
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21
github.com/emersion/go-smtp v0.14.0
github.com/google/subcommands v1.2.0
github.com/gosuri/uitable v0.0.4
github.com/hashicorp/go-uuid v1.0.2
github.com/hashicorp/go-version v1.2.1
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c
github.com/jesseduffield/gocui v0.3.0
github.com/k0kubun/pp v3.0.1+incompatible
github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f
github.com/knqyf263/go-cpe v0.0.0-20201213041631-54f6ab28673f
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/gost v0.1.7
github.com/kotakanbe/go-cve-dictionary v0.5.7
github.com/kotakanbe/go-pingscanner v0.1.0
github.com/kotakanbe/goval-dictionary v0.3.1
github.com/kotakanbe/logrus-prefixed-formatter v0.0.0-20180123152602-928f7356cb96
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mitchellh/go-homedir v1.1.0
github.com/nlopes/slack v0.6.0
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 // indirect
github.com/olekukonko/tablewriter v0.0.4
github.com/parnurzeal/gorequest v0.2.16
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
github.com/sirupsen/logrus v1.7.0
github.com/spf13/afero v1.5.1
github.com/spf13/cobra v1.1.1
github.com/takuzoo3868/go-msfdb v0.1.3
github.com/vulsio/go-exploitdb v0.1.4
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/oauth2 v0.0.0-20210125201302-af13f521f196
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009
)

1292
go.sum Normal file

File diff suppressed because it is too large Load Diff

17
gost/base.go Normal file
View File

@@ -0,0 +1,17 @@
// +build !scanner
package gost
import (
"github.com/future-architect/vuls/models"
"github.com/knqyf263/gost/db"
)
// 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{}.fillCvesWithRedHatAPI(driver, r)
}

190
gost/debian.go Normal file
View File

@@ -0,0 +1,190 @@
// +build !scanner
package gost
import (
"encoding/json"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/knqyf263/gost/db"
gostmodels "github.com/knqyf263/gost/models"
)
// Debian is Gost client for Debian GNU/Linux
type Debian struct {
Base
}
type packCves struct {
packName string
isSrcPack bool
cves []models.CveContent
}
func (deb Debian) supported(major string) bool {
_, ok := map[string]string{
"8": "jessie",
"9": "stretch",
"10": "buster",
}[major]
return ok
}
// DetectUnfixed fills cve information that has in Gost
func (deb Debian) DetectUnfixed(driver db.DB, r *models.ScanResult, _ bool) (nCVEs int, err error) {
if !deb.supported(major(r.Release)) {
// only logging
util.Log.Warnf("Debian %s is not supported yet", r.Release)
return 0, nil
}
linuxImage := "linux-image-" + r.RunningKernel.Release
// Add linux and set the version of running kernel to search OVAL.
if r.Container.ContainerID == "" {
newVer := ""
if p, ok := r.Packages[linuxImage]; ok {
newVer = p.NewVersion
}
r.Packages["linux"] = models.Package{
Name: "linux",
Version: r.RunningKernel.Version,
NewVersion: newVer,
}
}
// Debian Security Tracker does not support Package for Raspbian, so skip it.
var scanResult models.ScanResult
if r.Family != config.Raspbian {
scanResult = *r
} else {
scanResult = r.RemoveRaspbianPackFromResult()
}
packCvesList := []packCves{}
if config.Conf.Gost.IsFetchViaHTTP() {
url, _ := util.URLPathJoin(config.Conf.Gost.URL, "debian", major(scanResult.Release), "pkgs")
responses, err := getAllUnfixedCvesViaHTTP(r, url)
if err != nil {
return 0, err
}
for _, res := range responses {
debCves := map[string]gostmodels.DebianCVE{}
if err := json.Unmarshal([]byte(res.json), &debCves); err != nil {
return 0, err
}
cves := []models.CveContent{}
for _, debcve := range debCves {
cves = append(cves, *deb.ConvertToModel(&debcve))
}
packCvesList = append(packCvesList, packCves{
packName: res.request.packName,
isSrcPack: res.request.isSrcPack,
cves: cves,
})
}
} else {
if driver == nil {
return 0, nil
}
for _, pack := range scanResult.Packages {
cveDebs := driver.GetUnfixedCvesDebian(major(scanResult.Release), pack.Name)
cves := []models.CveContent{}
for _, cveDeb := range cveDebs {
cves = append(cves, *deb.ConvertToModel(&cveDeb))
}
packCvesList = append(packCvesList, packCves{
packName: pack.Name,
isSrcPack: false,
cves: cves,
})
}
// SrcPack
for _, pack := range scanResult.SrcPackages {
cveDebs := driver.GetUnfixedCvesDebian(major(scanResult.Release), pack.Name)
cves := []models.CveContent{}
for _, cveDeb := range cveDebs {
cves = append(cves, *deb.ConvertToModel(&cveDeb))
}
packCvesList = append(packCvesList, packCves{
packName: pack.Name,
isSrcPack: true,
cves: cves,
})
}
}
delete(r.Packages, "linux")
for _, p := range packCvesList {
for _, cve := range p.cves {
v, ok := r.ScannedCves[cve.CveID]
if ok {
if v.CveContents == nil {
v.CveContents = models.NewCveContents(cve)
} else {
v.CveContents[models.DebianSecurityTracker] = cve
}
} else {
v = models.VulnInfo{
CveID: cve.CveID,
CveContents: models.NewCveContents(cve),
Confidences: models.Confidences{models.DebianSecurityTrackerMatch},
}
nCVEs++
}
names := []string{}
if p.isSrcPack {
if srcPack, ok := r.SrcPackages[p.packName]; ok {
for _, binName := range srcPack.BinaryNames {
if _, ok := r.Packages[binName]; ok {
names = append(names, binName)
}
}
}
} else {
if p.packName == "linux" {
names = append(names, linuxImage)
} else {
names = append(names, p.packName)
}
}
for _, name := range names {
v.AffectedPackages = v.AffectedPackages.Store(models.PackageFixStatus{
Name: name,
FixState: "open",
NotFixedYet: true,
})
}
r.ScannedCves[cve.CveID] = v
}
}
return nCVEs, nil
}
// ConvertToModel converts gost model to vuls model
func (deb Debian) ConvertToModel(cve *gostmodels.DebianCVE) *models.CveContent {
severity := ""
for _, p := range cve.Package {
for _, r := range p.Release {
severity = r.Urgency
break
}
}
return &models.CveContent{
Type: models.DebianSecurityTracker,
CveID: cve.CveID,
Summary: cve.Description,
Cvss2Severity: severity,
Cvss3Severity: severity,
SourceLink: "https://security-tracker.debian.org/tracker/" + cve.CveID,
Optional: map[string]string{
"attack range": cve.Scope,
},
}
}

61
gost/debian_test.go Normal file
View File

@@ -0,0 +1,61 @@
package gost
import "testing"
func TestDebian_Supported(t *testing.T) {
type fields struct {
Base Base
}
type args struct {
major string
}
tests := []struct {
name string
args args
want bool
}{
{
name: "8 is supported",
args: args{
major: "8",
},
want: true,
},
{
name: "9 is supported",
args: args{
major: "9",
},
want: true,
},
{
name: "10 is supported",
args: args{
major: "10",
},
want: true,
},
{
name: "11 is not supported yet",
args: args{
major: "11",
},
want: false,
},
{
name: "empty string is not supported yet",
args: args{
major: "",
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
deb := Debian{}
if got := deb.supported(tt.args.major); got != tt.want {
t.Errorf("Debian.Supported() = %v, want %v", got, tt.want)
}
})
}
}

29
gost/gost.go Normal file
View File

@@ -0,0 +1,29 @@
// +build !scanner
package gost
import (
cnf "github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/knqyf263/gost/db"
)
// Client is the interface of OVAL client.
type Client interface {
DetectUnfixed(db.DB, *models.ScanResult, bool) (int, error)
FillCVEsWithRedHat(db.DB, *models.ScanResult) error
}
// NewClient make Client by family
func NewClient(family string) Client {
switch family {
case cnf.RedHat, cnf.CentOS:
return RedHat{}
case cnf.Debian, cnf.Raspbian:
return Debian{}
case cnf.Windows:
return Microsoft{}
default:
return Pseudo{}
}
}

129
gost/gost_test.go Normal file
View File

@@ -0,0 +1,129 @@
package gost
import (
"reflect"
"testing"
"github.com/future-architect/vuls/models"
gostmodels "github.com/knqyf263/gost/models"
)
func TestSetPackageStates(t *testing.T) {
var tests = []struct {
pkgstats []gostmodels.RedhatPackageState
installed models.Packages
release string
in models.VulnInfo
out models.PackageFixStatuses
}{
//0 one
{
pkgstats: []gostmodels.RedhatPackageState{
{
FixState: "Will not fix",
PackageName: "bouncycastle",
Cpe: "cpe:/o:redhat:enterprise_linux:7",
},
},
installed: models.Packages{
"bouncycastle": models.Package{},
},
release: "7",
in: models.VulnInfo{},
out: []models.PackageFixStatus{
{
Name: "bouncycastle",
FixState: "Will not fix",
NotFixedYet: true,
},
},
},
//1 two
{
pkgstats: []gostmodels.RedhatPackageState{
{
FixState: "Will not fix",
PackageName: "bouncycastle",
Cpe: "cpe:/o:redhat:enterprise_linux:7",
},
{
FixState: "Fix deferred",
PackageName: "pack_a",
Cpe: "cpe:/o:redhat:enterprise_linux:7",
},
// ignore not-installed-package
{
FixState: "Fix deferred",
PackageName: "pack_b",
Cpe: "cpe:/o:redhat:enterprise_linux:7",
},
},
installed: models.Packages{
"bouncycastle": models.Package{},
"pack_a": models.Package{},
},
release: "7",
in: models.VulnInfo{},
out: []models.PackageFixStatus{
{
Name: "bouncycastle",
FixState: "Will not fix",
NotFixedYet: true,
},
{
Name: "pack_a",
FixState: "Fix deferred",
NotFixedYet: true,
},
},
},
//2 ignore affected
{
pkgstats: []gostmodels.RedhatPackageState{
{
FixState: "affected",
PackageName: "bouncycastle",
Cpe: "cpe:/o:redhat:enterprise_linux:7",
},
},
installed: models.Packages{
"bouncycastle": models.Package{},
},
release: "7",
in: models.VulnInfo{
AffectedPackages: models.PackageFixStatuses{},
},
out: models.PackageFixStatuses{},
},
//3 look only the same os release.
{
pkgstats: []gostmodels.RedhatPackageState{
{
FixState: "Will not fix",
PackageName: "bouncycastle",
Cpe: "cpe:/o:redhat:enterprise_linux:6",
},
},
installed: models.Packages{
"bouncycastle": models.Package{},
},
release: "7",
in: models.VulnInfo{
AffectedPackages: models.PackageFixStatuses{},
},
out: models.PackageFixStatuses{},
},
}
r := RedHat{}
for i, tt := range tests {
out := r.mergePackageStates(tt.in, tt.pkgstats, tt.installed, tt.release)
if ok := reflect.DeepEqual(tt.out, out); !ok {
t.Errorf("[%d]\nexpected: %v:%T\n actual: %v:%T\n", i, tt.out, tt.out, out, out)
}
}
}

113
gost/microsoft.go Normal file
View File

@@ -0,0 +1,113 @@
// +build !scanner
package gost
import (
"strings"
"github.com/future-architect/vuls/models"
"github.com/knqyf263/gost/db"
gostmodels "github.com/knqyf263/gost/models"
)
// Microsoft is Gost client for windows
type Microsoft struct {
Base
}
// 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
}
cveIDs := []string{}
for cveID := range r.ScannedCves {
cveIDs = append(cveIDs, cveID)
}
for cveID, msCve := range driver.GetMicrosoftMulti(cveIDs) {
if _, ok := r.ScannedCves[cveID]; !ok {
continue
}
cveCont, mitigations := ms.ConvertToModel(&msCve)
v, _ := r.ScannedCves[cveID]
if v.CveContents == nil {
v.CveContents = models.CveContents{}
}
v.CveContents[models.Microsoft] = *cveCont
v.Mitigations = append(v.Mitigations, mitigations...)
r.ScannedCves[cveID] = v
}
return len(cveIDs), nil
}
// ConvertToModel converts gost model to vuls model
func (ms Microsoft) ConvertToModel(cve *gostmodels.MicrosoftCVE) (*models.CveContent, []models.Mitigation) {
v3score := 0.0
var v3Vector string
for _, scoreSet := range cve.ScoreSets {
if v3score < scoreSet.BaseScore {
v3score = scoreSet.BaseScore
v3Vector = scoreSet.Vector
}
}
var v3Severity string
for _, s := range cve.Severity {
v3Severity = s.Description
}
var refs []models.Reference
for _, r := range cve.References {
if r.AttrType == "External" {
refs = append(refs, models.Reference{Link: r.URL})
}
}
var cwe []string
if 0 < len(cve.CWE) {
cwe = []string{cve.CWE}
}
option := map[string]string{}
if 0 < len(cve.ExploitStatus) {
option["exploit"] = cve.ExploitStatus
}
if 0 < len(cve.Workaround) {
option["workaround"] = cve.Workaround
}
kbids := []string{}
for _, kbid := range cve.KBIDs {
kbids = append(kbids, kbid.KBID)
}
if 0 < len(kbids) {
option["kbids"] = strings.Join(kbids, ",")
}
vendorURL := "https://msrc.microsoft.com/update-guide/vulnerability/" + cve.CveID
mitigations := []models.Mitigation{}
if cve.Mitigation != "" {
mitigations = []models.Mitigation{
{
CveContentType: models.Microsoft,
Mitigation: cve.Mitigation,
URL: vendorURL,
},
}
}
return &models.CveContent{
Type: models.Microsoft,
CveID: cve.CveID,
Title: cve.Title,
Summary: cve.Description,
Cvss3Score: v3score,
Cvss3Vector: v3Vector,
Cvss3Severity: v3Severity,
References: refs,
CweIDs: cwe,
Published: cve.PublishDate,
LastModified: cve.LastUpdateDate,
SourceLink: vendorURL,
Optional: option,
}, mitigations
}

18
gost/pseudo.go Normal file
View File

@@ -0,0 +1,18 @@
// +build !scanner
package gost
import (
"github.com/future-architect/vuls/models"
"github.com/knqyf263/gost/db"
)
// 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
}

259
gost/redhat.go Normal file
View File

@@ -0,0 +1,259 @@
// +build !scanner
package gost
import (
"encoding/json"
"strconv"
"strings"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/knqyf263/gost/db"
gostmodels "github.com/knqyf263/gost/models"
)
// RedHat is Gost client for RedHat family linux
type RedHat struct {
Base
}
// 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.detectUnfixed(driver, r, ignoreWillNotFix)
}
func (red RedHat) detectUnfixed(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")
responses, err := getAllUnfixedCvesViaHTTP(r, prefix)
if err != nil {
return 0, err
}
for _, res := range responses {
// CVE-ID: RedhatCVE
cves := map[string]gostmodels.RedhatCVE{}
if err := json.Unmarshal([]byte(res.json), &cves); err != nil {
return 0, err
}
for _, cve := range cves {
if newly := red.setUnfixedCveToScanResult(&cve, r); newly {
nCVEs++
}
}
}
} else {
if driver == nil {
return 0, nil
}
for _, pack := range r.Packages {
// CVE-ID: RedhatCVE
cves := driver.GetUnfixedCvesRedhat(major(r.Release), pack.Name, ignoreWillNotFix)
for _, cve := range cves {
if newly := red.setUnfixedCveToScanResult(&cve, r); newly {
nCVEs++
}
}
}
}
return nCVEs, nil
}
func (red RedHat) fillCvesWithRedHatAPI(driver db.DB, r *models.ScanResult) error {
cveIDs := []string{}
for cveID, vuln := range r.ScannedCves {
if _, ok := vuln.CveContents[models.RedHatAPI]; ok {
continue
}
cveIDs = append(cveIDs, cveID)
}
if config.Conf.Gost.IsFetchViaHTTP() {
prefix, _ := util.URLPathJoin(config.Conf.Gost.URL,
"redhat", "cves")
responses, err := getCvesViaHTTP(cveIDs, prefix)
if err != nil {
return err
}
for _, res := range responses {
redCve := gostmodels.RedhatCVE{}
if err := json.Unmarshal([]byte(res.json), &redCve); err != nil {
return err
}
if redCve.ID == 0 {
continue
}
red.setFixedCveToScanResult(&redCve, r)
}
} else {
if driver == nil {
return nil
}
for _, redCve := range driver.GetRedhatMulti(cveIDs) {
if len(redCve.Name) == 0 {
continue
}
red.setFixedCveToScanResult(&redCve, r)
}
}
return nil
}
func (red RedHat) setFixedCveToScanResult(cve *gostmodels.RedhatCVE, r *models.ScanResult) {
cveCont, mitigations := red.ConvertToModel(cve)
v, ok := r.ScannedCves[cveCont.CveID]
if ok {
if v.CveContents == nil {
v.CveContents = models.NewCveContents(*cveCont)
} else {
v.CveContents[models.RedHatAPI] = *cveCont
}
} else {
v = models.VulnInfo{
CveID: cveCont.CveID,
CveContents: models.NewCveContents(*cveCont),
Confidences: models.Confidences{models.RedHatAPIMatch},
}
}
v.Mitigations = append(v.Mitigations, mitigations...)
r.ScannedCves[cveCont.CveID] = v
}
func (red RedHat) setUnfixedCveToScanResult(cve *gostmodels.RedhatCVE, r *models.ScanResult) (newly bool) {
cveCont, mitigations := red.ConvertToModel(cve)
v, ok := r.ScannedCves[cve.Name]
if ok {
if v.CveContents == nil {
v.CveContents = models.NewCveContents(*cveCont)
} else {
v.CveContents[models.RedHatAPI] = *cveCont
}
} else {
v = models.VulnInfo{
CveID: cveCont.CveID,
CveContents: models.NewCveContents(*cveCont),
Confidences: models.Confidences{models.RedHatAPIMatch},
}
newly = true
}
v.Mitigations = append(v.Mitigations, mitigations...)
pkgStats := red.mergePackageStates(v,
cve.PackageState, r.Packages, r.Release)
if 0 < len(pkgStats) {
v.AffectedPackages = pkgStats
r.ScannedCves[cve.Name] = v
}
return
}
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 !=
"cpe:/o:redhat:enterprise_linux:"+major(release) {
return
}
if !(pstate.FixState == "Will not fix" ||
pstate.FixState == "Fix deferred" ||
pstate.FixState == "Affected") {
return
}
if _, ok := installed[pstate.PackageName]; !ok {
return
}
notFixedYet := false
switch pstate.FixState {
case "Will not fix", "Fix deferred", "Affected":
notFixedYet = true
}
pkgStats = pkgStats.Store(models.PackageFixStatus{
Name: pstate.PackageName,
FixState: pstate.FixState,
NotFixedYet: notFixedYet,
})
}
return
}
func (red RedHat) parseCwe(str string) (cwes []string) {
if str != "" {
s := strings.Replace(str, "(", "|", -1)
s = strings.Replace(s, ")", "|", -1)
s = strings.Replace(s, "->", "|", -1)
for _, s := range strings.Split(s, "|") {
if s != "" {
cwes = append(cwes, s)
}
}
}
return
}
// ConvertToModel converts gost model to vuls model
func (red RedHat) ConvertToModel(cve *gostmodels.RedhatCVE) (*models.CveContent, []models.Mitigation) {
cwes := red.parseCwe(cve.Cwe)
details := []string{}
for _, detail := range cve.Details {
details = append(details, detail.Detail)
}
v2score := 0.0
if cve.Cvss.CvssBaseScore != "" {
v2score, _ = strconv.ParseFloat(cve.Cvss.CvssBaseScore, 64)
}
v2severity := ""
if v2score != 0 {
v2severity = cve.ThreatSeverity
}
v3score := 0.0
if cve.Cvss3.Cvss3BaseScore != "" {
v3score, _ = strconv.ParseFloat(cve.Cvss3.Cvss3BaseScore, 64)
}
v3severity := ""
if v3score != 0 {
v3severity = cve.ThreatSeverity
}
refs := []models.Reference{}
for _, r := range cve.References {
refs = append(refs, models.Reference{Link: r.Reference})
}
vendorURL := "https://access.redhat.com/security/cve/" + cve.Name
mitigations := []models.Mitigation{}
if cve.Mitigation != "" {
mitigations = []models.Mitigation{
{
CveContentType: models.RedHatAPI,
Mitigation: cve.Mitigation,
URL: vendorURL,
},
}
}
return &models.CveContent{
Type: models.RedHatAPI,
CveID: cve.Name,
Title: cve.Bugzilla.Description,
Summary: strings.Join(details, "\n"),
Cvss2Score: v2score,
Cvss2Vector: cve.Cvss.CvssScoringVector,
Cvss2Severity: v2severity,
Cvss3Score: v3score,
Cvss3Vector: cve.Cvss3.Cvss3ScoringVector,
Cvss3Severity: v3severity,
References: refs,
CweIDs: cwes,
Published: cve.PublicDate,
SourceLink: vendorURL,
}, mitigations
}

37
gost/redhat_test.go Normal file
View File

@@ -0,0 +1,37 @@
package gost
import (
"reflect"
"sort"
"testing"
)
func TestParseCwe(t *testing.T) {
var tests = []struct {
in string
out []string
}{
{
in: "CWE-665->(CWE-200|CWE-89)",
out: []string{"CWE-665", "CWE-200", "CWE-89"},
},
{
in: "CWE-841->CWE-770->CWE-454",
out: []string{"CWE-841", "CWE-770", "CWE-454"},
},
{
in: "(CWE-122|CWE-125)",
out: []string{"CWE-122", "CWE-125"},
},
}
r := RedHat{}
for i, tt := range tests {
out := r.parseCwe(tt.in)
sort.Strings(out)
sort.Strings(tt.out)
if !reflect.DeepEqual(tt.out, out) {
t.Errorf("[%d]expected: %s, actual: %s", i, tt.out, out)
}
}
}

188
gost/util.go Normal file
View File

@@ -0,0 +1,188 @@
package gost
import (
"net/http"
"strings"
"time"
"github.com/cenkalti/backoff"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
"github.com/parnurzeal/gorequest"
"golang.org/x/xerrors"
)
type response struct {
request request
json string
}
func getCvesViaHTTP(cveIDs []string, urlPrefix string) (
responses []response, err error) {
nReq := len(cveIDs)
reqChan := make(chan request, nReq)
resChan := make(chan response, nReq)
errChan := make(chan error, nReq)
defer close(reqChan)
defer close(resChan)
defer close(errChan)
go func() {
for _, cveID := range cveIDs {
reqChan <- request{
cveID: cveID,
}
}
}()
concurrency := 10
tasks := util.GenWorkers(concurrency)
for i := 0; i < nReq; i++ {
tasks <- func() {
select {
case req := <-reqChan:
url, err := util.URLPathJoin(
urlPrefix,
req.cveID,
)
if err != nil {
errChan <- err
} else {
util.Log.Debugf("HTTP Request to %s", url)
httpGet(url, req, resChan, errChan)
}
}
}
}
timeout := time.After(2 * 60 * time.Second)
var errs []error
for i := 0; i < nReq; i++ {
select {
case res := <-resChan:
responses = append(responses, res)
case err := <-errChan:
errs = append(errs, err)
case <-timeout:
return nil, xerrors.New("Timeout Fetching OVAL")
}
}
if len(errs) != 0 {
return nil, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
}
return
}
type request struct {
osMajorVersion string
packName string
isSrcPack bool
cveID string
}
func getAllUnfixedCvesViaHTTP(r *models.ScanResult, urlPrefix string) (
responses []response, err error) {
nReq := len(r.Packages) + len(r.SrcPackages)
reqChan := make(chan request, nReq)
resChan := make(chan response, nReq)
errChan := make(chan error, nReq)
defer close(reqChan)
defer close(resChan)
defer close(errChan)
go func() {
for _, pack := range r.Packages {
reqChan <- request{
osMajorVersion: major(r.Release),
packName: pack.Name,
isSrcPack: false,
}
}
for _, pack := range r.SrcPackages {
reqChan <- request{
osMajorVersion: major(r.Release),
packName: pack.Name,
isSrcPack: true,
}
}
}()
concurrency := 10
tasks := util.GenWorkers(concurrency)
for i := 0; i < nReq; i++ {
tasks <- func() {
select {
case req := <-reqChan:
url, err := util.URLPathJoin(
urlPrefix,
req.packName,
"unfixed-cves",
)
if err != nil {
errChan <- err
} else {
util.Log.Debugf("HTTP Request to %s", url)
httpGet(url, req, resChan, errChan)
}
}
}
}
timeout := time.After(2 * 60 * time.Second)
var errs []error
for i := 0; i < nReq; i++ {
select {
case res := <-resChan:
responses = append(responses, res)
case err := <-errChan:
errs = append(errs, err)
case <-timeout:
return nil, xerrors.New("Timeout Fetching OVAL")
}
}
if len(errs) != 0 {
return nil, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
}
return
}
func httpGet(url string, req request, resChan chan<- response, errChan chan<- error) {
var body string
var errs []error
var resp *http.Response
count, retryMax := 0, 3
f := func() (err error) {
// resp, body, errs = gorequest.New().SetDebug(config.Conf.Debug).Get(url).End()
resp, body, errs = gorequest.New().Timeout(10 * time.Second).Get(url).End()
if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
count++
if count == retryMax {
return nil
}
return xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %s", url, resp, errs)
}
return nil
}
notify := func(err error, t time.Duration) {
util.Log.Warnf("Failed to HTTP GET. retrying in %s seconds. err: %s", t, err)
}
err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
if err != nil {
errChan <- xerrors.Errorf("HTTP Error %w", err)
return
}
if count == retryMax {
errChan <- xerrors.New("Retry count exceeded")
return
}
resChan <- response{
request: req,
json: body,
}
}
func major(osVer string) (majorVersion string) {
return strings.Split(osVer, ".")[0]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 KiB

BIN
img/vuls-abstract.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -1,417 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.14.2-->
<key attr.name="Description" attr.type="string" for="graph" id="d0"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key for="graphml" id="d7" yfiles.type="resources"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d0"/>
<node id="n0">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="56.0" width="268.0" x="309.6849206349206" y="0.0"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="83.482421875" x="92.2587890625" y="18.93359375">Detect the OS<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="0.1619001116071429" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n1">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.decision">
<y:Geometry height="40.0" width="80.0" x="403.6849206349206" y="206.44247787610618"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="38.0" y="18.0">
<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n2">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="90.44247787610618" width="268.0" x="309.6849206349206" y="86.0"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="60.53125" modelName="custom" textColor="#000000" visible="true" width="170.763671875" x="48.61816406250006" y="14.95561393805309">Get installed packages
Debian/Ubuntu: dpkg-query
Amazon/RHEL/CentOS: rpm
FreeBSD: pkg<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="2.220446049250313E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n3">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="56.0" width="268.0" x="10.0" y="287.8409153761062"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="260.83984375" x="3.580078125" y="11.8671875">Check upgradable packages
Debian/Ubuntu: apt-get upgrade --dry-run<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n4">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.loopLimit">
<y:Geometry height="51.10998735777497" width="137.19216182048035" x="75.40391908975982" y="376.28592169721867"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="131.751953125" x="2.7201043477401754" y="9.422181178887513">foreach
upgradable packages<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="5.551115123125783E-16" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n5">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="56.0" width="268.0" x="10.0" y="459.8409153761062"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="213.619140625" x="27.1904296875" y="11.8671875">Parse changelog and get CVE IDs
Debian/Ubuntu: aptitude changelog<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n6">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.loopLimitEnd">
<y:Geometry height="50.0" width="137.0" x="75.5" y="545.8409153761062"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="55.24609375" x="40.876953125" y="15.93359375">end loop<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n7">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="625.8409153761062"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="194.904296875" x="36.5478515625" y="18.93359375">Select the CVE detail information<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="0.1619001116071429" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n8">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="287.8409153761062"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="46.3984375" modelName="custom" textColor="#000000" visible="true" width="232.744140625" x="17.6279296875" y="4.80078125">Get CVE IDs by using package manager
Amazon/RHEL: yum plugin security
FreeBSD: pkg audit<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n9">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.dataBase">
<y:Geometry height="65.22882427307195" width="136.83944374209864" x="411.5802781289507" y="687.385587863464"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="117.970703125" x="9.434370308549205" y="23.548005886535975">CVE DB (NVD / JVN)<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="-8.326672684688674E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n10">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="716.4553275126422"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="152.634765625" x="57.6826171875" y="11.8671875">Write results to JSON files
Reporting<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n11">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="56.0" width="268.0" x="309.6849206349206" y="287.8409153761062"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" textColor="#000000" visible="true" width="293.06640625" x="-12.533203124999943" y="11.8671875">Get all changelogs of updatable packages at once
CentOS: yum update --changelog<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="2.220446049250313E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<node id="n12">
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="56.0" width="268.0" x="309.6849206349206" y="373.8409153761062"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="205.52734375" x="31.236328125000057" y="18.93359375">Parse changelogs and get CVE IDs <y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="2.220446049250313E-16" nodeRatioY="0.1619001116071429" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
<edge id="e0" source="n2" target="n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="45.22123893805309" tx="0.0" ty="-20.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n1" target="n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-40.0" sy="0.0" tx="0.0" ty="-28.0">
<y:Point x="144.0" y="226.44247787610618"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="46.697265625" x="-56.79057374984495" y="-34.26562148912808">Debian
Ubuntu<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="1.9999999999998863" distanceToCenter="false" position="right" ratio="0.02215389573439544" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n3" target="n4">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="28.0" tx="0.0" ty="-25.554993678887485"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n4" target="n5">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="25.554993678887485" tx="0.0" ty="-28.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n5" target="n6">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="28.0" tx="0.0" ty="-25.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n6" target="n7">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="68.5" sy="0.0" tx="0.0" ty="-28.0">
<y:Point x="743.3698412698412" y="570.8409153761062"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e6" source="n1" target="n8">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="40.0" sy="0.0" tx="0.0" ty="-28.0">
<y:Point x="743.3698412698412" y="226.44247787610618"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="46.3984375" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="51.806640625" x="10.125014629061297" y="-48.39843398912805">Amazon
RHEL
FreeBSD<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="1.9999999999998863" distanceToCenter="false" position="left" ratio="0.022401276994204813" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e7" source="n8" target="n7">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="28.0" tx="0.0" ty="-28.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e8" source="n0" target="n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="28.0" tx="0.0" ty="-45.22123893805309"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e9" source="n7" target="n10">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="28.0" tx="0.0" ty="-28.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e10" source="n7" target="n9">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-134.01566143419018" sy="6.159084623893818" tx="0.0" ty="-29.333162136535975">
<y:Point x="480.0" y="660.0"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e11" source="n1" target="n11">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="20.0" tx="0.0" ty="-28.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="46.708984375" x="-53.35447755843876" y="11.632816010871807">CentOS<y:LabelModel>
<y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="right" ratio="0.5" segment="0"/>
</y:ModelParameter>
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
</y:EdgeLabel>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e12" source="n11" target="n12">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="28.0" tx="0.0" ty="-28.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e13" source="n12" target="n7">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="134.00000000000006" sy="0.0" tx="0.0" ty="-28.0">
<y:Point x="743.3698412698412" y="401.8409153761062"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d7">
<y:Resources/>
</data>
</graphml>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

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