forked from rapid7/metasploit-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
msfd.rb
165 lines (145 loc) · 3.72 KB
/
msfd.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#
# $Id$
#
# This plugin provides an msf daemon interface that spawns a listener on a
# defined port (default 55554) and gives each connecting client its own
# console interface. These consoles all share the same framework instance.
# Be aware that the console instance that spawns on the port is entirely
# unauthenticated, so realize that you have been warned.
#
# $Revision$
#
module Msf
###
#
# This class implements the msfd plugin interface.
#
###
class Plugin::Msfd < Msf::Plugin
#
# The default local hostname that the server listens on.
#
DefaultHost = "127.0.0.1"
#
# The default local port that the server listens on.
#
DefaultPort = 55554
#
# Initializes the msfd plugin. The following options are supported in the
# hash by this plugin:
#
# ServerHost
#
# The local hostname to listen on for connections. The default is
# 127.0.0.1.
#
# ServerPort
#
# The local port to listen on for connections. The default is 55554.
#
# SSL
#
# Use SSL
#
# RunInForeground
#
# Instructs the plugin to now execute the daemon in a worker thread and to
# instead allow the caller to manage executing the daemon through the
# ``run'' method.
#
# HostsAllowed
#
# List of hosts (in NBO) allowed to use msfd
#
# HostsDenied
#
# List of hosts (in NBO) not allowed to use msfd
#
def initialize(framework, opts)
super
# Start listening for connections.
self.server = Rex::Socket::TcpServer.create(
'LocalHost' => opts['ServerHost'] || DefaultHost,
'LocalPort' => opts['ServerPort'] || DefaultPort,
'SSL' => opts['SSL'])
# If the run in foreground flag is not specified, then go ahead and fire
# it off in a worker thread.
if (opts['RunInForeground'] != true)
Thread.new {
run(opts)
}
end
end
#
# Returns 'msfd'
#
def name
"msfd"
end
#
# Returns the msfd plugin description.
#
def desc
"Provides a console interface to users over a listening TCP port."
end
#
# Runs the msfd plugin by blocking on new connections and then spawning
# threads to handle the console interface for each client.
#
def run(opts={})
while true
client = server.accept
addr = Rex::Socket.resolv_nbo(client.peerhost)
if opts['HostsAllowed'] and
not opts['HostsAllowed'].find { |x| x == addr }
client.close
next
end
if opts['HostsDenied'] and
opts['HostsDenied'].find { |x| x == addr }
client.close
next
end
msg = "Msfd: New connection from #{client.peerhost}"
ilog(msg, 'core')
print_status(msg)
# Spawn a thread for the client connection
Thread.new(client) { |cli|
begin
Msf::Ui::Console::Driver.new(
Msf::Ui::Console::Driver::DefaultPrompt,
Msf::Ui::Console::Driver::DefaultPromptChar,
'Framework' => framework,
'LocalInput' => Rex::Ui::Text::Input::Socket.new(cli),
'LocalOutput' => Rex::Ui::Text::Output::Socket.new(cli),
'AllowCommandPassthru' => false,
'DisableBanner' => opts['DisableBanner'] ? true : false).run
rescue
elog("Msfd: Client error: #{$!}\n\n#{[email protected]("\n")}", 'core')
ensure
msg = "Msfd: Closing client connection with #{cli.peerhost}"
ilog(msg, 'core')
print_status(msg)
begin
cli.shutdown
cli.close
rescue IOError
end
end
}
end
end
#
# Closes the listener service.
#
def cleanup
ilog("Msfd: Shutting down server", 'core')
self.server.close
end
protected
#
# The listening socket instance.
#
attr_accessor :server
end
end