Class: Rex::Services::LocalRelay

Inherits:
Object
  • Object
show all
Includes:
Rex::Service
Defined in:
lib/rex/services/local_relay.rb

Overview

This service acts as a local TCP relay whereby clients can connect to a local listener that forwards to an arbitrary remote endpoint. Interaction with the remote endpoint socket requires that it implement the Rex::IO::Stream interface.

Defined Under Namespace

Modules: Stream, StreamServer Classes: Relay

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Rex::Service

#cleanup, #deref

Methods included from Ref

#cleanup, #deref, #ref, #refinit

Constructor Details

#initializeLocalRelay

Initializes the local tcp relay monitor.



112
113
114
115
116
117
# File 'lib/rex/services/local_relay.rb', line 112

def initialize
	self.relays       = Hash.new
	self.rfds         = Array.new
	self.relay_thread = nil
	self.relay_mutex  = Mutex.new
end

Class Method Details

.hardcore_alias(*args) ⇒ Object

Returns the hardcore alias for the local relay service.



128
129
130
# File 'lib/rex/services/local_relay.rb', line 128

def self.hardcore_alias(*args)
	"__#{args}"
end

Instance Method Details

#aliasObject

Returns the alias for this service.



135
136
137
# File 'lib/rex/services/local_relay.rb', line 135

def alias
	super || "Local Relay"
end

#each_tcp_relay(&block) ⇒ Object

Enumerate each TCP relay



250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/rex/services/local_relay.rb', line 250

def each_tcp_relay(&block)
	self.relays.each_pair { |name, relay|
		next if (relay.opts['__RelayType'] != 'tcp')

		yield(
			relay.opts['LocalHost'] || '0.0.0.0',
			relay.opts['LocalPort'],
			relay.opts['PeerHost'],
			relay.opts['PeerPort'],
			relay.opts)
	}
end

#startObject

Starts the thread that monitors the local relays.



142
143
144
145
146
147
148
149
150
151
152
# File 'lib/rex/services/local_relay.rb', line 142

def start
	if (!self.relay_thread)
		self.relay_thread = Rex::ThreadFactory.spawn("LocalRelay", false) {
			begin
				monitor_relays
			rescue ::Exception
				elog("Error in #{self} monitor_relays: #{$!}", 'rex')
			end
		}
	end
end

#start_relay(stream_server, name, opts = {}) ⇒ Object

Starts a local relay on the supplied local port. This listener will call the supplied callback procedures when various events occur.



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/rex/services/local_relay.rb', line 206

def start_relay(stream_server, name, opts = {})
	# Create a Relay instance with the local stream and remote stream
	relay = Relay.new(name, stream_server, opts)

	# Extend the stream_server so that we can associate it with this relay
	stream_server.extend(StreamServer)
	stream_server.relay = relay

	# Add the stream associations the appropriate lists and hashes
	self.relay_mutex.synchronize {
		self.relays[name] = relay

		self.rfds << stream_server
	}
end

#start_tcp_relay(lport, opts = {}) ⇒ Object

Starts a local TCP relay.



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/rex/services/local_relay.rb', line 186

def start_tcp_relay(lport, opts = {})
	# Make sure our options are valid
	if ((opts['PeerHost'] == nil or opts['PeerPort'] == nil) and (opts['Stream'] != true))
		raise ArgumentError, "Missing peer host or peer port.", caller
	end

	listener = Rex::Socket.create_tcp_server(
		'LocalHost' => opts['LocalHost'],
		'LocalPort' => lport)

	opts['LocalPort']   = lport
	opts['__RelayType'] = 'tcp'

	start_relay(listener, lport.to_s + (opts['LocalHost'] || '0.0.0.0'), opts)
end

#stopObject

Stops the thread that monitors the local relays and destroys all local listeners.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/rex/services/local_relay.rb', line 158

def stop
	if (self.relay_thread)
		self.relay_thread.kill
		self.relay_thread = nil
	end

	self.relay_mutex.synchronize {
		self.relays.delete_if { |k, v|
			v.shutdown
			v.close
			true
		}
	}

	# Flush the relay list and read fd list
	self.relays.clear
	self.rfds.clear
end

#stop_relay(name) ⇒ Object

Stops a relay with a given name.



232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/rex/services/local_relay.rb', line 232

def stop_relay(name)
	rv = false

	self.relay_mutex.synchronize {
		relay = self.relays[name]

		if (relay)
			close_relay(relay)
			rv = true
		end
	}

	rv
end

#stop_tcp_relay(lport, lhost = nil) ⇒ Object

Stops relaying on a given local port.



225
226
227
# File 'lib/rex/services/local_relay.rb', line 225

def stop_tcp_relay(lport, lhost = nil)
	stop_relay(lport.to_s + (lhost || '0.0.0.0'))
end