feat(detector): add known exploited vulnerabilities (#1331)
* feat(kevuln): add known exploited vulnerabilities * chore: transfer repository owner * feat: show CISA on top of CERT * chore: rename var * chore: rename var * chore: fix review * chore: fix message
This commit is contained in:
@@ -87,6 +87,9 @@ Vuls is a tool created to solve the problems listed above. It has the following
|
||||
- [US-CERT](https://www.us-cert.gov/ncas/alerts)
|
||||
- [JPCERT](http://www.jpcert.or.jp/at/2019.html)
|
||||
|
||||
- CISA(Cybersecurity & Infrastructure Security Agency)
|
||||
- [Known Exploited Vulnerabilities Catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)
|
||||
|
||||
- Libraries
|
||||
- [Node.js Security Working Group](https://github.com/nodejs/security-wg)
|
||||
- [Ruby Advisory Database](https://github.com/rubysec/ruby-advisory-db)
|
||||
|
||||
@@ -41,6 +41,7 @@ type Config struct {
|
||||
Gost GostConf `json:"gost,omitempty"`
|
||||
Exploit ExploitConf `json:"exploit,omitempty"`
|
||||
Metasploit MetasploitConf `json:"metasploit,omitempty"`
|
||||
KEVuln KEVulnConf `json:"kevuln,omitempty"`
|
||||
|
||||
Slack SlackConf `json:"-"`
|
||||
EMail SMTPConf `json:"-"`
|
||||
@@ -176,6 +177,7 @@ func (c *Config) ValidateOnReport() bool {
|
||||
&Conf.Gost,
|
||||
&Conf.Exploit,
|
||||
&Conf.Metasploit,
|
||||
&Conf.KEVuln,
|
||||
} {
|
||||
if err := cnf.Validate(); err != nil {
|
||||
errs = append(errs, xerrors.Errorf("Failed to validate %s: %+v", cnf.GetName(), err))
|
||||
|
||||
@@ -27,6 +27,7 @@ func (c TOMLLoader) Load(pathToToml, _ string) error {
|
||||
&Conf.Gost,
|
||||
&Conf.Exploit,
|
||||
&Conf.Metasploit,
|
||||
&Conf.KEVuln,
|
||||
} {
|
||||
cnf.Init()
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ func (cnf *GostConf) Init() {
|
||||
cnf.DebugSQL = Conf.DebugSQL
|
||||
}
|
||||
|
||||
// MetasploitConf is gost go-metasploitdb
|
||||
// MetasploitConf is go-msfdb config
|
||||
type MetasploitConf struct {
|
||||
VulnDict
|
||||
}
|
||||
@@ -274,3 +274,30 @@ func (cnf *MetasploitConf) Init() {
|
||||
cnf.setDefault("go-msfdb.sqlite3")
|
||||
cnf.DebugSQL = Conf.DebugSQL
|
||||
}
|
||||
|
||||
// KEVulnConf is go-kev config
|
||||
type KEVulnConf struct {
|
||||
VulnDict
|
||||
}
|
||||
|
||||
const kevulnDBType = "KEVULN_TYPE"
|
||||
const kevulnDBURL = "KEVULN_URL"
|
||||
const kevulnDBPATH = "KEVULN_SQLITE3_PATH"
|
||||
|
||||
// Init set options with the following priority.
|
||||
// 1. Environment variable
|
||||
// 2. config.toml
|
||||
func (cnf *KEVulnConf) Init() {
|
||||
cnf.Name = "kevuln"
|
||||
if os.Getenv(kevulnDBType) != "" {
|
||||
cnf.Type = os.Getenv(kevulnDBType)
|
||||
}
|
||||
if os.Getenv(kevulnDBURL) != "" {
|
||||
cnf.URL = os.Getenv(kevulnDBURL)
|
||||
}
|
||||
if os.Getenv(kevulnDBPATH) != "" {
|
||||
cnf.SQLite3Path = os.Getenv(kevulnDBPATH)
|
||||
}
|
||||
cnf.setDefault("go-kev.sqlite3")
|
||||
cnf.DebugSQL = Conf.DebugSQL
|
||||
}
|
||||
|
||||
@@ -111,6 +111,10 @@ func Detect(rs []models.ScanResult, dir string) ([]models.ScanResult, error) {
|
||||
}
|
||||
logging.Log.Infof("%s: %d exploits are detected", r.FormatServerName(), nMetasploitCve)
|
||||
|
||||
if err := FillWithKEVuln(&r, config.Conf.KEVuln); err != nil {
|
||||
return nil, xerrors.Errorf("Failed to fill with Known Exploited Vulnerabilities: %w", err)
|
||||
}
|
||||
|
||||
FillCweDict(&r)
|
||||
|
||||
r.ReportedBy, _ = os.Hostname()
|
||||
@@ -361,20 +365,20 @@ func FillCvesWithNvdJvn(r *models.ScanResult, cnf config.GoCveDictConf, logOpts
|
||||
func fillCertAlerts(cvedetail *cvemodels.CveDetail) (dict models.AlertDict) {
|
||||
for _, nvd := range cvedetail.Nvds {
|
||||
for _, cert := range nvd.Certs {
|
||||
dict.En = append(dict.En, models.Alert{
|
||||
dict.USCERT = append(dict.USCERT, models.Alert{
|
||||
URL: cert.Link,
|
||||
Title: cert.Title,
|
||||
Team: "us",
|
||||
Team: "uscert",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, jvn := range cvedetail.Jvns {
|
||||
for _, cert := range jvn.Certs {
|
||||
dict.Ja = append(dict.Ja, models.Alert{
|
||||
dict.JPCERT = append(dict.JPCERT, models.Alert{
|
||||
URL: cert.Link,
|
||||
Title: cert.Title,
|
||||
Team: "jp",
|
||||
Team: "jpcert",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
214
detector/kevuln.go
Normal file
214
detector/kevuln.go
Normal file
@@ -0,0 +1,214 @@
|
||||
//go:build !scanner
|
||||
// +build !scanner
|
||||
|
||||
package detector
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff"
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/logging"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/util"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
kevulndb "github.com/vulsio/go-kev/db"
|
||||
kevulnmodels "github.com/vulsio/go-kev/models"
|
||||
)
|
||||
|
||||
// FillWithKEVuln :
|
||||
func FillWithKEVuln(r *models.ScanResult, cnf config.KEVulnConf) error {
|
||||
if cnf.IsFetchViaHTTP() {
|
||||
var cveIDs []string
|
||||
for cveID := range r.ScannedCves {
|
||||
cveIDs = append(cveIDs, cveID)
|
||||
}
|
||||
prefix, err := util.URLPathJoin(cnf.GetURL(), "cves")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
responses, err := getKEVulnsViaHTTP(cveIDs, prefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, res := range responses {
|
||||
kevulns := []kevulnmodels.KEVuln{}
|
||||
if err := json.Unmarshal([]byte(res.json), &kevulns); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
alerts := []models.Alert{}
|
||||
if len(kevulns) > 0 {
|
||||
alerts = append(alerts, models.Alert{
|
||||
Title: "Known Exploited Vulnerabilities Catalog",
|
||||
URL: "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
|
||||
Team: "cisa",
|
||||
})
|
||||
}
|
||||
|
||||
v, ok := r.ScannedCves[res.request.cveID]
|
||||
if ok {
|
||||
v.AlertDict.CISA = alerts
|
||||
}
|
||||
r.ScannedCves[res.request.cveID] = v
|
||||
}
|
||||
} else {
|
||||
driver, locked, err := newKEVulnDB(&cnf)
|
||||
if locked {
|
||||
return xerrors.Errorf("SQLite3 is locked: %s", cnf.GetSQLite3Path())
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := driver.CloseDB(); err != nil {
|
||||
logging.Log.Errorf("Failed to close DB. err: %+v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
for cveID, vuln := range r.ScannedCves {
|
||||
if cveID == "" {
|
||||
continue
|
||||
}
|
||||
kevulns, err := driver.GetKEVulnByCveID(cveID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(kevulns) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
alerts := []models.Alert{}
|
||||
if len(kevulns) > 0 {
|
||||
alerts = append(alerts, models.Alert{
|
||||
Title: "Known Exploited Vulnerabilities Catalog",
|
||||
URL: "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
|
||||
Team: "cisa",
|
||||
})
|
||||
}
|
||||
|
||||
vuln.AlertDict.CISA = alerts
|
||||
r.ScannedCves[cveID] = vuln
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type kevulnResponse struct {
|
||||
request kevulnRequest
|
||||
json string
|
||||
}
|
||||
|
||||
func getKEVulnsViaHTTP(cveIDs []string, urlPrefix string) (
|
||||
responses []kevulnResponse, err error) {
|
||||
nReq := len(cveIDs)
|
||||
reqChan := make(chan kevulnRequest, nReq)
|
||||
resChan := make(chan kevulnResponse, nReq)
|
||||
errChan := make(chan error, nReq)
|
||||
defer close(reqChan)
|
||||
defer close(resChan)
|
||||
defer close(errChan)
|
||||
|
||||
go func() {
|
||||
for _, cveID := range cveIDs {
|
||||
reqChan <- kevulnRequest{
|
||||
cveID: cveID,
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
concurrency := 10
|
||||
tasks := util.GenWorkers(concurrency)
|
||||
for i := 0; i < nReq; i++ {
|
||||
tasks <- func() {
|
||||
req := <-reqChan
|
||||
url, err := util.URLPathJoin(
|
||||
urlPrefix,
|
||||
req.cveID,
|
||||
)
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
} else {
|
||||
logging.Log.Debugf("HTTP Request to %s", url)
|
||||
httpGetKEVuln(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 KEVuln")
|
||||
}
|
||||
}
|
||||
if len(errs) != 0 {
|
||||
return nil, xerrors.Errorf("Failed to fetch KEVuln. err: %w", errs)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type kevulnRequest struct {
|
||||
cveID string
|
||||
}
|
||||
|
||||
func httpGetKEVuln(url string, req kevulnRequest, resChan chan<- kevulnResponse, 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: %+v", url, resp, errs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
notify := func(err error, t time.Duration) {
|
||||
logging.Log.Warnf("Failed to HTTP GET. retrying in %s seconds. err: %+v", 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 <- kevulnResponse{
|
||||
request: req,
|
||||
json: body,
|
||||
}
|
||||
}
|
||||
|
||||
func newKEVulnDB(cnf config.VulnDictInterface) (driver kevulndb.DB, locked bool, err error) {
|
||||
if cnf.IsFetchViaHTTP() {
|
||||
return nil, false, nil
|
||||
}
|
||||
path := cnf.GetURL()
|
||||
if cnf.GetType() == "sqlite3" {
|
||||
path = cnf.GetSQLite3Path()
|
||||
}
|
||||
if driver, locked, err = kevulndb.NewDB(cnf.GetType(), path, cnf.GetDebugSQL(), kevulndb.Option{}); err != nil {
|
||||
if locked {
|
||||
return nil, true, xerrors.Errorf("kevulnDB is locked. err: %w", err)
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
return driver, false, nil
|
||||
}
|
||||
15
go.mod
15
go.mod
@@ -53,6 +53,7 @@ require (
|
||||
github.com/spf13/cobra v1.2.1
|
||||
github.com/vulsio/go-cve-dictionary v0.8.2-0.20211028094424-0a854f8e8f85
|
||||
github.com/vulsio/go-exploitdb v0.4.2-0.20211028071949-1ebf9c4f6c4d
|
||||
github.com/vulsio/go-kev v0.0.1
|
||||
github.com/vulsio/go-msfdb v0.2.1-0.20211028071756-4a9759bd9f14
|
||||
github.com/vulsio/gost v0.4.1-0.20211028071837-7ad032a6ffa8
|
||||
github.com/vulsio/goval-dictionary v0.6.1-0.20211028072035-e85e14b91ccc
|
||||
@@ -62,10 +63,10 @@ require (
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
||||
gopkg.in/ini.v1 v1.63.2 // indirect
|
||||
gorm.io/driver/mysql v1.1.2 // indirect
|
||||
gorm.io/driver/postgres v1.1.2 // indirect
|
||||
gorm.io/driver/sqlite v1.1.6 // indirect
|
||||
gopkg.in/ini.v1 v1.64.0 // indirect
|
||||
gorm.io/driver/mysql v1.2.0 // indirect
|
||||
gorm.io/driver/postgres v1.2.2 // indirect
|
||||
gorm.io/driver/sqlite v1.2.4 // indirect
|
||||
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009
|
||||
)
|
||||
|
||||
@@ -118,7 +119,7 @@ require (
|
||||
github.com/jackc/pgtype v1.8.1 // indirect
|
||||
github.com/jackc/pgx/v4 v4.13.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.2 // indirect
|
||||
github.com/jinzhu/now v1.1.3 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08 // indirect
|
||||
@@ -142,13 +143,13 @@ require (
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.19.1 // indirect
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
gorm.io/gorm v1.21.16 // indirect
|
||||
gorm.io/gorm v1.22.3 // indirect
|
||||
moul.io/http2curl v1.0.0 // indirect
|
||||
)
|
||||
|
||||
37
go.sum
37
go.sum
@@ -524,8 +524,9 @@ github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkg
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/elazarl/goproxy v0.0.0-20210110162100-a92cc753f88e h1:/cwV7t2xezilMljIftb7WlFtzGANRCnoOhPjtl2ifcs=
|
||||
github.com/elazarl/goproxy v0.0.0-20210110162100-a92cc753f88e/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/elazarl/goproxy v0.0.0-20211114080932-d06c3be7c11b h1:1XqENn2YoYZd6w3Awx+7oa+aR87DFIZJFLF2n1IojA0=
|
||||
github.com/elazarl/goproxy v0.0.0-20211114080932-d06c3be7c11b/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
|
||||
@@ -644,6 +645,7 @@ github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2
|
||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/gocarina/gocsv v0.0.0-20201208093247-67c824bc04d4/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
|
||||
github.com/gocarina/gocsv v0.0.0-20211020200912-82fc2684cc48/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
|
||||
github.com/goccy/go-yaml v1.8.1/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y=
|
||||
github.com/goccy/go-yaml v1.8.2 h1:gDYrSN12XK/wQTFjxWIgcIqjNCV/Zb5V09M7cq+dbCs=
|
||||
github.com/goccy/go-yaml v1.8.2/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y=
|
||||
@@ -1018,8 +1020,9 @@ github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:x
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
|
||||
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.3 h1:PlHq1bSCSZL9K0wUhbm2pGLoTWs2GwVhsP6emvGV/ZI=
|
||||
github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
|
||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
@@ -1108,6 +1111,7 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+
|
||||
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
|
||||
github.com/labstack/echo/v4 v4.1.17/go.mod h1:Tn2yRQL/UclUalpb5rPdXDevbkJ+lp/2svdyFBg6CHQ=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/liamg/clinch v1.5.6/go.mod h1:IXM+nLBuZ5sOQAYYf9+G51nkaA0WY9cszxE5nPXexhE=
|
||||
github.com/liamg/gifwrap v0.0.6/go.mod h1:oW1r2vIWLYyxW+U0io7YbpPSDIJ79FTlZ+hPnXFLW6E=
|
||||
@@ -1178,7 +1182,6 @@ github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lL
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
||||
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
|
||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
||||
@@ -1613,6 +1616,8 @@ github.com/vulsio/go-cve-dictionary v0.8.2-0.20211028094424-0a854f8e8f85 h1:nEha
|
||||
github.com/vulsio/go-cve-dictionary v0.8.2-0.20211028094424-0a854f8e8f85/go.mod h1:Ii9TEH35giMSWJM2FwGm1PCPxuBKrbaYhDun2PM7ERo=
|
||||
github.com/vulsio/go-exploitdb v0.4.2-0.20211028071949-1ebf9c4f6c4d h1:iMXVmz2f1Phor1TAmRKx324mDOuXst0GXGEboVRgysg=
|
||||
github.com/vulsio/go-exploitdb v0.4.2-0.20211028071949-1ebf9c4f6c4d/go.mod h1:2R5gwySHHjF3DoEt11xqnIWEJLS93CLfCUDPwYH+VdM=
|
||||
github.com/vulsio/go-kev v0.0.1 h1:FRAnSdrF4fgqBoeWnctydazLUMBJW9HWzwki+iAu5lw=
|
||||
github.com/vulsio/go-kev v0.0.1/go.mod h1:NrXTTkGG83ZYl7ypHHLqqzx6HvVkWH37qCizU5UoCS8=
|
||||
github.com/vulsio/go-msfdb v0.2.1-0.20211028071756-4a9759bd9f14 h1:2uYZw2gQ0kymwerTS1FXZbNgptnlye+SB7o3QlLDIBo=
|
||||
github.com/vulsio/go-msfdb v0.2.1-0.20211028071756-4a9759bd9f14/go.mod h1:NGdcwWxCK/ES8vZ/crzREqI69S5gH1MivCpSp1pa2Rc=
|
||||
github.com/vulsio/gost v0.4.1-0.20211028071837-7ad032a6ffa8 h1:jqsECpLRp1EAXGOdhPxHzqYjWP5l980GjJ8s/AUYH/4=
|
||||
@@ -2013,8 +2018,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
|
||||
@@ -2330,8 +2335,9 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c=
|
||||
gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.64.0 h1:Mj2zXEXcNb5joEiSA0zc3HZpTst/iyjNiR4CN8tDzOg=
|
||||
gopkg.in/ini.v1 v1.64.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
@@ -2362,24 +2368,23 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gorm.io/driver/mysql v1.0.6/go.mod h1:KdrTanmfLPPyAOeYGyG+UpDys7/7eeWT1zCq+oekYnU=
|
||||
gorm.io/driver/mysql v1.1.0/go.mod h1:KdrTanmfLPPyAOeYGyG+UpDys7/7eeWT1zCq+oekYnU=
|
||||
gorm.io/driver/mysql v1.1.1/go.mod h1:KdrTanmfLPPyAOeYGyG+UpDys7/7eeWT1zCq+oekYnU=
|
||||
gorm.io/driver/mysql v1.1.2 h1:OofcyE2lga734MxwcCW9uB4mWNXMr50uaGRVwQL2B0M=
|
||||
gorm.io/driver/mysql v1.1.2/go.mod h1:4P/X9vSc3WTrhTLZ259cpFd6xKNYiSSdSZngkSBGIMM=
|
||||
gorm.io/driver/mysql v1.2.0 h1:l8+9VwjjyzEkw0PNPBOr2JHhLOGVk7XEnl5hk42bcvs=
|
||||
gorm.io/driver/mysql v1.2.0/go.mod h1:4RQmTg4okPghdt+kbe6e1bTXIQp7Ny1NnBn/3Z6ghjk=
|
||||
gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg=
|
||||
gorm.io/driver/postgres v1.1.0/go.mod h1:hXQIwafeRjJvUm+OMxcFWyswJ/vevcpPLlGocwAwuqw=
|
||||
gorm.io/driver/postgres v1.1.2 h1:Amy3hCvLqM+/ICzjCnQr8wKFLVJTeOTdlMT7kCP+J1Q=
|
||||
gorm.io/driver/postgres v1.1.2/go.mod h1:/AGV0zvqF3mt9ZtzLzQmXWQ/5vr+1V1TyHZGZVjzmwI=
|
||||
gorm.io/driver/postgres v1.2.2 h1:Ka9W6feOU+rPM9m007eYLMD4QoZuYGBnQ3Jp0faGSwg=
|
||||
gorm.io/driver/postgres v1.2.2/go.mod h1:Ik3tK+a3FMp8ORZl29v4b3M0RsgXsaeMXh9s9eVMXco=
|
||||
gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw=
|
||||
gorm.io/driver/sqlite v1.1.6 h1:p3U8WXkVFTOLPED4JjrZExfndjOtya3db8w9/vEMNyI=
|
||||
gorm.io/driver/sqlite v1.1.6/go.mod h1:W8LmC/6UvVbHKah0+QOC7Ja66EaZXHwUTjgXY8YNWX8=
|
||||
gorm.io/driver/sqlite v1.2.4 h1:jx16ESo1WzNjgBJNSbhEDoMKJnlhkU8BuBR2C0GC7D8=
|
||||
gorm.io/driver/sqlite v1.2.4/go.mod h1:n8/CTEIEmo7lKrehQI4pd+rz6O514tMkBeCAR5UTXLs=
|
||||
gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
|
||||
gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
|
||||
gorm.io/gorm v1.21.9/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.21.10/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.21.11/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.21.12/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.21.16 h1:YBIQLtP5PLfZQz59qfrq7xbrK7KWQ+JsXXCH/THlMqs=
|
||||
gorm.io/gorm v1.21.16/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.22.3 h1:/JS6z+GStEQvJNW3t1FTwJwG/gZ+A7crFdRqtvG5ehA=
|
||||
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
|
||||
@@ -105,13 +105,12 @@ func (r *ScanResult) FilterInactiveWordPressLibs(detectInactive bool) {
|
||||
return false
|
||||
})
|
||||
r.ScannedCves = filtered
|
||||
return
|
||||
}
|
||||
|
||||
// ReportFileName returns the filename on localhost without extension
|
||||
func (r ScanResult) ReportFileName() (name string) {
|
||||
if r.Container.ContainerID == "" {
|
||||
return fmt.Sprintf("%s", r.ServerName)
|
||||
return r.ServerName
|
||||
}
|
||||
return fmt.Sprintf("%s@%s", r.Container.Name, r.ServerName)
|
||||
}
|
||||
@@ -246,17 +245,21 @@ func (r ScanResult) FormatMetasploitCveSummary() string {
|
||||
|
||||
// FormatAlertSummary returns a summary of CERT alerts
|
||||
func (r ScanResult) FormatAlertSummary() string {
|
||||
jaCnt := 0
|
||||
enCnt := 0
|
||||
cisaCnt := 0
|
||||
uscertCnt := 0
|
||||
jpcertCnt := 0
|
||||
for _, vuln := range r.ScannedCves {
|
||||
if len(vuln.AlertDict.En) > 0 {
|
||||
enCnt += len(vuln.AlertDict.En)
|
||||
if len(vuln.AlertDict.CISA) > 0 {
|
||||
cisaCnt += len(vuln.AlertDict.CISA)
|
||||
}
|
||||
if len(vuln.AlertDict.Ja) > 0 {
|
||||
jaCnt += len(vuln.AlertDict.Ja)
|
||||
if len(vuln.AlertDict.USCERT) > 0 {
|
||||
uscertCnt += len(vuln.AlertDict.USCERT)
|
||||
}
|
||||
if len(vuln.AlertDict.JPCERT) > 0 {
|
||||
jpcertCnt += len(vuln.AlertDict.JPCERT)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("en: %d, ja: %d alerts", enCnt, jaCnt)
|
||||
return fmt.Sprintf("cisa: %d, uscert: %d, jpcert: %d alerts", cisaCnt, uscertCnt, jpcertCnt)
|
||||
}
|
||||
|
||||
func (r ScanResult) isDisplayUpdatableNum(mode config.ScanMode) bool {
|
||||
@@ -418,11 +421,14 @@ func (r *ScanResult) SortForJSONOutput() {
|
||||
|
||||
v.CveContents.Sort()
|
||||
|
||||
sort.Slice(v.AlertDict.En, func(i, j int) bool {
|
||||
return v.AlertDict.En[i].Title < v.AlertDict.En[j].Title
|
||||
sort.Slice(v.AlertDict.USCERT, func(i, j int) bool {
|
||||
return v.AlertDict.USCERT[i].Title < v.AlertDict.USCERT[j].Title
|
||||
})
|
||||
sort.Slice(v.AlertDict.Ja, func(i, j int) bool {
|
||||
return v.AlertDict.Ja[i].Title < v.AlertDict.Ja[j].Title
|
||||
sort.Slice(v.AlertDict.JPCERT, func(i, j int) bool {
|
||||
return v.AlertDict.JPCERT[i].Title < v.AlertDict.JPCERT[j].Title
|
||||
})
|
||||
sort.Slice(v.AlertDict.CISA, func(i, j int) bool {
|
||||
return v.AlertDict.CISA[i].Title < v.AlertDict.CISA[j].Title
|
||||
})
|
||||
r.ScannedCves[k] = v
|
||||
}
|
||||
|
||||
@@ -212,11 +212,15 @@ func TestScanResult_Sort(t *testing.T) {
|
||||
},
|
||||
},
|
||||
AlertDict: AlertDict{
|
||||
En: []Alert{
|
||||
USCERT: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
Ja: []Alert{
|
||||
JPCERT: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
CISA: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
@@ -271,11 +275,15 @@ func TestScanResult_Sort(t *testing.T) {
|
||||
},
|
||||
},
|
||||
AlertDict: AlertDict{
|
||||
En: []Alert{
|
||||
USCERT: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
Ja: []Alert{
|
||||
JPCERT: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
CISA: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
@@ -333,11 +341,15 @@ func TestScanResult_Sort(t *testing.T) {
|
||||
},
|
||||
},
|
||||
AlertDict: AlertDict{
|
||||
En: []Alert{
|
||||
USCERT: []Alert{
|
||||
{Title: "b"},
|
||||
{Title: "a"},
|
||||
},
|
||||
Ja: []Alert{
|
||||
JPCERT: []Alert{
|
||||
{Title: "b"},
|
||||
{Title: "a"},
|
||||
},
|
||||
CISA: []Alert{
|
||||
{Title: "b"},
|
||||
{Title: "a"},
|
||||
},
|
||||
@@ -392,11 +404,15 @@ func TestScanResult_Sort(t *testing.T) {
|
||||
},
|
||||
},
|
||||
AlertDict: AlertDict{
|
||||
En: []Alert{
|
||||
USCERT: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
Ja: []Alert{
|
||||
JPCERT: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
CISA: []Alert{
|
||||
{Title: "a"},
|
||||
{Title: "b"},
|
||||
},
|
||||
|
||||
@@ -241,7 +241,6 @@ func (ps PackageFixStatuses) Sort() {
|
||||
sort.Slice(ps, func(i, j int) bool {
|
||||
return ps[i].Name < ps[j].Name
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// PackageFixStatus has name and other status about the package
|
||||
@@ -360,7 +359,7 @@ func (v VulnInfo) CveIDDiffFormat() string {
|
||||
if v.DiffStatus != "" {
|
||||
return fmt.Sprintf("%s %s", v.DiffStatus, v.CveID)
|
||||
}
|
||||
return fmt.Sprintf("%s", v.CveID)
|
||||
return v.CveID
|
||||
}
|
||||
|
||||
// Titles returns title (TUI)
|
||||
@@ -814,18 +813,27 @@ type Mitigation struct {
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// AlertDict has target cve JPCERT and USCERT alert data
|
||||
// AlertDict has target cve JPCERT, USCERT and CISA alert data
|
||||
type AlertDict struct {
|
||||
Ja []Alert `json:"ja"`
|
||||
En []Alert `json:"en"`
|
||||
CISA []Alert `json:"cisa"`
|
||||
JPCERT []Alert `json:"jpcert"`
|
||||
USCERT []Alert `json:"uscert"`
|
||||
}
|
||||
|
||||
func (a AlertDict) IsEmpty() bool {
|
||||
return len(a.CISA) == 0 && len(a.JPCERT) == 0 && len(a.USCERT) == 0
|
||||
}
|
||||
|
||||
// FormatSource returns which source has this alert
|
||||
func (a AlertDict) FormatSource() string {
|
||||
if len(a.En) != 0 || len(a.Ja) != 0 {
|
||||
return "CERT"
|
||||
var s []string
|
||||
if len(a.CISA) != 0 {
|
||||
s = append(s, "CISA")
|
||||
}
|
||||
return ""
|
||||
if len(a.USCERT) != 0 || len(a.JPCERT) != 0 {
|
||||
s = append(s, "CERT")
|
||||
}
|
||||
return strings.Join(s, "/")
|
||||
}
|
||||
|
||||
// Confidences is a list of Confidence
|
||||
|
||||
@@ -277,7 +277,7 @@ No CVE-IDs are found in updatable packages.
|
||||
// fmt.Sprintf("%4.1f", v2max),
|
||||
// fmt.Sprintf("%4.1f", v3max),
|
||||
exploits,
|
||||
vinfo.AlertDict.FormatSource(),
|
||||
fmt.Sprintf("%9s", vinfo.AlertDict.FormatSource()),
|
||||
fmt.Sprintf("%7s", vinfo.PatchStatus(r.Packages)),
|
||||
link,
|
||||
})
|
||||
@@ -292,7 +292,7 @@ No CVE-IDs are found in updatable packages.
|
||||
// "v3",
|
||||
// "v2",
|
||||
"PoC",
|
||||
"CERT",
|
||||
"Alert",
|
||||
"Fixed",
|
||||
"NVD",
|
||||
})
|
||||
@@ -475,11 +475,15 @@ No CVE-IDs are found in updatable packages.
|
||||
data = append(data, []string{"SANS/CWE Top25", sansTop25URLs[0]})
|
||||
}
|
||||
|
||||
for _, alert := range vuln.AlertDict.Ja {
|
||||
for _, alert := range vuln.AlertDict.CISA {
|
||||
data = append(data, []string{"CISA Alert", alert.URL})
|
||||
}
|
||||
|
||||
for _, alert := range vuln.AlertDict.JPCERT {
|
||||
data = append(data, []string{"JPCERT Alert", alert.URL})
|
||||
}
|
||||
|
||||
for _, alert := range vuln.AlertDict.En {
|
||||
for _, alert := range vuln.AlertDict.USCERT {
|
||||
data = append(data, []string{"US-CERT Alert", alert.URL})
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,11 @@ func (h VulsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
logging.Log.Infof("%s: %d exploits are detected", r.FormatServerName(), nMetasploitCve)
|
||||
|
||||
if err := detector.FillWithKEVuln(&r, config.Conf.KEVuln); err != nil {
|
||||
logging.Log.Errorf("Failed to fill with Known Exploited Vulnerabilities: %+v", err)
|
||||
http.Error(w, err.Error(), http.StatusServiceUnavailable)
|
||||
}
|
||||
|
||||
detector.FillCweDict(&r)
|
||||
|
||||
// set ReportedAt to current time when it's set to the epoch, ensures that ReportedAt will be set
|
||||
|
||||
@@ -103,6 +103,11 @@ func printConfigToml(ips []string) (err error) {
|
||||
#sqlite3Path = "/path/to/go-msfdb.sqlite3"
|
||||
#url = ""
|
||||
|
||||
[kevuln]
|
||||
#type = ["sqlite3", "mysql", "postgres", "redis", "http" ]
|
||||
#sqlite3Path = "/path/to/go-kev.sqlite3"
|
||||
#url = ""
|
||||
|
||||
# https://vuls.io/docs/en/config.toml.html#slack-section
|
||||
#[slack]
|
||||
#hookURL = "https://hooks.slack.com/services/abc123/defghijklmnopqrstuvwxyz"
|
||||
|
||||
24
tui/tui.go
24
tui/tui.go
@@ -636,7 +636,7 @@ func summaryLines(r models.ScanResult) string {
|
||||
cvssScore + " |",
|
||||
fmt.Sprintf("%-6s |", av),
|
||||
fmt.Sprintf("%3s |", exploits),
|
||||
fmt.Sprintf("%6s |", vinfo.AlertDict.FormatSource()),
|
||||
fmt.Sprintf("%9s |", vinfo.AlertDict.FormatSource()),
|
||||
fmt.Sprintf("%7s |", vinfo.PatchStatus(r.Packages)),
|
||||
strings.Join(pkgNames, ", "),
|
||||
}
|
||||
@@ -808,22 +808,32 @@ func setChangelogLayout(g *gocui.Gui) error {
|
||||
}
|
||||
}
|
||||
|
||||
if len(vinfo.AlertDict.En) > 0 {
|
||||
if len(vinfo.AlertDict.CISA) > 0 {
|
||||
lines = append(lines, "\n",
|
||||
"USCERT Alert",
|
||||
"=============",
|
||||
"CISA Alert",
|
||||
"===========",
|
||||
)
|
||||
for _, alert := range vinfo.AlertDict.En {
|
||||
for _, alert := range vinfo.AlertDict.CISA {
|
||||
lines = append(lines, fmt.Sprintf("* [%s](%s)", alert.Title, alert.URL))
|
||||
}
|
||||
}
|
||||
|
||||
if len(vinfo.AlertDict.Ja) > 0 {
|
||||
if len(vinfo.AlertDict.USCERT) > 0 {
|
||||
lines = append(lines, "\n",
|
||||
"USCERT Alert",
|
||||
"=============",
|
||||
)
|
||||
for _, alert := range vinfo.AlertDict.USCERT {
|
||||
lines = append(lines, fmt.Sprintf("* [%s](%s)", alert.Title, alert.URL))
|
||||
}
|
||||
}
|
||||
|
||||
if len(vinfo.AlertDict.JPCERT) > 0 {
|
||||
lines = append(lines, "\n",
|
||||
"JPCERT Alert",
|
||||
"=============",
|
||||
)
|
||||
for _, alert := range vinfo.AlertDict.Ja {
|
||||
for _, alert := range vinfo.AlertDict.JPCERT {
|
||||
if r.Lang == "ja" {
|
||||
lines = append(lines, fmt.Sprintf("* [%s](%s)", alert.Title, alert.URL))
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user