Compare commits
	
		
			30 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9708533565 | ||
| 
						 | 
					ac98b908e3 | ||
| 
						 | 
					9bacd98577 | ||
| 
						 | 
					d750205f31 | ||
| 
						 | 
					b4d0aa7532 | ||
| 
						 | 
					3e846233a3 | ||
| 
						 | 
					1a943776c3 | ||
| 
						 | 
					57ef45ebcd | ||
| 
						 | 
					b64115f283 | ||
| 
						 | 
					018eb29ce5 | ||
| 
						 | 
					77c7d2fe26 | ||
| 
						 | 
					336b72bbca | ||
| 
						 | 
					0deb1032cd | ||
| 
						 | 
					34c5644e63 | ||
| 
						 | 
					1f80738bef | ||
| 
						 | 
					66501663a0 | ||
| 
						 | 
					f677939975 | ||
| 
						 | 
					c465faeb6c | ||
| 
						 | 
					6a6c7bf8a4 | ||
| 
						 | 
					d19afe665f | ||
| 
						 | 
					c62ca7c645 | ||
| 
						 | 
					855b48f0c9 | ||
| 
						 | 
					555e34d035 | ||
| 
						 | 
					6b12ff35cd | ||
| 
						 | 
					d9813e822f | ||
| 
						 | 
					26273e7387 | ||
| 
						 | 
					b52f0120ff | ||
| 
						 | 
					76ade4c3b4 | ||
| 
						 | 
					110d74a91e | ||
| 
						 | 
					1819edf724 | 
							
								
								
									
										18
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -1,5 +1,19 @@
 | 
			
		||||
# Change Log
 | 
			
		||||
 | 
			
		||||
0.1.0 (2013-03-23)
 | 
			
		||||
## [v0.1.1](https://github.com/future-architect/vuls/tree/v0.1.1) (2016-04-06)
 | 
			
		||||
[Full Changelog](https://github.com/future-architect/vuls/compare/v0.1.0...v0.1.1)
 | 
			
		||||
 | 
			
		||||
Initial public release
 | 
			
		||||
**Merged pull requests:**
 | 
			
		||||
 | 
			
		||||
- Typo in Example [\#6](https://github.com/future-architect/vuls/pull/6) ([toli](https://github.com/toli))
 | 
			
		||||
 | 
			
		||||
## [v0.1.0](https://github.com/future-architect/vuls/tree/v0.1.0) (2016-04-04)
 | 
			
		||||
**Merged pull requests:**
 | 
			
		||||
 | 
			
		||||
- English translation [\#4](https://github.com/future-architect/vuls/pull/4) ([hikachan](https://github.com/hikachan))
 | 
			
		||||
- English translation [\#3](https://github.com/future-architect/vuls/pull/3) ([chewyinping](https://github.com/chewyinping))
 | 
			
		||||
- Add a Bitdeli Badge to README [\#2](https://github.com/future-architect/vuls/pull/2) ([bitdeli-chef](https://github.com/bitdeli-chef))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								README.md
									
									
									
									
									
								
							@@ -24,7 +24,7 @@ To avoid downtime in production environment, it is common for system administrat
 | 
			
		||||
This leads to the following problems.
 | 
			
		||||
- System administrator will have to constantly watch out for any new vulnerabilities in NVD(National Vulnerability Database) and etc.
 | 
			
		||||
- It might be impossible for the system administrator to monitor all the software if there are a large number of software installed in server.
 | 
			
		||||
- It is expensive to perform anaylsis to determine the servers affected by new vulnerabilities. The possibility of overlooking a server or two during analysis is there.
 | 
			
		||||
- It is expensive to perform analysis to determine the servers affected by new vulnerabilities. The possibility of overlooking a server or two during analysis is there.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Vuls is a tool created to solve the problems listed above. It has the following characteristics.
 | 
			
		||||
@@ -79,7 +79,7 @@ This can be done in the following steps.
 | 
			
		||||
 | 
			
		||||
- We are using the old AMI (amzn-ami-hvm-2015.09.1.x86_64-gp2 - ami-383c1956) for this example
 | 
			
		||||
- Instance size: t2.medium
 | 
			
		||||
    - For the first time, t2.medium and above is required for the data fetch from NVD
 | 
			
		||||
    - For the first time, t2.medium and above is required for the data fetch from NVD(about 2.3GB of memory needed)
 | 
			
		||||
    - You can switch to t2.nano after the initial data fetch.
 | 
			
		||||
- Add the following to the cloud-init, to avoid auto-update at the first launch.
 | 
			
		||||
 | 
			
		||||
@@ -97,6 +97,7 @@ Create a keypair then append public key to authorized_keys
 | 
			
		||||
```bash
 | 
			
		||||
$ ssh-keygen -t rsa
 | 
			
		||||
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
 | 
			
		||||
$ chmod 600 ~/.ssh/authorized_keys
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Step3. Install requirements
 | 
			
		||||
@@ -129,7 +130,7 @@ Set the OS environment variable to current shell
 | 
			
		||||
$ source /etc/profile.d/goenv.sh
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Step4. Deploy go-cve-dictionary
 | 
			
		||||
## Step4. Deploy [go-cve-dictionary](https://github.com/kotakanbe/go-cve-dictionary)
 | 
			
		||||
 | 
			
		||||
go get
 | 
			
		||||
 | 
			
		||||
@@ -194,7 +195,7 @@ $ vuls prepare
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ vuls scan
 | 
			
		||||
INFO[0000] Begin scannig (config: /home/ec2-user/config.toml)
 | 
			
		||||
INFO[0000] Begin scanning (config: /home/ec2-user/config.toml)
 | 
			
		||||
 | 
			
		||||
... snip ...
 | 
			
		||||
 | 
			
		||||
@@ -241,7 +242,7 @@ $ vuls tui
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## go-cve-dictinary  
 | 
			
		||||
- Fetch vulnerbility information from NVD, JVN(Japanese), then insert into SQLite.
 | 
			
		||||
- Fetch vulnerability information from NVD, JVN(Japanese), then insert into SQLite.
 | 
			
		||||
 | 
			
		||||
## Vuls
 | 
			
		||||
- Scan vulnerabilities on the servers and create a list of the CVE ID
 | 
			
		||||
@@ -280,7 +281,7 @@ web/app server in the same configuration under the load balancer
 | 
			
		||||
 | 
			
		||||
# Usage: Automatic Server Discovery
 | 
			
		||||
 | 
			
		||||
Discovery subcommand discovers active servers specifed in CIDR range, then print the template of config file(TOML format) to terminal.
 | 
			
		||||
Discovery subcommand discovers active servers specified in CIDR range, then print the template of config file(TOML format) to terminal.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ vuls discover -help
 | 
			
		||||
@@ -288,7 +289,7 @@ discover:
 | 
			
		||||
        discover 192.168.0.0/24
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Exapmle
 | 
			
		||||
## Example
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ vuls discover 172.31.4.0/24
 | 
			
		||||
@@ -390,7 +391,7 @@ You can customize your configuration using this template.
 | 
			
		||||
    subjectPrefix = "[vuls]"
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
- Defualt section
 | 
			
		||||
- Default section
 | 
			
		||||
    ```
 | 
			
		||||
    [default]
 | 
			
		||||
    #port        = "22"
 | 
			
		||||
@@ -399,7 +400,7 @@ You can customize your configuration using this template.
 | 
			
		||||
    #keyPath     = "/home/username/.ssh/id_rsa"
 | 
			
		||||
    #keyPassword = "password"
 | 
			
		||||
    ```
 | 
			
		||||
    Items of the defualt section will be used if not specified.
 | 
			
		||||
    Items of the default section will be used if not specified.
 | 
			
		||||
 | 
			
		||||
- servers section
 | 
			
		||||
    ```
 | 
			
		||||
@@ -448,7 +449,7 @@ prepare:
 | 
			
		||||
  -debug
 | 
			
		||||
        debug mode
 | 
			
		||||
  -use-unattended-upgrades
 | 
			
		||||
        [Depricated] For Ubuntu, install unattended-upgrades
 | 
			
		||||
        [Deprecated] For Ubuntu, install unattended-upgrades
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
@@ -490,9 +491,9 @@ scan:
 | 
			
		||||
  -report-slack
 | 
			
		||||
        Slack report
 | 
			
		||||
  -use-unattended-upgrades
 | 
			
		||||
        [Depricated] For Ubuntu. Scan by unattended-upgrades or not (use apt-get upgrade --dry-run by default)
 | 
			
		||||
        [Deprecated] For Ubuntu. Scan by unattended-upgrades or not (use apt-get upgrade --dry-run by default)
 | 
			
		||||
  -use-yum-plugin-security
 | 
			
		||||
        [Depricated] For CentOS 5. Scan by yum-plugin-security or not (use yum check-update by default)
 | 
			
		||||
        [Deprecated] For CentOS 5. Scan by yum-plugin-security or not (use yum check-update by default)
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@@ -588,7 +589,7 @@ If your system is behind HTTP proxy, you have to specify --http-proxy option.
 | 
			
		||||
- How to Daemonize go-cve-dictionary  
 | 
			
		||||
Use Systemd, Upstart or supervisord, daemontools...
 | 
			
		||||
 | 
			
		||||
- How to update vulnerbility data automatically.  
 | 
			
		||||
- How to update vulnerability data automatically.
 | 
			
		||||
Use job scheduler like Cron (with -last2y option).
 | 
			
		||||
 | 
			
		||||
- How to cross compile
 | 
			
		||||
@@ -603,8 +604,11 @@ Log wrote to under /var/log/vuls/
 | 
			
		||||
- Debug  
 | 
			
		||||
Run with --debug, --sql-debug option.
 | 
			
		||||
 | 
			
		||||
- Ajusting Open File Limit  
 | 
			
		||||
[Riak docs](http://docs.basho.com/riak/latest/ops/tuning/open-files-limit/) is awesome.
 | 
			
		||||
 | 
			
		||||
- Windows  
 | 
			
		||||
Use Microsoft Baseline Secuirty Analyzer. [MBSA](https://technet.microsoft.com/en-us/security/cc184924.aspx)
 | 
			
		||||
Use Microsoft Baseline Security Analyzer. [MBSA](https://technet.microsoft.com/en-us/security/cc184924.aspx)
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ type DiscoverCmd struct {
 | 
			
		||||
func (*DiscoverCmd) Name() string { return "discover" }
 | 
			
		||||
 | 
			
		||||
// Synopsis return synopsis
 | 
			
		||||
func (*DiscoverCmd) Synopsis() string { return "Host discovery in the CIDR." }
 | 
			
		||||
func (*DiscoverCmd) Synopsis() string { return "Host discovery in the CIDR" }
 | 
			
		||||
 | 
			
		||||
// Usage return usage
 | 
			
		||||
func (*DiscoverCmd) Usage() string {
 | 
			
		||||
@@ -77,7 +77,7 @@ func (p *DiscoverCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(hosts) < 1 {
 | 
			
		||||
			logrus.Errorf("Active hosts not found in %s.", cidr)
 | 
			
		||||
			logrus.Errorf("Active hosts not found in %s", cidr)
 | 
			
		||||
			return subcommands.ExitSuccess
 | 
			
		||||
		} else if err := printConfigToml(hosts); err != nil {
 | 
			
		||||
			logrus.Errorf("Failed to parse template. err: %s", err)
 | 
			
		||||
 
 | 
			
		||||
@@ -78,7 +78,7 @@ func (p *PrepareCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
 | 
			
		||||
// Execute execute
 | 
			
		||||
func (p *PrepareCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
 | 
			
		||||
	logrus.Infof("Begin Preparing (config: %s)", p.configPath)
 | 
			
		||||
	logrus.Infof("Start Preparing (config: %s)", p.configPath)
 | 
			
		||||
 | 
			
		||||
	err := c.Load(p.configPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -121,7 +121,7 @@ func (p *PrepareCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{
 | 
			
		||||
	logger.Info("Installing...")
 | 
			
		||||
	if errs := scan.Prepare(); 0 < len(errs) {
 | 
			
		||||
		for _, e := range errs {
 | 
			
		||||
			logger.Errorf("Failed: %s.", e)
 | 
			
		||||
			logger.Errorf("Failed: %s", e)
 | 
			
		||||
		}
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ type ScanCmd struct {
 | 
			
		||||
func (*ScanCmd) Name() string { return "scan" }
 | 
			
		||||
 | 
			
		||||
// Synopsis return synopsis
 | 
			
		||||
func (*ScanCmd) Synopsis() string { return "Scan vulnerabilities." }
 | 
			
		||||
func (*ScanCmd) Synopsis() string { return "Scan vulnerabilities" }
 | 
			
		||||
 | 
			
		||||
// Usage return usage
 | 
			
		||||
func (*ScanCmd) Usage() string {
 | 
			
		||||
@@ -130,7 +130,7 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
// Execute execute
 | 
			
		||||
func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
 | 
			
		||||
 | 
			
		||||
	logrus.Infof("Begin scannig (config: %s)", p.configPath)
 | 
			
		||||
	logrus.Infof("Start scanning (config: %s)", p.configPath)
 | 
			
		||||
	err := c.Load(p.configPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Errorf("Error loading %s, %s", p.configPath, err)
 | 
			
		||||
@@ -192,17 +192,17 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log.Info("Detecting OS... ")
 | 
			
		||||
	Log.Info("Detecting the type of OS... ")
 | 
			
		||||
	err = scan.InitServers(Log)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		Log.Errorf("Failed to init servers. err: %s", err)
 | 
			
		||||
		Log.Errorf("Failed to init servers. Check the configuration. err: %s", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log.Info("Scanning vulnerabilities... ")
 | 
			
		||||
	if errs := scan.Scan(); 0 < len(errs) {
 | 
			
		||||
		for _, e := range errs {
 | 
			
		||||
			Log.Errorf("Failed to scan. err: %s.", e)
 | 
			
		||||
			Log.Errorf("Failed to scan. err: %s", e)
 | 
			
		||||
		}
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ type TuiCmd struct {
 | 
			
		||||
func (*TuiCmd) Name() string { return "tui" }
 | 
			
		||||
 | 
			
		||||
// Synopsis return synopsis
 | 
			
		||||
func (*TuiCmd) Synopsis() string { return "Run Tui view to anayze vulnerabilites." }
 | 
			
		||||
func (*TuiCmd) Synopsis() string { return "Run Tui view to anayze vulnerabilites" }
 | 
			
		||||
 | 
			
		||||
// Usage return usage
 | 
			
		||||
func (*TuiCmd) Usage() string {
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ type TOMLLoader struct {
 | 
			
		||||
func (c TOMLLoader) Load(pathToToml string) (err error) {
 | 
			
		||||
	var conf Config
 | 
			
		||||
	if _, err := toml.DecodeFile(pathToToml, &conf); err != nil {
 | 
			
		||||
		log.Error("Load config failed.", err)
 | 
			
		||||
		log.Error("Load config failed", err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -86,12 +86,12 @@ func (c TOMLLoader) Load(pathToToml string) (err error) {
 | 
			
		||||
			s.CpeNames = d.CpeNames
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s.LogMsgAnsiColor = Colors[i%len(conf.Servers)]
 | 
			
		||||
		s.LogMsgAnsiColor = Colors[i%len(Colors)]
 | 
			
		||||
		i++
 | 
			
		||||
 | 
			
		||||
		servers[name] = s
 | 
			
		||||
	}
 | 
			
		||||
	log.Debug("Config loaded.")
 | 
			
		||||
	log.Debug("Config loaded")
 | 
			
		||||
	log.Debugf("%s", pp.Sprintf("%v", servers))
 | 
			
		||||
	Conf.Servers = servers
 | 
			
		||||
	return
 | 
			
		||||
 
 | 
			
		||||
@@ -127,19 +127,18 @@ func (api cvedictClient) FetchCveDetails(cveIDs []string) (cveDetails cve.CveDet
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (api cvedictClient) httpGet(key, url string, resChan chan<- response, errChan chan<- error) {
 | 
			
		||||
 | 
			
		||||
	var body string
 | 
			
		||||
	var errs []error
 | 
			
		||||
	var resp *http.Response
 | 
			
		||||
	f := func() (err error) {
 | 
			
		||||
		resp, body, errs = gorequest.New().SetDebug(config.Conf.Debug).Get(url).End()
 | 
			
		||||
		if len(errs) > 0 || resp.StatusCode != 200 {
 | 
			
		||||
			errChan <- fmt.Errorf("HTTP error. errs: %v, url: %s", errs, url)
 | 
			
		||||
			return fmt.Errorf("HTTP GET error: %v, code: %d, url: %s", errs, resp.StatusCode, url)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	notify := func(err error, t time.Duration) {
 | 
			
		||||
		log.Warnf("Failed to get. retrying in %s seconds. err: %s", t, err)
 | 
			
		||||
		log.Warnf("Failed to HTTP GET. retrying in %s seconds. err: %s", t, err)
 | 
			
		||||
	}
 | 
			
		||||
	err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -219,12 +218,12 @@ func (api cvedictClient) httpPost(key, url string, query map[string]string) ([]c
 | 
			
		||||
		}
 | 
			
		||||
		resp, body, errs = req.End()
 | 
			
		||||
		if len(errs) > 0 || resp.StatusCode != 200 {
 | 
			
		||||
			return fmt.Errorf("HTTP error. errs: %v, url: %s", errs, url)
 | 
			
		||||
			return fmt.Errorf("HTTP POST errors: %v, code: %d, url: %s", errs, resp.StatusCode, url)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	notify := func(err error, t time.Duration) {
 | 
			
		||||
		log.Warnf("Failed to get. retrying in %s seconds. err: %s", t, err)
 | 
			
		||||
		log.Warnf("Failed to HTTP POST. retrying in %s seconds. err: %s", t, err)
 | 
			
		||||
	}
 | 
			
		||||
	err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								db/db.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								db/db.go
									
									
									
									
									
								
							@@ -226,7 +226,7 @@ func SelectLatestScanHistory() (m.ScanHistory, error) {
 | 
			
		||||
	db.Order("scanned_at desc").First(&scanHistory)
 | 
			
		||||
 | 
			
		||||
	if scanHistory.ID == 0 {
 | 
			
		||||
		return m.ScanHistory{}, fmt.Errorf("No scanHistory records.")
 | 
			
		||||
		return m.ScanHistory{}, fmt.Errorf("No scanHistory records")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	results := []m.ScanResult{}
 | 
			
		||||
 
 | 
			
		||||
@@ -602,7 +602,6 @@ func summaryLines(data models.ScanResult) string {
 | 
			
		||||
		}
 | 
			
		||||
		stable.AddRow(icols...)
 | 
			
		||||
	}
 | 
			
		||||
	// ignore UnknownCves
 | 
			
		||||
	return fmt.Sprintf("%s", stable)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -625,7 +624,6 @@ func setDetailLayout(g *gocui.Gui) error {
 | 
			
		||||
		//      currentScanResult.KnownCves[currentCveInfo],
 | 
			
		||||
		//      currentScanResult.Family)
 | 
			
		||||
 | 
			
		||||
		//TODO error handling
 | 
			
		||||
		text, err := detailLines()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
@@ -654,6 +652,10 @@ type dataForTmpl struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func detailLines() (string, error) {
 | 
			
		||||
	if len(currentScanResult.KnownCves) == 0 {
 | 
			
		||||
		return "No vulnerable packages", nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cveInfo := currentScanResult.KnownCves[currentCveInfo]
 | 
			
		||||
	cveID := cveInfo.CveDetail.CveID
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -174,7 +174,7 @@ func (o *debian) scanPackages() error {
 | 
			
		||||
 | 
			
		||||
	var unsecurePacks []CvePacksInfo
 | 
			
		||||
	if unsecurePacks, err = o.scanUnsecurePackages(packs); err != nil {
 | 
			
		||||
		o.log.Errorf("Failed to scan valnerable packages")
 | 
			
		||||
		o.log.Errorf("Failed to scan vulnerable packages")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	o.setUnsecurePackages(unsecurePacks)
 | 
			
		||||
@@ -346,7 +346,7 @@ func (o *debian) fillCandidateVersion(packs []models.PackageInfo) ([]models.Pack
 | 
			
		||||
		case err := <-errChan:
 | 
			
		||||
			return nil, err
 | 
			
		||||
		case <-timeout:
 | 
			
		||||
			return nil, fmt.Errorf("Timeout fillCandidateVersion.")
 | 
			
		||||
			return nil, fmt.Errorf("Timeout fillCandidateVersion")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return result, nil
 | 
			
		||||
@@ -500,7 +500,7 @@ func (o *debian) scanPackageCveInfos(unsecurePacks []models.PackageInfo) (cvePac
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
		case <-timeout:
 | 
			
		||||
			return nil, fmt.Errorf("Timeout scanPackageCveIds.")
 | 
			
		||||
			return nil, fmt.Errorf("Timeout scanPackageCveIds")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -199,7 +199,7 @@ util-linux (2.26.2-6) unstable; urgency=medium`,
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		_, err := d.getCveIDParsingChangelog(tt.in[2], tt.in[0], "version number do'nt match case")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Errorf("Returning error is unexpected.")
 | 
			
		||||
			t.Errorf("Returning error is unexpected")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -504,7 +504,7 @@ Calculating upgrade... Done
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		actual, err := d.parseAptGetUpgrade(tt.in)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Errorf("Returning error is unexpected.")
 | 
			
		||||
			t.Errorf("Returning error is unexpected")
 | 
			
		||||
		}
 | 
			
		||||
		if len(tt.expected) != len(actual) {
 | 
			
		||||
			t.Errorf("Result length is not as same as expected. expected: %d, actual: %d", len(tt.expected), len(actual))
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
package scan
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sort"
 | 
			
		||||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
@@ -52,6 +53,10 @@ func (l *linux) setDistributionInfo(fam, rel string) {
 | 
			
		||||
	l.Release = rel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *linux) getDistributionInfo() string {
 | 
			
		||||
	return fmt.Sprintf("%s %s", l.Family, l.Release)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *linux) convertToModel() (models.ScanResult, error) {
 | 
			
		||||
	var cves, unknownScoreCves []models.CveInfo
 | 
			
		||||
	for _, p := range l.UnsecurePackages {
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,7 @@ func detectRedhat(c config.ServerInfo) (itsMe bool, red osTypeInterface) {
 | 
			
		||||
	red = newRedhat(c)
 | 
			
		||||
 | 
			
		||||
	// set sudo option flag
 | 
			
		||||
	c.SudoOpt = config.SudoOption{ExecBySudoSh: true}
 | 
			
		||||
	c.SudoOpt = config.SudoOption{ExecBySudo: true}
 | 
			
		||||
	red.setServerInfo(c)
 | 
			
		||||
 | 
			
		||||
	if r := sshExec(c, "ls /etc/fedora-release", noSudo); r.isSuccess() {
 | 
			
		||||
@@ -160,7 +160,7 @@ func (o *redhat) installYumChangelog() error {
 | 
			
		||||
 | 
			
		||||
		cmd := "rpm -q " + packName
 | 
			
		||||
		if r := o.ssh(cmd, noSudo); r.isSuccess() {
 | 
			
		||||
			o.log.Infof("Ignored: %s already installed.", packName)
 | 
			
		||||
			o.log.Infof("Ignored: %s already installed", packName)
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -170,7 +170,7 @@ func (o *redhat) installYumChangelog() error {
 | 
			
		||||
				"Failed to install %s. status: %d, stdout: %s, stderr: %s",
 | 
			
		||||
				packName, r.ExitStatus, r.Stdout, r.Stderr)
 | 
			
		||||
		}
 | 
			
		||||
		o.log.Infof("Installed: %s.", packName)
 | 
			
		||||
		o.log.Infof("Installed: %s", packName)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
@@ -228,7 +228,7 @@ func (o *redhat) scanPackages() error {
 | 
			
		||||
 | 
			
		||||
	var unsecurePacks []CvePacksInfo
 | 
			
		||||
	if unsecurePacks, err = o.scanUnsecurePackages(); err != nil {
 | 
			
		||||
		o.log.Errorf("Failed to scan valnerable packages")
 | 
			
		||||
		o.log.Errorf("Failed to scan vulnerable packages")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	o.setUnsecurePackages(unsecurePacks)
 | 
			
		||||
@@ -516,7 +516,7 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (CvePacksList, err
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("Failed to parse %s. err: %s", cmd, err)
 | 
			
		||||
	}
 | 
			
		||||
	o.log.Debugf("%s", pp.Sprintf("%s", vulnerablePackInfoList))
 | 
			
		||||
	o.log.Debugf("%s", pp.Sprintf("%v", vulnerablePackInfoList))
 | 
			
		||||
	for i, packInfo := range vulnerablePackInfoList {
 | 
			
		||||
		installedPack, found := o.Packages.FindByName(packInfo.Name)
 | 
			
		||||
		if !found {
 | 
			
		||||
@@ -544,7 +544,7 @@ func (o *redhat) scanUnsecurePackagesUsingYumPluginSecurity() (CvePacksList, err
 | 
			
		||||
 | 
			
		||||
	// get advisoryID(RHSA, ALAS) - CVE IDs
 | 
			
		||||
	cmd = "yum updateinfo --security update"
 | 
			
		||||
	r = o.ssh(util.PrependProxyEnv(cmd), noSudo)
 | 
			
		||||
	r = o.ssh(util.PrependProxyEnv(cmd), sudo)
 | 
			
		||||
	if !r.isSuccess() {
 | 
			
		||||
		return nil, fmt.Errorf(
 | 
			
		||||
			"Failed to %s. status: %d, stdout: %s, stderr: %s",
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ type osTypeInterface interface {
 | 
			
		||||
	setServerInfo(config.ServerInfo)
 | 
			
		||||
	getServerInfo() config.ServerInfo
 | 
			
		||||
	setDistributionInfo(string, string)
 | 
			
		||||
	getDistributionInfo() string
 | 
			
		||||
	checkRequiredPackagesInstalled() error
 | 
			
		||||
	scanPackages() error
 | 
			
		||||
	scanVulnByCpeName() error
 | 
			
		||||
@@ -108,7 +109,7 @@ func detectOs(c config.ServerInfo) (osType osTypeInterface) {
 | 
			
		||||
func InitServers(localLogger *logrus.Entry) (err error) {
 | 
			
		||||
	Log = localLogger
 | 
			
		||||
	if servers, err = detectServersOS(); err != nil {
 | 
			
		||||
		err = fmt.Errorf("Failed to detect OS")
 | 
			
		||||
		err = fmt.Errorf("Failed to detect the type of OS. err: %s", err)
 | 
			
		||||
	} else {
 | 
			
		||||
		Log.Debugf("%s", pp.Sprintf("%s", servers))
 | 
			
		||||
	}
 | 
			
		||||
@@ -128,10 +129,26 @@ func detectServersOS() (osi []osTypeInterface, err error) {
 | 
			
		||||
	for i := 0; i < len(config.Conf.Servers); i++ {
 | 
			
		||||
		select {
 | 
			
		||||
		case res := <-osTypeChan:
 | 
			
		||||
			Log.Infof("(%d/%d) Successfully detected. %s: %s",
 | 
			
		||||
				i+1, len(config.Conf.Servers),
 | 
			
		||||
				res.getServerInfo().ServerName,
 | 
			
		||||
				res.getDistributionInfo())
 | 
			
		||||
			osi = append(osi, res)
 | 
			
		||||
		case <-timeout:
 | 
			
		||||
			Log.Error("Timeout Occured while detecting OS.")
 | 
			
		||||
			err = fmt.Errorf("Timeout!")
 | 
			
		||||
			Log.Error("Timeout occured while detecting")
 | 
			
		||||
			err = fmt.Errorf("Timeout")
 | 
			
		||||
			for servername := range config.Conf.Servers {
 | 
			
		||||
				found := false
 | 
			
		||||
				for _, o := range osi {
 | 
			
		||||
					if servername == o.getServerInfo().ServerName {
 | 
			
		||||
						found = true
 | 
			
		||||
						break
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if !found {
 | 
			
		||||
					Log.Errorf("Failed to detect. servername: %s", servername)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -151,7 +168,7 @@ func Prepare() []error {
 | 
			
		||||
// Scan scan
 | 
			
		||||
func Scan() []error {
 | 
			
		||||
	if len(servers) == 0 {
 | 
			
		||||
		return []error{fmt.Errorf("Not initialize yet.")}
 | 
			
		||||
		return []error{fmt.Errorf("No server defined. Check the configuration")}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log.Info("Check required packages for scanning...")
 | 
			
		||||
@@ -160,12 +177,12 @@ func Scan() []error {
 | 
			
		||||
		return errs
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log.Info("Scanning vuluneable OS packages...")
 | 
			
		||||
	Log.Info("Scanning vulnerable OS packages...")
 | 
			
		||||
	if errs := scanPackages(); errs != nil {
 | 
			
		||||
		return errs
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log.Info("Scanning vulnerable software specified in CPE...")
 | 
			
		||||
	Log.Info("Scanning vulnerable software specified in the CPE...")
 | 
			
		||||
	if errs := scanVulnByCpeName(); errs != nil {
 | 
			
		||||
		return errs
 | 
			
		||||
	}
 | 
			
		||||
@@ -201,7 +218,7 @@ func GetScanResults() (results models.ScanResults, err error) {
 | 
			
		||||
	for _, s := range servers {
 | 
			
		||||
		r, err := s.convertToModel()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return results, fmt.Errorf("Failed converting to model: %s.", err)
 | 
			
		||||
			return results, fmt.Errorf("Failed converting to model: %s", err)
 | 
			
		||||
		}
 | 
			
		||||
		results = append(results, r)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -94,11 +94,11 @@ func parallelSSHExec(fn func(osTypeInterface) error, timeoutSec ...int) (errs []
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				errs = append(errs, err)
 | 
			
		||||
			} else {
 | 
			
		||||
				logrus.Debug("Parallel SSH Success.")
 | 
			
		||||
				logrus.Debug("Parallel SSH Success")
 | 
			
		||||
			}
 | 
			
		||||
		case <-time.After(time.Duration(timeout) * time.Second):
 | 
			
		||||
			logrus.Errorf("Parallel SSH Timeout.")
 | 
			
		||||
			errs = append(errs, fmt.Errorf("Timed out!"))
 | 
			
		||||
			logrus.Errorf("Parallel SSH Timeout")
 | 
			
		||||
			errs = append(errs, fmt.Errorf("Timed out"))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
@@ -225,7 +225,7 @@ func sshConnect(c conf.ServerInfo) (client *ssh.Client, err error) {
 | 
			
		||||
 | 
			
		||||
	var auths = []ssh.AuthMethod{}
 | 
			
		||||
	if auths, err = addKeyAuth(auths, c.KeyPath, c.KeyPassword); err != nil {
 | 
			
		||||
		logrus.Fatalf("Faild to add keyAuth. err: %s", err)
 | 
			
		||||
		logrus.Fatalf("Failed to add keyAuth. err: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.Password != "" {
 | 
			
		||||
@@ -240,7 +240,7 @@ func sshConnect(c conf.ServerInfo) (client *ssh.Client, err error) {
 | 
			
		||||
	//  log.Debugf("config: %s", pp.Sprintf("%v", config))
 | 
			
		||||
 | 
			
		||||
	notifyFunc := func(e error, t time.Duration) {
 | 
			
		||||
		logrus.Warnf("Faild to ssh %s@%s:%s. err: %s, Retrying in %s...",
 | 
			
		||||
		logrus.Warnf("Failed to ssh %s@%s:%s. err: %s, Retrying in %s...",
 | 
			
		||||
			c.User, c.Host, c.Port, e, t)
 | 
			
		||||
		logrus.Debugf("sshConInfo: %s", pp.Sprintf("%v", c))
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
// Name.
 | 
			
		||||
// Name is Vuls
 | 
			
		||||
const Name string = "vuls"
 | 
			
		||||
 | 
			
		||||
// Version.
 | 
			
		||||
const Version string = "0.1.0"
 | 
			
		||||
// Version of Vuls
 | 
			
		||||
const Version string = "0.1.2"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user