-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds a plugin that offers the fzuse command to offer a different UI for the selection of modules. It requires fzf to be present.
- Loading branch information
Showing
2 changed files
with
154 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
require 'socket' | ||
|
||
# this is the main routine that's executed in the grandchild process (msfconsole -> fzf -> this) | ||
if $PROGRAM_NAME == __FILE__ | ||
exit 64 unless ARGV.length == 2 | ||
|
||
UNIXSocket.open(ARGV[0]) do |sock| | ||
sock.write ARGV[1] + "\n" | ||
sock.flush | ||
|
||
puts sock.read | ||
end | ||
exit 0 | ||
end | ||
|
||
module Msf | ||
class Plugin::FuzzyUse < Msf::Plugin | ||
class ConsoleCommandDispatcher | ||
include Msf::Ui::Console::CommandDispatcher | ||
|
||
FZF_THEME = { | ||
'fg' => '-1', | ||
'fg+' => 'white:regular:bold', | ||
'bg' => '-1', | ||
'bg+' => '-1', | ||
'hl' => '-1', | ||
'hl+' => 'red:regular:bold', | ||
'info' => '-1', | ||
'marker' => '-1', | ||
'prompt' => '-1', | ||
'spinner' => '-1', | ||
'pointer' => 'blue:bold', | ||
'header' => '-1', | ||
'border' => '-1', | ||
'label' => '-1', | ||
'query' => '-1' | ||
}.freeze | ||
|
||
def initialize(driver) | ||
super | ||
|
||
@module_dispatcher = Msf::Ui::Console::CommandDispatcher::Modules.new(driver) | ||
end | ||
|
||
def name | ||
'FuzzyUse' | ||
end | ||
|
||
# | ||
# Returns the hash of commands supported by this dispatcher. | ||
# | ||
def commands | ||
{ | ||
'fzuse' => 'A fuzzy use command added by the FuzzyUse plugin' | ||
} | ||
end | ||
|
||
def pipe_server(socket_path) | ||
server = UNIXServer.new(socket_path) | ||
File.chmod(0600, socket_path) | ||
loop do | ||
client = server.accept | ||
begin | ||
unless (input_string = client.gets&.chomp).blank? | ||
if (mod = framework.modules.create(input_string)) | ||
client.puts(Serializer::ReadableText.dump_module(mod)) | ||
end | ||
end | ||
rescue StandardError | ||
end | ||
client.close | ||
end | ||
rescue EOFError | ||
ensure | ||
server.close if server | ||
File.delete(socket_path) if File.exist?(socket_path) | ||
end | ||
|
||
# | ||
# This method handles the fzuse command. | ||
# | ||
def cmd_fzuse(*args) | ||
selection = nil | ||
|
||
Dir.mktmpdir('msf-fzuse-') do |dir| | ||
socket_path = File.join(dir, "msf-fzuse.sock") | ||
server_thread = Thread.new { pipe_server(socket_path) } | ||
|
||
query = args.empty? ? '' : args.first | ||
ruby = RbConfig::CONFIG['bindir'] + '/' + RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT'] | ||
|
||
color = "--color=#{FZF_THEME.map { |key, value| "#{key}:#{value}" }.join(',')}" | ||
Open3.popen3('fzf', '--select-1', '--query', query, '--pointer=->', color, '--preview', "'#{ruby}' '#{__FILE__}' '#{socket_path}' '{1}'", '--preview-label', "Module Information") do |stdin, stdout, stderr, wait_thr| | ||
framework.modules.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 | ||
selection = stdout.read | ||
end | ||
|
||
server_thread.kill | ||
server_thread.join | ||
end | ||
|
||
return if selection.blank? | ||
|
||
selection.strip! | ||
@module_dispatcher.cmd_use(selection) | ||
end | ||
end | ||
|
||
def initialize(framework, opts) | ||
super | ||
|
||
unless defined?(UNIXSocket) | ||
# This isn't a requirement that can be fixed by installing something | ||
print_error("The FuzzyUse plugin has loaded but the Ruby environment does not support UNIX sockets.") | ||
return | ||
end | ||
|
||
missing_requirements = [] | ||
missing_requirements << 'fzf' unless Msf::Util::Helper.which('fzf') | ||
|
||
unless missing_requirements.empty? | ||
print_error("The FuzzyUse plugin has loaded but the following requirements are missing: #{missing_requirements.join(', ')}") | ||
print_error("Please install the missing requirements, then reload the plugin by running: `unload fzuse` and `load fzuse`.") | ||
return | ||
end | ||
|
||
add_console_dispatcher(ConsoleCommandDispatcher) | ||
|
||
print_status('FuzzyUse plugin loaded.') | ||
end | ||
|
||
def cleanup | ||
remove_console_dispatcher('FuzzyUse') | ||
end | ||
|
||
def name | ||
'fuzzy_use' | ||
end | ||
|
||
def desc | ||
'A plugin offering a fuzzy use command' | ||
end | ||
|
||
end | ||
end |