Class: Nessus
- Inherits:
-
Object
- Object
- Nessus
- Defined in:
- lib/audit/lib/nessus_new.rb
Instance Attribute Summary collapse
-
#token ⇒ Object
readonly
Returns the value of attribute token.
Class Method Summary collapse
Instance Method Summary collapse
- #delete_policy(id) ⇒ Object
- #delete_report(uuid) ⇒ Object
- #execute_command(command, parameters, fail_on_error = true) ⇒ Object
- #get_policy_ids(policy_name) ⇒ Object
- #import_policy(filename) ⇒ Object
- #import_policy_file(file) ⇒ Object
-
#initialize(options = {}) ⇒ Nessus
constructor
A new instance of Nessus.
- #list_plugin_families ⇒ Object
- #list_plugin_family(family_name) ⇒ Object
- #list_report(uuid) ⇒ Object
- #list_reports ⇒ Object
- #login(username, password) ⇒ Object
- #logout ⇒ Object
-
#new_policy(options) ⇒ Object
Allowed values for configuration keys are:.
- #save_report(uuid, file) ⇒ Object
- #scan_status(uuid) ⇒ Object
-
#scan_targets(options) ⇒ Object
Scan targets completely and return when scan is finished.
-
#start_scan(options) ⇒ Object
Start a new nessus scan.
- #upload_file(file) ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Nessus
Returns a new instance of Nessus.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/audit/lib/nessus_new.rb', line 10 def initialize( = {}) = {:host => "127.0.0.1", :port => "8834", :timeout => "120"}.merge() @host = [:host] @port = [:port] @timeout = [:timeout] if [:logger] then @logger = [:logger] else @logger = Logger.new(STDOUT) end @token = nil end |
Instance Attribute Details
#token ⇒ Object (readonly)
Returns the value of attribute token.
8 9 10 |
# File 'lib/audit/lib/nessus_new.rb', line 8 def token @token end |
Class Method Details
.get_policy_name_from_file(file) ⇒ Object
227 228 229 |
# File 'lib/audit/lib/nessus_new.rb', line 227 def self.get_policy_name_from_file(file) return (Document.new(File.new(file)).elements.inject("NessusClientData_v2/Policy/policyName", []) {|r, x| r << x.text})[0] end |
Instance Method Details
#delete_policy(id) ⇒ Object
81 82 83 84 85 |
# File 'lib/audit/lib/nessus_new.rb', line 81 def delete_policy(id) return execute_command("policy/delete", [{:value => "policy_id=#{id}"}, {:type => :cookie, :value => "token=#{@token}"}]) end |
#delete_report(uuid) ⇒ Object
174 175 176 177 178 |
# File 'lib/audit/lib/nessus_new.rb', line 174 def delete_report(uuid) report = execute_command("report/delete", [{:value => "report=#{uuid}"}, {:type => :cookie, :value => "token=#{@token}"}]) end |
#execute_command(command, parameters, fail_on_error = true) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/audit/lib/nessus_new.rb', line 26 def execute_command(command, parameters, fail_on_error = true) cmd = "curl --silent --max-time #{@timeout} --insecure " parameters.each do|param| if param[:type].nil? || param[:type] == :data then cmd << "--data \"#{param[:value]}\" " elsif param[:type] == :form then cmd << "--form \"#{param[:value]}\" " elsif param[:type] == :cookie then cmd << "--cookie \"#{param[:value]}\" " else raise "unknown parameter type #{param[:type]}" end end cmd << "https://#{@host}:#{@port}/#{command}" @logger.info {"Executing command: #{cmd}"} result_str = `#{cmd}` raise "unexpected return value from nessus command #{command} " unless result_str.class == String result = Document.new(result_str) status = result.elements.inject("reply/status", []) {|r, x| r << x.text} if fail_on_error then raise "Invalid return status for nessus command #{command}" unless status && status.length == 1 && status[0] == "OK" end return result end |
#get_policy_ids(policy_name) ⇒ Object
87 88 89 90 91 |
# File 'lib/audit/lib/nessus_new.rb', line 87 def get_policy_ids(policy_name) policies = execute_command("policy/list", [{:type => :cookie, :value => "token=#{@token}"}]) return policies.elements.inject("/reply/contents/policies/policy[policyName='#{policy_name}']/policyID", []) {|r, x| r << x.text} end |
#import_policy(filename) ⇒ Object
75 76 77 78 79 |
# File 'lib/audit/lib/nessus_new.rb', line 75 def import_policy(filename) return execute_command("file/policy/import", [{:value => "file=#{filename}"}, {:type => :cookie, :value => "token=#{@token}"}]) end |
#import_policy_file(file) ⇒ Object
94 95 96 97 98 99 100 101 102 103 |
# File 'lib/audit/lib/nessus_new.rb', line 94 def import_policy_file(file) policy_name = Nessus.get_policy_name_from_file(file) policy_ids = get_policy_ids(policy_name) policy_ids.each do|id| delete_policy(id) end uploaded_name = upload_file(file) policies = import_policy(uploaded_name) return policies.elements.inject("/reply/contents/policies/policy[policyName='#{policy_name}']/policyID", []) {|r, x| r << x.text}[0] end |
#list_plugin_families ⇒ Object
269 270 271 272 273 |
# File 'lib/audit/lib/nessus_new.rb', line 269 def list_plugin_families() reply = execute_command("plugins/list", [{:type => :cookie, :value => "token=#{@token}"}]) return reply.elements.inject("/reply/contents/pluginFamilyList/family/familyName", []) {|r, x| r << x.text} end |
#list_plugin_family(family_name) ⇒ Object
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/audit/lib/nessus_new.rb', line 275 def list_plugin_family(family_name) reply = execute_command("plugins/list/family", [{:type => :cookie, :value => "token=#{@token}"}, {:value => "family=#{family_name}"}]) results = [] reply.elements.each("/reply/contents/pluginList/plugin") do|elem| result = {} elem.elements.each do|subelem| result[subelem.name] = subelem.text end results << result end return results end |
#list_report(uuid) ⇒ Object
152 153 154 155 156 157 158 159 160 |
# File 'lib/audit/lib/nessus_new.rb', line 152 def list_report(uuid) reports = list_reports() report = reports.reject {|rep| rep["name"] != uuid} return nil if report.length != 1 return report[0] end |
#list_reports ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/audit/lib/nessus_new.rb', line 137 def list_reports() reply = execute_command("report/list", [{:type => :cookie, :value => "token=#{@token}"}]) results = [] reply.elements.each("/reply/contents/reports/report") do|elem| result = {} elem.elements.each do|subelem| result[subelem.name] = subelem.text end results << result end return results end |
#login(username, password) ⇒ Object
58 59 60 61 62 63 64 |
# File 'lib/audit/lib/nessus_new.rb', line 58 def login(username, password) result = execute_command("login", [{:value => "login=#{username}"}, {:value => "password=#{password}"}]) token = result.elements.inject("reply/contents/token", []) {|r, x| r << x.text} raise "Invalid token during nessus login" unless token && token.length == 1 @token = token[0] end |
#logout ⇒ Object
221 222 223 224 225 |
# File 'lib/audit/lib/nessus_new.rb', line 221 def logout() execute_command("logout", [{:type => :cookie, :value => "token=#{@token}"}]) @token = nil end |
#new_policy(options) ⇒ Object
Allowed values for configuration keys are:
"policy_name": "some_name"
"policy_shared": "0" if the policy is not shared, or "1" if it is shared
"SSH settings[entry]:SSH user name :": "root"
"SSH settings[file]:SSH private key to use :": {:type => :file, :file => "/tmp/key.pem"}
"plugin_selection.family.Service detection": "enabled", "disabled", "mixed"
"plugin_selection.individual_plugin.19679": "enabled", "disabled"
"SSH settings[radio]:Elevate privileges with :": "Nothing", "sudo", "su", ...
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/audit/lib/nessus_new.rb', line 240 def new_policy() raise "missing option \"policy_name\"" unless ["policy_name"] raise "missing option \"policy_shared\"" unless ["policy_shared"] cmd_params = [{:type => :cookie, :value => "token=#{@token}"}] .each do|key,value| if value.class() == String then cmd_params << {:value => "#{key}=#{value}"} elsif value.class() == Hash then if value[:type] == :file then filename = upload_file(value[:file]) cmd_params << {:value => "#{key}=#{filename}"} else raise "Unknown value hash type '#{value[:type]}' for policy configuration key '#{key}'" end else raise "Unknown value type '#{value.class()} for policy configuration key '#{key}'" end end reply = execute_command("policy/add", cmd_params) policy_ids = reply.elements.inject("/reply/contents/policy/policyID", []) {|r, x| r << x.text} raise "Policy '#{["policy_name"]}' already exists or was not imported (#{policy_ids.length()})" unless policy_ids.length() == 1 return policy_ids[0] end |
#save_report(uuid, file) ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/audit/lib/nessus_new.rb', line 162 def save_report(uuid, file) report = execute_command("file/report/download", [{:value => "report=#{uuid}"}, {:type => :cookie, :value => "token=#{@token}"}], false) if report.elements.inject("/NessusClientData_v2", []) {|r, x| r << x}.empty? then raise "error during save_report" end File.open(file, 'w') {|file| file << report.to_s} end |
#scan_status(uuid) ⇒ Object
130 131 132 133 134 135 |
# File 'lib/audit/lib/nessus_new.rb', line 130 def scan_status(uuid) report = list_report(uuid) return "unknown" unless report return report["status"] end |
#scan_targets(options) ⇒ Object
Scan targets completely and return when scan is finished
Note: Only one of :policy_id, :policy_name or :policy_file needs to be specified.
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/audit/lib/nessus_new.rb', line 190 def scan_targets() raise "Need parameter :targets" unless [:targets] raise "Need parameter :report_file" unless [:report_file] policy_id = "" if [:policy_id] then policy_id = [:policy_id] elsif [:policy_name] then policy_ids = get_policy_ids(policy_name) raise "No policy with this name (#{policy_name}) found" if policy_ids.empty? raise "Several policies with this name (#{policy_name}) found" if policy_ids.length > 1 policy_id = policy_ids[0] elsif [:policy_file] then policy_id = import_policy_file([:policy_file]) else raise "Need parameter :policy_file, :policy_name or :policy_id" end scan_uuid = start_scan(:policy_id => policy_id, :targets => [:targets]) while scan_status(scan_uuid) != "completed" do sleep 30 end save_report(scan_uuid, [:report_file]) delete_policy(policy_id) if [:delete_policy] delete_report(scan_uuid) if [:delete_report] return scan_uuid end |
#start_scan(options) ⇒ Object
Start a new nessus scan
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/audit/lib/nessus_new.rb', line 109 def start_scan() raise "Missing parameter :policy_id" unless [:policy_id] raise "Missing parameter :targets" unless [:targets] scan_opts = [{:value => "policy_id=#{[:policy_id]}"}, {:type => :cookie, :value => "token=#{@token}"}] if [:targets].class() == String then scan_opts << {:value => "target=#{[:targets]}"} elsif [:targets].class() == Array then [:targets].each do|target| scan_opts << {:value => "target=#{target}"} end else raise "Unknown target type #{[:targets].class().name()}" end scan_reply = execute_command("scan/new", scan_opts) return scan_reply.elements.inject("/reply/contents/scan/uuid", []) {|r, x| r << x.text}[0] end |
#upload_file(file) ⇒ Object
66 67 68 69 70 71 72 73 |
# File 'lib/audit/lib/nessus_new.rb', line 66 def upload_file(file) raise "File '#{file}' is not accessible" unless File.exist?(file) && File.readable?(file) reply = execute_command("file/upload", [{:type => :cookie, :value => "token=#{@token}"}, {:type => :form, :value => "Filedata=@#{file}"}]) return reply.elements.inject("/reply/contents/fileUploaded", []) {|r, x| r << x.text}[0] end |