nexty 0.20

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.csv
2
+ *.swp
3
+ config.yaml
4
+ *.gem
5
+ *.rbc
6
+ .bundle
7
+ .config
8
+ .yardoc
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@nexty
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "nexpose"#, :git=>"git@github.com:thesp0nge/nexpose-client.git", :branch=>"devel"
4
+ gem "rainbow"
5
+ gem "rake"
6
+ gem "rspec"
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010-2012 Paolo Perego
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Nexty
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'nexty'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install nexty
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new
6
+
7
+ task :default => :spec
8
+ task :test => :spec
data/bin/nexty ADDED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ class String
4
+ def starts_with?(pattern)
5
+ ! self.match(/^#{pattern}/).nil?
6
+ end
7
+ end
8
+
9
+ class Numeric
10
+ def duration
11
+ secs = self.to_int
12
+ mins = secs / 60
13
+ hours = mins / 60
14
+ days = hours / 24
15
+
16
+ return "#{days} days and #{hours % 24} hours" if days > 0
17
+ return "#{hours} hours and #{mins % 60} minutes" if days == 0 and hours > 0
18
+ return "#{mins} minutes and #{secs % 60} seconds" if days == 0 and hours == 0 and mins > 0
19
+ return "#{secs} seconds" if days == 0 and hours == 0 and mins == 0
20
+ end
21
+ end
22
+
23
+ if RUBY_VERSION.split('.')[1] == "8"
24
+ require 'rubygems'
25
+ end
26
+
27
+ require 'time'
28
+ require 'rainbow'
29
+ require 'nexpose'
30
+ require 'nexty'
31
+ require 'getoptlong'
32
+ require 'csv'
33
+
34
+ opts = GetoptLong.new(
35
+ [ '--report', '-r', GetoptLong::REQUIRED_ARGUMENT ],
36
+ [ '--host', '-H', GetoptLong::REQUIRED_ARGUMENT ],
37
+ [ '--full-export', '-f', GetoptLong::REQUIRED_ARGUMENT ],
38
+ [ '--download', '-d', GetoptLong::REQUIRED_ARGUMENT ]
39
+ )
40
+
41
+
42
+
43
+ trap("INT") { puts '['+'INTERRUPTED'.color(:red)+']'; exit -1 }
44
+
45
+
46
+ # templates = nsc.report_template_listing
47
+ #
48
+ # templates.each do |template|
49
+ # p template[:template_id]
50
+ # end
51
+
52
+ conn = Nexty::Connector.new
53
+ nsc = conn.nsc
54
+
55
+ begin
56
+ printf "Connecting to #{conn.config["config"]["host"]}:#{conn.config["config"]["port"]} - ".color(:white)
57
+ nsc.login
58
+ rescue ::Nexpose::APIError => e
59
+ printf "failed\n".color(:red)
60
+ $stderr.puts("#{e.reason}")
61
+ exit(1)
62
+ end
63
+ printf "succeded\n".color(:green)
64
+
65
+
66
+ opts.each do |opt, arg|
67
+ case opt
68
+
69
+ when '--download'
70
+
71
+ file_name = "export_#{Time.now.strftime("%Y%m%d%H%M%s")}.csv"
72
+ puts "Report saved: #{Nexty::Report.download(arg, file_name, nsc)}".color(:white)
73
+
74
+ when '--full-export'
75
+
76
+ fn = Nexty::Report.generate_from_a_template(arg, nsc)
77
+ file_name = "export_#{Time.now.strftime("%Y%m%d%H%M%s")}.csv"
78
+ nsc.logout
79
+ begin
80
+ printf "Connecting to #{conn.config["config"]["host"]}:#{conn.config["config"]["port"]} - ".color(:white)
81
+ nsc.login
82
+ rescue ::Nexpose::APIError => e
83
+ printf "failed\n".color(:red)
84
+ $stderr.puts("#{e.reason}")
85
+ exit(1)
86
+ end
87
+ printf "succeded\n".color(:green)
88
+
89
+ puts "Report saved: #{Nexty::Report.download(fn, file_name, nsc)}".color(:white)
90
+
91
+ when '--report'
92
+ fn = Nexty::Report.generate_from_a_list_of_sites(arg, nsc)
93
+ puts "Report saved: #{fn}".color(:white)
94
+
95
+ when '--host'
96
+
97
+ dev= Nexty::Device.find_by_address(nsc, arg)
98
+ if ! dev.nil?
99
+ puts "#{dev.address} found @ site #{dev.site_id}. Risk score = #{dev.riskscore} * #{dev.riskfactor}".color(:green)
100
+ else
101
+ puts "#{arg} not found".color{:red}
102
+ end
103
+ end
104
+ end
105
+
106
+
107
+ nsc.logout
@@ -0,0 +1,6 @@
1
+ config:
2
+ host: "127.0.0.1"
3
+ port: "3790"
4
+ user: "nxadmin"
5
+ pass: "nxadmin"
6
+
@@ -0,0 +1,19 @@
1
+ require 'singleton'
2
+ require 'yaml'
3
+
4
+ module Nexty
5
+ class Config
6
+ include Singleton
7
+
8
+ def read(file)
9
+ if file.nil? or !File.exists?(file)
10
+ return {"config" => {"host"=>"127.0.0.1", "port"=>"3790", "user"=>"nxadmin", "pass"=>"nxadmin"}}
11
+ end
12
+ config = YAML.load_file(file)
13
+
14
+ return config
15
+ end
16
+
17
+
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ require 'nexty/config'
2
+ module Nexty
3
+ class Connector
4
+
5
+ attr_reader :nsc, :config
6
+ def initialize(file="./conf/config.yaml")
7
+ @config = Nexty::Config.instance.read(file)
8
+ @nsc = Nexpose::Connection.new(@config["config"]["host"],
9
+ @config["config"]["user"],
10
+ @config["config"]["pass"],
11
+ @config["config"]["port"])
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ module Nexty
2
+ class Device
3
+ def self.all(connection)
4
+ @devices = []
5
+
6
+ r = connection.execute('<SiteDeviceListingRequest session-id="' + connection.session_id + '"/>')
7
+ if (r.success)
8
+ r.res.elements.each('SiteDeviceListingResponse/SiteDevices') do |rr|
9
+ @sid = rr.attribute("site-id")
10
+ rr.elements.each('device') do |d|
11
+ @devices.push(Nexpose::Device.new(d.attributes['id'], @sid, d.attributes["address"], d.attributes["riskfactor"], d.attributes['riskscore']))
12
+ end
13
+ end
14
+ end
15
+ @devices
16
+ end
17
+
18
+ def self.find_by_address(connection, address)
19
+ devices = Nexty::Device.all(connection)
20
+ devices.each do |d|
21
+ if d.address == address
22
+ return d
23
+ end
24
+ end
25
+
26
+ return nil
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,77 @@
1
+ module Nexty
2
+ class Report
3
+
4
+ # def self.generate_from_ip_list(ip_list, nsc)
5
+ # ips = Nexty::Sites.load_from_file(ip_list)
6
+
7
+ # report = Nexpose::ReportAdHoc.new(nsc, 'SOX Vulns', 'csv')
8
+ # ips.each do |ip|
9
+ # report.addFilter('device',addFilter('device',
10
+ # end
11
+ # end
12
+
13
+
14
+ def self.download(url, filename, nsc)
15
+ return nil if url.nil? or url.empty?
16
+ uri = URI.parse(url)
17
+ http = Net::HTTP.new(uri.host, uri.port)
18
+ http.use_ssl = true
19
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE # XXX: security issue
20
+ headers = {'Cookie' => "nexposeCCSessionID=#{nsc.session_id}"}
21
+ resp = http.get(uri.path, headers)
22
+
23
+ file = File.open(filename, "w")
24
+ file.write(resp.body)
25
+ file.close
26
+
27
+ filename
28
+ end
29
+
30
+ def self.generate(nsc, list, options={:template=>'', :filename=> '', :format=>"csv", :scan_to_include=>1})
31
+
32
+ options[:filename] = "export_#{Time.now.strftime("%Y%m%d%H%M%s")}.csv" if options[:filename].nil? or options[:filename].empty?
33
+ report = Nexpose::ReportConfig.new(nsc)
34
+ report.set_name(options[:filename])
35
+ report.set_template_id(options[:template])
36
+ report.set_format(options[:format])
37
+
38
+ list.each do |item|
39
+ site_config = Nexpose::SiteConfig.new
40
+ site_config.getSiteConfig(nsc, item[:site_id])
41
+ scan_history = nsc.site_scan_history(item[:site_id])
42
+ scan_history.sort! { |a,b| b[:start_time] <=> a[:start_time]}
43
+ scan_history.take(options[:scan_to_include]).each do |scan|
44
+ report.addFilter('scan', scan[:scan_id])
45
+ end
46
+ end
47
+
48
+ report.saveReport
49
+
50
+ url = nil
51
+ while not url
52
+ url = nsc.report_last(report.config_id)
53
+ select(nil, nil, nil, 10)
54
+ end
55
+
56
+ full_url="https://#{nsc.host}:#{nsc.port}#{url}"
57
+
58
+ {:url=>full_url, :filename=>options[:filename]}
59
+ end
60
+
61
+ def self.generate_from_a_template(template_name, nsc)
62
+ sites=nsc.site_listing
63
+ result = Nexty::Report.generate(nsc, sites, {:template=>template_name, :filename=>nil, :format=>'csv', :scan_to_include=>1})
64
+ result[:url]
65
+ end
66
+
67
+ def self.generate_from_a_list_of_sites(site_list=nil, nsc)
68
+ sites=Nexty::Sites.load_from_file(site_list)
69
+ s = []
70
+ sites.each do |site|
71
+ s << nsc.find_site_by_name(site)
72
+ end
73
+ result = Nexty::Report.generate(nsc, s, {:template=>"template-per-vulnerability-meeting", :format=>'csv', :filename=>nil, :scan_to_include=>4})
74
+ Nexty::Report.download(result[:url], result[:filename], nsc)
75
+ end
76
+ end
77
+ end
data/lib/nexty/site.rb ADDED
@@ -0,0 +1,56 @@
1
+ module Nexty
2
+ class Sites
3
+ # Public: load site names from a text file returning it in an array
4
+ #
5
+ # file - the filename
6
+ #
7
+ # Example
8
+ # Nexty::Sites.load_from_file('./important_sites.txt')
9
+ # # => ['www', 'mail', 'dns']
10
+ #
11
+ # Nexty::Sites.load_from_file('./doesnt_exists_file.foo')
12
+ # # => []
13
+ #
14
+ # Returns an Array containing the site names or an empty Array if the file
15
+ # doesn't exist.
16
+ def self.load_from_file(file)
17
+ if !File.exists?(file)
18
+ return []
19
+ end
20
+
21
+ ret = []
22
+ File.open(file).each_line{ |s|
23
+ ret << s.chomp
24
+ }
25
+
26
+ ret
27
+
28
+ end
29
+ end
30
+ end
31
+
32
+ module Nexpose
33
+ module NexposeAPI
34
+ include XMLUtils
35
+
36
+ def find_site_by_name(name)
37
+ r = execute(make_xml('SiteListingRequest', {}))
38
+ res = {}
39
+
40
+ if (r.success)
41
+ r.res.elements.each("//SiteSummary") do |site|
42
+ if (site.attributes['name'] == name)
43
+ res = {
44
+ :site_id => site.attributes['id'].to_i,
45
+ :name => site.attributes['name'].to_s,
46
+ :risk_factor => site.attributes['riskfactor'].to_f,
47
+ :risk_score => site.attributes['riskscore'].to_f,
48
+ }
49
+ end
50
+ end
51
+ end
52
+ res
53
+ end
54
+ end
55
+ end
56
+
@@ -0,0 +1,3 @@
1
+ module Nexty
2
+ VERSION = "0.20"
3
+ end
data/lib/nexty.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'nexty/version'
2
+ require 'nexty/connector'
3
+ require 'nexty/site'
4
+ require 'nexty/report'
5
+ require 'nexty/device'
data/nexty.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/nexty/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Paolo Perego"]
6
+ gem.email = ["thesp0nge@gmail.com"]
7
+ gem.description = %q{A command line interface to your Nexpose VA tool}
8
+ gem.summary = %q{A command line interface to your Nexpose VA tool}
9
+ gem.homepage = ""
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "nexty"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Nexty::VERSION
17
+
18
+ end
@@ -0,0 +1,5 @@
1
+ a
2
+ b
3
+ c
4
+ d
5
+ e
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Site loading from file " do
4
+ it "should return an empty array if the file doesn't exist" do
5
+ a = Nexty::Sites.load_from_file('./spec/data/sites_non_existant.txt')
6
+ a.should be_empty
7
+ a.should_not be_nil
8
+ end
9
+
10
+ it "should return an array with site names" do
11
+ a = Nexty::Sites.load_from_file('./spec/data/sites.txt')
12
+ a.should_not be_empty
13
+ a.should include 'a'
14
+ end
15
+ end
@@ -0,0 +1 @@
1
+ require 'nexty'
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nexty
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.20'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Paolo Perego
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-04 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A command line interface to your Nexpose VA tool
15
+ email:
16
+ - thesp0nge@gmail.com
17
+ executables:
18
+ - nexty
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - .rvmrc
24
+ - Gemfile
25
+ - LICENSE.txt
26
+ - README.md
27
+ - Rakefile
28
+ - bin/nexty
29
+ - conf/config.yaml.sample
30
+ - lib/nexty.rb
31
+ - lib/nexty/config.rb
32
+ - lib/nexty/connector.rb
33
+ - lib/nexty/device.rb
34
+ - lib/nexty/report.rb
35
+ - lib/nexty/site.rb
36
+ - lib/nexty/version.rb
37
+ - nexty.gemspec
38
+ - spec/data/sites.txt
39
+ - spec/nexty_site_spec.rb
40
+ - spec/spec_helper.rb
41
+ homepage: ''
42
+ licenses: []
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ segments:
54
+ - 0
55
+ hash: -671521822909928412
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 1.8.24
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: A command line interface to your Nexpose VA tool
68
+ test_files:
69
+ - spec/data/sites.txt
70
+ - spec/nexty_site_spec.rb
71
+ - spec/spec_helper.rb