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
This commit is contained in:
Kota Kanbe
2018-11-30 15:41:59 +09:00
committed by GitHub
parent 9d7b115bb5
commit 6e82981ee3
4 changed files with 47 additions and 25 deletions

View File

@@ -20,11 +20,12 @@ package models
import (
"bytes"
"fmt"
"github.com/future-architect/vuls/alert"
"regexp"
"strings"
"time"
"github.com/future-architect/vuls/alert"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/cwe"
"github.com/future-architect/vuls/util"
@@ -189,6 +190,9 @@ func (r ScanResult) FilterUnfixed() ScanResult {
return r
}
filtered := r.ScannedCves.Find(func(v VulnInfo) bool {
if len(v.CpeURIs) != 0 {
return true
}
NotFixedAll := true
for _, p := range v.AffectedPackages {
NotFixedAll = NotFixedAll && p.NotFixedYet

View File

@@ -20,11 +20,12 @@ package models
import (
"bytes"
"fmt"
"github.com/future-architect/vuls/alert"
"sort"
"strings"
"time"
"github.com/future-architect/vuls/alert"
"github.com/future-architect/vuls/config"
exploitmodels "github.com/mozqnet/go-exploitdb/models"
)
@@ -694,6 +695,23 @@ type AlertDict struct {
En []alert.Alert
}
// HasAlert returns whether or not it has En or Ja entries.
func (a AlertDict) HasAlert() bool {
return len(a.En) != 0 || len(a.Ja) != 0
}
// FormatSource returns which source has this alert
func (a AlertDict) FormatSource() string {
s := []string{}
if len(a.En) != 0 {
s = append(s, "USCERT")
}
if len(a.Ja) != 0 {
s = append(s, "JPCERT")
}
return strings.Join(s, "/")
}
// Confidences is a list of Confidence
type Confidences []Confidence

View File

@@ -20,13 +20,14 @@ package report
import (
"bytes"
"fmt"
"github.com/future-architect/vuls/alert"
"os"
"sort"
"strings"
"text/template"
"time"
"github.com/future-architect/vuls/alert"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
"github.com/future-architect/vuls/util"
@@ -636,10 +637,15 @@ func summaryLines(r models.ScanResult) string {
packname := vinfo.AffectedPackages.FormatTuiSummary()
packname += strings.Join(vinfo.CpeURIs, ", ")
alert := " "
if vinfo.AlertDict.HasAlert() {
alert = "! "
}
var cols []string
cols = []string{
fmt.Sprintf(indexFormat, i+1),
vinfo.CveID,
alert + vinfo.CveID,
cvssScore + " |",
fmt.Sprintf("%8s |", vinfo.AttackVector()),
fmt.Sprintf("%7s |", vinfo.PatchStatus(r.Packages)),
@@ -764,13 +770,17 @@ func setChangelogLayout(g *gocui.Gui) error {
}
}
if config.Conf.Lang == "ja" && len(vinfo.AlertDict.Ja) > 0 {
if len(vinfo.AlertDict.Ja) > 0 {
lines = append(lines, "\n",
"JPCERT Alert",
"=============",
)
for _, alert := range vinfo.AlertDict.Ja {
lines = append(lines, fmt.Sprintf("* [%s](%s)", alert.Title, alert.URL))
if config.Conf.Lang == "ja" {
lines = append(lines, fmt.Sprintf("* [%s](%s)", alert.Title, alert.URL))
} else {
lines = append(lines, fmt.Sprintf("* [JPCERT](%s)", alert.URL))
}
}
}
@@ -884,17 +894,6 @@ func detailLines() (string, error) {
}
}
alerts := []alert.Alert{}
for _, alert := range vinfo.AlertDict.En {
alerts = append(alerts, alert)
}
// Only show JPCERT alert to Japanese users
if config.Conf.Lang == "ja" {
for _, alert := range vinfo.AlertDict.Ja {
alerts = append(alerts, alert)
}
}
data := dataForTmpl{
CveID: vinfo.CveID,
Cvsses: fmt.Sprintf("%s\n", table),
@@ -902,7 +901,6 @@ func detailLines() (string, error) {
Mitigation: fmt.Sprintf("%s (%s)", mitigation.Value, mitigation.Type),
Confidences: vinfo.Confidences,
Cwes: cwes,
Alerts: alerts,
Links: util.Distinct(links),
References: refs,
}
@@ -949,11 +947,6 @@ Confidence
{{range $confidence := .Confidences -}}
* {{$confidence.DetectionMethod}}
{{end}}
Alerts
-----------
{{range .Alerts -}}
* [{{.Title}}]({{.URL}})
{{end}}
References
-----------
{{range .References -}}

View File

@@ -50,7 +50,6 @@ func formatScanSummary(rs ...models.ScanResult) string {
r.FormatServerName(),
fmt.Sprintf("%s%s", r.Family, r.Release),
r.FormatUpdatablePacksSummary(),
r.FormatExploitCveSummary(),
}
} else {
cols = []interface{}{
@@ -78,6 +77,7 @@ func formatOneLineSummary(rs ...models.ScanResult) string {
r.ScannedCves.FormatFixedStatus(r.Packages),
r.FormatUpdatablePacksSummary(),
r.FormatExploitCveSummary(),
r.FormatAlertSummary(),
}
} else {
cols = []interface{}{
@@ -116,8 +116,14 @@ No CVE-IDs are found in updatable packages.
// packname := vinfo.AffectedPackages.FormatTuiSummary()
// packname += strings.Join(vinfo.CpeURIs, ", ")
exploits := ""
if 0 < len(vinfo.Exploits) {
exploits = " Y"
}
data = append(data, []string{
vinfo.CveID,
vinfo.AlertDict.FormatSource(),
fmt.Sprintf("%4.1f", max),
// fmt.Sprintf("%4.1f", v2max),
// fmt.Sprintf("%4.1f", v3max),
@@ -125,7 +131,7 @@ No CVE-IDs are found in updatable packages.
fmt.Sprintf("%7s", vinfo.PatchStatus(r.Packages)),
// packname,
fmt.Sprintf("https://nvd.nist.gov/vuln/detail/%s", vinfo.CveID),
fmt.Sprintf("%t", 0 < len(vinfo.Exploits)),
exploits,
})
}
@@ -133,6 +139,7 @@ No CVE-IDs are found in updatable packages.
table := tablewriter.NewWriter(&b)
table.SetHeader([]string{
"CVE-ID",
"CERT",
"CVSS",
// "v3",
// "v2",