CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/plugins/fzuse.rb
Views: 11705
1
require 'socket'
2
3
# this is the main routine that's executed in the grandchild process (msfconsole -> fzf -> this)
4
if $PROGRAM_NAME == __FILE__
5
exit 64 unless ARGV.length == 2
6
7
UNIXSocket.open(ARGV[0]) do |sock|
8
sock.write ARGV[1] + "\n"
9
sock.flush
10
11
puts sock.read
12
end
13
exit 0
14
end
15
16
module Msf
17
class Plugin::FuzzyUse < Msf::Plugin
18
class ConsoleCommandDispatcher
19
include Msf::Ui::Console::CommandDispatcher
20
21
FZF_THEME = {
22
'fg' => '-1',
23
'fg+' => 'white:regular:bold',
24
'bg' => '-1',
25
'bg+' => '-1',
26
'hl' => '-1',
27
'hl+' => 'red:regular:bold',
28
'info' => '-1',
29
'marker' => '-1',
30
'prompt' => '-1',
31
'spinner' => '-1',
32
'pointer' => 'blue:bold',
33
'header' => '-1',
34
'border' => '-1',
35
'label' => '-1',
36
'query' => '-1'
37
}.freeze
38
39
def initialize(driver)
40
super
41
42
@module_dispatcher = Msf::Ui::Console::CommandDispatcher::Modules.new(driver)
43
end
44
45
def name
46
'FuzzyUse'
47
end
48
49
#
50
# Returns the hash of commands supported by this dispatcher.
51
#
52
def commands
53
{
54
'fzuse' => 'A fuzzy use command added by the FuzzyUse plugin'
55
}
56
end
57
58
def pipe_server(socket_path)
59
server = UNIXServer.new(socket_path)
60
File.chmod(0600, socket_path)
61
loop do
62
client = server.accept
63
begin
64
unless (input_string = client.gets&.chomp).blank?
65
if (mod = framework.modules.create(input_string))
66
client.puts(Serializer::ReadableText.dump_module(mod))
67
end
68
end
69
rescue StandardError
70
end
71
client.close
72
end
73
rescue EOFError
74
ensure
75
server.close if server
76
File.delete(socket_path) if File.exist?(socket_path)
77
end
78
79
#
80
# This method handles the fzuse command.
81
#
82
def cmd_fzuse(*args)
83
selection = nil
84
85
Dir.mktmpdir('msf-fzuse-') do |dir|
86
socket_path = File.join(dir, "msf-fzuse.sock")
87
server_thread = Thread.new { pipe_server(socket_path) }
88
89
query = args.empty? ? '' : args.first
90
ruby = RbConfig::CONFIG['bindir'] + '/' + RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT']
91
92
color = "--color=#{FZF_THEME.map { |key, value| "#{key}:#{value}" }.join(',')}"
93
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|
94
framework.modules.module_types.each do |module_type|
95
framework.modules.module_names(module_type).each do |module_name|
96
stdin.puts "#{module_type}/#{module_name}"
97
end
98
end
99
stdin.close
100
selection = stdout.read
101
end
102
103
server_thread.kill
104
server_thread.join
105
end
106
107
return if selection.blank?
108
109
selection.strip!
110
@module_dispatcher.cmd_use(selection)
111
end
112
end
113
114
def initialize(framework, opts)
115
super
116
117
unless defined?(UNIXSocket)
118
# This isn't a requirement that can be fixed by installing something
119
print_error("The FuzzyUse plugin has loaded but the Ruby environment does not support UNIX sockets.")
120
return
121
end
122
123
missing_requirements = []
124
missing_requirements << 'fzf' unless Msf::Util::Helper.which('fzf')
125
126
unless missing_requirements.empty?
127
print_error("The FuzzyUse plugin has loaded but the following requirements are missing: #{missing_requirements.join(', ')}")
128
print_error("Please install the missing requirements, then reload the plugin by running: `unload fzuse` and `load fzuse`.")
129
return
130
end
131
132
add_console_dispatcher(ConsoleCommandDispatcher)
133
134
print_status('FuzzyUse plugin loaded.')
135
end
136
137
def cleanup
138
remove_console_dispatcher('FuzzyUse')
139
end
140
141
def name
142
'fuzzy_use'
143
end
144
145
def desc
146
'A plugin offering a fuzzy use command'
147
end
148
149
end
150
end
151
152