Completed
Pull Request — master (#769)
by
unknown
05:02
created

scan.rpmQa   A

Complexity

Conditions 5

Size

Total Lines 14
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
dl 0
loc 14
rs 9.3333
c 0
b 0
f 0
nop 1
1
/* Vuls - Vulnerability Scanner
2
Copyright (C) 2016  Future Corporation , Japan.
3
4
This program is free software: you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation, either version 3 of the License, or
7
(at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
package scan
19
20
import (
21
	"fmt"
22
	"strings"
23
	"encoding/json"
24
25
	"github.com/future-architect/vuls/config"
26
	"github.com/future-architect/vuls/models"
27
	"github.com/future-architect/vuls/util"
28
	"github.com/k0kubun/pp"
29
	"time"
30
)
31
32
func Wpscan() (err error) {
0 ignored issues
show
introduced by
exported function Wpscan should have comment or be unexported
Loading history...
33
	if err = wpscanVuln(); err != nil {
34
		return err
35
	}
36
	return
37
}
38
39
func wpscanVuln() (err error) {
40
	errChan := make(chan error, len(config.Conf.Servers))
41
	defer close(errChan)
42
	for _, s := range config.Conf.Servers {
43
		go func(s config.ServerInfo) {
44
			defer func() {
45
				if p := recover(); p != nil {
46
					util.Log.Debugf("Panic: %s on %s", p, s.ServerName)
47
				}
48
			}()
49
			errChan <- detectWp(s)
50
		}(s)
51
	}
52
53
	timeout := time.After(time.Duration(10000) * time.Second)
54
	for i := 0; i < len(config.Conf.Servers); i++ {
55
		select {
56
		case _ = <-errChan:
57
		/*
58
			if 0 < len(res.getErrs()) {
59
				errServers = append(errServers, res)
60
				util.Log.Errorf("(%d/%d) Failed: %s, err: %s",
61
					i+1, len(config.Conf.Servers),
62
					res.getServerInfo().ServerName,
63
					res.getErrs())
64
			} else {
65
				servers = append(servers, res)
66
				util.Log.Infof("(%d/%d) Detected: %s: %s",
67
					i+1, len(config.Conf.Servers),
68
					res.getServerInfo().ServerName,
69
					res.getDistro())
70
			}
71
			*/
72
		case <-timeout:
73
			msg := "Timed out while detecting servers"
74
			util.Log.Error(msg)
75
			for servername, sInfo := range config.Conf.Servers {
76
				found := false
77
				for _, o := range append(servers, errServers...) {
78
					if servername == o.getServerInfo().ServerName {
79
						found = true
80
						break
81
					}
82
				}
83
				if !found {
84
					u := &unknown{}
85
					u.setServerInfo(sInfo)
86
					u.setErrs([]error{
87
						fmt.Errorf("Timed out"),
88
					})
89
					errServers = append(errServers, u)
90
					util.Log.Errorf("(%d/%d) Timed out: %s",
91
						i+1, len(config.Conf.Servers),
92
						servername)
93
					i++
94
				}
95
			}
96
		}
97
	}
98
99
100
	return
101
}
102
type Hoge struct {
0 ignored issues
show
introduced by
exported type Hoge should have comment or be unexported
Loading history...
103
	Version Huga `json:"-"`
104
}
105
106
107
type Huga struct {
0 ignored issues
show
introduced by
exported type Huga should have comment or be unexported
Loading history...
108
	Release_date string `json:"release_date"`
0 ignored issues
show
introduced by
don't use underscores in Go names; struct field Release_date should be ReleaseDate
Loading history...
109
	Changelog_url string `json:"changelog_url"`
0 ignored issues
show
introduced by
don't use underscores in Go names; struct field Changelog_url should be ChangelogURL
Loading history...
110
	Status string `json:"status"`
111
	Vulnerabilities []Piyo `json:"vulnerabilities"`
112
}
113
114
type Piyo struct {
0 ignored issues
show
introduced by
exported type Piyo should have comment or be unexported
Loading history...
115
	Published_date string `json:"-"`
0 ignored issues
show
introduced by
don't use underscores in Go names; struct field Published_date should be PublishedDate
Loading history...
116
	Vuln_type string `json:"omit_empty,omitempty"`
0 ignored issues
show
introduced by
don't use underscores in Go names; struct field Vuln_type should be VulnType
Loading history...
117
	References int `json:"num,string"`
118
}
119
120
func detectWp(c config.ServerInfo) (err error) {
121
	if len(c.WpPath) != 0 {
122
		pp.Print("1")
123
	}
124
	cmd := fmt.Sprintf("wp core version --path=%s", c.WpPath)
125
126
	pp.Print(cmd)
127
	var coreVersion string
128
	if r := exec(c, cmd, noSudo); r.isSuccess() {
129
		tmp := strings.Split(r.Stdout, ".")
130
		coreVersion = strings.Join(tmp, "")
131
		coreVersion = strings.TrimRight(coreVersion, "\r\n")
132
		pp.Print(coreVersion)
133
	}
134
	cmd = fmt.Sprintf("curl -H 'Authorization: Token token=%s' https://wpvulndb.com/api/v3/wordpresses/%s", c.WpToken, coreVersion)
135
	if r := exec(c, cmd, noSudo); r.isSuccess() {
136
		tmp := strings.Split(r.Stdout, "{")
137
		tmp = unset(tmp, 1)
138
		tmp1 := strings.Join(tmp, "{")
139
140
		animals := Huga{}
141
		err := json.Unmarshal([]byte(tmp1), &animals)
142
		pp.Print(err)
143
	}
144
	return err
145
	/*
146
		cmd = fmt.Sprintf("wp plugin list --path=/var/www/html/wordpress --format=json%s", c.WordpressPath)
147
		cmd = fmt.Sprintf("wp theme list --path=/var/www/html/wordpress --format=json%s", c.WordpressPath)
148
	*/
149
}
150
151
func unset(s []string, i int) []string {
152
	if i >= len(s) {
153
		return s
154
	}
155
	return append(s[:i], s[i+1:]...)
156
}
157
158
func isRunningKernel(pack models.Package, family string, kernel models.Kernel) (isKernel, running bool) {
159
	switch family {
160
	case config.SUSEEnterpriseServer:
161
		if pack.Name == "kernel-default" {
162
			// Remove the last period and later because uname don't show that.
163
			ss := strings.Split(pack.Release, ".")
164
			rel := strings.Join(ss[0:len(ss)-1], ".")
165
			ver := fmt.Sprintf("%s-%s-default", pack.Version, rel)
166
			return true, kernel.Release == ver
167
		}
168
		return false, false
169
170
	case config.RedHat, config.Oracle, config.CentOS, config.Amazon:
171
		if pack.Name == "kernel" {
172
			ver := fmt.Sprintf("%s-%s.%s", pack.Version, pack.Release, pack.Arch)
173
			return true, kernel.Release == ver
174
		}
175
		return false, false
176
177
	default:
178
		util.Log.Warnf("Reboot required is not implemented yet: %s, %v", family, kernel)
179
	}
180
	return false, false
181
}
182
183
func rpmQa(distro config.Distro) string {
184
	const old = "rpm -qa --queryformat \"%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n\""
185
	const new = "rpm -qa --queryformat \"%{NAME} %{EPOCHNUM} %{VERSION} %{RELEASE} %{ARCH}\n\""
186
	switch distro.Family {
187
	case config.SUSEEnterpriseServer:
188
		if v, _ := distro.MajorVersion(); v < 12 {
189
			return old
190
		}
191
		return new
192
	default:
193
		if v, _ := distro.MajorVersion(); v < 6 {
194
			return old
195
		}
196
		return new
197
	}
198
}
199