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
@@ -22,7 +22,7 @@ module Sys
|
|
22
22
|
###
|
23
23
|
class EventLog
|
24
24
|
|
25
|
-
class <<self
|
25
|
+
class << self
|
26
26
|
attr_accessor :client
|
27
27
|
end
|
28
28
|
|
@@ -60,6 +60,11 @@ class EventLog
|
|
60
60
|
def initialize(hand)
|
61
61
|
self.client = self.class.client
|
62
62
|
self.handle = hand
|
63
|
+
ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.handle) )
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.finalize(client,handle)
|
67
|
+
proc { self.close(client,handle) }
|
63
68
|
end
|
64
69
|
|
65
70
|
#
|
@@ -169,16 +174,19 @@ class EventLog
|
|
169
174
|
end
|
170
175
|
|
171
176
|
#
|
172
|
-
#
|
177
|
+
# Close the event log
|
173
178
|
#
|
174
|
-
def close
|
179
|
+
def self.close(client, handle)
|
175
180
|
request = Packet.create_request('stdapi_sys_eventlog_close')
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
response = client.send_request(request)
|
181
|
+
request.add_tlv(TLV_TYPE_EVENT_HANDLE, handle);
|
182
|
+
response = client.send_request(request, nil)
|
180
183
|
return nil
|
181
184
|
end
|
185
|
+
|
186
|
+
# Instance method
|
187
|
+
def close
|
188
|
+
self.class.close(self.client, self.handle)
|
189
|
+
end
|
182
190
|
end
|
183
191
|
|
184
|
-
end end end end end end
|
192
|
+
end end end end end end
|
@@ -284,8 +284,14 @@ class Process < Rex::Post::Process
|
|
284
284
|
'memory' => Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Memory.new(self),
|
285
285
|
'thread' => Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Thread.new(self),
|
286
286
|
})
|
287
|
+
|
288
|
+
ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.handle) )
|
287
289
|
end
|
288
290
|
|
291
|
+
def self.finalize(client,handle)
|
292
|
+
proc { self.close(client,handle) }
|
293
|
+
end
|
294
|
+
|
289
295
|
#
|
290
296
|
# Returns the executable name of the process.
|
291
297
|
#
|
@@ -303,20 +309,23 @@ class Process < Rex::Post::Process
|
|
303
309
|
#
|
304
310
|
# Closes the handle to the process that was opened.
|
305
311
|
#
|
306
|
-
def close
|
312
|
+
def self.close(client, handle)
|
307
313
|
request = Packet.create_request('stdapi_sys_process_close')
|
308
|
-
|
309
314
|
request.add_tlv(TLV_TYPE_HANDLE, handle)
|
310
|
-
|
311
|
-
response = client.send_request(request)
|
312
|
-
|
315
|
+
response = client.send_request(request, nil)
|
313
316
|
handle = nil;
|
314
|
-
|
315
317
|
return true
|
316
318
|
end
|
319
|
+
|
320
|
+
#
|
321
|
+
# Instance method
|
322
|
+
#
|
323
|
+
def close(handle=self.handle)
|
324
|
+
self.class.close(self.client, handle)
|
325
|
+
end
|
317
326
|
|
318
327
|
#
|
319
|
-
# Block
|
328
|
+
# Block until this process terminates on the remote side.
|
320
329
|
# By default we choose not to allow a packet responce timeout to
|
321
330
|
# occur as we may be waiting indefinatly for the process to terminate.
|
322
331
|
#
|
@@ -29,6 +29,12 @@ class RegistryKey
|
|
29
29
|
self.base_key = base_key
|
30
30
|
self.perm = perm
|
31
31
|
self.hkey = hkey
|
32
|
+
|
33
|
+
ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.hkey) )
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.finalize(client,hkey)
|
37
|
+
proc { self.close(client,hkey) }
|
32
38
|
end
|
33
39
|
|
34
40
|
##
|
@@ -99,12 +105,17 @@ class RegistryKey
|
|
99
105
|
# Closes the open key. This must be called if the registry
|
100
106
|
# key was opened.
|
101
107
|
#
|
102
|
-
def close()
|
103
|
-
if
|
104
|
-
return
|
108
|
+
def self.close(client, hkey)
|
109
|
+
if hkey != nil
|
110
|
+
return client.sys.registry.close_key(hkey)
|
105
111
|
end
|
106
112
|
|
107
|
-
return false
|
113
|
+
return false
|
114
|
+
end
|
115
|
+
|
116
|
+
# Instance method for the same
|
117
|
+
def close()
|
118
|
+
self.class.close(self.client, self.hkey)
|
108
119
|
end
|
109
120
|
|
110
121
|
##
|
@@ -34,6 +34,11 @@ class Thread < Rex::Post::Thread
|
|
34
34
|
self.process = process
|
35
35
|
self.handle = handle
|
36
36
|
self.tid = tid
|
37
|
+
ObjectSpace.define_finalizer( self, self.class.finalize(self.process.client, self.handle) )
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.finalize(client,handle)
|
41
|
+
proc { self.close(client,handle) }
|
37
42
|
end
|
38
43
|
|
39
44
|
##
|
@@ -153,17 +158,18 @@ class Thread < Rex::Post::Thread
|
|
153
158
|
#
|
154
159
|
# Closes the thread handle.
|
155
160
|
#
|
156
|
-
def close
|
161
|
+
def self.close(client, handle)
|
157
162
|
request = Packet.create_request('stdapi_sys_process_thread_close')
|
158
|
-
|
159
163
|
request.add_tlv(TLV_TYPE_THREAD_HANDLE, handle)
|
160
|
-
|
161
|
-
process.client.send_request(request)
|
162
|
-
|
164
|
+
client.send_request(request, nil)
|
163
165
|
handle = nil
|
164
|
-
|
165
166
|
return true
|
166
167
|
end
|
168
|
+
|
169
|
+
# Instance method
|
170
|
+
def close
|
171
|
+
self.class.close(self.process.client, self.handle)
|
172
|
+
end
|
167
173
|
|
168
174
|
attr_reader :process, :handle, :tid # :nodoc:
|
169
175
|
protected
|
@@ -171,4 +177,4 @@ protected
|
|
171
177
|
|
172
178
|
end
|
173
179
|
|
174
|
-
end; end; end; end; end; end
|
180
|
+
end; end; end; end; end; end
|
@@ -187,5 +187,25 @@ TLV_TYPE_EVENT_DATA = TLV_META_TYPE_RAW | 4013
|
|
187
187
|
TLV_TYPE_POWER_FLAGS = TLV_META_TYPE_UINT | 4100
|
188
188
|
TLV_TYPE_POWER_REASON = TLV_META_TYPE_UINT | 4101
|
189
189
|
|
190
|
+
##
|
191
|
+
#
|
192
|
+
# Webcam
|
193
|
+
#
|
194
|
+
##
|
195
|
+
|
196
|
+
TLV_TYPE_WEBCAM_IMAGE = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 1)
|
197
|
+
TLV_TYPE_WEBCAM_INTERFACE_ID= TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 2)
|
198
|
+
TLV_TYPE_WEBCAM_QUALITY = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 3)
|
199
|
+
TLV_TYPE_WEBCAM_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 4)
|
200
|
+
|
201
|
+
##
|
202
|
+
#
|
203
|
+
# Audio
|
204
|
+
#
|
205
|
+
##
|
206
|
+
|
207
|
+
TLV_TYPE_AUDIO_DURATION = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1)
|
208
|
+
TLV_TYPE_AUDIO_DATA = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 2)
|
209
|
+
|
190
210
|
end; end; end; end; end
|
191
211
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Post
|
5
|
+
module Meterpreter
|
6
|
+
module Extensions
|
7
|
+
module Stdapi
|
8
|
+
module Webcam
|
9
|
+
|
10
|
+
###
|
11
|
+
#
|
12
|
+
# This meterpreter extension can list and capture from webcams and/or microphone
|
13
|
+
#
|
14
|
+
###
|
15
|
+
class Webcam
|
16
|
+
|
17
|
+
def initialize(client)
|
18
|
+
@client = client
|
19
|
+
end
|
20
|
+
|
21
|
+
def webcam_list
|
22
|
+
response = client.send_request(Packet.create_request('webcam_list'))
|
23
|
+
names = []
|
24
|
+
response.get_tlvs( TLV_TYPE_WEBCAM_NAME ).each{ |tlv|
|
25
|
+
names << tlv.value
|
26
|
+
}
|
27
|
+
names
|
28
|
+
end
|
29
|
+
|
30
|
+
# Starts recording video from video source of index #{cam}
|
31
|
+
def webcam_start(cam)
|
32
|
+
request = Packet.create_request('webcam_start')
|
33
|
+
request.add_tlv(TLV_TYPE_WEBCAM_INTERFACE_ID, cam)
|
34
|
+
client.send_request(request)
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def webcam_get_frame(quality)
|
39
|
+
request = Packet.create_request('webcam_get_frame')
|
40
|
+
request.add_tlv(TLV_TYPE_WEBCAM_QUALITY, quality)
|
41
|
+
response = client.send_request(request)
|
42
|
+
response.get_tlv( TLV_TYPE_WEBCAM_IMAGE ).value
|
43
|
+
end
|
44
|
+
|
45
|
+
def webcam_stop
|
46
|
+
client.send_request( Packet.create_request( 'webcam_stop' ) )
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
# Record from default audio source for #{duration} seconds;
|
51
|
+
# returns a low-quality wav file
|
52
|
+
def record_mic(duration)
|
53
|
+
request = Packet.create_request('webcam_audio_record')
|
54
|
+
request.add_tlv(TLV_TYPE_AUDIO_DURATION, duration)
|
55
|
+
response = client.send_request(request)
|
56
|
+
response.get_tlv( TLV_TYPE_AUDIO_DATA ).value
|
57
|
+
end
|
58
|
+
|
59
|
+
attr_accessor :client
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end; end; end; end; end; end
|
@@ -14,9 +14,10 @@ module Meterpreter
|
|
14
14
|
#
|
15
15
|
###
|
16
16
|
class RequestError < ArgumentError
|
17
|
-
def initialize(method,
|
17
|
+
def initialize(method, einfo, ecode=nil)
|
18
18
|
@method = method
|
19
|
-
@result =
|
19
|
+
@result = einfo
|
20
|
+
@code = ecode || einfo
|
20
21
|
end
|
21
22
|
|
22
23
|
def to_s
|
@@ -26,8 +27,11 @@ class RequestError < ArgumentError
|
|
26
27
|
# The method that failed.
|
27
28
|
attr_reader :method
|
28
29
|
|
29
|
-
# The error result that occurred, typically a windows error
|
30
|
+
# The error result that occurred, typically a windows error message.
|
30
31
|
attr_reader :result
|
32
|
+
|
33
|
+
# The error result that occurred, typically a windows error code.
|
34
|
+
attr_reader :code
|
31
35
|
end
|
32
36
|
|
33
37
|
###
|
@@ -38,7 +42,7 @@ end
|
|
38
42
|
###
|
39
43
|
module PacketDispatcher
|
40
44
|
|
41
|
-
PacketTimeout =
|
45
|
+
PacketTimeout = 600
|
42
46
|
|
43
47
|
##
|
44
48
|
#
|
@@ -79,12 +83,19 @@ module PacketDispatcher
|
|
79
83
|
# Sends a packet and waits for a timeout for the given time interval.
|
80
84
|
#
|
81
85
|
def send_request(packet, t = self.response_timeout)
|
86
|
+
|
87
|
+
if not t
|
88
|
+
send_packet(packet)
|
89
|
+
return nil
|
90
|
+
end
|
91
|
+
|
82
92
|
response = send_packet_wait_response(packet, t)
|
83
93
|
|
84
94
|
if (response == nil)
|
85
95
|
raise TimeoutError.new("Send timed out")
|
86
96
|
elsif (response.result != 0)
|
87
|
-
|
97
|
+
einfo = lookup_error(response.result)
|
98
|
+
e = RequestError.new(packet.method, einfo, response.result)
|
88
99
|
|
89
100
|
e.set_backtrace(caller)
|
90
101
|
|
@@ -139,7 +150,7 @@ module PacketDispatcher
|
|
139
150
|
self.alive = true
|
140
151
|
|
141
152
|
# Spawn a thread for receiving packets
|
142
|
-
self.receiver_thread = ::
|
153
|
+
self.receiver_thread = Rex::ThreadFactory.spawn("MeterpreterReceiver", false) do
|
143
154
|
while (self.alive)
|
144
155
|
begin
|
145
156
|
rv = Rex::ThreadSafe.select([ self.sock.fd ], nil, nil, 0.25)
|
@@ -191,7 +202,7 @@ module PacketDispatcher
|
|
191
202
|
end
|
192
203
|
|
193
204
|
# Spawn a new thread that monitors the socket
|
194
|
-
self.dispatcher_thread = ::
|
205
|
+
self.dispatcher_thread = Rex::ThreadFactory.spawn("MeterpreterDispatcher", false) do
|
195
206
|
begin
|
196
207
|
# Whether we're finished or not is determined by the receiver
|
197
208
|
# thread above.
|
@@ -27,19 +27,7 @@ class PacketResponseWaiter
|
|
27
27
|
self.completion_routine = completion_routine
|
28
28
|
self.completion_param = completion_param
|
29
29
|
else
|
30
|
-
self.done
|
31
|
-
self.wthread = initialize_waiter_thread
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
#
|
36
|
-
# Create an idle thread we can wait on
|
37
|
-
#
|
38
|
-
def initialize_waiter_thread
|
39
|
-
::Thread.new do
|
40
|
-
while (! self.done)
|
41
|
-
::IO.select(nil,nil,nil,5.0)
|
42
|
-
end
|
30
|
+
self.done = false
|
43
31
|
end
|
44
32
|
end
|
45
33
|
|
@@ -61,7 +49,6 @@ class PacketResponseWaiter
|
|
61
49
|
self.completion_routine.call(response, self.completion_param)
|
62
50
|
else
|
63
51
|
self.done = true
|
64
|
-
self.wthread.kill
|
65
52
|
end
|
66
53
|
end
|
67
54
|
|
@@ -71,10 +58,16 @@ class PacketResponseWaiter
|
|
71
58
|
#
|
72
59
|
def wait(interval)
|
73
60
|
if( interval and interval == -1 )
|
74
|
-
self.
|
61
|
+
while(not self.done)
|
62
|
+
::IO.select(nil, nil, nil, 0.1)
|
63
|
+
end
|
75
64
|
else
|
76
65
|
begin
|
77
|
-
Timeout.timeout(interval) {
|
66
|
+
Timeout.timeout(interval) {
|
67
|
+
while(not self.done)
|
68
|
+
::IO.select(nil, nil, nil, 0.1)
|
69
|
+
end
|
70
|
+
}
|
78
71
|
rescue Timeout::Error
|
79
72
|
self.response = nil
|
80
73
|
end
|
@@ -82,7 +75,7 @@ class PacketResponseWaiter
|
|
82
75
|
return self.response
|
83
76
|
end
|
84
77
|
|
85
|
-
attr_accessor :rid, :done, :response
|
78
|
+
attr_accessor :rid, :done, :response # :nodoc:
|
86
79
|
attr_accessor :completion_routine, :completion_param # :nodoc:
|
87
80
|
end
|
88
81
|
|
@@ -389,7 +389,7 @@ class Console::CommandDispatcher::Core
|
|
389
389
|
self.bgjob_id += 1
|
390
390
|
|
391
391
|
# Get the script name
|
392
|
-
self.bgjobs[jid] = ::
|
392
|
+
self.bgjobs[jid] = Rex::ThreadFactory.spawn("MeterpreterBGRun(#{args[0]})-#{jid}", false, jid, args) do |myjid,xargs|
|
393
393
|
::Thread.current[:args] = xargs.dup
|
394
394
|
begin
|
395
395
|
# the rest of the arguments get passed in through the binding
|
@@ -177,7 +177,7 @@ class Console::CommandDispatcher::NetworkPug
|
|
177
177
|
response, @channel = client.networkpug.networkpug_start(interface, filter)
|
178
178
|
|
179
179
|
if(@channel)
|
180
|
-
@thread_stuff = ::
|
180
|
+
@thread_stuff = Rex::ThreadFactory.spawn("MeterpreterNetworkPUGReceiver", false) {
|
181
181
|
proxy_packets()
|
182
182
|
}
|
183
183
|
|
@@ -194,17 +194,27 @@ class Console::CommandDispatcher::NetworkPug
|
|
194
194
|
return
|
195
195
|
end
|
196
196
|
|
197
|
+
client.networkpug.networkpug_stop(interface)
|
198
|
+
|
199
|
+
#print_line("client.networkpug.networkpug_stop returned")
|
200
|
+
|
197
201
|
if(@thread_stuff)
|
198
|
-
|
199
|
-
|
202
|
+
# print_line("killing thread")
|
203
|
+
@thread_stuff.kill
|
200
204
|
|
201
|
-
|
205
|
+
#print_line("joining thread")
|
206
|
+
#@thread_stuff.join
|
207
|
+
# meterpreter dies if i try to join.. not sure why.
|
202
208
|
|
203
|
-
@
|
209
|
+
@thread_stuff = nil
|
210
|
+
|
211
|
+
#print_line("closing tapdev")
|
204
212
|
@tapdev.close
|
213
|
+
|
214
|
+
#print_line("closing channel")
|
215
|
+
#@channel.close
|
205
216
|
end
|
206
217
|
|
207
|
-
client.networkpug.networkpug_stop(interface)
|
208
218
|
print_status("Packet slinging stopped on #{interface}")
|
209
219
|
return true
|
210
220
|
end
|