Initial commit of the fzuse plugin
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
module Msf
|
||||
###
|
||||
#
|
||||
# This class illustrates a fuzzy_use plugin. Plugins can change the behavior of
|
||||
# the framework by adding new features, new user interface commands, or
|
||||
# through any other arbitrary means. They are designed to have a very loose
|
||||
# definition in order to make them as useful as possible.
|
||||
#
|
||||
###
|
||||
class Plugin::FuzzyUse < Msf::Plugin
|
||||
|
||||
###
|
||||
#
|
||||
# This class implements a fuzzy_use console command dispatcher.
|
||||
#
|
||||
###
|
||||
class ConsoleCommandDispatcher
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
def initialize(driver)
|
||||
super
|
||||
|
||||
@module_dispatcher = Msf::Ui::Console::CommandDispatcher::Modules.new(driver)
|
||||
end
|
||||
|
||||
#
|
||||
# The dispatcher's name.
|
||||
#
|
||||
def name
|
||||
'FuzzyUse'
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the hash of commands supported by this dispatcher.
|
||||
#
|
||||
def commands
|
||||
{
|
||||
'fzuse' => 'A fuzzy_use command added by the fuzzy_use plugin'
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# This method handles the fuzzy_use command.
|
||||
#
|
||||
def cmd_fzuse(*args)
|
||||
unless Msf::Util::Helper.which('fzf')
|
||||
print_error('This command requires that the `fzf` utility be installed.')
|
||||
return
|
||||
end
|
||||
|
||||
previewer = File.join(Msf::Config.install_root, 'tools', 'modules', 'print.py')
|
||||
|
||||
module_types = framework.modules.module_types
|
||||
|
||||
query = args.empty? ? '' : args.first
|
||||
|
||||
selection = nil
|
||||
# alternative preview:
|
||||
# jq \'to_entries[] | select(.value.fullname == "{1}") | .value\' db/modules_metadata_base.json | bat --language=json --color=always
|
||||
stdin, stdout, stderr, wait_thr = Open3.popen3('fzf', '--select-1', '--query', query, '--preview', "#{previewer} {1}", '--preview-label', "Module Information") do |stdin, stdout, stderr, wait_thr|
|
||||
module_types
|
||||
module_types.each do |module_type|
|
||||
framework.modules.module_names(module_type).each do |module_name|
|
||||
stdin.puts "#{module_type}/#{module_name}"
|
||||
end
|
||||
end
|
||||
stdin.close
|
||||
|
||||
exit_status = wait_thr.value
|
||||
|
||||
selection = stdout.read
|
||||
end
|
||||
|
||||
selection.strip!
|
||||
return if selection.blank?
|
||||
|
||||
@module_dispatcher.cmd_use(selection)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# The constructor is called when an instance of the plugin is created. The
|
||||
# framework instance that the plugin is being associated with is passed in
|
||||
# the framework parameter. Plugins should call the parent constructor when
|
||||
# inheriting from Msf::Plugin to ensure that the framework attribute on
|
||||
# their instance gets set.
|
||||
#
|
||||
def initialize(framework, opts)
|
||||
super
|
||||
|
||||
# If this plugin is being loaded in the context of a console application
|
||||
# that uses the framework's console user interface driver, register
|
||||
# console dispatcher commands.
|
||||
add_console_dispatcher(ConsoleCommandDispatcher)
|
||||
|
||||
print_status('FuzzyUse plugin loaded.')
|
||||
end
|
||||
|
||||
#
|
||||
# The cleanup routine for plugins gives them a chance to undo any actions
|
||||
# they may have done to the framework. For instance, if a console
|
||||
# dispatcher was added, then it should be removed in the cleanup routine.
|
||||
#
|
||||
def cleanup
|
||||
# If we had previously registered a console dispatcher with the console,
|
||||
# deregister it now.
|
||||
remove_console_dispatcher('FuzzyUse')
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a short, friendly name for the plugin.
|
||||
#
|
||||
def name
|
||||
'fuzzy_use'
|
||||
end
|
||||
|
||||
#
|
||||
# This method returns a brief description of the plugin. It should be no
|
||||
# more than 60 characters, but there are no hard limits.
|
||||
#
|
||||
def desc
|
||||
'Demonstrates using framework plugins'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Executable
+103
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python
|
||||
import argparse
|
||||
import json
|
||||
import pathlib
|
||||
|
||||
from rich import box
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.syntax import Syntax
|
||||
from rich.table import Table
|
||||
from rich.tree import Tree
|
||||
|
||||
__version__ = '1.0'
|
||||
|
||||
RANKS = {
|
||||
600: 'Excellent',
|
||||
500: 'Great',
|
||||
400: 'Good',
|
||||
300: 'Normal',
|
||||
200: 'Average',
|
||||
100: 'Low',
|
||||
0: 'Manual'
|
||||
}
|
||||
|
||||
framework_root = pathlib.Path(__file__).parent.parent.parent
|
||||
|
||||
def get_notes(module_metadata):
|
||||
tree = Tree('Notes', hide_root=True)
|
||||
for key, values in module_metadata.get('notes', {}).items():
|
||||
node = tree.add(key)
|
||||
for value in values:
|
||||
node.add(value)
|
||||
return tree
|
||||
|
||||
def get_description(module_metadata):
|
||||
description = ''
|
||||
paragraphs = module_metadata['description'].split('\n\n')
|
||||
for paragraph in paragraphs:
|
||||
for line in paragraph.split('\n'):
|
||||
description += line.strip() + '\n'
|
||||
description += '\n'
|
||||
return description.strip()
|
||||
|
||||
def get_authors(module_metadata):
|
||||
return get_bulleted_list(module_metadata['author'])
|
||||
|
||||
def get_targets(module_metadata):
|
||||
return get_bulleted_list(module_metadata['targets'])
|
||||
|
||||
def get_references(module_metadata):
|
||||
references = []
|
||||
for reference in module_metadata.get('references', []):
|
||||
if reference.startswith('URL-'):
|
||||
reference = reference[4:]
|
||||
references.append(reference)
|
||||
return get_bulleted_list(references)
|
||||
|
||||
def get_bulleted_list(items):
|
||||
formatted = ''
|
||||
for item in items:
|
||||
formatted += f"[bold]•[/bold] {item}\n"
|
||||
return formatted.strip()
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='fzuse helper', conflict_handler='resolve')
|
||||
parser.add_argument('module_name', help='module name to display')
|
||||
parser.add_argument('-v', '--version', action='version', version='%(prog)s Version: ' + __version__)
|
||||
arguments = parser.parse_args()
|
||||
|
||||
with (framework_root / 'db' / 'modules_metadata_base.json').open('r') as file_h:
|
||||
all_metadata = json.load(file_h)
|
||||
module_metadata = next((metadata for metadata in all_metadata.values() if metadata['fullname'] == arguments.module_name), None)
|
||||
if not module_metadata:
|
||||
return
|
||||
|
||||
table = Table(show_header=False, box=box.MINIMAL)
|
||||
table.add_column(justify='right')
|
||||
table.add_column()
|
||||
|
||||
table.add_row('[bold]Name[/bold]', module_metadata['name'])
|
||||
table.add_row('[bold]Module[/bold]', module_metadata['fullname'])
|
||||
table.add_row('[bold]Platform[/bold]', module_metadata['platform'])
|
||||
table.add_row('[bold]Arch[/bold]', module_metadata['arch'])
|
||||
table.add_row('[bold]Rank[/bold]', RANKS[module_metadata['rank']])
|
||||
table.add_row('[bold]Disclosed[/bold]', module_metadata['disclosure_date'])
|
||||
|
||||
console = Console()
|
||||
console.print(table)
|
||||
|
||||
panel_title = lambda v: f"[bold]{v}[/bold]"
|
||||
console.print(Panel(get_authors(module_metadata), title=panel_title('Provided by'), title_align='left'))
|
||||
console.print(Panel(get_notes(module_metadata), title=panel_title('Notes'), title_align='left'))
|
||||
if module_metadata.get('targets'):
|
||||
console.print(Panel(get_targets(module_metadata), title=panel_title('Targets'), title_align='left'))
|
||||
console.print(Panel(get_description(module_metadata), title=panel_title('Description'), title_align='left'))
|
||||
if module_metadata.get('references'):
|
||||
console.print(Panel(get_references(module_metadata), title=panel_title('References'), title_align='left'))
|
||||
if module_metadata.get('path', ''):
|
||||
syntax = Syntax.from_path(framework_root / module_metadata['path'][1:], background_color='default', line_numbers=True)
|
||||
console.print(Panel(syntax, title=panel_title('Source code'), title_align='left'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user