Files
metasploit-gs/plugins/besecure.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

351 lines
10 KiB
Ruby
Raw Normal View History

2020-04-12 08:56:17 +03:00
#
# This plugin provides integration with beSECURE. Written by Noam Rathaus.
#
# Distributed under MIT license:
# http://www.opensource.org/licenses/mit-license.php
#
# Version 10.5.17
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
require 'base64'
require 'zlib'
2020-04-12 08:56:17 +03:00
require 'tempfile'
require 'pathname'
module Msf
2023-01-30 12:25:46 +11:00
class Plugin::BeSECURE < Msf::Plugin
class BeSECURECommandDispatcher
include Msf::Ui::Console::CommandDispatcher
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
def name
'beSECURE'
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
def commands
{
'besecure_help' => 'Displays help',
'besecure_version' => 'Display the version of the beSECURE server',
'besecure_apikey' => 'Set the beSECURE API Key',
'besecure_hostname' => 'Set the beSECURE Hostname',
'besecure_debug' => 'Enable/Disable debugging',
'besecure_ssl_verify' => 'Enable/Disable SSL verification',
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
'besecure_report_list' => 'Display list of reports',
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
'besecure_report_download' => 'Save a report to disk',
'besecure_report_import' => 'Import report specified by ID into framework'
}
2020-04-12 08:56:17 +03:00
end
2023-01-30 12:25:46 +11:00
def cmd_besecure_help
print_status('besecure_help Display this help')
print_status('besecure_debug Enable/Disable debugging')
print_status('besecure_version Display the version of the beSECURE server')
print_status('besecure_apikey Set the beSECURE API Key')
print_status('besecure_ssl_verify Set whether to verify or not SSL')
print_status('besecure_hostname Set the beSECURE Hostname')
print_status
print_status('REPORTS')
print_status('=======')
print_status('besecure_report_list Lists reports')
print_status('besecure_report_download Downloads an beSECURE report specified by ID')
print_status('besecure_report_import Import report specified by ID into framework')
2020-04-12 08:56:17 +03:00
end
2023-01-30 12:25:46 +11:00
# Verify the database is connected and usable
def database?
2023-01-30 13:05:34 +11:00
if !(framework.db && framework.db.usable)
2023-01-30 12:25:46 +11:00
return false
else
return true
end
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
# Verify correct number of arguments and verify -h was not given. Return
# true if correct number of arguments and help was not requested.
def args?(args, min = 1, max = nil)
if !max then max = min end
2023-01-30 13:05:34 +11:00
if ((args.length < min) || (args.length > max) || (args[0] == '-h'))
2023-01-30 12:25:46 +11:00
return false
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
return true
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
#--------------------------
# Basic Functions
#--------------------------
def cmd_besecure_hostname(*args)
if args?(args)
@hostname = args[0]
print_good(@hostname)
else
print_status('Usage:')
print_status('besecure_hostname string')
end
2020-12-06 04:37:51 -05:00
end
2023-01-30 12:25:46 +11:00
def cmd_besecure_apikey(*args)
if args?(args)
@apikey = args[0]
print_good(@apikey)
else
print_status('Usage:')
print_status('besecure_apikey string')
end
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
def cmd_besecure_ssl_verify(*args)
if args?(args)
@ssl_verify = args[0]
2023-01-30 13:05:34 +11:00
if (@ssl_verify != 'yes') && (@ssl_verify != 'no')
2023-01-30 12:25:46 +11:00
@ssl_verify = 'yes'
end
print_good(@ssl_verify)
else
print_status('Usage:')
print_status("besecure_ssl_verify 'yes'/'no' (default is yes)")
end
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
def cmd_besecure_debug(*args)
if args?(args)
@debug = args[0].to_i
print_good(@debug)
else
print_status('Usage:')
print_status('besecure_debug integer')
end
end
2020-12-06 04:37:51 -05:00
2023-01-30 12:25:46 +11:00
def cmd_besecure_version
req = Net::HTTP::Post.new('/json.cgi', { 'Host' => @hostname })
2023-01-30 12:25:46 +11:00
req.set_form_data({ 'apikey' => @apikey, 'primary' => 'interface' })
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
if @debug
print_status(req.body)
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
http = Net::HTTP.new(@hostname, 443)
if @debug
http.set_debug_output($stdout) # Logger.new("foo.log") works too
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
http.use_ssl = true
if @ssl_verify == 'no'
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
2020-04-12 08:56:17 +03:00
2023-01-30 13:07:16 +11:00
res = http.start { |h| h.request(req) }
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
unless res
print_error("#{@hostname} - Connection timed out")
return ''
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
body = ''
begin
body = JSON.parse(res.body)
rescue JSON::ParserError
print_error("#{@hostname} - Unable to parse the response")
return ''
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
if body['error']
2024-01-07 13:24:11 -05:00
print_error("#{@hostname} - An error occurred:")
2023-01-30 12:25:46 +11:00
print_error(body)
return ''
end
2020-12-06 04:37:51 -05:00
2023-01-30 12:25:46 +11:00
print_good(body['version'])
2020-12-06 04:37:51 -05:00
end
2023-01-30 12:25:46 +11:00
#--------------------------
# Report Functions
#--------------------------
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
def cmd_besecure_report_list(*_args)
tbl = Rex::Text::Table.new(
'Columns' => ['ID', 'Name', 'Hosts']
)
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
if @hostname.empty?
print_error('Missing host value')
return ''
end
2020-04-12 08:56:17 +03:00
req = Net::HTTP::Post.new('/json.cgi', { 'Host' => @hostname })
2023-01-30 12:25:46 +11:00
req.set_form_data({ 'apikey' => @apikey, 'primary' => 'admin', 'secondary' => 'networks', 'action' => 'returnnetworks', 'search_limit' => 10000 })
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
if @debug
print_status(req.body)
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
http = Net::HTTP.new(@hostname, 443)
2020-04-12 08:56:17 +03:00
if @debug
2020-12-06 04:37:51 -05:00
http.set_debug_output($stdout) # Logger.new("foo.log") works too
2020-04-12 08:56:17 +03:00
end
http.use_ssl = true
2020-12-06 04:37:51 -05:00
if @ssl_verify == 'no'
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
2023-01-30 13:07:16 +11:00
res = http.start { |h| h.request(req) }
2020-04-12 08:56:17 +03:00
unless res
print_error("#{@hostname} - Connection timed out")
return ''
end
body = ''
begin
body = JSON.parse(res.body)
rescue JSON::ParserError
print_error("#{@hostname} - Unable to parse the response")
return ''
end
2023-01-30 12:25:46 +11:00
2020-04-12 08:56:17 +03:00
if body['error']
2024-01-07 13:24:11 -05:00
print_error("#{@hostname} - An error occurred:")
2020-04-12 08:56:17 +03:00
print_error(body)
return ''
end
2023-01-30 12:25:46 +11:00
data = body['data']
data.each do |item|
tbl << [ item['ID'], item['Name'], item['PrettyRange']]
2020-04-12 08:56:17 +03:00
end
2023-01-30 12:25:46 +11:00
# print_good(body)
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
print_good('beSECURE list of reports')
print_line
print_line tbl.to_s
print_line
2020-04-12 08:56:17 +03:00
end
2023-01-30 12:25:46 +11:00
def cmd_besecure_report_download(*args)
if args?(args, 4)
req = Net::HTTP::Post.new('/json.cgi', { 'Host' => @hostname })
2023-01-30 12:25:46 +11:00
format_file = args[1]
req.set_form_data({ 'apikey' => @apikey, 'primary' => 'vulnerabilities', 'secondary' => 'report', 'action' => 'getreport', 'network' => args[0], 'format' => format_file })
http = Net::HTTP.new(@hostname, 443)
if @debug
http.set_debug_output($stdout) # Logger.new("foo.log") works too
end
http.use_ssl = true
if @ssl_verify == 'no'
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
2023-01-30 13:07:16 +11:00
res = http.start { |h| h.request(req) }
2023-01-30 12:25:46 +11:00
unless res
print_error("#{@hostname} - Connection timed out")
return ''
end
body = ''
begin
body = JSON.parse(res.body)
rescue JSON::ParserError
print_error("#{@hostname} - Unable to parse the response")
return ''
end
if body['error']
2024-01-07 13:24:11 -05:00
print_error("#{@hostname} - An error occurred:")
2023-01-30 12:25:46 +11:00
print_error(body)
return ''
end
decompressed = ''
if format_file != 'json'
compressed_base64 = body['compresseddata']
compressed = Base64.decode64(compressed_base64)
decompressed = Zlib::Inflate.inflate(compressed)
else
decompressed = body
end
if @debug
print_status(decompressed)
end
::FileUtils.mkdir_p(args[2])
name = ::File.join(args[2], args[3])
print_status("Saving report to #{name}")
output = ::File.new(name, 'w')
output.puts(decompressed)
output.close
###
# Return the report
return decompressed
else
print_status('Usage: besecure_report_download <network_id> <format_name> <path> <report_name>')
2020-05-17 18:11:03 +03:00
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
return ''
end
def cmd_besecure_report_import(*args)
if args?(args, 2)
if !database?
print_error('Database not ready')
return ''
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
tempfile = Tempfile.new('results')
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
res = cmd_besecure_report_download(args[0], 'nbe', File.dirname(tempfile) + '/', File.basename(tempfile))
if res.empty?
print_error('An empty report has been received')
return ''
end
print_status('Importing report to database.')
framework.db.import_file({ filename: tempfile })
tempfile.unlink
else
print_status('Usage: besecure_report_import <network_id> <format_name>')
print_status('Only the NBE and XML formats are supported for importing.')
end
2020-04-12 08:56:17 +03:00
end
2023-01-30 13:05:34 +11:00
end
2023-01-30 12:25:46 +11:00
#------------------------------
# Plugin initialization
#------------------------------
def initialize(framework, opts)
super
add_console_dispatcher(BeSECURECommandDispatcher)
print_status('Welcome to beSECURE integration by Noam Rathaus.')
print_status
print_status('beSECURE integration requires a database connection. Once the ')
print_status('database is ready, connect to the beSECURE server using besecure_connect.')
print_status('For additional commands use besecure_help.')
print_status
@debug = nil
2020-04-12 08:56:17 +03:00
end
2023-01-30 12:25:46 +11:00
def cleanup
remove_console_dispatcher('beSECURE')
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
def name
'beSECURE'
end
2020-04-12 08:56:17 +03:00
2023-01-30 12:25:46 +11:00
def desc
'Integrates with the beSECURE - open source vulnerability management'
end
2020-04-12 08:56:17 +03:00
end
end