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>
This commit is contained in:
@@ -9,24 +9,27 @@ import (
|
||||
cvedb "github.com/kotakanbe/go-cve-dictionary/db"
|
||||
ovaldb "github.com/kotakanbe/goval-dictionary/db"
|
||||
exploitdb "github.com/mozqnet/go-exploitdb/db"
|
||||
metasploitdb "github.com/takuzoo3868/go-msfdb/db"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// DBClient is a dictionarie's db client for reporting
|
||||
type DBClient struct {
|
||||
CveDB cvedb.DB
|
||||
OvalDB ovaldb.DB
|
||||
GostDB gostdb.DB
|
||||
ExploitDB exploitdb.DB
|
||||
CveDB cvedb.DB
|
||||
OvalDB ovaldb.DB
|
||||
GostDB gostdb.DB
|
||||
ExploitDB exploitdb.DB
|
||||
MetasploitDB metasploitdb.DB
|
||||
}
|
||||
|
||||
// DBClientConf has a configuration of Vulnerability DBs
|
||||
type DBClientConf struct {
|
||||
CveDictCnf config.GoCveDictConf
|
||||
OvalDictCnf config.GovalDictConf
|
||||
GostCnf config.GostConf
|
||||
ExploitCnf config.ExploitConf
|
||||
DebugSQL bool
|
||||
CveDictCnf config.GoCveDictConf
|
||||
OvalDictCnf config.GovalDictConf
|
||||
GostCnf config.GostConf
|
||||
ExploitCnf config.ExploitConf
|
||||
MetasploitCnf config.MetasploitConf
|
||||
DebugSQL bool
|
||||
}
|
||||
|
||||
// NewDBClient returns db clients
|
||||
@@ -66,11 +69,21 @@ func NewDBClient(cnf DBClientConf) (dbclient *DBClient, locked bool, err error)
|
||||
cnf.ExploitCnf.SQLite3Path, err)
|
||||
}
|
||||
|
||||
metasploitdb, locked, err := NewMetasploitDB(cnf)
|
||||
if locked {
|
||||
return nil, true, xerrors.Errorf("metasploitDB is locked: %s",
|
||||
cnf.MetasploitCnf.SQLite3Path)
|
||||
} else if err != nil {
|
||||
util.Log.Warnf("Unable to use metasploitDB: %s, err: %s",
|
||||
cnf.MetasploitCnf.SQLite3Path, err)
|
||||
}
|
||||
|
||||
return &DBClient{
|
||||
CveDB: cveDriver,
|
||||
OvalDB: ovaldb,
|
||||
GostDB: gostdb,
|
||||
ExploitDB: exploitdb,
|
||||
CveDB: cveDriver,
|
||||
OvalDB: ovaldb,
|
||||
GostDB: gostdb,
|
||||
ExploitDB: exploitdb,
|
||||
MetasploitDB: metasploitdb,
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
@@ -177,6 +190,32 @@ func NewExploitDB(cnf DBClientConf) (driver exploitdb.DB, locked bool, err error
|
||||
return driver, false, nil
|
||||
}
|
||||
|
||||
// NewMetasploitDB returns db client for Metasploit
|
||||
func NewMetasploitDB(cnf DBClientConf) (driver metasploitdb.DB, locked bool, err error) {
|
||||
if config.Conf.Metasploit.IsFetchViaHTTP() {
|
||||
return nil, false, nil
|
||||
}
|
||||
path := cnf.MetasploitCnf.URL
|
||||
if cnf.MetasploitCnf.Type == "sqlite3" {
|
||||
path = cnf.MetasploitCnf.SQLite3Path
|
||||
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
util.Log.Warnf("--msfdb-path=%s file not found. Fetch go-msfdb before reporting if you want to display metasploit modules of detected CVE-IDs. For details, see `https://github.com/takuzoo3868/go-msfdb`", path)
|
||||
return nil, false, nil
|
||||
}
|
||||
}
|
||||
|
||||
util.Log.Debugf("Open metasploit db (%s): %s", cnf.MetasploitCnf.Type, path)
|
||||
if driver, locked, err = metasploitdb.NewDB(cnf.MetasploitCnf.Type, path, cnf.DebugSQL, false); err != nil {
|
||||
if locked {
|
||||
util.Log.Errorf("metasploitDB is locked. err: %+v", err)
|
||||
return nil, true, err
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
return driver, false, nil
|
||||
}
|
||||
|
||||
// CloseDB close dbs
|
||||
func (d DBClient) CloseDB() {
|
||||
if d.CveDB != nil {
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/future-architect/vuls/github"
|
||||
"github.com/future-architect/vuls/gost"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/msf"
|
||||
"github.com/future-architect/vuls/oval"
|
||||
"github.com/future-architect/vuls/util"
|
||||
"github.com/future-architect/vuls/wordpress"
|
||||
@@ -31,6 +32,7 @@ import (
|
||||
cvemodels "github.com/kotakanbe/go-cve-dictionary/models"
|
||||
ovaldb "github.com/kotakanbe/goval-dictionary/db"
|
||||
exploitdb "github.com/mozqnet/go-exploitdb/db"
|
||||
metasploitdb "github.com/takuzoo3868/go-msfdb/db"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
@@ -208,6 +210,14 @@ func FillCveInfo(dbclient DBClient, r *models.ScanResult, cpeURIs []string, igno
|
||||
util.Log.Infof("%s: %d exploits are detected",
|
||||
r.FormatServerName(), nExploitCve)
|
||||
|
||||
util.Log.Infof("Fill metasploit module information with Metasploit-DB")
|
||||
nMetasploitCve, err := FillWithMetasploit(dbclient.MetasploitDB, r)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("Failed to fill with metasploit: %w", err)
|
||||
}
|
||||
util.Log.Infof("%s: %d modules are detected",
|
||||
r.FormatServerName(), nMetasploitCve)
|
||||
|
||||
fillCweDict(r)
|
||||
return nil
|
||||
}
|
||||
@@ -358,6 +368,12 @@ func FillWithExploit(driver exploitdb.DB, r *models.ScanResult) (nExploitCve int
|
||||
return exploit.FillWithExploit(driver, r)
|
||||
}
|
||||
|
||||
// FillWithMetasploit fills metasploit modules with metasploit database
|
||||
// https://github.com/takuzoo3868/go-msfdb
|
||||
func FillWithMetasploit(driver metasploitdb.DB, r *models.ScanResult) (nMetasploitCve int, err error) {
|
||||
return msf.FillWithMetasploit(driver, r)
|
||||
}
|
||||
|
||||
func fillVulnByCpeURIs(driver cvedb.DB, r *models.ScanResult, cpeURIs []string) (nCVEs int, err error) {
|
||||
if len(cpeURIs) != 0 && driver == nil && !config.Conf.CveDict.IsFetchViaHTTP() {
|
||||
return 0, xerrors.Errorf("cpeURIs %s specified, but cve-dictionary DB not found. Fetch cve-dictionary beofre reporting. For details, see `https://github.com/kotakanbe/go-cve-dictionary#deploy-go-cve-dictionary`",
|
||||
@@ -605,6 +621,7 @@ func EnsureUUIDs(configPath string, results models.ScanResults) (err error) {
|
||||
ovalDict := &c.Conf.OvalDict
|
||||
gost := &c.Conf.Gost
|
||||
exploit := &c.Conf.Exploit
|
||||
metasploit := &c.Conf.Metasploit
|
||||
http := &c.Conf.HTTP
|
||||
if http.URL == "" {
|
||||
http = nil
|
||||
@@ -646,38 +663,40 @@ func EnsureUUIDs(configPath string, results models.ScanResults) (err error) {
|
||||
}
|
||||
|
||||
c := struct {
|
||||
CveDict *c.GoCveDictConf `toml:"cveDict"`
|
||||
OvalDict *c.GovalDictConf `toml:"ovalDict"`
|
||||
Gost *c.GostConf `toml:"gost"`
|
||||
Exploit *c.ExploitConf `toml:"exploit"`
|
||||
Slack *c.SlackConf `toml:"slack"`
|
||||
Email *c.SMTPConf `toml:"email"`
|
||||
HTTP *c.HTTPConf `toml:"http"`
|
||||
Syslog *c.SyslogConf `toml:"syslog"`
|
||||
AWS *c.AWS `toml:"aws"`
|
||||
Azure *c.Azure `toml:"azure"`
|
||||
Stride *c.StrideConf `toml:"stride"`
|
||||
HipChat *c.HipChatConf `toml:"hipChat"`
|
||||
ChatWork *c.ChatWorkConf `toml:"chatWork"`
|
||||
Saas *c.SaasConf `toml:"saas"`
|
||||
CveDict *c.GoCveDictConf `toml:"cveDict"`
|
||||
OvalDict *c.GovalDictConf `toml:"ovalDict"`
|
||||
Gost *c.GostConf `toml:"gost"`
|
||||
Exploit *c.ExploitConf `toml:"exploit"`
|
||||
Metasploit *c.MetasploitConf `toml:"metasploit"`
|
||||
Slack *c.SlackConf `toml:"slack"`
|
||||
Email *c.SMTPConf `toml:"email"`
|
||||
HTTP *c.HTTPConf `toml:"http"`
|
||||
Syslog *c.SyslogConf `toml:"syslog"`
|
||||
AWS *c.AWS `toml:"aws"`
|
||||
Azure *c.Azure `toml:"azure"`
|
||||
Stride *c.StrideConf `toml:"stride"`
|
||||
HipChat *c.HipChatConf `toml:"hipChat"`
|
||||
ChatWork *c.ChatWorkConf `toml:"chatWork"`
|
||||
Saas *c.SaasConf `toml:"saas"`
|
||||
|
||||
Default c.ServerInfo `toml:"default"`
|
||||
Servers map[string]c.ServerInfo `toml:"servers"`
|
||||
}{
|
||||
CveDict: cveDict,
|
||||
OvalDict: ovalDict,
|
||||
Gost: gost,
|
||||
Exploit: exploit,
|
||||
Slack: slack,
|
||||
Email: email,
|
||||
HTTP: http,
|
||||
Syslog: syslog,
|
||||
AWS: aws,
|
||||
Azure: azure,
|
||||
Stride: stride,
|
||||
HipChat: hipChat,
|
||||
ChatWork: chatWork,
|
||||
Saas: saas,
|
||||
CveDict: cveDict,
|
||||
OvalDict: ovalDict,
|
||||
Gost: gost,
|
||||
Exploit: exploit,
|
||||
Metasploit: metasploit,
|
||||
Slack: slack,
|
||||
Email: email,
|
||||
HTTP: http,
|
||||
Syslog: syslog,
|
||||
AWS: aws,
|
||||
Azure: azure,
|
||||
Stride: stride,
|
||||
HipChat: hipChat,
|
||||
ChatWork: chatWork,
|
||||
Saas: saas,
|
||||
|
||||
Default: c.Conf.Default,
|
||||
Servers: c.Conf.Servers,
|
||||
|
||||
@@ -618,7 +618,7 @@ func summaryLines(r models.ScanResult) string {
|
||||
pkgNames = append(pkgNames, vinfo.LibraryFixedIns.Names()...)
|
||||
|
||||
exploits := ""
|
||||
if 0 < len(vinfo.Exploits) {
|
||||
if 0 < len(vinfo.Exploits) || 0 < len(vinfo.Metasploits) {
|
||||
exploits = "POC"
|
||||
}
|
||||
|
||||
@@ -770,6 +770,21 @@ func setChangelogLayout(g *gocui.Gui) error {
|
||||
}
|
||||
}
|
||||
|
||||
if len(vinfo.Metasploits) != 0 {
|
||||
lines = append(lines, "\n",
|
||||
"Metasploit Modules",
|
||||
"==================",
|
||||
)
|
||||
for _, module := range vinfo.Metasploits {
|
||||
lines = append(lines, fmt.Sprintf("* %s: %s", module.Name, module.Description))
|
||||
if 0 < len(module.URLs) {
|
||||
for _, u := range module.URLs {
|
||||
lines = append(lines, fmt.Sprintf(" - %s", u))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(vinfo.AlertDict.En) > 0 {
|
||||
lines = append(lines, "\n",
|
||||
"USCERT Alert",
|
||||
@@ -822,6 +837,7 @@ type dataForTmpl struct {
|
||||
CveID string
|
||||
Cvsses string
|
||||
Exploits []models.Exploit
|
||||
Metasploits []models.Metasploit
|
||||
Summary string
|
||||
Mitigation string
|
||||
Confidences models.Confidences
|
||||
|
||||
@@ -71,6 +71,7 @@ func formatOneLineSummary(rs ...models.ScanResult) string {
|
||||
r.ScannedCves.FormatFixedStatus(r.Packages),
|
||||
r.FormatUpdatablePacksSummary(),
|
||||
r.FormatExploitCveSummary(),
|
||||
r.FormatMetasploitCveSummary(),
|
||||
r.FormatAlertSummary(),
|
||||
}
|
||||
} else {
|
||||
@@ -126,7 +127,7 @@ No CVE-IDs are found in updatable packages.
|
||||
// packname += strings.Join(vinfo.CpeURIs, ", ")
|
||||
|
||||
exploits := ""
|
||||
if 0 < len(vinfo.Exploits) {
|
||||
if 0 < len(vinfo.Exploits) || 0 < len(vinfo.Metasploits) {
|
||||
exploits = "POC"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user