Handle kernel's vulns using OVAL
This commit is contained in:
15
README.ja.md
15
README.ja.md
@@ -767,6 +767,19 @@ configtest:
|
||||
|
||||
configtestサブコマンドは、config.tomlで定義されたサーバ/コンテナに対してSSH可能かどうかをチェックする。
|
||||
|
||||
## Fast Scan Mode
|
||||
|
||||
| Distribution | Release | Requirements |
|
||||
|:-------------|-------------------:|:-------------|
|
||||
| Ubuntu | 12, 14, 16| - |
|
||||
| Debian | 7, 8| reboot-notifier|
|
||||
| CentOS | 6, 7| - |
|
||||
| Amazon | All | - |
|
||||
| RHEL | 5, 6, 7 | - |
|
||||
| Oracle Linux | 5, 6, 7 | - |
|
||||
| FreeBSD | 10, 11 | - |
|
||||
| Raspbian | Jessie, Stretch | - |
|
||||
|
||||
## Deep Scan Mode
|
||||
|
||||
Deep Scan Modeではスキャン対象サーバ上にいくつかの依存パッケージが必要。
|
||||
@@ -781,7 +794,7 @@ Deep Scan Modeでスキャンするためには、下記のパッケージが必
|
||||
| Distribution | Release | Requirements |
|
||||
|:-------------|-------------------:|:-------------|
|
||||
| Ubuntu | 12, 14, 16| - |
|
||||
| Debian | 7, 8| aptitude |
|
||||
| Debian | 7, 8| aptitude, reboot-notifier |
|
||||
| CentOS | 6, 7| yum-plugin-changelog, yum-utils |
|
||||
| Amazon | All | yum-plugin-changelog, yum-utils |
|
||||
| RHEL | 5 | yum-utils, yum-security, yum-changelog |
|
||||
|
||||
15
README.md
15
README.md
@@ -776,6 +776,19 @@ configtest:
|
||||
|
||||
The configtest subcommand checks whether vuls is able to connect via SSH to servers/containers defined in the config.toml
|
||||
|
||||
## Fast Scan Mode
|
||||
|
||||
| Distribution | Release | Requirements |
|
||||
|:-------------|-------------------:|:-------------|
|
||||
| Ubuntu | 12, 14, 16| - |
|
||||
| Debian | 7, 8| reboot-notifier|
|
||||
| CentOS | 6, 7| - |
|
||||
| Amazon | All | - |
|
||||
| RHEL | 5, 6, 7 | - |
|
||||
| Oracle Linux | 5, 6, 7 | - |
|
||||
| FreeBSD | 10, 11 | - |
|
||||
| Raspbian | Jessie, Stretch | - |
|
||||
|
||||
## Deep Scan Mode
|
||||
|
||||
Some dependent packages are needed in Deep Scan Mode.
|
||||
@@ -788,7 +801,7 @@ In order to scan with deep scan mode, the following dependencies are required, s
|
||||
| Distribution | Release | Requirements |
|
||||
|:-------------|-------------------:|:-------------|
|
||||
| Ubuntu | 12, 14, 16| - |
|
||||
| Debian | 7, 8| aptitude |
|
||||
| Debian | 7, 8| aptitude, reboot-notifier |
|
||||
| CentOS | 6, 7| yum-plugin-changelog, yum-utils |
|
||||
| Amazon | All | yum-plugin-changelog, yum-utils |
|
||||
| RHEL | 5 | yum-utils, yum-security, yum-changelog |
|
||||
|
||||
@@ -44,9 +44,10 @@ type ScanResult struct {
|
||||
// Scanned Vulns by SSH scan + CPE + OVAL
|
||||
ScannedCves VulnInfos
|
||||
|
||||
Packages Packages
|
||||
Errors []string
|
||||
Optional [][]interface{}
|
||||
RunningKernel Kernel
|
||||
Packages Packages
|
||||
Errors []string
|
||||
Optional [][]interface{}
|
||||
|
||||
Config struct {
|
||||
Scan config.Config
|
||||
@@ -54,6 +55,13 @@ type ScanResult struct {
|
||||
}
|
||||
}
|
||||
|
||||
// Kernel has the Release, version and whether need restart
|
||||
type Kernel struct {
|
||||
Release string
|
||||
Version string
|
||||
RebootRequired bool
|
||||
}
|
||||
|
||||
// FilterByCvssOver is filter function.
|
||||
func (r ScanResult) FilterByCvssOver(over float64) ScanResult {
|
||||
filtered := r.ScannedCves.Find(func(v VulnInfo) bool {
|
||||
|
||||
181
oval/debian.go
181
oval/debian.go
@@ -29,40 +29,6 @@ type DebianBase struct {
|
||||
Base
|
||||
}
|
||||
|
||||
// FillWithOval returns scan result after updating CVE info by OVAL
|
||||
func (o DebianBase) FillWithOval(r *models.ScanResult) (err error) {
|
||||
var relatedDefs ovalResult
|
||||
if o.isFetchViaHTTP() {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(o.family, r.Release, r.Packages); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, defPacks := range relatedDefs.entries {
|
||||
o.update(r, defPacks)
|
||||
}
|
||||
|
||||
for _, vuln := range r.ScannedCves {
|
||||
switch models.NewCveContentType(o.family) {
|
||||
case models.Debian:
|
||||
if cont, ok := vuln.CveContents[models.Debian]; ok {
|
||||
cont.SourceLink = "https://security-tracker.debian.org/tracker/" + cont.CveID
|
||||
vuln.CveContents[models.Debian] = cont
|
||||
}
|
||||
case models.Ubuntu:
|
||||
if cont, ok := vuln.CveContents[models.Ubuntu]; ok {
|
||||
cont.SourceLink = "http://people.ubuntu.com/~ubuntu-security/cve/" + cont.CveID
|
||||
vuln.CveContents[models.Ubuntu] = cont
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o DebianBase) update(r *models.ScanResult, defPacks defPacks) {
|
||||
ovalContent := *o.convertToModel(&defPacks.def)
|
||||
ovalContent.Type = models.NewCveContentType(o.family)
|
||||
@@ -136,6 +102,57 @@ func NewDebian() Debian {
|
||||
}
|
||||
}
|
||||
|
||||
// FillWithOval returns scan result after updating CVE info by OVAL
|
||||
func (o Debian) FillWithOval(r *models.ScanResult) (err error) {
|
||||
|
||||
//Debian's uname gives both of kernel release(uname -r), version(kernel-image version)
|
||||
linuxImage := "linux-image-" + r.RunningKernel.Release
|
||||
// Add linux and set the version of running kernel to search OVAL.
|
||||
if r.Container.ContainerID == "" {
|
||||
r.Packages["linux"] = models.Package{
|
||||
Name: "linux",
|
||||
Version: r.RunningKernel.Version,
|
||||
}
|
||||
}
|
||||
|
||||
var relatedDefs ovalResult
|
||||
if o.isFetchViaHTTP() {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(o.family, r.Release, r.Packages); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
delete(r.Packages, "linux")
|
||||
|
||||
for _, defPacks := range relatedDefs.entries {
|
||||
// Remove linux added above to search for oval
|
||||
// linux is not a real package name (key of affected packages in OVAL)
|
||||
if _, ok := defPacks.actuallyAffectedPackNames["linux"]; ok {
|
||||
defPacks.actuallyAffectedPackNames[linuxImage] = true
|
||||
delete(defPacks.actuallyAffectedPackNames, "linux")
|
||||
for i, p := range defPacks.def.AffectedPacks {
|
||||
if p.Name == "linux" {
|
||||
p.Name = linuxImage
|
||||
defPacks.def.AffectedPacks[i] = p
|
||||
}
|
||||
}
|
||||
}
|
||||
o.update(r, defPacks)
|
||||
}
|
||||
|
||||
for _, vuln := range r.ScannedCves {
|
||||
if cont, ok := vuln.CveContents[models.Debian]; ok {
|
||||
cont.SourceLink = "https://security-tracker.debian.org/tracker/" + cont.CveID
|
||||
vuln.CveContents[models.Debian] = cont
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ubuntu is the interface for Debian OVAL
|
||||
type Ubuntu struct {
|
||||
DebianBase
|
||||
@@ -151,3 +168,99 @@ func NewUbuntu() Ubuntu {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// FillWithOval returns scan result after updating CVE info by OVAL
|
||||
func (o Ubuntu) FillWithOval(r *models.ScanResult) (err error) {
|
||||
ovalKernelImageNames := []string{
|
||||
"linux-aws",
|
||||
"linux-azure",
|
||||
"linux-flo",
|
||||
"linux-gcp",
|
||||
"linux-gke",
|
||||
"linux-goldfish",
|
||||
"linux-hwe",
|
||||
"linux-hwe-edge",
|
||||
"linux-kvm",
|
||||
"linux-mako",
|
||||
"linux-raspi2",
|
||||
"linux-snapdragon",
|
||||
}
|
||||
linuxImage := "linux-image-" + r.RunningKernel.Release
|
||||
|
||||
found := false
|
||||
if r.Container.ContainerID == "" {
|
||||
for _, n := range ovalKernelImageNames {
|
||||
if _, ok := r.Packages[n]; ok {
|
||||
v, ok := r.Packages[linuxImage]
|
||||
if ok {
|
||||
// Set running kernel version
|
||||
p := r.Packages[n]
|
||||
p.Version = v.Version
|
||||
p.NewVersion = v.NewVersion
|
||||
r.Packages[n] = p
|
||||
} else {
|
||||
util.Log.Warnf("Running kernel image %s is not found: %s",
|
||||
linuxImage, r.RunningKernel.Version)
|
||||
}
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
// linux-generic is described as "linux" in Ubuntu's oval.
|
||||
// Add "linux" and set the version of running kernel to search OVAL.
|
||||
v, ok := r.Packages[linuxImage]
|
||||
if ok {
|
||||
r.Packages["linux"] = models.Package{
|
||||
Name: "linux",
|
||||
Version: v.Version,
|
||||
NewVersion: v.NewVersion,
|
||||
}
|
||||
} else {
|
||||
util.Log.Warnf("%s is not found. Running: %s",
|
||||
linuxImage, r.RunningKernel.Release)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var relatedDefs ovalResult
|
||||
if o.isFetchViaHTTP() {
|
||||
if relatedDefs, err = getDefsByPackNameViaHTTP(r); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if relatedDefs, err = getDefsByPackNameFromOvalDB(o.family, r.Release, r.Packages); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
delete(r.Packages, "linux")
|
||||
}
|
||||
|
||||
for _, defPacks := range relatedDefs.entries {
|
||||
|
||||
// Remove "linux" added above to search for oval
|
||||
// "linux" is not a real package name (key of affected packages in OVAL)
|
||||
if _, ok := defPacks.actuallyAffectedPackNames["linux"]; !found && ok {
|
||||
defPacks.actuallyAffectedPackNames[linuxImage] = true
|
||||
delete(defPacks.actuallyAffectedPackNames, "linux")
|
||||
for i, p := range defPacks.def.AffectedPacks {
|
||||
if p.Name == "linux" {
|
||||
p.Name = linuxImage
|
||||
defPacks.def.AffectedPacks[i] = p
|
||||
}
|
||||
}
|
||||
}
|
||||
o.update(r, defPacks)
|
||||
}
|
||||
|
||||
for _, vuln := range r.ScannedCves {
|
||||
if cont, ok := vuln.CveContents[models.Ubuntu]; ok {
|
||||
cont.SourceLink = "http://people.ubuntu.com/~ubuntu-security/cve/" + cont.CveID
|
||||
vuln.CveContents[models.Ubuntu] = cont
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -146,8 +146,5 @@ func (b Base) CheckIfOvalFresh(osFamily, release string) (ok bool, err error) {
|
||||
|
||||
func (b Base) isFetchViaHTTP() bool {
|
||||
// Default value of OvalDBType is sqlite3
|
||||
if config.Conf.OvalDBURL != "" && config.Conf.OvalDBType == "sqlite3" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return config.Conf.OvalDBURL != "" && config.Conf.OvalDBType == "sqlite3"
|
||||
}
|
||||
|
||||
43
oval/util.go
43
oval/util.go
@@ -58,7 +58,7 @@ func (e defPacks) toPackStatuses(family string, packs models.Packages) (ps model
|
||||
})
|
||||
}
|
||||
|
||||
case config.CentOS:
|
||||
case config.CentOS, config.Debian:
|
||||
// There are many packages that has been fixed in RedHat, but not been fixed in CentOS
|
||||
for name := range e.actuallyAffectedPackNames {
|
||||
pack, ok := packs[name]
|
||||
@@ -79,8 +79,7 @@ func (e defPacks) toPackStatuses(family string, packs models.Packages) (ps model
|
||||
return
|
||||
}
|
||||
|
||||
packNewVer := fmt.Sprintf("%s-%s", pack.NewVersion, pack.NewRelease)
|
||||
if packNewVer == "" {
|
||||
if pack.NewVersion == "" {
|
||||
// compare version: installed vs oval
|
||||
vera := rpmver.NewVersion(fmt.Sprintf("%s-%s", pack.Version, pack.Release))
|
||||
verb := rpmver.NewVersion(ovalPackVer)
|
||||
@@ -94,6 +93,7 @@ func (e defPacks) toPackStatuses(family string, packs models.Packages) (ps model
|
||||
})
|
||||
} else {
|
||||
// compare version: newVer vs oval
|
||||
packNewVer := fmt.Sprintf("%s-%s", pack.NewVersion, pack.NewRelease)
|
||||
vera := rpmver.NewVersion(packNewVer)
|
||||
verb := rpmver.NewVersion(ovalPackVer)
|
||||
notFixedYet := false
|
||||
@@ -193,11 +193,15 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult) (
|
||||
if res.pack.Name != p.Name {
|
||||
continue
|
||||
}
|
||||
|
||||
if p.NotFixedYet {
|
||||
relatedDefs.upsert(def, p.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
if less, err := lessThan(r.Family, *res.pack, p); err != nil {
|
||||
if !p.NotFixedYet {
|
||||
util.Log.Debugf("Failed to parse versions: %s", err)
|
||||
util.Log.Debugf("%#v\n%#v", *res.pack, p)
|
||||
}
|
||||
util.Log.Debugf("Failed to parse versions: %s", err)
|
||||
util.Log.Debugf("%#v\n%#v", *res.pack, p)
|
||||
} else if less {
|
||||
relatedDefs.upsert(def, p.Name)
|
||||
}
|
||||
@@ -278,23 +282,28 @@ func getDefsByPackNameFromOvalDB(family, osRelease string,
|
||||
return
|
||||
}
|
||||
defer ovaldb.CloseDB()
|
||||
for _, pack := range installedPacks {
|
||||
definitions, err := ovaldb.GetByPackName(osRelease, pack.Name)
|
||||
for _, installedPack := range installedPacks {
|
||||
definitions, err := ovaldb.GetByPackName(osRelease, installedPack.Name)
|
||||
if err != nil {
|
||||
return relatedDefs, fmt.Errorf("Failed to get %s OVAL info by package name: %v", family, err)
|
||||
}
|
||||
for _, def := range definitions {
|
||||
for _, p := range def.AffectedPacks {
|
||||
if pack.Name != p.Name {
|
||||
for _, ovalPack := range def.AffectedPacks {
|
||||
if installedPack.Name != ovalPack.Name {
|
||||
continue
|
||||
}
|
||||
if less, err := lessThan(family, pack, p); err != nil {
|
||||
if !p.NotFixedYet {
|
||||
util.Log.Debugf("Failed to parse versions: %s", err)
|
||||
util.Log.Debugf("%#v\n%#v", pack, p)
|
||||
}
|
||||
|
||||
if ovalPack.NotFixedYet {
|
||||
relatedDefs.upsert(def, installedPack.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
less, err := lessThan(family, installedPack, ovalPack)
|
||||
if err != nil {
|
||||
util.Log.Debugf("Failed to parse versions: %s", err)
|
||||
util.Log.Debugf("%#v\n%#v", installedPack, ovalPack)
|
||||
} else if less {
|
||||
relatedDefs.upsert(def, pack.Name)
|
||||
relatedDefs.upsert(def, installedPack.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,10 +170,6 @@ func FillWithOval(r *models.ScanResult) (err error) {
|
||||
case c.Oracle:
|
||||
ovalClient = oval.NewOracle()
|
||||
ovalFamily = c.Oracle
|
||||
//TODO
|
||||
// case c.Suse:
|
||||
// ovalClient = oval.New()
|
||||
// ovalFamily = c.Oracle
|
||||
case c.Amazon, c.Raspbian, c.FreeBSD:
|
||||
return nil
|
||||
default:
|
||||
|
||||
60
scan/base.go
60
scan/base.go
@@ -75,6 +75,27 @@ func (l *base) getPlatform() models.Platform {
|
||||
return l.Platform
|
||||
}
|
||||
|
||||
func (l *base) runningKernel() (release, version string, err error) {
|
||||
r := l.exec("uname -r", noSudo)
|
||||
if !r.isSuccess() {
|
||||
return "", "", fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
release = strings.TrimSpace(r.Stdout)
|
||||
|
||||
switch l.Distro.Family {
|
||||
case config.Debian:
|
||||
r := l.exec("uname -a", noSudo)
|
||||
if !r.isSuccess() {
|
||||
return "", "", fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
ss := strings.Fields(r.Stdout)
|
||||
if 6 < len(ss) {
|
||||
version = ss[6]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (l *base) allContainers() (containers []config.Container, err error) {
|
||||
switch l.ServerInfo.Containers.Type {
|
||||
case "", "docker":
|
||||
@@ -265,16 +286,6 @@ func (l *base) isAwsInstanceID(str string) bool {
|
||||
}
|
||||
|
||||
func (l *base) convertToModel() models.ScanResult {
|
||||
//TODO Remove
|
||||
// for _, p := range l.VulnInfos {
|
||||
// sort.Slice(p.Packages, func(i, j int) bool {
|
||||
// return p.Packages[i].Name < p.Packages[j].Name
|
||||
// })
|
||||
// }
|
||||
// sort.Slice(l.VulnInfos, func(i, j int) bool {
|
||||
// return l.VulnInfos[i].CveID < l.VulnInfos[j].CveID
|
||||
// })
|
||||
|
||||
ctype := l.ServerInfo.Containers.Type
|
||||
if l.ServerInfo.Container.ContainerID != "" && ctype == "" {
|
||||
ctype = "docker"
|
||||
@@ -291,24 +302,19 @@ func (l *base) convertToModel() models.ScanResult {
|
||||
errs = append(errs, fmt.Sprintf("%s", e))
|
||||
}
|
||||
|
||||
//TODO Remove
|
||||
// Avoid null slice being null in JSON
|
||||
// for cveID := range l.VulnInfos {
|
||||
// l.VulnInfos[i].NilToEmpty()
|
||||
// }
|
||||
|
||||
return models.ScanResult{
|
||||
JSONVersion: models.JSONVersion,
|
||||
ServerName: l.ServerInfo.ServerName,
|
||||
ScannedAt: time.Now(),
|
||||
Family: l.Distro.Family,
|
||||
Release: l.Distro.Release,
|
||||
Container: container,
|
||||
Platform: l.Platform,
|
||||
ScannedCves: l.VulnInfos,
|
||||
Packages: l.Packages,
|
||||
Optional: l.ServerInfo.Optional,
|
||||
Errors: errs,
|
||||
JSONVersion: models.JSONVersion,
|
||||
ServerName: l.ServerInfo.ServerName,
|
||||
ScannedAt: time.Now(),
|
||||
Family: l.Distro.Family,
|
||||
Release: l.Distro.Release,
|
||||
Container: container,
|
||||
Platform: l.Platform,
|
||||
ScannedCves: l.VulnInfos,
|
||||
RunningKernel: l.Kernel,
|
||||
Packages: l.Packages,
|
||||
Optional: l.ServerInfo.Optional,
|
||||
Errors: errs,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
110
scan/debian.go
110
scan/debian.go
@@ -154,56 +154,92 @@ func (o *debian) checkIfSudoNoPasswd() error {
|
||||
}
|
||||
|
||||
func (o *debian) checkDependencies() error {
|
||||
if !config.Conf.Deep {
|
||||
o.log.Infof("Dependencies... No need")
|
||||
return nil
|
||||
}
|
||||
packNames := []string{}
|
||||
|
||||
switch o.Distro.Family {
|
||||
case config.Ubuntu, config.Raspbian:
|
||||
o.log.Infof("Dependencies... No need")
|
||||
return nil
|
||||
|
||||
case config.Debian:
|
||||
// Debian needs aptitude to get changelogs.
|
||||
// Because unable to get changelogs via apt-get changelog on Debian.
|
||||
if r := o.exec("test -f /usr/bin/aptitude", noSudo); !r.isSuccess() {
|
||||
msg := fmt.Sprintf("aptitude is not installed: %s", r)
|
||||
o.log.Errorf(msg)
|
||||
return fmt.Errorf(msg)
|
||||
// https://askubuntu.com/a/742844
|
||||
packNames = append(packNames, "reboot-notifier")
|
||||
|
||||
if !config.Conf.Deep {
|
||||
// Debian needs aptitude to get changelogs.
|
||||
// Because unable to get changelogs via apt-get changelog on Debian.
|
||||
packNames = append(packNames, "aptitude")
|
||||
}
|
||||
o.log.Infof("Dependencies... Pass")
|
||||
return nil
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Not implemented yet: %s", o.Distro)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *debian) scanPackages() error {
|
||||
installed, updatable, err := o.scanInstalledPackages()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan installed packages")
|
||||
return err
|
||||
}
|
||||
o.setPackages(installed)
|
||||
|
||||
if config.Conf.Deep || o.Distro.Family == config.Raspbian {
|
||||
unsecure, err := o.scanUnsecurePackages(updatable)
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan vulnerable packages")
|
||||
return err
|
||||
for _, name := range packNames {
|
||||
//TODO --show-format
|
||||
cmd := "dpkg-query -W " + name
|
||||
if r := o.exec(cmd, noSudo); !r.isSuccess() {
|
||||
msg := fmt.Sprintf("%s is not installed", name)
|
||||
o.log.Errorf(msg)
|
||||
return fmt.Errorf(msg)
|
||||
}
|
||||
o.setVulnInfos(unsecure)
|
||||
return nil
|
||||
}
|
||||
|
||||
o.log.Infof("Dependencies... Pass")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *debian) scanInstalledPackages() (models.Packages, models.Packages, error) {
|
||||
installed := models.Packages{}
|
||||
updatable := models.Packages{}
|
||||
func (o *debian) scanPackages() error {
|
||||
// collect the running kernel information
|
||||
release, version, err := o.runningKernel()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan the running kernel version: %s", err)
|
||||
return err
|
||||
}
|
||||
rebootRequired, err := o.rebootRequired()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to detect the kernel reboot required: %s", err)
|
||||
return err
|
||||
}
|
||||
o.Kernel = models.Kernel{
|
||||
Version: version,
|
||||
Release: release,
|
||||
RebootRequired: rebootRequired,
|
||||
}
|
||||
|
||||
installed, updatable, err := o.scanInstalledPackages()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan installed packages: %s", err)
|
||||
return err
|
||||
}
|
||||
o.Packages = installed
|
||||
|
||||
if config.Conf.Deep || o.Distro.Family == config.Raspbian {
|
||||
unsecures, err := o.scanUnsecurePackages(updatable)
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan vulnerable packages: %s", err)
|
||||
return err
|
||||
}
|
||||
o.VulnInfos = unsecures
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// https://askubuntu.com/a/742844
|
||||
func (o *debian) rebootRequired() (bool, error) {
|
||||
r := o.exec("test -f /var/run/reboot-required", noSudo)
|
||||
switch r.ExitStatus {
|
||||
case 0:
|
||||
return true, nil
|
||||
case 1:
|
||||
return false, nil
|
||||
default:
|
||||
return false, fmt.Errorf("Failed to check reboot reauired: %s", r)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *debian) scanInstalledPackages() (models.Packages, models.Packages, error) {
|
||||
installed, updatable := models.Packages{}, models.Packages{}
|
||||
r := o.exec("dpkg-query -W", noSudo)
|
||||
if !r.isSuccess() {
|
||||
return nil, nil, fmt.Errorf("Failed to SSH: %s", r)
|
||||
@@ -336,9 +372,9 @@ func (o *debian) ensureChangelogCache(current cache.Meta) (*cache.Meta, error) {
|
||||
return &cached, nil
|
||||
}
|
||||
|
||||
func (o *debian) fillCandidateVersion(packages models.Packages) (err error) {
|
||||
func (o *debian) fillCandidateVersion(updatables models.Packages) (err error) {
|
||||
names := []string{}
|
||||
for name := range packages {
|
||||
for name := range updatables {
|
||||
names = append(names, name)
|
||||
}
|
||||
cmd := fmt.Sprintf("LANGUAGE=en_US.UTF-8 apt-cache policy %s", strings.Join(names, " "))
|
||||
@@ -352,18 +388,18 @@ func (o *debian) fillCandidateVersion(packages models.Packages) (err error) {
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to parse %s", err)
|
||||
}
|
||||
pack, ok := packages[k]
|
||||
pack, ok := updatables[k]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", k)
|
||||
}
|
||||
pack.NewVersion = ver.Candidate
|
||||
packages[k] = pack
|
||||
updatables[k] = pack
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *debian) getUpdatablePackNames() (packNames []string, err error) {
|
||||
cmd := util.PrependProxyEnv("LANGUAGE=en_US.UTF-8 apt-get upgrade --dry-run")
|
||||
cmd := util.PrependProxyEnv("LANGUAGE=en_US.UTF-8 apt-get dist-upgrade --dry-run")
|
||||
r := o.exec(cmd, noSudo)
|
||||
if r.isSuccess(0, 1) {
|
||||
return o.parseAptGetUpgrade(r.Stdout)
|
||||
|
||||
@@ -303,49 +303,7 @@ Reading state information... Done
|
||||
The following packages will be upgraded:
|
||||
apt ca-certificates cpio dpkg e2fslibs e2fsprogs gnupg gpgv libc-bin libc6 libcomerr2 libpcre3
|
||||
libpng12-0 libss2 libssl1.0.0 libudev0 multiarch-support openssl tzdata udev upstart
|
||||
21 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
|
||||
Inst dpkg [1.16.1.2ubuntu7.5] (1.16.1.2ubuntu7.7 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf dpkg (1.16.1.2ubuntu7.7 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst upstart [1.5-0ubuntu7.2] (1.5-0ubuntu7.3 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst libc-bin [2.15-0ubuntu10.10] (2.15-0ubuntu10.13 Ubuntu:12.04/precise-updates [amd64]) [libc6:amd64 ]
|
||||
Conf libc-bin (2.15-0ubuntu10.13 Ubuntu:12.04/precise-updates [amd64]) [libc6:amd64 ]
|
||||
Inst libc6 [2.15-0ubuntu10.10] (2.15-0ubuntu10.13 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf libc6 (2.15-0ubuntu10.13 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst libudev0 [175-0ubuntu9.9] (175-0ubuntu9.10 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst tzdata [2015a-0ubuntu0.12.04] (2015g-0ubuntu0.12.04 Ubuntu:12.04/precise-updates [all])
|
||||
Conf tzdata (2015g-0ubuntu0.12.04 Ubuntu:12.04/precise-updates [all])
|
||||
Inst e2fslibs [1.42-1ubuntu2] (1.42-1ubuntu2.3 Ubuntu:12.04/precise-updates [amd64]) [e2fsprogs:amd64 on e2fslibs:amd64] [e2fsprogs:amd64 ]
|
||||
Conf e2fslibs (1.42-1ubuntu2.3 Ubuntu:12.04/precise-updates [amd64]) [e2fsprogs:amd64 ]
|
||||
Inst e2fsprogs [1.42-1ubuntu2] (1.42-1ubuntu2.3 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf e2fsprogs (1.42-1ubuntu2.3 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst gpgv [1.4.11-3ubuntu2.7] (1.4.11-3ubuntu2.9 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf gpgv (1.4.11-3ubuntu2.9 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst gnupg [1.4.11-3ubuntu2.7] (1.4.11-3ubuntu2.9 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf gnupg (1.4.11-3ubuntu2.9 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst apt [0.8.16~exp12ubuntu10.22] (0.8.16~exp12ubuntu10.26 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf apt (0.8.16~exp12ubuntu10.26 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst libcomerr2 [1.42-1ubuntu2] (1.42-1ubuntu2.3 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf libcomerr2 (1.42-1ubuntu2.3 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst libss2 [1.42-1ubuntu2] (1.42-1ubuntu2.3 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf libss2 (1.42-1ubuntu2.3 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst libssl1.0.0 [1.0.1-4ubuntu5.21] (1.0.1-4ubuntu5.34 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf libssl1.0.0 (1.0.1-4ubuntu5.34 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst libpcre3 [8.12-4] (8.12-4ubuntu0.1 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst libpng12-0 [1.2.46-3ubuntu4] (1.2.46-3ubuntu4.2 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst multiarch-support [2.15-0ubuntu10.10] (2.15-0ubuntu10.13 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf multiarch-support (2.15-0ubuntu10.13 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst cpio [2.11-7ubuntu3.1] (2.11-7ubuntu3.2 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst udev [175-0ubuntu9.9] (175-0ubuntu9.10 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst openssl [1.0.1-4ubuntu5.33] (1.0.1-4ubuntu5.34 Ubuntu:12.04/precise-updates [amd64])
|
||||
Inst ca-certificates [20141019ubuntu0.12.04.1] (20160104ubuntu0.12.04.1 Ubuntu:12.04/precise-updates [all])
|
||||
Conf libudev0 (175-0ubuntu9.10 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf upstart (1.5-0ubuntu7.3 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf libpcre3 (8.12-4ubuntu0.1 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf libpng12-0 (1.2.46-3ubuntu4.2 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf cpio (2.11-7ubuntu3.2 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf udev (175-0ubuntu9.10 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf openssl (1.0.1-4ubuntu5.34 Ubuntu:12.04/precise-updates [amd64])
|
||||
Conf ca-certificates (20160104ubuntu0.12.04.1 Ubuntu:12.04/precise-updates [all])`,
|
||||
21 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.`,
|
||||
[]string{
|
||||
"apt",
|
||||
"ca-certificates",
|
||||
@@ -386,124 +344,6 @@ The following packages will be upgraded:
|
||||
ntpdate passwd python3.4 python3.4-minimal rsyslog sudo sysv-rc
|
||||
sysvinit-utils tzdata udev util-linux
|
||||
59 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
|
||||
Inst base-files [7.2ubuntu5.2] (7.2ubuntu5.4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf base-files (7.2ubuntu5.4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst coreutils [8.21-1ubuntu5.1] (8.21-1ubuntu5.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf coreutils (8.21-1ubuntu5.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst dpkg [1.17.5ubuntu5.3] (1.17.5ubuntu5.5 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf dpkg (1.17.5ubuntu5.5 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libc-bin [2.19-0ubuntu6.5] (2.19-0ubuntu6.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libc6 [2.19-0ubuntu6.5] (2.19-0ubuntu6.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libgcc1 [1:4.9.1-0ubuntu1] (1:4.9.3-0ubuntu4 Ubuntu:14.04/trusty-updates [amd64]) []
|
||||
Inst gcc-4.9-base [4.9.1-0ubuntu1] (4.9.3-0ubuntu4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf gcc-4.9-base (4.9.3-0ubuntu4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libgcc1 (1:4.9.3-0ubuntu4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libc6 (2.19-0ubuntu6.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libc-bin (2.19-0ubuntu6.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst e2fslibs [1.42.9-3ubuntu1] (1.42.9-3ubuntu1.3 Ubuntu:14.04/trusty-updates [amd64]) [e2fsprogs:amd64 on e2fslibs:amd64] [e2fsprogs:amd64 ]
|
||||
Conf e2fslibs (1.42.9-3ubuntu1.3 Ubuntu:14.04/trusty-updates [amd64]) [e2fsprogs:amd64 ]
|
||||
Inst e2fsprogs [1.42.9-3ubuntu1] (1.42.9-3ubuntu1.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf e2fsprogs (1.42.9-3ubuntu1.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst login [1:4.1.5.1-1ubuntu9] (1:4.1.5.1-1ubuntu9.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf login (1:4.1.5.1-1ubuntu9.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst mount [2.20.1-5.1ubuntu20.4] (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf mount (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst tzdata [2015a-0ubuntu0.14.04] (2015g-0ubuntu0.14.04 Ubuntu:14.04/trusty-updates [all])
|
||||
Conf tzdata (2015g-0ubuntu0.14.04 Ubuntu:14.04/trusty-updates [all])
|
||||
Inst sysvinit-utils [2.88dsf-41ubuntu6] (2.88dsf-41ubuntu6.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst sysv-rc [2.88dsf-41ubuntu6] (2.88dsf-41ubuntu6.3 Ubuntu:14.04/trusty-updates [all])
|
||||
Conf sysv-rc (2.88dsf-41ubuntu6.3 Ubuntu:14.04/trusty-updates [all])
|
||||
Conf sysvinit-utils (2.88dsf-41ubuntu6.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst util-linux [2.20.1-5.1ubuntu20.4] (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf util-linux (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst gcc-4.8-base [4.8.2-19ubuntu1] (4.8.4-2ubuntu1~14.04.1 Ubuntu:14.04/trusty-updates [amd64]) [libstdc++6:amd64 ]
|
||||
Conf gcc-4.8-base (4.8.4-2ubuntu1~14.04.1 Ubuntu:14.04/trusty-updates [amd64]) [libstdc++6:amd64 ]
|
||||
Inst libstdc++6 [4.8.2-19ubuntu1] (4.8.4-2ubuntu1~14.04.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libstdc++6 (4.8.4-2ubuntu1~14.04.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libapt-pkg4.12 [1.0.1ubuntu2.6] (1.0.1ubuntu2.11 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libapt-pkg4.12 (1.0.1ubuntu2.11 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst gpgv [1.4.16-1ubuntu2.1] (1.4.16-1ubuntu2.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf gpgv (1.4.16-1ubuntu2.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst gnupg [1.4.16-1ubuntu2.1] (1.4.16-1ubuntu2.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf gnupg (1.4.16-1ubuntu2.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst apt [1.0.1ubuntu2.6] (1.0.1ubuntu2.11 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf apt (1.0.1ubuntu2.11 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst bsdutils [1:2.20.1-5.1ubuntu20.4] (1:2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf bsdutils (1:2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst passwd [1:4.1.5.1-1ubuntu9] (1:4.1.5.1-1ubuntu9.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf passwd (1:4.1.5.1-1ubuntu9.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libuuid1 [2.20.1-5.1ubuntu20.4] (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libuuid1 (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libblkid1 [2.20.1-5.1ubuntu20.4] (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libblkid1 (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libcomerr2 [1.42.9-3ubuntu1] (1.42.9-3ubuntu1.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libcomerr2 (1.42.9-3ubuntu1.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libmount1 [2.20.1-5.1ubuntu20.4] (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libmount1 (2.20.1-5.1ubuntu20.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libpcre3 [1:8.31-2ubuntu2] (1:8.31-2ubuntu2.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libpcre3 (1:8.31-2ubuntu2.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libss2 [1.42.9-3ubuntu1] (1.42.9-3ubuntu1.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libss2 (1.42.9-3ubuntu1.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libapt-inst1.5 [1.0.1ubuntu2.6] (1.0.1ubuntu2.11 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libexpat1 [2.1.0-4ubuntu1] (2.1.0-4ubuntu1.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libffi6 [3.1~rc1+r3.0.13-12] (3.1~rc1+r3.0.13-12ubuntu0.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libgcrypt11 [1.5.3-2ubuntu4.1] (1.5.3-2ubuntu4.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libtasn1-6 [3.4-3ubuntu0.1] (3.4-3ubuntu0.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libgnutls-openssl27 [2.12.23-12ubuntu2.1] (2.12.23-12ubuntu2.4 Ubuntu:14.04/trusty-updates [amd64]) []
|
||||
Inst libgnutls26 [2.12.23-12ubuntu2.1] (2.12.23-12ubuntu2.4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libsqlite3-0 [3.8.2-1ubuntu2] (3.8.2-1ubuntu2.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst python3.4 [3.4.0-2ubuntu1] (3.4.3-1ubuntu1~14.04.3 Ubuntu:14.04/trusty-updates [amd64]) []
|
||||
Inst libpython3.4-stdlib [3.4.0-2ubuntu1] (3.4.3-1ubuntu1~14.04.3 Ubuntu:14.04/trusty-updates [amd64]) []
|
||||
Inst python3.4-minimal [3.4.0-2ubuntu1] (3.4.3-1ubuntu1~14.04.3 Ubuntu:14.04/trusty-updates [amd64]) []
|
||||
Inst libssl1.0.0 [1.0.1f-1ubuntu2.8] (1.0.1f-1ubuntu2.16 Ubuntu:14.04/trusty-updates [amd64]) []
|
||||
Inst libpython3.4-minimal [3.4.0-2ubuntu1] (3.4.3-1ubuntu1~14.04.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst ntpdate [1:4.2.6.p5+dfsg-3ubuntu2.14.04.2] (1:4.2.6.p5+dfsg-3ubuntu2.14.04.8 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libdrm2 [2.4.56-1~ubuntu2] (2.4.64-1~ubuntu14.04.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libpng12-0 [1.2.50-1ubuntu2] (1.2.50-1ubuntu2.14.04.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst initscripts [2.88dsf-41ubuntu6] (2.88dsf-41ubuntu6.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst libcgmanager0 [0.24-0ubuntu7.3] (0.24-0ubuntu7.5 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst udev [204-5ubuntu20.10] (204-5ubuntu20.18 Ubuntu:14.04/trusty-updates [amd64]) []
|
||||
Inst libudev1 [204-5ubuntu20.10] (204-5ubuntu20.18 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst multiarch-support [2.19-0ubuntu6.5] (2.19-0ubuntu6.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf multiarch-support (2.19-0ubuntu6.7 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst apt-utils [1.0.1ubuntu2.6] (1.0.1ubuntu2.11 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst dh-python [1.20140128-1ubuntu8] (1.20140128-1ubuntu8.2 Ubuntu:14.04/trusty-updates [all])
|
||||
Inst iproute2 [3.12.0-2] (3.12.0-2ubuntu1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst ifupdown [0.7.47.2ubuntu4.1] (0.7.47.2ubuntu4.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst isc-dhcp-client [4.2.4-7ubuntu12] (4.2.4-7ubuntu12.4 Ubuntu:14.04/trusty-updates [amd64]) []
|
||||
Inst isc-dhcp-common [4.2.4-7ubuntu12] (4.2.4-7ubuntu12.4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst rsyslog [7.4.4-1ubuntu2.5] (7.4.4-1ubuntu2.6 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst sudo [1.8.9p5-1ubuntu1] (1.8.9p5-1ubuntu1.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Inst cpio [2.11+dfsg-1ubuntu1.1] (2.11+dfsg-1ubuntu1.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libapt-inst1.5 (1.0.1ubuntu2.11 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libexpat1 (2.1.0-4ubuntu1.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libffi6 (3.1~rc1+r3.0.13-12ubuntu0.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libgcrypt11 (1.5.3-2ubuntu4.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libtasn1-6 (3.4-3ubuntu0.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libgnutls26 (2.12.23-12ubuntu2.4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libgnutls-openssl27 (2.12.23-12ubuntu2.4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libsqlite3-0 (3.8.2-1ubuntu2.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libssl1.0.0 (1.0.1f-1ubuntu2.16 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libpython3.4-minimal (3.4.3-1ubuntu1~14.04.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf python3.4-minimal (3.4.3-1ubuntu1~14.04.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libpython3.4-stdlib (3.4.3-1ubuntu1~14.04.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf python3.4 (3.4.3-1ubuntu1~14.04.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf ntpdate (1:4.2.6.p5+dfsg-3ubuntu2.14.04.8 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libdrm2 (2.4.64-1~ubuntu14.04.1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libpng12-0 (1.2.50-1ubuntu2.14.04.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf initscripts (2.88dsf-41ubuntu6.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libcgmanager0 (0.24-0ubuntu7.5 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf libudev1 (204-5ubuntu20.18 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf udev (204-5ubuntu20.18 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf apt-utils (1.0.1ubuntu2.11 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf dh-python (1.20140128-1ubuntu8.2 Ubuntu:14.04/trusty-updates [all])
|
||||
Conf iproute2 (3.12.0-2ubuntu1 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf ifupdown (0.7.47.2ubuntu4.3 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf isc-dhcp-common (4.2.4-7ubuntu12.4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf isc-dhcp-client (4.2.4-7ubuntu12.4 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf rsyslog (7.4.4-1ubuntu2.6 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf sudo (1.8.9p5-1ubuntu1.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
Conf cpio (2.11+dfsg-1ubuntu1.2 Ubuntu:14.04/trusty-updates [amd64])
|
||||
`,
|
||||
[]string{
|
||||
"apt",
|
||||
|
||||
@@ -78,23 +78,48 @@ func (o *bsd) checkDependencies() error {
|
||||
}
|
||||
|
||||
func (o *bsd) scanPackages() error {
|
||||
var err error
|
||||
var packs models.Packages
|
||||
if packs, err = o.scanInstalledPackages(); err != nil {
|
||||
o.log.Errorf("Failed to scan installed packages")
|
||||
// collect the running kernel information
|
||||
release, version, err := o.runningKernel()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan the running kernel version: %s", err)
|
||||
return err
|
||||
}
|
||||
o.setPackages(packs)
|
||||
o.Kernel = models.Kernel{
|
||||
Release: release,
|
||||
Version: version,
|
||||
}
|
||||
|
||||
var vinfos models.VulnInfos
|
||||
if vinfos, err = o.scanUnsecurePackages(); err != nil {
|
||||
o.log.Errorf("Failed to scan vulnerable packages")
|
||||
rebootRequired, err := o.rebootRequired()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to detect the kernel reboot required: %s", err)
|
||||
return err
|
||||
}
|
||||
o.setVulnInfos(vinfos)
|
||||
o.Kernel.RebootRequired = rebootRequired
|
||||
|
||||
packs, err := o.scanInstalledPackages()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan installed packages: %s", err)
|
||||
return err
|
||||
}
|
||||
o.Packages = packs
|
||||
|
||||
unsecures, err := o.scanUnsecurePackages()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan vulnerable packages: %s", err)
|
||||
return err
|
||||
}
|
||||
o.VulnInfos = unsecures
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *bsd) rebootRequired() (bool, error) {
|
||||
r := o.exec("freebsd-version -k", noSudo)
|
||||
if !r.isSuccess() {
|
||||
return false, fmt.Errorf("Failed to SSH: %s", r)
|
||||
}
|
||||
return o.Kernel.Release != strings.TrimSpace(r.Stdout), nil
|
||||
}
|
||||
|
||||
func (o *bsd) scanInstalledPackages() (models.Packages, error) {
|
||||
cmd := util.PrependProxyEnv("pkg version -v")
|
||||
r := o.exec(cmd, noSudo)
|
||||
|
||||
@@ -223,32 +223,58 @@ func (o *redhat) checkDependencies() error {
|
||||
func (o *redhat) scanPackages() error {
|
||||
installed, err := o.scanInstalledPackages()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan installed packages")
|
||||
o.log.Errorf("Failed to scan installed packages: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
rebootRequired, err := o.rebootRequired()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to detect the kernel reboot required: %s", err)
|
||||
return err
|
||||
}
|
||||
o.Kernel.RebootRequired = rebootRequired
|
||||
|
||||
updatable, err := o.scanUpdatablePackages()
|
||||
if err != nil {
|
||||
o.log.Errorf("Failed to scan installed packages")
|
||||
o.log.Errorf("Failed to scan installed packages: %s", err)
|
||||
return err
|
||||
}
|
||||
installed.MergeNewVersion(updatable)
|
||||
o.setPackages(installed)
|
||||
o.Packages = installed
|
||||
|
||||
if !config.Conf.Deep && o.Distro.Family != config.Amazon {
|
||||
return nil
|
||||
}
|
||||
|
||||
var vinfos models.VulnInfos
|
||||
if vinfos, err = o.scanUnsecurePackages(updatable); err != nil {
|
||||
o.log.Errorf("Failed to scan vulnerable packages")
|
||||
var unsecures models.VulnInfos
|
||||
if unsecures, err = o.scanUnsecurePackages(updatable); err != nil {
|
||||
o.log.Errorf("Failed to scan vulnerable packages: %s", err)
|
||||
return err
|
||||
}
|
||||
o.setVulnInfos(vinfos)
|
||||
o.VulnInfos = unsecures
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *redhat) rebootRequired() (bool, error) {
|
||||
r := o.exec("rpm -q --last kernel | head -n1", noSudo)
|
||||
if !r.isSuccess() {
|
||||
return false, fmt.Errorf("Failed to detect the last installed kernel : %v", r)
|
||||
}
|
||||
lastInstalledKernelVer := strings.Fields(r.Stdout)[0]
|
||||
running := fmt.Sprintf("kernel-%s", o.Kernel.Release)
|
||||
return running != lastInstalledKernelVer, nil
|
||||
}
|
||||
|
||||
func (o *redhat) scanInstalledPackages() (models.Packages, error) {
|
||||
release, version, err := o.runningKernel()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
o.Kernel = models.Kernel{
|
||||
Release: release,
|
||||
Version: version,
|
||||
}
|
||||
|
||||
installed := models.Packages{}
|
||||
var cmd string
|
||||
majorVersion, _ := o.Distro.MajorVersion()
|
||||
@@ -258,24 +284,35 @@ func (o *redhat) scanInstalledPackages() (models.Packages, error) {
|
||||
cmd = "rpm -qa --queryformat '%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH}\n'"
|
||||
}
|
||||
r := o.exec(cmd, noSudo)
|
||||
if r.isSuccess() {
|
||||
// openssl 0 1.0.1e 30.el6.11 x86_64
|
||||
lines := strings.Split(r.Stdout, "\n")
|
||||
for _, line := range lines {
|
||||
if trimed := strings.TrimSpace(line); len(trimed) != 0 {
|
||||
pack, err := o.parseInstalledPackagesLine(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
installed[pack.Name] = pack
|
||||
}
|
||||
}
|
||||
return installed, nil
|
||||
if !r.isSuccess() {
|
||||
return nil, fmt.Errorf("Scan packages failed: %s", r)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Scan packages failed. status: %d, stdout: %s, stderr: %s",
|
||||
r.ExitStatus, r.Stdout, r.Stderr)
|
||||
// openssl 0 1.0.1e 30.el6.11 x86_64
|
||||
lines := strings.Split(r.Stdout, "\n")
|
||||
for _, line := range lines {
|
||||
if trimed := strings.TrimSpace(line); len(trimed) != 0 {
|
||||
pack, err := o.parseInstalledPackagesLine(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Kernel package may be isntalled multiple versions.
|
||||
// From the viewpoint of vulnerability detection,
|
||||
// pay attention only to the running kernel
|
||||
if pack.Name == "kernel" {
|
||||
ver := fmt.Sprintf("%s-%s.%s", pack.Version, pack.Release, pack.Arch)
|
||||
if o.Kernel.Release != ver {
|
||||
o.log.Debugf("Not a running kernel: %s, uname: %s", ver, release)
|
||||
continue
|
||||
} else {
|
||||
o.log.Debugf("Running kernel: %s, uname: %s", ver, release)
|
||||
}
|
||||
}
|
||||
installed[pack.Name] = pack
|
||||
}
|
||||
}
|
||||
return installed, nil
|
||||
}
|
||||
|
||||
func (o *redhat) parseInstalledPackagesLine(line string) (models.Package, error) {
|
||||
|
||||
@@ -667,14 +667,14 @@ python-ordereddict 0 1.1 3.el6ev installed
|
||||
bind-utils 30 9.3.6 25.P1.el5_11.8 updates
|
||||
pytalloc 0 2.0.7 2.el6 @CentOS 6.5/6.5`
|
||||
|
||||
r.setPackages(models.NewPackages(
|
||||
r.Packages = models.NewPackages(
|
||||
models.Package{Name: "audit-libs"},
|
||||
models.Package{Name: "bash"},
|
||||
models.Package{Name: "python-libs"},
|
||||
models.Package{Name: "python-ordereddict"},
|
||||
models.Package{Name: "bind-utils"},
|
||||
models.Package{Name: "pytalloc"},
|
||||
))
|
||||
)
|
||||
var tests = []struct {
|
||||
in string
|
||||
out models.Packages
|
||||
|
||||
@@ -63,14 +63,9 @@ type osPackages struct {
|
||||
|
||||
// unsecure packages
|
||||
VulnInfos models.VulnInfos
|
||||
}
|
||||
|
||||
func (p *osPackages) setPackages(pi models.Packages) {
|
||||
p.Packages = pi
|
||||
}
|
||||
|
||||
func (p *osPackages) setVulnInfos(vi models.VulnInfos) {
|
||||
p.VulnInfos = vi
|
||||
// kernel information
|
||||
Kernel models.Kernel
|
||||
}
|
||||
|
||||
func detectOS(c config.ServerInfo) (osType osTypeInterface) {
|
||||
|
||||
Reference in New Issue
Block a user