From 958513bd8687a370172d5ed85dc0cafa595117df Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Fri, 9 Feb 2018 19:45:46 -0600 Subject: [PATCH 1/4] Fix #9522, Add output file support to the vulns command This adds a new feature for the vulns command for msfconsole. It allows the user to be able to save the vulnerability as a CSV file. Fix #9522 --- lib/msf/ui/console/command_dispatcher/db.rb | 40 +++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index 3155a0a7c9..6e36f62323 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -777,6 +777,7 @@ class Db print_line "Usage: vulns [addr range]" print_line print_line " -h,--help Show this help information" + print_line " -o Send output to a file in csv format" print_line " -p,--port List vulns matching this port spec" print_line " -s List vulns matching these service names" print_line " -R,--rhosts Set RHOSTS from the results of the search" @@ -801,6 +802,7 @@ class Db search_term = nil show_info = false set_rhosts = false + output_file = nil # Short-circuit help if args.delete "-h" @@ -817,6 +819,14 @@ class Db when "-h","--help" cmd_vulns_help return + when "-o", "--output" + output_file = args.shift + if output_file + output_file = File.expand_path(output_file) + else + print_error("Invalid output filename") + return + end when "-p","--port" unless (arg_port_range(args.shift, port_ranges, true)) return @@ -846,6 +856,10 @@ class Db host_ranges.push(nil) if host_ranges.empty? ports = port_ranges.flatten.uniq svcs.flatten! + tbl = Rex::Text::Table.new( + 'Header' => 'Vulnerabilities', + 'Columns' => ['Timestamp', 'Host', 'Name', 'References', 'Information'] + ) each_host_range_chunk(host_ranges) do |host_search| framework.db.hosts(framework.db.workspace, false, host_search).each do |host| @@ -857,19 +871,34 @@ class Db ) end reflist = vuln.refs.map { |r| r.name } + if(vuln.service) # Skip this one if the user specified a port and it # doesn't match. next unless ports.empty? or ports.include? vuln.service.port # Same for service names next unless svcs.empty? or svcs.include?(vuln.service.name) - print_status("Time: #{vuln.created_at} Vuln: host=#{host.address} name=#{vuln.name} refs=#{reflist.join(',')} #{(show_info && vuln.info) ? "info=#{vuln.info}" : ""}") - else # This vuln has no service, so it can't match next unless ports.empty? and svcs.empty? - print_status("Time: #{vuln.created_at} Vuln: host=#{host.address} name=#{vuln.name} refs=#{reflist.join(',')} #{(show_info && vuln.info) ? "info=#{vuln.info}" : ""}") end + + print_status("Time: #{vuln.created_at} Vuln: host=#{host.address} name=#{vuln.name} refs=#{reflist.join(',')} #{(show_info && vuln.info) ? "info=#{vuln.info}" : ""}") + + if output_file + row = [] + row << vuln.created_at + row << host.address + row << vuln.name + row << reflist * "," + if show_info && vuln.info + row << "info=#{vuln.info}" + else + row << '' + end + tbl << row + end + if set_rhosts addr = (host.scope ? host.address + '%' + host.scope : host.address) rhosts << addr @@ -878,6 +907,11 @@ class Db end end + unless tbl.rows.empty? + File.write(output_file, tbl.to_csv) + print_status("Wrote vulnerability information to #{output_file}") + end + # Finally, handle the case where the user wants the resulting list # of hosts to go into RHOSTS. set_rhosts_from_addrs(rhosts.uniq) if set_rhosts From 46a0ea65829b721be0073b6f168993551d803d27 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Fri, 9 Feb 2018 20:06:43 -0600 Subject: [PATCH 2/4] Fix db_spec --- spec/lib/msf/ui/console/command_dispatcher/db_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/lib/msf/ui/console/command_dispatcher/db_spec.rb b/spec/lib/msf/ui/console/command_dispatcher/db_spec.rb index 7bccc9b9cc..57f047a3a8 100644 --- a/spec/lib/msf/ui/console/command_dispatcher/db_spec.rb +++ b/spec/lib/msf/ui/console/command_dispatcher/db_spec.rb @@ -265,6 +265,7 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Db do "Print all vulnerabilities in the database", "Usage: vulns [addr range]", " -h,--help Show this help information", + " -o Send output to a file in csv format", " -p,--port List vulns matching this port spec", " -s List vulns matching these service names", " -R,--rhosts Set RHOSTS from the results of the search", From 81e0d562614ce2a6257363493bcb5055383094e4 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Fri, 9 Feb 2018 20:28:12 -0600 Subject: [PATCH 3/4] Always write the file as long as the option is set --- lib/msf/ui/console/command_dispatcher/db.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index 6e36f62323..02bd215f1c 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -907,7 +907,7 @@ class Db end end - unless tbl.rows.empty? + if out_file File.write(output_file, tbl.to_csv) print_status("Wrote vulnerability information to #{output_file}") end From b9faa9e92bf8ab74ccade01a889a736dc2acb68b Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Fri, 9 Feb 2018 20:28:55 -0600 Subject: [PATCH 4/4] Fix a typo --- lib/msf/ui/console/command_dispatcher/db.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index 02bd215f1c..356061eab7 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -907,7 +907,7 @@ class Db end end - if out_file + if output_file File.write(output_file, tbl.to_csv) print_status("Wrote vulnerability information to #{output_file}") end