Add Oracle Linux support (#386)

Adding support for Oracle Linux
This commit is contained in:
Avi Miller
2017-03-16 19:07:43 +11:00
committed by Kota Kanbe
parent 6342cf79f5
commit 986762ca85
5 changed files with 188 additions and 43 deletions

View File

@@ -46,7 +46,7 @@ Vuls is a tool created to solve the problems listed above. It has the following
# Main Features
- Scan for any vulnerabilities in Linux/FreeBSD Server
- Supports Ubuntu, Debian, CentOS, Amazon Linux, RHEL, FreeBSD and Raspbian
- Supports Ubuntu, Debian, CentOS, Amazon Linux, RHEL, Oracle Linux, FreeBSD and Raspbian
- Cloud, on-premise, Docker
- Scan middleware that are not included in OS package management
- Scan middleware, programming language libraries and framework for vulnerability
@@ -361,15 +361,16 @@ Scan speed is fast and resource usage is light.
- On Amazon, RHEL and FreeBSD
High speed scan and resource usage is light because Vuls can get CVE IDs by using package manager(no need to parse a changelog).
| Distribution| Scan Speed |
|:------------|:-------------------|
| Ubuntu | First time: Slow / From the second time: Fast |
| Debian | First time: Slow / From the second time: Fast |
| CentOS | Fast |
| Amazon | Fast |
| RHEL | Fast |
| FreeBSD | Fast |
| Raspbian | First time: Slow / From the second time: Fast |
| Distribution | Scan Speed |
|:-------------|:-------------------|
| Ubuntu | First time: Slow / From the second time: Fast |
| Debian | First time: Slow / From the second time: Fast |
| CentOS | Fast |
| Amazon | Fast |
| RHEL | Fast |
| Oracle Linux | Fast |
| FreeBSD | Fast |
| Raspbian | First time: Slow / From the second time: Fast |
----
@@ -393,15 +394,16 @@ If there is a staging environment with the same configuration as the production
# Support OS
| Distribution| Release |
|:------------|-------------------:|
| Ubuntu | 12, 14, 16|
| Debian | 7, 8|
| RHEL | 5, 6, 7|
| CentOS | 6, 7|
| Amazon Linux| All|
| FreeBSD | 10, 11|
| Raspbian | Wheezy, Jessie |
| Distribution | Release |
|:-------------|-------------------:|
| Ubuntu | 12, 14, 16|
| Debian | 7, 8|
| RHEL | 5, 6, 7|
| Oracle Linux | 5, 6, 7|
| CentOS | 6, 7|
| Amazon Linux | All|
| FreeBSD | 10, 11|
| Raspbian | Wheezy, Jessie |
----
@@ -623,16 +625,18 @@ The configtest subcommand checks the following
In order to scan, the following dependencies are required, so you need to install them manually or with tools such as Ansible.
| Distribution| Release | Requirements |
|:------------|-------------------:|:-------------|
| Ubuntu | 12, 14, 16| - |
| Debian | 7, 8| aptitude |
| CentOS | 6, 7| yum-plugin-changelog |
| Amazon | All | - |
| RHEL | 5 | yum-security |
| RHEL | 6, 7 | - |
| FreeBSD | 10 | - |
| Raspbian | Wheezy, Jessie | - |
| Distribution | Release | Requirements |
|:-------------|-------------------:|:-------------|
| Ubuntu | 12, 14, 16| - |
| Debian | 7, 8| aptitude |
| CentOS | 6, 7| yum-plugin-changelog |
| Amazon | All | - |
| RHEL | 5 | yum-security |
| RHEL | 6, 7 | - |
| Oracle Linux | 5 | yum-security |
| Oracle Linux | 6, 7 | - |
| FreeBSD | 10 | - |
| Raspbian | Wheezy, Jessie | - |
## Check /etc/sudoers
@@ -646,13 +650,13 @@ vuls ALL=(ALL) NOPASSWD:/usr/bin/yum --changelog --assumeno update *
Defaults:vuls env_keep="http_proxy https_proxy HTTP_PROXY HTTPS_PROXY"
```
- RHEL 5
- RHEL 5 / Oracle Linux 5
```
vuls ALL=(ALL) NOPASSWD:/usr/bin/yum --color=never repolist, /usr/bin/yum --color=never list-security --security, /usr/bin/yum --color=never check-update, /usr/bin/yum --color=never info-security
Defaults:vuls env_keep="http_proxy https_proxy HTTP_PROXY HTTPS_PROXY"
```
- RHEL 6, 7
- RHEL 6, 7 / Oracle Linux 6, 7
```
vuls ALL=(ALL) NOPASSWD:/usr/bin/yum --color=never repolist, /usr/bin/yum --color=never --security updateinfo list updates, /usr/bin/yum --color=never check-update, /usr/bin/yum --color=never --security updateinfo updates
Defaults:vuls env_keep="http_proxy https_proxy HTTP_PROXY HTTPS_PROXY"
@@ -1033,6 +1037,7 @@ Confidence 100 / YumUpdateSecurityMatch
- `CWE` means [CWE - Common Weakness Enumeration](https://nvd.nist.gov/cwe.cfm) of the CVE.
- `NVD` `MITRE` `CVE Details` `CVSS Caluculator`
- `RHEL-CVE` means the URL of OS distributor support.
- `Oracle-CVE` means the URL of the Oracle Linux errata information.
- `Package` shows the package version information including this vulnerability.
- `Confidence` means the reliability of detection.
- `100` is highly reliable
@@ -1041,7 +1046,7 @@ Confidence 100 / YumUpdateSecurityMatch
| Detection Method | Confidence | OS |Description|
|:-----------------------|-------------------:|:---------------------------------|:--|
| YumUpdateSecurityMatch | 100 | RHEL, Amazon Linux |Detection using yum-plugin-security|
| YumUpdateSecurityMatch | 100 | RHEL, Oracle Linux, Amazon Linux |Detection using yum-plugin-security|
| ChangelogExactMatch | 95 | CentOS, Ubuntu, Debian, Raspbian |Exact version match between changelog and package version|
| ChangelogLenientMatch | 50 | Ubuntu, Debian, Raspbian |Lenient version match between changelog and package version|
| PkgAuditMatch | 100 | FreeBSD |Detection using pkg audit|

View File

@@ -393,6 +393,21 @@ func distroLinks(cveInfo models.CveInfo, osFamily string) []distroLink {
})
}
return links
case "oraclelinux":
links := []distroLink{
{
"Oracle-CVE",
fmt.Sprintf(oracleSecurityBaseURL, cveID),
},
}
for _, advisory := range cveInfo.DistroAdvisories {
links = append(links, distroLink{
// "Oracle-ELSA"
advisory.AdvisoryID,
fmt.Sprintf(oracleELSABaseBaseURL, advisory.AdvisoryID),
})
}
return links
case "amazon":
links := []distroLink{
{

View File

@@ -33,6 +33,8 @@ const (
redhatSecurityBaseURL = "https://access.redhat.com/security/cve"
redhatRHSABaseBaseURL = "https://rhn.redhat.com/errata/%s.html"
amazonSecurityBaseURL = "https://alas.aws.amazon.com/%s.html"
oracleSecurityBaseURL = "https://linux.oracle.com/cve/%s.html"
oracleELSABaseBaseURL = "https://linux.oracle.com/errata/%s.html"
ubuntuSecurityBaseURL = "http://people.ubuntu.com/~ubuntu-security/cve"
debianTrackerBaseURL = "https://security-tracker.debian.org/tracker"

View File

@@ -54,6 +54,23 @@ func detectRedhat(c config.ServerInfo) (itsMe bool, red osTypeInterface) {
return true, red
}
if r := exec(c, "ls /etc/oracle-release", noSudo); r.isSuccess() {
// Need to discover Oracle Linux first, because it provides an
// /etc/redhat-release that matches the upstream distribution
if r := exec(c, "cat /etc/oracle-release", noSudo); r.isSuccess() {
re := regexp.MustCompile(`(.*) release (\d[\d.]*)`)
result := re.FindStringSubmatch(strings.TrimSpace(r.Stdout))
if len(result) != 3 {
util.Log.Warn("Failed to parse Oracle Linux version: %s", r)
return true, red
}
release := result[2]
red.setDistro("oraclelinux", release)
return true, red
}
}
if r := exec(c, "ls /etc/redhat-release", noSudo); r.isSuccess() {
// https://www.rackaid.com/blog/how-to-determine-centos-or-red-hat-version/
// e.g.
@@ -115,7 +132,7 @@ func (o *redhat) checkIfSudoNoPasswd() error {
{"yum --changelog --assumeno update yum", []int{0, 1}},
}
case "rhel":
case "rhel", "oraclelinux":
majorVersion, err := o.Distro.MajorVersion()
if err != nil {
return fmt.Errorf("Not implemented yet: %s, err: %s", o.Distro, err)
@@ -187,7 +204,7 @@ func (o *redhat) checkDependencies() error {
switch o.Distro.Family {
case "centos":
packName = "yum-plugin-changelog"
case "rhel":
case "rhel", "oraclelinux":
if majorVersion < 6 {
packName = "yum-security"
} else {
@@ -265,7 +282,7 @@ func (o *redhat) parseScannedPackagesLine(line string) (models.PackageInfo, erro
func (o *redhat) scanVulnInfos() ([]models.VulnInfo, error) {
if o.Distro.Family != "centos" {
// Amazon, RHEL has yum updateinfo as default
// Amazon, RHEL, Oracle Linux has yum updateinfo as default
// yum updateinfo can collenct vendor advisory information.
return o.scanUnsecurePackagesUsingYumPluginSecurity()
}
@@ -608,7 +625,7 @@ type distroAdvisoryCveIDs struct {
}
// Scaning unsecure packages using yum-plugin-security.
// Amazon, RHEL
// Amazon, RHEL, Oracle Linux
func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (models.VulnInfos, error) {
if o.Distro.Family == "centos" {
// CentOS has no security channel.
@@ -623,13 +640,13 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (models.VulnInfos,
return nil, fmt.Errorf("Failed to SSH: %s", r)
}
// get advisoryID(RHSA, ALAS) - package name,version
// get advisoryID(RHSA, ALAS, ELSA) - package name,version
major, err := (o.Distro.MajorVersion())
if err != nil {
return nil, fmt.Errorf("Not implemented yet: %s, err: %s", o.Distro, err)
}
if o.Distro.Family == "rhel" && major == 5 {
if (o.Distro.Family == "rhel" || o.Distro.Family == "oraclelinux") && major == 5 {
cmd = "yum --color=never list-security --security"
} else {
cmd = "yum --color=never --security updateinfo list updates"
@@ -671,8 +688,8 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (models.VulnInfos,
dict[advIDPackNames.AdvisoryID] = packInfoList
}
// get advisoryID(RHSA, ALAS) - CVE IDs
if o.Distro.Family == "rhel" && major == 5 {
// get advisoryID(RHSA, ALAS, ELSA) - CVE IDs
if (o.Distro.Family == "rhel" || o.Distro.Family == "oraclelinux") && major == 5 {
cmd = "yum --color=never info-security"
} else {
cmd = "yum --color=never --security updateinfo updates"
@@ -772,7 +789,7 @@ func (o *redhat) parseYumUpdateinfo(stdout string) (result []distroAdvisoryCveID
// So use yum check-update && parse changelog
return result, fmt.Errorf(
"yum updateinfo is not suppported on CentOS")
case "rhel", "amazon":
case "rhel", "amazon", "oraclelinux":
// nop
}
@@ -933,14 +950,15 @@ func (o *redhat) extractPackNameVerRel(nameVerRel string) (name, ver, rel string
return
}
// parseYumUpdateinfoListAvailable collect AdvisorID(RHSA, ALAS), packages
// parseYumUpdateinfoListAvailable collect AdvisorID(RHSA, ALAS, ELSA), packages
func (o *redhat) parseYumUpdateinfoListAvailable(stdout string) (advisoryIDPacksList, error) {
result := []advisoryIDPacks{}
lines := strings.Split(stdout, "\n")
for _, line := range lines {
if !(strings.HasPrefix(line, "RHSA") ||
strings.HasPrefix(line, "ALAS")) {
strings.HasPrefix(line, "ALAS") ||
strings.HasPrefix(line, "ELSA")) {
continue
}

View File

@@ -344,6 +344,111 @@ func TestParseYumUpdateinfoToGetSeverity(t *testing.T) {
}
}
func TestParseYumUpdateinfoOL(t *testing.T) {
stdout := `===============================================================================
bind security update
===============================================================================
Update ID : ELSA-2017-0276
Release : Oracle Linux 7
Type : security
Status : final
Issued : 2017-02-15
CVEs : CVE-2017-3135
Description : [32:9.9.4-38.2]
: - Fix CVE-2017-3135 (ISC change 4557)
: - Fix and test caching CNAME before DNAME (ISC
: change 4558)
Severity : Moderate
===============================================================================
openssl security update
===============================================================================
Update ID : ELSA-2017-0286
Release : Oracle Linux 7
Type : security
Status : final
Issued : 2017-02-15
CVEs : CVE-2016-8610
: CVE-2017-3731
Description : [1.0.1e-48.4]
: - fix CVE-2017-3731 - DoS via truncated packets
: with RC4-MD5 cipher
: - fix CVE-2016-8610 - DoS of single-threaded
: servers via excessive alerts
Severity : Moderate
===============================================================================
Unbreakable Enterprise kernel security update
===============================================================================
Update ID : ELSA-2017-3520
Release : Oracle Linux 7
Type : security
Status : final
Issued : 2017-02-15
CVEs : CVE-2017-6074
Description : kernel-uek
: [4.1.12-61.1.28]
: - dccp: fix freeing skb too early for
: IPV6_RECVPKTINFO (Andrey Konovalov) [Orabug:
: 25598257] {CVE-2017-6074}
Severity : Important
`
issued, _ := time.Parse("2006-01-02", "2017-02-15")
r := newRedhat(config.ServerInfo{})
r.Distro = config.Distro{Family: "oraclelinux"}
var tests = []struct {
in string
out []distroAdvisoryCveIDs
}{
{
stdout,
[]distroAdvisoryCveIDs{
{
DistroAdvisory: models.DistroAdvisory{
AdvisoryID: "ELSA-2017-0276",
Severity: "Moderate",
Issued: issued,
},
CveIDs: []string{"CVE-2017-3135"},
},
{
DistroAdvisory: models.DistroAdvisory{
AdvisoryID: "ELSA-2017-0286",
Severity: "Moderate",
Issued: issued,
},
CveIDs: []string{
"CVE-2016-8610",
"CVE-2017-3731",
},
},
{
DistroAdvisory: models.DistroAdvisory{
AdvisoryID: "ELSA-2017-3520",
Severity: "Important",
Issued: issued,
},
CveIDs: []string{"CVE-2017-6074"},
},
},
},
}
for _, tt := range tests {
actual, _ := r.parseYumUpdateinfo(tt.in)
for i, advisoryCveIDs := range actual {
if !reflect.DeepEqual(tt.out[i], advisoryCveIDs) {
e := pp.Sprintf("%v", tt.out[i])
a := pp.Sprintf("%v", advisoryCveIDs)
t.Errorf("[%d] Alas is not same. \nexpected: %s\nactual: %s",
i, e, a)
}
}
}
}
func TestParseYumUpdateinfoRHEL(t *testing.T) {
stdout := `===============================================================================