librex 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +1 -1
- data/Rakefile +13 -0
- data/lib/rex.rb +4 -1
- data/lib/rex/assembly/nasm.rb +4 -0
- data/lib/rex/compat.rb +31 -1
- data/lib/rex/encoder/alpha2/generic.rb +11 -10
- data/lib/rex/exceptions.rb +1 -1
- data/lib/rex/exploitation/egghunter.rb +27 -0
- data/lib/rex/file.rb +13 -0
- data/lib/rex/io/stream.rb +9 -1
- data/lib/rex/io/stream_abstraction.rb +18 -7
- data/lib/rex/io/stream_server.rb +2 -2
- data/lib/rex/job_container.rb +1 -1
- data/lib/rex/mime/message.rb +5 -4
- data/lib/rex/ole.rb +83 -6
- data/lib/rex/ole/propset.rb +144 -0
- data/lib/rex/parser/ip360_aspl_xml.rb +102 -0
- data/lib/rex/parser/ip360_xml.rb +93 -0
- data/lib/rex/parser/nessus_xml.rb +118 -0
- data/lib/rex/parser/netsparker_xml.rb +94 -0
- data/lib/rex/parser/retina_xml.rb +109 -0
- data/lib/rex/post/meterpreter/channel.rb +15 -8
- data/lib/rex/post/meterpreter/client.rb +32 -3
- data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +14 -5
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +3 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +5 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +16 -8
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -7
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +15 -4
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +13 -7
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +20 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +63 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +18 -7
- data/lib/rex/post/meterpreter/packet_response_waiter.rb +10 -17
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +16 -6
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +4 -5
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +2 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +4 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +157 -0
- data/lib/rex/proto/dhcp/server.rb +8 -4
- data/lib/rex/proto/http/client.rb +19 -45
- data/lib/rex/proto/http/packet.rb +8 -5
- data/lib/rex/proto/http/response.rb +8 -3
- data/lib/rex/proto/http/server.rb +1 -1
- data/lib/rex/proto/proxy/socks4a.rb +4 -4
- data/lib/rex/proto/rfb.rb +19 -0
- data/lib/rex/proto/rfb.rb.ut.rb +37 -0
- data/lib/rex/proto/rfb/cipher.rb +78 -0
- data/lib/rex/proto/rfb/client.rb +207 -0
- data/lib/rex/proto/rfb/constants.rb +52 -0
- data/lib/rex/proto/tftp/server.rb +20 -17
- data/lib/rex/services/local_relay.rb +1 -1
- data/lib/rex/socket.rb +69 -10
- data/lib/rex/socket/comm/local.rb +7 -4
- data/lib/rex/socket/range_walker.rb +14 -1
- data/lib/rex/text.rb +28 -3
- data/lib/rex/text.rb.ut.rb +14 -0
- data/lib/rex/thread_factory.rb +42 -0
- data/lib/rex/ui/text/input/buffer.rb +1 -1
- data/lib/rex/zip/archive.rb +74 -9
- data/lib/rex/zip/entry.rb +6 -1
- metadata +22 -7
@@ -56,16 +56,15 @@ class Console::CommandDispatcher::Sniffer
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def cmd_sniffer_start(*args)
|
59
|
-
intf = args
|
59
|
+
intf = args.shift.to_i
|
60
60
|
if (intf == 0)
|
61
61
|
print_error("Usage: sniffer_start [interface-id] [packet-buffer (1-200000)] [bpf filter (posix meterpreter only)]")
|
62
62
|
return
|
63
63
|
end
|
64
|
-
maxp = args
|
65
|
-
|
66
|
-
filter = args[2..-1].join(" ")
|
64
|
+
maxp = (args.shift || 50000).to_i
|
65
|
+
bpf = args.join(" ")
|
67
66
|
|
68
|
-
client.sniffer.capture_start(intf, maxp,
|
67
|
+
client.sniffer.capture_start(intf, maxp, bpf)
|
69
68
|
print_status("Capture started on interface #{intf} (#{maxp} packet buffer)")
|
70
69
|
return true
|
71
70
|
end
|
@@ -16,6 +16,7 @@ class Console::CommandDispatcher::Stdapi
|
|
16
16
|
require 'rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net'
|
17
17
|
require 'rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys'
|
18
18
|
require 'rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui'
|
19
|
+
require 'rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam'
|
19
20
|
|
20
21
|
Klass = Console::CommandDispatcher::Stdapi
|
21
22
|
|
@@ -25,6 +26,7 @@ class Console::CommandDispatcher::Stdapi
|
|
25
26
|
Klass::Net,
|
26
27
|
Klass::Sys,
|
27
28
|
Klass::Ui,
|
29
|
+
Klass::Webcam,
|
28
30
|
]
|
29
31
|
|
30
32
|
include Console::CommandDispatcher
|
@@ -223,7 +223,7 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|
223
223
|
stat = client.fs.file.stat(src)
|
224
224
|
|
225
225
|
if (stat.directory?)
|
226
|
-
client.fs.dir.download(dest, src, recursive) { |step, src, dst|
|
226
|
+
client.fs.dir.download(dest, src, recursive, true) { |step, src, dst|
|
227
227
|
print_status("#{step.ljust(11)}: #{src} -> #{dst}")
|
228
228
|
}
|
229
229
|
elsif (stat.file?)
|
@@ -247,7 +247,9 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|
247
247
|
end
|
248
248
|
|
249
249
|
# Get a temporary file path
|
250
|
-
|
250
|
+
meterp_temp = Tempfile.new('meterp')
|
251
|
+
meterp_temp.binmode
|
252
|
+
temp_path = meterp_temp.path
|
251
253
|
|
252
254
|
begin
|
253
255
|
# Download the remote file to the temporary file
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'rex/post/meterpreter'
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Post
|
5
|
+
module Meterpreter
|
6
|
+
module Ui
|
7
|
+
|
8
|
+
###
|
9
|
+
#
|
10
|
+
# Webcam - Capture video from the remote system
|
11
|
+
#
|
12
|
+
###
|
13
|
+
class Console::CommandDispatcher::Stdapi::Webcam
|
14
|
+
|
15
|
+
Klass = Console::CommandDispatcher::Stdapi::Webcam
|
16
|
+
|
17
|
+
include Console::CommandDispatcher
|
18
|
+
|
19
|
+
#
|
20
|
+
# List of supported commands.
|
21
|
+
#
|
22
|
+
def commands
|
23
|
+
{
|
24
|
+
"webcam_list" => "List webcams",
|
25
|
+
"webcam_snap" => "Take a snapshot from the specified webcam",
|
26
|
+
"record_mic" => "Record audio from the default microphone for X seconds"
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Name for this dispatcher
|
32
|
+
#
|
33
|
+
def name
|
34
|
+
"Stdapi: Webcam"
|
35
|
+
end
|
36
|
+
|
37
|
+
def cmd_webcam_list
|
38
|
+
begin
|
39
|
+
client.webcam.webcam_list.each_with_index { |name, indx|
|
40
|
+
print_line("#{indx + 1}: #{name}")
|
41
|
+
}
|
42
|
+
return true
|
43
|
+
rescue
|
44
|
+
print_error("No webcams were found")
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def cmd_webcam_snap(*args)
|
50
|
+
path = Rex::Text.rand_text_alpha(8) + ".jpeg"
|
51
|
+
quality = 50
|
52
|
+
view = true
|
53
|
+
index = 1
|
54
|
+
wc_list = []
|
55
|
+
|
56
|
+
webcam_snap_opts = Rex::Parser::Arguments.new(
|
57
|
+
"-h" => [ false, "Help Banner" ],
|
58
|
+
"-i" => [ true, "The index of the webcam to use (Default: 1)" ],
|
59
|
+
"-q" => [ true, "The JPEG image quality (Default: '#{quality}')" ],
|
60
|
+
"-p" => [ true, "The JPEG image path (Default: '#{path}')" ],
|
61
|
+
"-v" => [ true, "Automatically view the JPEG image (Default: '#{view}')" ]
|
62
|
+
)
|
63
|
+
|
64
|
+
webcam_snap_opts.parse( args ) { | opt, idx, val |
|
65
|
+
case opt
|
66
|
+
when "-h"
|
67
|
+
print_line( "Usage: webcam_snap [options]\n" )
|
68
|
+
print_line( "Grab a frame from the specified webcam." )
|
69
|
+
print_line( webcam_snap_opts.usage )
|
70
|
+
return
|
71
|
+
when "-i"
|
72
|
+
index = val.to_i
|
73
|
+
when "-q"
|
74
|
+
quality = val.to_i
|
75
|
+
when "-p"
|
76
|
+
path = val
|
77
|
+
when "-v"
|
78
|
+
view = false if ( val =~ /^(f|n|0)/i )
|
79
|
+
end
|
80
|
+
}
|
81
|
+
begin
|
82
|
+
wc_list << client.webcam.webcam_list
|
83
|
+
rescue
|
84
|
+
end
|
85
|
+
if wc_list.length > 0
|
86
|
+
print_status("Starting...")
|
87
|
+
client.webcam.webcam_start(index)
|
88
|
+
data = client.webcam.webcam_get_frame(quality)
|
89
|
+
print_good("Got frame")
|
90
|
+
client.webcam.webcam_stop
|
91
|
+
print_status("Stopped")
|
92
|
+
|
93
|
+
if( data )
|
94
|
+
::File.open( path, 'wb' ) do |fd|
|
95
|
+
fd.write( data )
|
96
|
+
end
|
97
|
+
path = ::File.expand_path( path )
|
98
|
+
print_line( "Webcam shot saved to: #{path}" )
|
99
|
+
Rex::Compat.open_file( path ) if view
|
100
|
+
end
|
101
|
+
return true
|
102
|
+
else
|
103
|
+
print_error("No webcams where found")
|
104
|
+
return false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def cmd_record_mic(*args)
|
109
|
+
path = Rex::Text.rand_text_alpha(8) + ".wav"
|
110
|
+
play = true
|
111
|
+
duration = 1
|
112
|
+
|
113
|
+
record_mic_opts = Rex::Parser::Arguments.new(
|
114
|
+
"-h" => [ false, "Help Banner" ],
|
115
|
+
"-d" => [ true, "Number of seconds to record (Default: 1)" ],
|
116
|
+
"-f" => [ true, "The wav file path (Default: '#{::File.expand_path( "[randomname].wav" )}')" ],
|
117
|
+
"-p" => [ true, "Automatically play the captured audio (Default: '#{play}')" ]
|
118
|
+
)
|
119
|
+
|
120
|
+
record_mic_opts.parse( args ) { | opt, idx, val |
|
121
|
+
case opt
|
122
|
+
when "-h"
|
123
|
+
print_line( "Usage: record_mic [options]\n" )
|
124
|
+
print_line( "Records audio from the default microphone." )
|
125
|
+
print_line( record_mic_opts.usage )
|
126
|
+
return
|
127
|
+
when "-d"
|
128
|
+
duration = val.to_i
|
129
|
+
when "-f"
|
130
|
+
path = val
|
131
|
+
when "-p"
|
132
|
+
play = false if ( val =~ /^(f|n|0)/i )
|
133
|
+
end
|
134
|
+
}
|
135
|
+
|
136
|
+
print_status("Starting...")
|
137
|
+
data = client.webcam.record_mic(duration)
|
138
|
+
print_status("Stopped")
|
139
|
+
|
140
|
+
if( data )
|
141
|
+
::File.open( path, 'wb' ) do |fd|
|
142
|
+
fd.write( data )
|
143
|
+
end
|
144
|
+
path = ::File.expand_path( path )
|
145
|
+
print_line( "Audio saved to: #{path}" )
|
146
|
+
Rex::Compat.play_sound( path ) if play
|
147
|
+
end
|
148
|
+
return true
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: server.rb
|
1
|
+
# $Id: server.rb 11003 2010-11-12 06:19:49Z hdm $
|
2
2
|
|
3
3
|
require 'rex/socket'
|
4
4
|
require 'rex/proto/dhcp'
|
@@ -36,7 +36,9 @@ class Server
|
|
36
36
|
if ipstart
|
37
37
|
self.start_ip = Rex::Socket.addr_atoi(ipstart)
|
38
38
|
else
|
39
|
-
|
39
|
+
# Use the first 3 octects of the server's IP to construct the
|
40
|
+
# default range of x.x.x.32-254
|
41
|
+
self.start_ip = "#{self.ipstring[0..2]}\x20".unpack("N").first
|
40
42
|
end
|
41
43
|
self.current_ip = start_ip
|
42
44
|
|
@@ -44,7 +46,9 @@ class Server
|
|
44
46
|
if ipend
|
45
47
|
self.end_ip = Rex::Socket.addr_atoi(ipend)
|
46
48
|
else
|
47
|
-
|
49
|
+
# Use the first 3 octects of the server's IP to construct the
|
50
|
+
# default range of x.x.x.32-254
|
51
|
+
self.end_ip = "#{self.ipstring[0..2]}\xfe".unpack("N").first
|
48
52
|
end
|
49
53
|
|
50
54
|
# netmask
|
@@ -95,7 +99,7 @@ class Server
|
|
95
99
|
'Context' => context
|
96
100
|
)
|
97
101
|
|
98
|
-
self.thread =
|
102
|
+
self.thread = Rex::ThreadFactory.spawn("DHCPServerMonitor", false) {
|
99
103
|
monitor_socket
|
100
104
|
}
|
101
105
|
end
|
@@ -328,7 +328,9 @@ class Client
|
|
328
328
|
def send_recv(req, t = -1, persist=false)
|
329
329
|
@pipeline = persist
|
330
330
|
send_request(req)
|
331
|
-
read_response(t)
|
331
|
+
res = read_response(t)
|
332
|
+
res.request = req.to_s if res
|
333
|
+
res
|
332
334
|
end
|
333
335
|
|
334
336
|
#
|
@@ -361,10 +363,12 @@ class Client
|
|
361
363
|
rv != Packet::ParseCode::Completed and
|
362
364
|
rv != Packet::ParseCode::Error
|
363
365
|
)
|
366
|
+
|
364
367
|
begin
|
365
|
-
buff = conn.get_once(-1, 1)
|
366
|
-
rv = resp.parse( buff || '')
|
367
368
|
|
369
|
+
buff = conn.get_once(-1, 1)
|
370
|
+
rv = resp.parse( buff || '' )
|
371
|
+
|
368
372
|
##########################################################################
|
369
373
|
# XXX: NOTE: BUG: get_once currently (as of r10042) rescues "Exception"
|
370
374
|
# As such, the following rescue block will ever be reached. -jjd
|
@@ -390,7 +394,7 @@ class Client
|
|
390
394
|
rblob = rbody.to_s + rbufq.to_s
|
391
395
|
tries = 0
|
392
396
|
begin
|
393
|
-
# XXX This doesn't deal with chunked encoding or "Content-type: text/html; charset=..."
|
397
|
+
# XXX: This doesn't deal with chunked encoding or "Content-type: text/html; charset=..."
|
394
398
|
while tries < 1000 and resp.headers["Content-Type"]== "text/html" and rblob !~ /<\/html>/i
|
395
399
|
buff = conn.get_once(-1, 0.05)
|
396
400
|
break if not buff
|
@@ -405,50 +409,20 @@ class Client
|
|
405
409
|
end
|
406
410
|
end
|
407
411
|
end
|
408
|
-
resp
|
409
|
-
end
|
410
|
-
|
411
|
-
#
|
412
|
-
# Read a response from the server (starting with existing data)
|
413
|
-
#
|
414
|
-
def reread_response(resp, t = -1)
|
415
|
-
|
416
|
-
resp.max_data = config['read_max_data']
|
417
|
-
resp.reset_except_queue
|
418
|
-
resp.parse('')
|
419
|
-
|
420
|
-
# Wait at most t seconds for the full response to be read in. We only
|
421
|
-
# do this if t was specified as a negative value indicating an infinite
|
422
|
-
# wait cycle. If t were specified as nil it would indicate that no
|
423
|
-
# response parsing is required.
|
424
|
-
|
425
|
-
return resp if not t
|
426
|
-
|
427
|
-
Timeout.timeout((t < 0) ? nil : t) do
|
428
412
|
|
429
|
-
|
413
|
+
return resp if not resp
|
430
414
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
rescue ::Errno::EPIPE, ::EOFError, ::IOError
|
441
|
-
case resp.state
|
442
|
-
when Packet::ParseState::ProcessingHeader
|
443
|
-
resp = nil
|
444
|
-
when Packet::ParseState::ProcessingBody
|
445
|
-
# truncated request, good enough
|
446
|
-
resp.error = :truncated
|
447
|
-
end
|
448
|
-
break
|
449
|
-
end
|
450
|
-
end
|
415
|
+
# As a last minute hack, we check to see if we're dealing with a 100 Continue here.
|
416
|
+
if resp.proto == '1.1' and resp.code == 100
|
417
|
+
# If so, our real response becaome the body, so we re-parse it.
|
418
|
+
body = resp.body
|
419
|
+
resp = Response.new
|
420
|
+
resp.max_data = config['read_max_data']
|
421
|
+
rv = resp.parse(body)
|
422
|
+
# XXX: At some point, this may benefit from processing post-completion code
|
423
|
+
# as seen above.
|
451
424
|
end
|
425
|
+
|
452
426
|
resp
|
453
427
|
end
|
454
428
|
|
@@ -85,7 +85,8 @@ class Packet
|
|
85
85
|
|
86
86
|
# Continue on to the body if the header was processed
|
87
87
|
if(self.state == ParseState::ProcessingBody)
|
88
|
-
|
88
|
+
# Chunked encoding sets the parsing state on its own
|
89
|
+
if (self.body_bytes_left == 0 and not self.transfer_chunked)
|
89
90
|
self.state = ParseState::Completed
|
90
91
|
else
|
91
92
|
parse_body
|
@@ -165,7 +166,9 @@ class Packet
|
|
165
166
|
# Converts the packet to a string.
|
166
167
|
#
|
167
168
|
def to_s
|
168
|
-
|
169
|
+
# Duplicate and make sure this is 8BIT safe for Ruby 1.9
|
170
|
+
content = self.body.unpack("C*").pack("C*")
|
171
|
+
|
169
172
|
# Update the content length field in the header with the body length.
|
170
173
|
if (content)
|
171
174
|
if !self.compress.nil?
|
@@ -264,6 +267,7 @@ protected
|
|
264
267
|
def parse_header
|
265
268
|
|
266
269
|
head,data = self.bufq.split(/\r?\n\r?\n/, 2)
|
270
|
+
|
267
271
|
return if not data
|
268
272
|
|
269
273
|
self.headers.from_s(head)
|
@@ -346,7 +350,7 @@ protected
|
|
346
350
|
clen = self.bufq.slice!(/^[a-fA-F0-9]+\r?\n/)
|
347
351
|
|
348
352
|
clen.rstrip! if (clen)
|
349
|
-
|
353
|
+
|
350
354
|
# if we happen to fall upon the end of the buffer for the next chunk len and have no data left, go get some more...
|
351
355
|
if clen.nil? and self.bufq.length == 0
|
352
356
|
return
|
@@ -358,7 +362,7 @@ protected
|
|
358
362
|
return
|
359
363
|
end
|
360
364
|
|
361
|
-
self.body_bytes_left = clen.
|
365
|
+
self.body_bytes_left = clen.to_i(16)
|
362
366
|
|
363
367
|
if (self.body_bytes_left == 0)
|
364
368
|
self.bufq.sub!(/^\r?\n/s,'')
|
@@ -373,7 +377,6 @@ protected
|
|
373
377
|
# to our body state.
|
374
378
|
if (self.body_bytes_left > 0)
|
375
379
|
part = self.bufq.slice!(0, self.body_bytes_left)
|
376
|
-
|
377
380
|
self.body += part
|
378
381
|
self.body_bytes_left -= part.length
|
379
382
|
# Otherwise, just read it all.
|
@@ -74,12 +74,17 @@ class Response < Packet
|
|
74
74
|
"HTTP\/#{proto} #{code}#{(message and message.length > 0) ? ' ' + message : ''}\r\n"
|
75
75
|
end
|
76
76
|
|
77
|
-
|
77
|
+
#
|
78
|
+
# Used to store a copy of the original request
|
79
|
+
#
|
80
|
+
attr_accessor :request
|
81
|
+
|
82
|
+
|
83
|
+
attr_accessor :code
|
78
84
|
attr_accessor :message
|
79
85
|
attr_accessor :proto
|
80
|
-
|
81
86
|
end
|
82
87
|
|
83
88
|
end
|
84
89
|
end
|
85
|
-
end
|
90
|
+
end
|
@@ -165,7 +165,7 @@ class Socks4a
|
|
165
165
|
@relay_client = relay_client
|
166
166
|
@relay_sock = relay_sock
|
167
167
|
# start the relay thread (modified from Rex::IO::StreamAbstraction)
|
168
|
-
@relay_thread = ::
|
168
|
+
@relay_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyServerRelay", false) do
|
169
169
|
loop do
|
170
170
|
closed = false
|
171
171
|
buf = nil
|
@@ -234,7 +234,7 @@ class Socks4a
|
|
234
234
|
#
|
235
235
|
def start
|
236
236
|
# create a thread to handle this client request so as to not block the socks4a server
|
237
|
-
@client_thread = ::
|
237
|
+
@client_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyClient", false) do
|
238
238
|
begin
|
239
239
|
@server.add_client( self )
|
240
240
|
# get the initial client request packet
|
@@ -378,7 +378,7 @@ class Socks4a
|
|
378
378
|
# signal we are now running
|
379
379
|
@running = true
|
380
380
|
# start the servers main thread to pick up new clients
|
381
|
-
@server_thread = ::
|
381
|
+
@server_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyServer", false) do
|
382
382
|
while( @running ) do
|
383
383
|
begin
|
384
384
|
# accept the client connection
|
@@ -437,4 +437,4 @@ class Socks4a
|
|
437
437
|
|
438
438
|
end
|
439
439
|
|
440
|
-
end; end; end
|
440
|
+
end; end; end
|