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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 -}}
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user