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
+
1
16
module Msf
2
17
###
3
18
#
@@ -39,37 +54,60 @@ def commands
39
54
}
40
55
end
41
56
57
+ def start_pipe_server ( socket_path )
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
+ unless ( input_string = client . gets &.chomp ) . blank?
64
+ if ( mod = framework . modules . create ( input_string ) )
65
+ client . puts ( Serializer ::ReadableText . dump_module ( mod ) )
66
+ end
67
+ end
68
+ client . close
69
+ end
70
+ rescue EOFError
71
+ ensure
72
+ server . close if server
73
+ File . delete ( socket_path ) if File . exist? ( socket_path )
74
+ end
75
+
76
+ Thread . new do
77
+ pipe_server ( socket_path )
78
+ end
79
+ end
80
+
42
81
#
43
82
# This method handles the fuzzy_use command.
44
83
#
45
84
def cmd_fzuse ( *args )
46
- previewer = File . join ( Msf ::Config . install_root , 'tools' , 'modules' , 'print.py' )
47
- metadata_path = Msf ::Modules ::Metadata ::Cache . instance . get_user_store
85
+ selection = nil
48
86
49
- module_types = framework . modules . module_types
87
+ Dir . mktmpdir ( 'msf-fzuse-' ) do |dir |
88
+ File . chmod ( 0700 , dir )
89
+ socket_path = File . join ( dir , "msf-fzuse.sock" )
90
+ server_thread = start_pipe_server ( socket_path )
50
91
51
- query = args . empty? ? '' : args . first
52
-
53
- selection = nil
54
- # alternative preview:
55
- # jq \'to_entries[] | select(.value.fullname == "{1}") | .value\' db/modules_metadata_base.json | bat --language=json --color=always
56
- stdin , stdout , stderr , wait_thr = Open3 . popen3 ( 'fzf' , '--select-1' , '--query' , query , '--preview' , "#{ previewer } --metadata-path '#{ metadata_path } ' '{1}'" , '--preview-label' , "Module Information" ) do |stdin , stdout , stderr , wait_thr |
57
- module_types
58
- module_types . each do |module_type |
59
- framework . modules . module_names ( module_type ) . each do |module_name |
60
- stdin . puts "#{ module_type } /#{ module_name } "
92
+ query = args . empty? ? '' : args . first
93
+ ruby = RbConfig ::CONFIG [ 'bindir' ] + '/' + RbConfig ::CONFIG [ 'ruby_install_name' ] + RbConfig ::CONFIG [ 'EXEEXT' ]
94
+
95
+ Open3 . popen3 ( 'fzf' , '--select-1' , '--query' , query , '--preview' , "'#{ ruby } ' '#{ __FILE__ } ' '#{ socket_path } ' '{1}'" , '--preview-label' , "Module Information" ) do |stdin , stdout , stderr , wait_thr |
96
+ framework . modules . module_types . each do |module_type |
97
+ framework . modules . module_names ( module_type ) . each do |module_name |
98
+ stdin . puts "#{ module_type } /#{ module_name } "
99
+ end
61
100
end
101
+ stdin . close
102
+ selection = stdout . read
62
103
end
63
- stdin . close
64
104
65
- exit_status = wait_thr . value
66
-
67
- selection = stdout . read
105
+ server_thread . kill
68
106
end
69
107
70
- selection . strip!
71
108
return if selection . blank?
72
-
109
+
110
+ selection . strip!
73
111
@module_dispatcher . cmd_use ( selection )
74
112
end
75
113
end
@@ -83,11 +121,9 @@ def cmd_fzuse(*args)
83
121
#
84
122
def initialize ( framework , opts )
85
123
super
86
-
124
+
87
125
missing_requirements = [ ]
88
126
missing_requirements << 'fzf' unless Msf ::Util ::Helper . which ( 'fzf' )
89
- missing_requirements << 'python' unless Msf ::Util ::Helper . which ( 'python' )
90
- missing_requirements << 'python-rich' unless system ( "python -c 'import rich'" , out : File ::NULL , err : File ::NULL )
91
127
92
128
unless missing_requirements . empty?
93
129
print_error ( "The FuzzyUse plugin has loaded but the following requirements are missing: #{ missing_requirements . join ( ', ' ) } " )
0 commit comments