2020-05-11 10:22:20 +01:00
|
|
|
# -*- coding: binary -*-
|
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
|
|
module Msf
|
|
|
|
|
module Ui
|
|
|
|
|
###
|
|
|
|
|
#
|
|
|
|
|
# Displays Metasploit information useful for Debugging.
|
|
|
|
|
#
|
|
|
|
|
###
|
|
|
|
|
module Debug
|
|
|
|
|
COMMAND_HISTORY_TOTAL = 50
|
2020-09-25 09:24:40 +01:00
|
|
|
FRAMEWORK_LOG_LINE_TOTAL = 50
|
2020-09-25 13:11:24 +01:00
|
|
|
WEB_SERVICE_LOG_LINE_TOTAL = 150
|
2020-09-25 13:01:56 +01:00
|
|
|
|
|
|
|
|
# "[mm/dd/yyyy hh:mm:ss] [e([ANY_NUMBER])]" Indicates the start of an error message
|
|
|
|
|
# The end of an error message is indicated by the start of the next log message [mm/dd/yyyy hh:mm:ss] [[ANY_LETTER]([ANY_NUMBER])]
|
|
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# When using the commented regex, the below example framework.log will only return three separate errors, and their accompanying traces:
|
|
|
|
|
#
|
|
|
|
|
# [05/15/2020 14:13:38] [e(0)] core: [-] Error during IRB: undefined method `[]' for nil:NilClass
|
|
|
|
|
#
|
|
|
|
|
# [06/19/2020 12:05:02] [i(0)] core: Trying to continue despite failed database creation: could not connect to server: Connection refused
|
|
|
|
|
# Is the server running on host "127.0.0.1" and accepting
|
|
|
|
|
# TCP/IP connections on port 5433?
|
|
|
|
|
#
|
|
|
|
|
# [05/15/2020 14:19:20] [e(0)] core: [-] Error while running command debug: can't modify frozen String
|
|
|
|
|
# Call stack:
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/msf/ui/debug.rb:33:in `get_all'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/msf/ui/console/command_dispatcher/core.rb:318:in `cmd_debug'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:523:in `run_command'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:474:in `block in run_single'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:468:in `each'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:468:in `run_single'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/rex/ui/text/shell.rb:158:in `run'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
|
|
|
|
|
#
|
|
|
|
|
# [06/19/2020 11:51:44] [d(2)] core: Stager osx/armle/reverse_tcp and stage osx/x64/meterpreter have incompatible architectures: armle - x64
|
|
|
|
|
#
|
|
|
|
|
# [05/15/2020 14:23:55] [e(0)] core: [-] Error during IRB: undefined method `[]' for nil:NilClass
|
|
|
|
|
FRAMEWORK_ERROR_REGEX = %r|\[\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}\] \[e\(\d+\)\] (?:(?!\[\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}\] \[[A-Za-z]\(\d+\)\]).)+|m
|
|
|
|
|
FRAMEWORK_ERROR_TOTAL = 10
|
|
|
|
|
|
|
|
|
|
# "[-]" Indicates the start of an error message
|
|
|
|
|
# The end of an error message is indicated by a \n character followed by any non-whitespace character
|
|
|
|
|
#
|
|
|
|
|
# When using the commented regex, the below example msf-ws.log will only return three separate errors, and their accompanying traces:
|
|
|
|
|
#
|
|
|
|
|
# [-] Error that does not return a stack trace.
|
|
|
|
|
# Writing PID to /Users/agalway/.msf4/msf-ws.pid
|
|
|
|
|
# Thin web server (v1.7.2 codename Bachmanity)
|
|
|
|
|
# Maximum connections set to 1024
|
|
|
|
|
# Listening on localhost:5443, CTRL+C to stop
|
|
|
|
|
#
|
|
|
|
|
#
|
|
|
|
|
# [-] Error handling request: wrong number of arguments (given 4, expected 1).
|
|
|
|
|
# Call Stack:
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/msf/core/db_manager/service.rb:44:in `get_service'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/msf/core/db_manager/note.rb:136:in `block in report_note'
|
|
|
|
|
# /Users/agalway/vendor/bundle/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:416:in `with_connection'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/msf/core/db_manager/note.rb:81:in `report_note'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/msf/core/web_services/servlet/note_servlet.rb:42:in `block (2 levels) in report_note'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/msf/core/web_services/servlet_helper.rb:78:in `exec_report_job'
|
|
|
|
|
# /Users/agalway/vendor/bundle/gems/thin-1.7.2/bin/thin:6:in `<top (required)>'
|
|
|
|
|
# /Users/agalway/vendor/bundle/bin/thin:23:in `load'
|
|
|
|
|
# /Users/agalway/vendor/bundle/bin/thin:23:in `<main>'
|
|
|
|
|
# [-] Error handling request: wrong number of arguments (given 4, expected 1).
|
|
|
|
|
# Call Stack:
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/msf/core/db_manager/service.rb:44:in `get_service'
|
|
|
|
|
# /Users/Shared/Relocated_Items/Security/rapid7/metasploit-framework/lib/msf/core/db_manager/note.rb:136:in `block in report_note'
|
|
|
|
|
# /Users/agalway/vendor/bundle/gems/activerecord-5.2.4.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:416:in `with_connection'
|
|
|
|
|
# /Users/agalway/vendor/bundle/gems/thin-1.7.2/bin/thin:6:in `<top (required)>'
|
|
|
|
|
# /Users/agalway/vendor/bundle/bin/thin:23:in `load'
|
|
|
|
|
# /Users/agalway/vendor/bundle/bin/thin:23:in `<main>'
|
|
|
|
|
WEB_SERVICE_ERROR_REGEX = %r|\[-\].+?\n(?!\s)|m
|
|
|
|
|
WEB_SERVICE_ERROR_TOTAL = 10
|
|
|
|
|
|
2020-05-11 10:22:20 +01:00
|
|
|
ISSUE_LINK = 'https://github.com/rapid7/metasploit-framework/issues/new/choose'
|
|
|
|
|
PREAMBLE = <<~PREMABLE
|
|
|
|
|
Please provide the below information in any Github issues you open. New issues can be opened here #{ISSUE_LINK.dup}
|
|
|
|
|
%red%undENSURE YOU HAVE REMOVED ANY SENSITIVE INFORMATION BEFORE SUBMITTING!%clr
|
|
|
|
|
|
|
|
|
|
===8<=== CUT AND PASTE EVERYTHING BELOW THIS LINE ===8<===
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PREMABLE
|
|
|
|
|
|
2021-11-18 12:27:46 +00:00
|
|
|
ERROR_BLURB = 'An error occurred when trying to build this section:'
|
|
|
|
|
|
2020-05-11 10:22:20 +01:00
|
|
|
def self.issue_link
|
|
|
|
|
return ISSUE_LINK.dup
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.preamble
|
|
|
|
|
return PREAMBLE.dup
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.all(framework, driver)
|
|
|
|
|
all_information = preamble
|
|
|
|
|
all_information << datastore(framework, driver)
|
2021-11-18 12:27:46 +00:00
|
|
|
all_information << database_configuration(framework)
|
2020-05-11 10:22:20 +01:00
|
|
|
all_information << history(driver)
|
|
|
|
|
all_information << errors
|
|
|
|
|
all_information << logs
|
|
|
|
|
all_information << versions(framework)
|
|
|
|
|
|
|
|
|
|
all_information
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.datastore(framework, driver)
|
|
|
|
|
|
|
|
|
|
# Generate an ini with the existing config file
|
|
|
|
|
ini = Rex::Parser::Ini.new(Msf::Config.config_file)
|
|
|
|
|
|
|
|
|
|
# Delete all groups from the config ini that potentially have more up to date information
|
|
|
|
|
ini.keys.each do |key|
|
2020-07-15 20:59:17 +01:00
|
|
|
unless key.start_with?("framework/database") || key.start_with?("framework/features")
|
2020-07-01 14:12:27 +01:00
|
|
|
ini.delete(key)
|
2020-05-11 10:22:20 +01:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Retrieve and add more up to date information
|
2023-03-21 14:02:30 +00:00
|
|
|
add_hash_to_ini_group(ini, framework.datastore.to_h, driver.get_config_core)
|
2020-05-11 10:22:20 +01:00
|
|
|
add_hash_to_ini_group(ini, driver.get_config, driver.get_config_group)
|
|
|
|
|
|
|
|
|
|
if driver.active_module
|
2023-03-21 14:02:30 +00:00
|
|
|
add_hash_to_ini_group(ini, driver.active_module.datastore.to_h, driver.active_module.refname)
|
2020-05-11 10:22:20 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Filter credentials
|
|
|
|
|
ini.each do |key, value|
|
|
|
|
|
if key =~ %r{^framework/database/}
|
|
|
|
|
value.transform_values! { '[Filtered]' }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if ini.to_s.empty?
|
|
|
|
|
content = 'The local config file is empty, no global variables are set, and there is no active module.'
|
|
|
|
|
else
|
|
|
|
|
content = ini.to_s
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
build_section(
|
|
|
|
|
'Module/Datastore',
|
|
|
|
|
'The following global/module datastore, and database setup was configured before the issue occurred:',
|
|
|
|
|
content
|
|
|
|
|
)
|
|
|
|
|
rescue StandardError => e
|
2021-11-18 12:27:46 +00:00
|
|
|
build_section(
|
|
|
|
|
'Module/Datastore',
|
|
|
|
|
ERROR_BLURB,
|
|
|
|
|
section_build_error('Failed to extract Datastore', e)
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.database_configuration(framework)
|
|
|
|
|
output = "```\nSession Type: #{db_connection_info(framework)}\n```\n\n"
|
|
|
|
|
|
|
|
|
|
if framework.db&.active
|
|
|
|
|
current_workspace = framework.db.workspace
|
|
|
|
|
example_workspaces = ::Mdm::Workspace.order(id: :desc).take(10)
|
|
|
|
|
ordered_workspaces = ([current_workspace] + example_workspaces).uniq.sort_by(&:id)
|
|
|
|
|
workspace_rows = ordered_workspaces.map do |workspace|
|
2022-11-02 17:28:23 -05:00
|
|
|
id = current_workspace.id == workspace.id ? "#{workspace.id.to_fs(:delimited)} **(Current)**" : workspace.id.to_fs(:delimited)
|
2021-11-18 12:27:46 +00:00
|
|
|
[
|
|
|
|
|
id,
|
2022-11-02 17:28:23 -05:00
|
|
|
workspace.hosts.count.to_fs(:delimited),
|
|
|
|
|
workspace.vulns.count.to_fs(:delimited),
|
|
|
|
|
workspace.notes.count.to_fs(:delimited),
|
|
|
|
|
workspace.services.count.to_fs(:delimited)
|
2021-11-18 12:27:46 +00:00
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
totals_row = [
|
2022-11-02 17:28:23 -05:00
|
|
|
"**Total (#{::Mdm::Workspace.count.to_fs(:delimited)})**",
|
|
|
|
|
"**#{::Mdm::Host.count.to_fs(:delimited)}**",
|
|
|
|
|
"**#{::Mdm::Vuln.count.to_fs(:delimited)}**",
|
|
|
|
|
"**#{::Mdm::Note.count.to_fs(:delimited)}**",
|
|
|
|
|
"**#{::Mdm::Service.count.to_fs(:delimited)}**"
|
2021-11-18 12:27:46 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
table = "| ID | Hosts | Vulnerabilities | Notes | Services |\n"
|
|
|
|
|
table += "|-:|-:|-:|-:|-:|\n"
|
|
|
|
|
table += (workspace_rows + [totals_row]).map { |x| "| #{x.join(" | ")} |" }.join("\n")
|
|
|
|
|
output += table
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# The markdown table can't be placed in a code block or it will not render as a table.
|
|
|
|
|
build_section_no_block(
|
|
|
|
|
'Database Configuration',
|
|
|
|
|
'The database contains the following information:',
|
|
|
|
|
output
|
|
|
|
|
)
|
|
|
|
|
rescue StandardError => e
|
|
|
|
|
build_section(
|
|
|
|
|
'Database Configuration',
|
|
|
|
|
ERROR_BLURB,
|
|
|
|
|
section_build_error('Failed to extract Database configuration', e)
|
|
|
|
|
)
|
2020-05-11 10:22:20 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.history(driver)
|
|
|
|
|
end_pos = Readline::HISTORY.length - 1
|
|
|
|
|
start_pos = end_pos - COMMAND_HISTORY_TOTAL > driver.hist_last_saved ? end_pos - (COMMAND_HISTORY_TOTAL - 1) : driver.hist_last_saved
|
|
|
|
|
|
|
|
|
|
commands = ''
|
|
|
|
|
while start_pos <= end_pos
|
|
|
|
|
# Formats command position in history to 6 characters in length
|
|
|
|
|
commands += "#{'%-6.6s' % start_pos.to_s} #{Readline::HISTORY[start_pos]}\n"
|
|
|
|
|
start_pos += 1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
build_section(
|
|
|
|
|
'History',
|
|
|
|
|
'The following commands were ran during the session and before this issue occurred:',
|
|
|
|
|
commands
|
|
|
|
|
)
|
|
|
|
|
rescue StandardError => e
|
2021-11-18 12:27:46 +00:00
|
|
|
build_section(
|
|
|
|
|
'History',
|
|
|
|
|
ERROR_BLURB,
|
|
|
|
|
section_build_error('Failed to extract History', e)
|
|
|
|
|
)
|
2020-05-11 10:22:20 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.errors
|
2020-09-25 13:01:56 +01:00
|
|
|
errors = build_regex_file_section(Pathname.new(Msf::Config.log_directory).join('framework.log'),
|
|
|
|
|
FRAMEWORK_ERROR_TOTAL,
|
|
|
|
|
FRAMEWORK_ERROR_REGEX,
|
|
|
|
|
'Framework Errors',
|
|
|
|
|
'The following framework errors occurred before the issue occurred:')
|
|
|
|
|
|
|
|
|
|
errors += build_regex_file_section(Pathname.new(Msf::Config.log_directory).join('msf-ws.log'),
|
|
|
|
|
WEB_SERVICE_ERROR_TOTAL,
|
|
|
|
|
WEB_SERVICE_ERROR_REGEX,
|
|
|
|
|
'Web Service Errors',
|
|
|
|
|
'The following web service errors occurred before the issue occurred:')
|
2020-09-25 14:45:33 +01:00
|
|
|
errors
|
2020-05-11 10:22:20 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.logs
|
2020-09-25 13:01:56 +01:00
|
|
|
logs = build_file_section(Pathname.new(Msf::Config.log_directory).join('framework.log'),
|
2020-09-25 09:24:40 +01:00
|
|
|
FRAMEWORK_LOG_LINE_TOTAL,
|
|
|
|
|
'Framework Logs',
|
|
|
|
|
'The following framework logs were recorded before the issue occurred:')
|
2020-05-11 10:22:20 +01:00
|
|
|
|
2020-09-25 13:01:56 +01:00
|
|
|
logs += build_file_section(Pathname.new(Msf::Config.log_directory).join('msf-ws.log'),
|
2020-09-25 09:24:40 +01:00
|
|
|
WEB_SERVICE_LOG_LINE_TOTAL,
|
|
|
|
|
'Web Service Logs',
|
|
|
|
|
'The following web service logs were recorded before the issue occurred:')
|
2020-09-25 14:45:33 +01:00
|
|
|
logs
|
2020-05-11 10:22:20 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.versions(framework)
|
|
|
|
|
|
|
|
|
|
str = <<~VERSIONS
|
|
|
|
|
Framework: #{framework.version}
|
|
|
|
|
Ruby: #{RUBY_DESCRIPTION}
|
2022-07-19 15:26:05 +01:00
|
|
|
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
|
2020-05-11 10:22:20 +01:00
|
|
|
Install Root: #{Msf::Config.install_root}
|
|
|
|
|
Session Type: #{db_connection_info(framework)}
|
|
|
|
|
Install Method: #{installation_method}
|
|
|
|
|
VERSIONS
|
|
|
|
|
|
|
|
|
|
build_section('Version/Install', 'The versions and install method of your Metasploit setup:', str)
|
|
|
|
|
rescue StandardError => e
|
2021-11-18 12:27:46 +00:00
|
|
|
build_section(
|
|
|
|
|
'Version/Install',
|
|
|
|
|
ERROR_BLURB,
|
|
|
|
|
section_build_error('Failed to extract Versions', e)
|
|
|
|
|
)
|
2020-05-11 10:22:20 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class << self
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
2020-09-25 13:01:56 +01:00
|
|
|
def build_regex_file_section(path, match_total, regex, header_name, blurb)
|
|
|
|
|
unless File.file?(path)
|
2020-09-25 14:45:33 +01:00
|
|
|
return build_section(
|
2020-09-25 13:01:56 +01:00
|
|
|
header_name,
|
|
|
|
|
blurb,
|
|
|
|
|
"#{path.basename.to_s} does not exist."
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
file_contents = File.read(path)
|
|
|
|
|
matches = file_contents.scan(regex)
|
|
|
|
|
|
|
|
|
|
if matches.empty?
|
|
|
|
|
return build_section(
|
|
|
|
|
header_name,
|
|
|
|
|
blurb,
|
|
|
|
|
"No matching patterns were found in #{path.basename}."
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# +.scan+ can sometimes return each match as a single item array
|
|
|
|
|
matches.flatten!
|
|
|
|
|
|
|
|
|
|
# create a string consisting of the last +match_total+ matches
|
|
|
|
|
# if +matches.length+ < +match_total+ then concat all matches
|
|
|
|
|
str = concat_str_array_from_last_idx(matches, match_total)
|
|
|
|
|
|
|
|
|
|
build_section(
|
|
|
|
|
header_name,
|
|
|
|
|
blurb,
|
|
|
|
|
str
|
|
|
|
|
)
|
|
|
|
|
rescue StandardError => e
|
2021-11-18 12:27:46 +00:00
|
|
|
build_section(
|
|
|
|
|
header_name,
|
|
|
|
|
ERROR_BLURB,
|
|
|
|
|
section_build_error("Failed to extract matches from #{path.basename}", e)
|
|
|
|
|
)
|
2020-09-25 13:01:56 +01:00
|
|
|
end
|
|
|
|
|
|
2020-09-25 09:24:40 +01:00
|
|
|
def build_file_section(path, line_total, header_name, blurb)
|
2020-09-25 13:01:56 +01:00
|
|
|
unless File.file?(path)
|
|
|
|
|
return build_section(
|
|
|
|
|
header_name,
|
|
|
|
|
blurb,
|
|
|
|
|
"#{path.basename.to_s} does not exist."
|
|
|
|
|
)
|
2020-09-25 09:24:40 +01:00
|
|
|
end
|
|
|
|
|
|
2020-09-25 13:01:56 +01:00
|
|
|
log_lines = File.readlines(path)
|
|
|
|
|
|
|
|
|
|
# create a string consisting of the last +line_total+ lines
|
|
|
|
|
# if +log_lines.length+ < +line_total+ then concat all lines
|
|
|
|
|
str = concat_str_array_from_last_idx(log_lines, line_total)
|
|
|
|
|
|
2020-09-25 09:24:40 +01:00
|
|
|
build_section(
|
|
|
|
|
header_name,
|
|
|
|
|
blurb,
|
|
|
|
|
str
|
|
|
|
|
)
|
|
|
|
|
rescue StandardError => e
|
2021-11-18 12:27:46 +00:00
|
|
|
build_section(
|
|
|
|
|
header_name,
|
|
|
|
|
ERROR_BLURB,
|
|
|
|
|
section_build_error("Failed to extract contents of #{path.basename.to_s}", e)
|
|
|
|
|
)
|
2020-09-25 09:24:40 +01:00
|
|
|
end
|
|
|
|
|
|
2020-05-11 10:22:20 +01:00
|
|
|
def add_hash_to_ini_group(ini, hash, group_name)
|
|
|
|
|
if hash.empty?
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
unless ini.group?(group_name)
|
|
|
|
|
ini.add_group(group_name)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
hash.each_pair do |k, v|
|
|
|
|
|
ini[group_name][k] = v
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def concat_str_array_from_last_idx(array, concat_total)
|
|
|
|
|
start_pos = array.length > concat_total ? array.length - concat_total : 0
|
|
|
|
|
end_pos = array.length - 1
|
|
|
|
|
|
|
|
|
|
str = array[start_pos..end_pos].join('')
|
|
|
|
|
|
|
|
|
|
str.strip
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Copy pasta of the print_connection_info method in console/command_dispatcher/db.rb
|
|
|
|
|
def db_connection_info(framework)
|
|
|
|
|
unless framework.db.connection_established?
|
|
|
|
|
return "#{framework.db.driver} selected, no connection"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
cdb = ''
|
|
|
|
|
if framework.db.driver == 'http'
|
|
|
|
|
cdb = framework.db.name
|
|
|
|
|
else
|
2020-04-03 09:38:15 -05:00
|
|
|
::ApplicationRecord.connection_pool.with_connection do |conn|
|
2020-05-11 10:22:20 +01:00
|
|
|
if conn.respond_to?(:current_database)
|
|
|
|
|
cdb = conn.current_database
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if cdb.empty?
|
|
|
|
|
output = "Connected Database Name could not be extracted. DB Connection type: #{framework.db.driver}."
|
|
|
|
|
else
|
|
|
|
|
output = "Connected to #{cdb}. Connection type: #{framework.db.driver}."
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
output
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def build_section(header_name, blurb, content)
|
|
|
|
|
<<~SECTION
|
|
|
|
|
## %grn#{header_name.strip}%clr
|
|
|
|
|
|
|
|
|
|
#{blurb.strip}
|
|
|
|
|
#{with_collapsible_wrapper(content.strip)}
|
|
|
|
|
|
|
|
|
|
SECTION
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def with_collapsible_wrapper(content)
|
|
|
|
|
<<~WRAPPER
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Collapse</summary>
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
#{content}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
WRAPPER
|
|
|
|
|
end
|
|
|
|
|
|
2021-11-18 12:27:46 +00:00
|
|
|
def with_collapsible_wrapper_no_block(content)
|
|
|
|
|
<<~WRAPPER
|
|
|
|
|
<details>
|
|
|
|
|
<summary>Collapse</summary>
|
|
|
|
|
|
|
|
|
|
#{content}
|
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
WRAPPER
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Useful for building tables or other content that can't be placed inside a code block.
|
|
|
|
|
def build_section_no_block(header_name, blurb, content)
|
|
|
|
|
<<~SECTION
|
|
|
|
|
## %grn#{header_name.strip}%clr
|
|
|
|
|
|
|
|
|
|
#{blurb.strip}
|
|
|
|
|
#{with_collapsible_wrapper_no_block(content.strip)}
|
|
|
|
|
|
|
|
|
|
SECTION
|
|
|
|
|
end
|
|
|
|
|
|
2020-05-11 10:22:20 +01:00
|
|
|
def installation_method
|
|
|
|
|
if File.exist?(File.join(Msf::Config.install_root, 'version.yml'))
|
|
|
|
|
'Omnibus Installer'
|
|
|
|
|
elsif File.directory?(File.join(Msf::Config.install_root, '.git'))
|
|
|
|
|
'Git Clone'
|
|
|
|
|
else
|
|
|
|
|
'Other - Please specify'
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def section_build_error(msg, error)
|
|
|
|
|
"#{msg}: #{error.class} - #{error.message} \n Call stack:\n#{error.backtrace.join("\n")}"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|