librex 0.0.28 → 0.0.29
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.markdown +1 -1
- data/Rakefile +1 -1
- data/lib/rex/parser/arguments.rb +12 -2
- data/lib/rex/parser/nexpose_xml.rb +2 -1
- data/lib/rex/parser/nmap_xml.rb +12 -4
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +9 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +5 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +31 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +2 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +32 -0
- data/lib/rex/post/meterpreter/ui/console.rb +2 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +24 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +97 -48
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +4 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +1 -26
- data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
- data/lib/rex/proto/proxy/socks4a.rb +5 -5
- data/lib/rex/ui/interactive.rb +5 -0
- metadata +3 -3
data/README.markdown
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
A non-official re-packaging of the Rex library as a gem for easy of usage of the Metasploit REX framework in a non Metasploit application. I received permission from HDM to create this package.
|
4
4
|
|
5
5
|
Currently based on:
|
6
|
-
SVN Revision:
|
6
|
+
SVN Revision: 12371
|
7
7
|
|
8
8
|
# Credits
|
9
9
|
The Metasploit development team <http://www.metasploit.com>
|
data/Rakefile
CHANGED
@@ -86,7 +86,7 @@ task :update do
|
|
86
86
|
system "mv README.markdown.1 README.markdown &> /dev/null"
|
87
87
|
|
88
88
|
system "git commit -a -m \"Updated for Revision #{rev[1]}\" &> /dev/null"
|
89
|
-
puts "Commiting and Pushing Updates for Revision #{rev[1]}"
|
89
|
+
puts "[*] Commiting and Pushing Updates for Revision #{rev[1]}"
|
90
90
|
system "git push &> /dev/null"
|
91
91
|
|
92
92
|
#Twitter tweet for the update, I am that lazy yes.
|
data/lib/rex/parser/arguments.rb
CHANGED
@@ -26,6 +26,11 @@ class Arguments
|
|
26
26
|
#
|
27
27
|
def initialize(fmt)
|
28
28
|
self.fmt = fmt
|
29
|
+
# I think reduce is a better name for this method, but it doesn't exist
|
30
|
+
# before 1.8.7, so use the stupid inject instead.
|
31
|
+
self.longest = fmt.keys.inject(0) { |max, str|
|
32
|
+
max = ((max > str.length) ? max : str.length)
|
33
|
+
}
|
29
34
|
end
|
30
35
|
|
31
36
|
#
|
@@ -77,7 +82,7 @@ class Arguments
|
|
77
82
|
fmt.sort.each { |entry|
|
78
83
|
fmtspec, val = entry
|
79
84
|
|
80
|
-
txt << " #{fmtspec}" + ((val[0] == true) ? " <opt> " : " ")
|
85
|
+
txt << " #{fmtspec.ljust(longest)}" + ((val[0] == true) ? " <opt> " : " ")
|
81
86
|
txt << val[1] + "\n"
|
82
87
|
}
|
83
88
|
|
@@ -89,7 +94,12 @@ class Arguments
|
|
89
94
|
return fmt.include?(search)
|
90
95
|
end
|
91
96
|
|
92
|
-
|
97
|
+
def arg_required?(opt)
|
98
|
+
fmt[opt][0] if fmt[opt]
|
99
|
+
end
|
100
|
+
|
101
|
+
attr_accessor :fmt # :nodoc:
|
102
|
+
attr_accessor :longest # :nodoc:
|
93
103
|
|
94
104
|
end
|
95
105
|
|
@@ -29,6 +29,7 @@ class NexposeXMLStreamParser
|
|
29
29
|
@host["os_vendor"] = attributes["vendor"]
|
30
30
|
@host["os_family"] = attributes["family"]
|
31
31
|
@host["os_product"] = attributes["product"]
|
32
|
+
@host["os_version"] = attributes["version"]
|
32
33
|
@host["arch"] = attributes["arch"]
|
33
34
|
@host["os_certainty"] = attributes["certainty"]
|
34
35
|
end
|
@@ -76,7 +77,7 @@ class NexposeXMLStreamParser
|
|
76
77
|
when "vulnerability"
|
77
78
|
callback.call(:vuln, @vuln) if callback
|
78
79
|
reset_state
|
79
|
-
when "service","reference"
|
80
|
+
when "service","reference","names"
|
80
81
|
@state = :generic_state
|
81
82
|
end
|
82
83
|
end
|
data/lib/rex/parser/nmap_xml.rb
CHANGED
@@ -70,10 +70,18 @@ class NmapXMLStreamParser
|
|
70
70
|
@host["addr"] = attributes["addr"]
|
71
71
|
end
|
72
72
|
when "osclass"
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
# If there is more than one, take the highest accuracy. In case of
|
74
|
+
# a tie, this will have the effect of taking the last one in the
|
75
|
+
# list. Last is really no better than first but nmap appears to
|
76
|
+
# put OSes in chronological order, at least for Windows.
|
77
|
+
# Accordingly, this will report XP instead of 2000, 7 instead of
|
78
|
+
# Vista, etc, when each has the same accuracy.
|
79
|
+
if (@host["os_accuracy"].to_i <= attributes["accuracy"].to_i)
|
80
|
+
@host["os_vendor"] = attributes["vendor"]
|
81
|
+
@host["os_family"] = attributes["osfamily"]
|
82
|
+
@host["os_version"] = attributes["osgen"]
|
83
|
+
@host["os_accuracy"] = attributes["accuracy"]
|
84
|
+
end
|
77
85
|
when "osmatch"
|
78
86
|
if(attributes["accuracy"].to_i == 100)
|
79
87
|
@host["os_match"] = attributes["name"]
|
@@ -96,7 +96,15 @@ Separator = "\\"
|
|
96
96
|
def File.stat(name)
|
97
97
|
return client.fs.filestat.new(name)
|
98
98
|
end
|
99
|
-
|
99
|
+
|
100
|
+
#
|
101
|
+
# Determines if a file exists and returns true/false
|
102
|
+
#
|
103
|
+
def File.exists?(name)
|
104
|
+
r = client.fs.filestat.new(name) rescue nil
|
105
|
+
r ? true : false
|
106
|
+
end
|
107
|
+
|
100
108
|
#
|
101
109
|
# Performs a delete on the specified file.
|
102
110
|
#
|
@@ -1,4 +1,9 @@
|
|
1
1
|
$:.unshift(File.join(File.dirname(__FILE__)))
|
2
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', '..','..','..','..','..', 'lib'))
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
require 'rex'
|
6
|
+
|
2
7
|
require 'railgun/api_constants.rb.ut'
|
3
8
|
require 'railgun/buffer_item.rb.ut'
|
4
9
|
require 'railgun/dll_function.rb.ut'
|
@@ -25,6 +25,8 @@
|
|
25
25
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_helper'
|
26
26
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_function'
|
27
27
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/buffer_item'
|
28
|
+
require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv'
|
29
|
+
require 'rex/post/meterpreter/packet'
|
28
30
|
|
29
31
|
module Rex
|
30
32
|
module Post
|
@@ -299,8 +301,36 @@ class DLL
|
|
299
301
|
end
|
300
302
|
end
|
301
303
|
#puts return_hash
|
302
|
-
#puts "finished"
|
303
304
|
|
305
|
+
#puts "finished"
|
306
|
+
# puts("
|
307
|
+
#=== START of proccess_function_call snapshot ===
|
308
|
+
# {
|
309
|
+
# :platform => '#{@native == 'Q' ? 'x64/win64' : 'x86/win32'}',
|
310
|
+
# :name => '#{function.windows_name}',
|
311
|
+
# :params => #{function.params},
|
312
|
+
# :return_type => '#{function.return_type}',
|
313
|
+
# :dll_name => '#{@dll_path}',
|
314
|
+
# :ruby_args => #{args.inspect},
|
315
|
+
# :request_to_client => {
|
316
|
+
# TLV_TYPE_RAILGUN_SIZE_OUT => #{out_only_size_bytes},
|
317
|
+
# TLV_TYPE_RAILGUN_STACKBLOB => #{literal_pairs_blob.inspect},
|
318
|
+
# TLV_TYPE_RAILGUN_BUFFERBLOB_IN => #{in_only_buffer.inspect},
|
319
|
+
# TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT => #{inout_buffer.inspect},
|
320
|
+
# TLV_TYPE_RAILGUN_DLLNAME => '#{@dll_path}',
|
321
|
+
# TLV_TYPE_RAILGUN_FUNCNAME => '#{function.windows_name}',
|
322
|
+
# },
|
323
|
+
# :response_from_client => {
|
324
|
+
# TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT => #{rec_inout_buffers.inspect},
|
325
|
+
# TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT => #{rec_out_only_buffers.inspect},
|
326
|
+
# TLV_TYPE_RAILGUN_BACK_RET => #{rec_return_value.inspect},
|
327
|
+
# TLV_TYPE_RAILGUN_BACK_ERR => #{rec_last_error},
|
328
|
+
# },
|
329
|
+
# :returned_hash => #{return_hash.inspect},
|
330
|
+
# },
|
331
|
+
#=== END of proccess_function_call snapshot ===
|
332
|
+
# ")
|
333
|
+
#
|
304
334
|
return return_hash
|
305
335
|
end
|
306
336
|
|
@@ -219,6 +219,38 @@ class UI < Rex::Post::UI
|
|
219
219
|
return response.get_tlv_value(TLV_TYPE_KEYS_DUMP);
|
220
220
|
end
|
221
221
|
|
222
|
+
#
|
223
|
+
# Extract the keystroke from the buffer data
|
224
|
+
#
|
225
|
+
def keyscan_extract(buffer_data)
|
226
|
+
outp = ""
|
227
|
+
buffer_data.unpack("n*").each do |inp|
|
228
|
+
fl = (inp & 0xff00) >> 8
|
229
|
+
vk = (inp & 0xff)
|
230
|
+
kc = VirtualKeyCodes[vk]
|
231
|
+
|
232
|
+
f_shift = fl & (1<<1)
|
233
|
+
f_ctrl = fl & (1<<2)
|
234
|
+
f_alt = fl & (1<<3)
|
235
|
+
|
236
|
+
if(kc)
|
237
|
+
name = ((f_shift != 0 and kc.length > 1) ? kc[1] : kc[0])
|
238
|
+
case name
|
239
|
+
when /^.$/
|
240
|
+
outp << name
|
241
|
+
when /shift|click/i
|
242
|
+
when 'Space'
|
243
|
+
outp << " "
|
244
|
+
else
|
245
|
+
outp << " <#{name}> "
|
246
|
+
end
|
247
|
+
else
|
248
|
+
outp << " <0x%.2x> " % vk
|
249
|
+
end
|
250
|
+
end
|
251
|
+
return outp
|
252
|
+
end
|
253
|
+
|
222
254
|
protected
|
223
255
|
attr_accessor :client # :nodoc:
|
224
256
|
|
@@ -80,6 +80,8 @@ class Console
|
|
80
80
|
#
|
81
81
|
def interact_with_channel(channel)
|
82
82
|
channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)
|
83
|
+
channel.on_command_proc = self.on_command_proc if self.on_command_proc
|
84
|
+
channel.on_print_proc = self.on_print_proc if self.on_print_proc
|
83
85
|
|
84
86
|
channel.interact(input, output)
|
85
87
|
channel.reset_ui
|
@@ -36,6 +36,11 @@ module Console::CommandDispatcher
|
|
36
36
|
@@file_hash[name] = klass
|
37
37
|
end
|
38
38
|
|
39
|
+
def initialize(shell)
|
40
|
+
@msf_loaded = nil
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
39
44
|
#
|
40
45
|
# Returns the meterpreter client context.
|
41
46
|
#
|
@@ -43,6 +48,24 @@ module Console::CommandDispatcher
|
|
43
48
|
shell.client
|
44
49
|
end
|
45
50
|
|
51
|
+
#
|
52
|
+
# Returns true if the client has a framework object.
|
53
|
+
#
|
54
|
+
# Used for firing framework session events
|
55
|
+
#
|
56
|
+
def msf_loaded?
|
57
|
+
return @msf_loaded unless @msf_loaded.nil?
|
58
|
+
# if we get here we must not have initialized yet
|
59
|
+
|
60
|
+
if client.framework
|
61
|
+
# We have a framework instance so the msf libraries should be
|
62
|
+
# available. Load up the ones we're going to use
|
63
|
+
require 'msf/base/serializer/readable_text'
|
64
|
+
end
|
65
|
+
@msf_loaded = !!(client.framework)
|
66
|
+
@msf_loaded
|
67
|
+
end
|
68
|
+
|
46
69
|
#
|
47
70
|
# Log that an error occurred.
|
48
71
|
#
|
@@ -59,4 +82,4 @@ end
|
|
59
82
|
end
|
60
83
|
end
|
61
84
|
end
|
62
|
-
end
|
85
|
+
end
|
@@ -27,23 +27,9 @@ class Console::CommandDispatcher::Core
|
|
27
27
|
self.bgjobs = []
|
28
28
|
self.bgjob_id = 0
|
29
29
|
|
30
|
-
@msf_loaded = nil
|
31
30
|
end
|
32
31
|
|
33
|
-
|
34
|
-
return @msf_loaded unless @msf_loaded.nil?
|
35
|
-
# if we get here we must not have initialized yet
|
36
|
-
|
37
|
-
if client.framework
|
38
|
-
# We have a framework instance so the msf libraries should be
|
39
|
-
# available. Load up the ones we're going to use
|
40
|
-
require 'msf/base/serializer/readable_text'
|
41
|
-
end
|
42
|
-
@msf_loaded = !!(client.framework)
|
43
|
-
@msf_loaded
|
44
|
-
end
|
45
|
-
|
46
|
-
@@use_opts = Rex::Parser::Arguments.new(
|
32
|
+
@@load_opts = Rex::Parser::Arguments.new(
|
47
33
|
"-l" => [ false, "List all available extensions" ],
|
48
34
|
"-h" => [ false, "Help menu." ])
|
49
35
|
|
@@ -61,7 +47,8 @@ class Console::CommandDispatcher::Core
|
|
61
47
|
"interact" => "Interacts with a channel",
|
62
48
|
"irb" => "Drop into irb scripting mode",
|
63
49
|
"migrate" => "Migrate the server to another process",
|
64
|
-
"use" => "
|
50
|
+
"use" => "Deprecated alias for 'load'",
|
51
|
+
"load" => "Load one or more meterpreter extensions",
|
65
52
|
"quit" => "Terminate the meterpreter session",
|
66
53
|
"resource" => "Run the commands stored in a file",
|
67
54
|
"read" => "Reads data from a channel",
|
@@ -85,6 +72,13 @@ class Console::CommandDispatcher::Core
|
|
85
72
|
"Core"
|
86
73
|
end
|
87
74
|
|
75
|
+
def cmd_background_help
|
76
|
+
print_line "Usage: background"
|
77
|
+
print_line
|
78
|
+
print_line "Stop interacting with this session and return to the parent prompt"
|
79
|
+
print_line
|
80
|
+
end
|
81
|
+
|
88
82
|
def cmd_background
|
89
83
|
client.interacting = false
|
90
84
|
end
|
@@ -93,37 +87,61 @@ class Console::CommandDispatcher::Core
|
|
93
87
|
# Displays information about active channels
|
94
88
|
#
|
95
89
|
@@channel_opts = Rex::Parser::Arguments.new(
|
90
|
+
"-c" => [ true, "Close the given channel." ],
|
91
|
+
"-i" => [ true, "Interact with the given channel." ],
|
96
92
|
"-l" => [ false, "List active channels." ],
|
97
|
-
"-
|
93
|
+
"-r" => [ true, "Read from the given channel." ],
|
94
|
+
"-w" => [ true, "Write to the given channel." ],
|
95
|
+
"-h" => [ false, "Help menu." ])
|
96
|
+
|
97
|
+
def cmd_channel_help
|
98
|
+
print_line "Usage: channel [options]"
|
99
|
+
print_line
|
100
|
+
print_line "Displays information about active channels."
|
101
|
+
print_line @@channel_opts.usage
|
102
|
+
end
|
98
103
|
|
99
104
|
#
|
100
105
|
# Performs operations on the supplied channel.
|
101
106
|
#
|
102
107
|
def cmd_channel(*args)
|
103
|
-
if
|
104
|
-
|
108
|
+
if args.include?("-h") or args.include?("--help")
|
109
|
+
cmd_channel_help
|
110
|
+
return
|
105
111
|
end
|
106
112
|
|
107
113
|
mode = nil
|
114
|
+
chan = nil
|
115
|
+
data = []
|
108
116
|
|
109
117
|
# Parse options
|
110
118
|
@@channel_opts.parse(args) { |opt, idx, val|
|
111
119
|
case opt
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
+
when "-l"
|
121
|
+
mode = :list
|
122
|
+
when "-c"
|
123
|
+
mode = :close
|
124
|
+
chan = val
|
125
|
+
when "-i"
|
126
|
+
mode = :interact
|
127
|
+
chan = val
|
128
|
+
when "-r"
|
129
|
+
mode = :read
|
130
|
+
chan = val
|
131
|
+
when "-w"
|
132
|
+
mode = :write
|
133
|
+
chan = val
|
134
|
+
end
|
135
|
+
if @@channel_opts.arg_required?(opt)
|
136
|
+
unless chan
|
137
|
+
print_error("Channel ID required")
|
138
|
+
return
|
139
|
+
end
|
120
140
|
end
|
121
141
|
}
|
122
142
|
|
123
|
-
|
124
|
-
|
125
|
-
return true
|
126
|
-
elsif (mode == 'list')
|
143
|
+
case mode
|
144
|
+
when :list
|
127
145
|
tbl = Rex::Ui::Text::Table.new(
|
128
146
|
'Indent' => 4,
|
129
147
|
'Columns' =>
|
@@ -144,6 +162,17 @@ class Console::CommandDispatcher::Core
|
|
144
162
|
else
|
145
163
|
print("\n" + tbl.to_s + "\n")
|
146
164
|
end
|
165
|
+
when :close
|
166
|
+
cmd_close(chan)
|
167
|
+
when :interact
|
168
|
+
cmd_interact(chan)
|
169
|
+
when :read
|
170
|
+
cmd_read(chan)
|
171
|
+
when :write
|
172
|
+
cmd_write(chan)
|
173
|
+
else
|
174
|
+
# No mode, no service.
|
175
|
+
return true
|
147
176
|
end
|
148
177
|
end
|
149
178
|
|
@@ -239,17 +268,24 @@ class Console::CommandDispatcher::Core
|
|
239
268
|
print_status("Migration completed successfully.")
|
240
269
|
end
|
241
270
|
|
271
|
+
def cmd_load_help
|
272
|
+
print_line("Usage: load ext1 ext2 ext3 ...")
|
273
|
+
print_line
|
274
|
+
print_line "Loads a meterpreter extension module or modules."
|
275
|
+
print_line @@load_opts.usage
|
276
|
+
end
|
277
|
+
|
242
278
|
#
|
243
279
|
# Loads one or more meterpreter extensions.
|
244
280
|
#
|
245
|
-
def
|
281
|
+
def cmd_load(*args)
|
246
282
|
if (args.length == 0)
|
247
283
|
args.unshift("-h")
|
248
284
|
end
|
249
285
|
|
250
286
|
modules = nil
|
251
287
|
|
252
|
-
@@
|
288
|
+
@@load_opts.parse(args) { |opt, idx, val|
|
253
289
|
case opt
|
254
290
|
when "-l"
|
255
291
|
exts = []
|
@@ -263,10 +299,7 @@ class Console::CommandDispatcher::Core
|
|
263
299
|
|
264
300
|
return true
|
265
301
|
when "-h"
|
266
|
-
|
267
|
-
"Usage: use ext1 ext2 ext3 ...\n\n" +
|
268
|
-
"Loads a meterpreter extension module or modules.\n" +
|
269
|
-
@@use_opts.usage)
|
302
|
+
cmd_load_help
|
270
303
|
return true
|
271
304
|
end
|
272
305
|
}
|
@@ -299,7 +332,7 @@ class Console::CommandDispatcher::Core
|
|
299
332
|
return true
|
300
333
|
end
|
301
334
|
|
302
|
-
def
|
335
|
+
def cmd_load_tabs(str, words)
|
303
336
|
tabs = []
|
304
337
|
path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter')
|
305
338
|
::Dir.entries(path).each { |f|
|
@@ -312,6 +345,13 @@ class Console::CommandDispatcher::Core
|
|
312
345
|
return tabs
|
313
346
|
end
|
314
347
|
|
348
|
+
def cmd_use(*args)
|
349
|
+
#print_error("Warning: The 'use' command is deprecated in favor of 'load'")
|
350
|
+
cmd_load(*args)
|
351
|
+
end
|
352
|
+
alias cmd_use_help cmd_load_help
|
353
|
+
alias cmd_use_tabs cmd_load_tabs
|
354
|
+
|
315
355
|
#
|
316
356
|
# Reads data from a channel.
|
317
357
|
#
|
@@ -487,6 +527,13 @@ class Console::CommandDispatcher::Core
|
|
487
527
|
end
|
488
528
|
end
|
489
529
|
|
530
|
+
def cmd_info_help
|
531
|
+
print_line 'Usage: info <module>'
|
532
|
+
print_line
|
533
|
+
print_line 'Prints information about a post-exploitation module'
|
534
|
+
print_line
|
535
|
+
end
|
536
|
+
|
490
537
|
#
|
491
538
|
# Show info for a given Post module.
|
492
539
|
#
|
@@ -495,8 +542,8 @@ class Console::CommandDispatcher::Core
|
|
495
542
|
def cmd_info(*args)
|
496
543
|
return unless msf_loaded?
|
497
544
|
|
498
|
-
if args.length != 1
|
499
|
-
|
545
|
+
if args.length != 1 or args.include?("-h")
|
546
|
+
cmd_info_help
|
500
547
|
return
|
501
548
|
end
|
502
549
|
|
@@ -524,9 +571,17 @@ class Console::CommandDispatcher::Core
|
|
524
571
|
"-f" => [ true, "Write the contents of a file on disk" ],
|
525
572
|
"-h" => [ false, "Help menu." ])
|
526
573
|
|
574
|
+
def cmd_write_help
|
575
|
+
print_line "Usage: write [options] channel_id"
|
576
|
+
print_line
|
577
|
+
print_line "Writes data to the supplied channel."
|
578
|
+
print_line @@write_opts.usage
|
579
|
+
end
|
580
|
+
|
527
581
|
def cmd_write(*args)
|
528
|
-
if (args.length == 0)
|
529
|
-
|
582
|
+
if (args.length == 0 or args.include?("-h"))
|
583
|
+
cmd_write_help
|
584
|
+
return
|
530
585
|
end
|
531
586
|
|
532
587
|
src_file = nil
|
@@ -534,12 +589,6 @@ class Console::CommandDispatcher::Core
|
|
534
589
|
|
535
590
|
@@write_opts.parse(args) { |opt, idx, val|
|
536
591
|
case opt
|
537
|
-
when "-h"
|
538
|
-
print(
|
539
|
-
"Usage: write [options] channel_id\n\n" +
|
540
|
-
"Writes data to the supplied channel.\n" +
|
541
|
-
@@write_opts.usage)
|
542
|
-
return true
|
543
592
|
when "-f"
|
544
593
|
src_file = val
|
545
594
|
else
|
@@ -225,10 +225,12 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|
225
225
|
if (stat.directory?)
|
226
226
|
client.fs.dir.download(dest, src, recursive, true) { |step, src, dst|
|
227
227
|
print_status("#{step.ljust(11)}: #{src} -> #{dst}")
|
228
|
+
client.framework.events.on_session_download(client, src, dest) if msf_loaded?
|
228
229
|
}
|
229
230
|
elsif (stat.file?)
|
230
231
|
client.fs.file.download(dest, src) { |step, src, dst|
|
231
232
|
print_status("#{step.ljust(11)}: #{src} -> #{dst}")
|
233
|
+
client.framework.events.on_session_download(client, src, dest) if msf_loaded?
|
232
234
|
}
|
233
235
|
end
|
234
236
|
}
|
@@ -417,10 +419,12 @@ class Console::CommandDispatcher::Stdapi::Fs
|
|
417
419
|
if (stat.directory?)
|
418
420
|
client.fs.dir.upload(dest, src, recursive) { |step, src, dst|
|
419
421
|
print_status("#{step.ljust(11)}: #{src} -> #{dst}")
|
422
|
+
client.framework.events.on_session_upload(client, src, dest) if msf_loaded?
|
420
423
|
}
|
421
424
|
elsif (stat.file?)
|
422
425
|
client.fs.file.upload(dest, src) { |step, src, dst|
|
423
426
|
print_status("#{step.ljust(11)}: #{src} -> #{dst}")
|
427
|
+
client.framework.events.on_session_upload(client, src, dest) if msf_loaded?
|
424
428
|
}
|
425
429
|
end
|
426
430
|
}
|
@@ -51,7 +51,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
51
51
|
"execute" => "Execute a command",
|
52
52
|
"getpid" => "Get the current process identifier",
|
53
53
|
"getuid" => "Get the user that the server is running as",
|
54
|
-
"getprivs" => "
|
54
|
+
"getprivs" => "List all privileges available to the current process",
|
55
55
|
"kill" => "Terminate a process",
|
56
56
|
"ps" => "List running processes",
|
57
57
|
"reboot" => "Reboots the remote computer",
|
@@ -277,32 +277,7 @@ class Console::CommandDispatcher::Stdapi::Ui
|
|
277
277
|
def cmd_keyscan_dump(*args)
|
278
278
|
print_line("Dumping captured keystrokes...")
|
279
279
|
data = client.ui.keyscan_dump
|
280
|
-
|
281
|
-
data.unpack("n*").each do |inp|
|
282
|
-
fl = (inp & 0xff00) >> 8
|
283
|
-
vk = (inp & 0xff)
|
284
|
-
kc = VirtualKeyCodes[vk]
|
285
|
-
|
286
|
-
f_shift = fl & (1<<1)
|
287
|
-
f_ctrl = fl & (1<<2)
|
288
|
-
f_alt = fl & (1<<3)
|
289
|
-
|
290
|
-
if(kc)
|
291
|
-
name = ((f_shift != 0 and kc.length > 1) ? kc[1] : kc[0])
|
292
|
-
case name
|
293
|
-
when /^.$/
|
294
|
-
outp << name
|
295
|
-
when /shift|click/i
|
296
|
-
when 'Space'
|
297
|
-
outp << " "
|
298
|
-
else
|
299
|
-
outp << " <#{name}> "
|
300
|
-
end
|
301
|
-
else
|
302
|
-
outp << " <0x%.2x> " % vk
|
303
|
-
end
|
304
|
-
end
|
305
|
-
print_line(outp)
|
280
|
+
print_line(client.ui.keyscan_extract(data))
|
306
281
|
|
307
282
|
return true
|
308
283
|
end
|
@@ -68,6 +68,8 @@ module Console::InteractiveChannel
|
|
68
68
|
def _stream_read_local_write_remote(channel)
|
69
69
|
data = user_input.gets
|
70
70
|
return if not data
|
71
|
+
|
72
|
+
self.on_command_proc.call(data.strip) if self.on_command_proc
|
71
73
|
self.write(data)
|
72
74
|
end
|
73
75
|
|
@@ -77,6 +79,7 @@ module Console::InteractiveChannel
|
|
77
79
|
def _stream_read_remote_write_local(channel)
|
78
80
|
data = self.lsock.sysread(16384)
|
79
81
|
|
82
|
+
self.on_print_proc.call(data.strip) if self.on_print_proc
|
80
83
|
user_output.print(data)
|
81
84
|
end
|
82
85
|
|
@@ -226,7 +226,6 @@ class Socks4a
|
|
226
226
|
@rsock = nil
|
227
227
|
@client_thread = nil
|
228
228
|
@mutex = ::Mutex.new
|
229
|
-
@closed = false
|
230
229
|
end
|
231
230
|
|
232
231
|
#
|
@@ -248,8 +247,9 @@ class Socks4a
|
|
248
247
|
params = {
|
249
248
|
'PeerHost' => request.dest_ip,
|
250
249
|
'PeerPort' => request.dest_port,
|
251
|
-
'Comm' => @server.opts['Comm']
|
252
250
|
}
|
251
|
+
params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context')
|
252
|
+
|
253
253
|
@rsock = Rex::Socket::Tcp.create( params )
|
254
254
|
# and send back success to the client
|
255
255
|
response = Packet.new
|
@@ -262,8 +262,8 @@ class Socks4a
|
|
262
262
|
params = {
|
263
263
|
'LocalHost' => '0.0.0.0',
|
264
264
|
'LocalPort' => 0,
|
265
|
-
'Comm' => @server.opts['Comm']
|
266
265
|
}
|
266
|
+
params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context')
|
267
267
|
bsock = Rex::Socket::TcpServer.create( params )
|
268
268
|
# send back the bind success to the client
|
269
269
|
response = Packet.new
|
@@ -353,7 +353,7 @@ class Socks4a
|
|
353
353
|
# Create a new Socks4a server.
|
354
354
|
#
|
355
355
|
def initialize( opts={} )
|
356
|
-
@opts = { 'ServerHost' => '0.0.0.0', 'ServerPort' => 1080
|
356
|
+
@opts = { 'ServerHost' => '0.0.0.0', 'ServerPort' => 1080 }
|
357
357
|
@opts = @opts.merge( opts )
|
358
358
|
@server = nil
|
359
359
|
@clients = ::Array.new
|
@@ -373,7 +373,7 @@ class Socks4a
|
|
373
373
|
#
|
374
374
|
def start
|
375
375
|
begin
|
376
|
-
# create the servers main socket
|
376
|
+
# create the servers main socket (ignore the context here because we don't want a remote bind)
|
377
377
|
@server = Rex::Socket::TcpServer.create( 'LocalHost' => @opts['ServerHost'], 'LocalPort' => @opts['ServerPort'] )
|
378
378
|
# signal we are now running
|
379
379
|
@running = true
|
data/lib/rex/ui/interactive.rb
CHANGED
@@ -108,6 +108,9 @@ module Interactive
|
|
108
108
|
#
|
109
109
|
attr_accessor :completed
|
110
110
|
|
111
|
+
attr_accessor :on_print_proc
|
112
|
+
attr_accessor :on_command_proc
|
113
|
+
|
111
114
|
protected
|
112
115
|
|
113
116
|
#
|
@@ -148,6 +151,7 @@ protected
|
|
148
151
|
def _stream_read_remote_write_local(stream)
|
149
152
|
data = stream.get
|
150
153
|
|
154
|
+
self.on_print_proc.call(data) if self.on_print_proc
|
151
155
|
user_output.print(data)
|
152
156
|
end
|
153
157
|
|
@@ -157,6 +161,7 @@ protected
|
|
157
161
|
def _stream_read_local_write_remote(stream)
|
158
162
|
data = user_input.gets
|
159
163
|
|
164
|
+
self.on_command_proc.call(data) if self.on_command_proc
|
160
165
|
stream.put(data)
|
161
166
|
end
|
162
167
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: librex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.29
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Metasploit Development Team
|
@@ -11,11 +11,11 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-04-
|
14
|
+
date: 2011-04-19 00:00:00 -05:00
|
15
15
|
default_executable:
|
16
16
|
dependencies: []
|
17
17
|
|
18
|
-
description: Rex provides a variety of classes useful for security testing and exploit development. Based on SVN Revision
|
18
|
+
description: Rex provides a variety of classes useful for security testing and exploit development. Based on SVN Revision 12371
|
19
19
|
email:
|
20
20
|
- hdm@metasploit.com
|
21
21
|
- jacob.hammack@hammackj.com
|