librex 0.0.12 → 0.0.13

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.
Files changed (27) hide show
  1. data/README.markdown +1 -1
  2. data/Rakefile +1 -1
  3. data/lib/rex/io/stream.rb +1 -1
  4. data/lib/rex/parser/nmap_xml.rb +4 -1
  5. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +6 -0
  6. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +31 -0
  7. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +47 -0
  8. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +36 -0
  9. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/{model.rb → dll.rb} +4 -226
  10. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +100 -0
  11. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +42 -0
  12. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +148 -0
  13. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +127 -0
  14. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +2 -1
  15. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +3 -2
  16. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +1 -1
  17. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +75 -0
  18. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +103 -0
  19. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +44 -0
  20. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +2 -2
  21. data/lib/rex/proto/dhcp/server.rb +7 -6
  22. data/lib/rex/proto/ntlm/utils.rb +505 -100
  23. data/lib/rex/proto/rfb/cipher.rb +6 -0
  24. data/lib/rex/proto/smb/client.rb +40 -332
  25. data/lib/rex/proto/smb/simpleclient.rb +3 -1
  26. data/lib/rex/proto/smb/utils.rb +0 -4
  27. metadata +14 -4
@@ -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: 11938
6
+ SVN Revision: 12182
7
7
 
8
8
  # Credits
9
9
  The Metasploit development team <http://www.metasploit.com>
data/Rakefile CHANGED
@@ -17,7 +17,7 @@ task :update do
17
17
  system "git rm lib/rex.rb"
18
18
  system "git rm lib/rex.rb.ts.rb"
19
19
  system "git rm -rf lib/rex/"
20
- system "git commit -a -m \"Removed old code.\""
20
+ # system "git commit -a -m \"Removed old code.\""
21
21
  system "mkdir lib"
22
22
 
23
23
  puts "[*] Checking out Metasploit trunk"
@@ -95,7 +95,7 @@ module Stream
95
95
  false
96
96
  end
97
97
  rescue ::Errno::EBADF, ::Errno::ENOTSOCK
98
- return ::EOFError
98
+ raise ::EOFError
99
99
  rescue StreamClosedError, ::IOError, ::EOFError, ::Errno::EPIPE
100
100
  # If the thing that lead to the closure was an abortive close, then
101
101
  # don't raise the stream closed error.
@@ -84,9 +84,12 @@ class NmapXMLStreamParser
84
84
  # <state> refers to the state of a port; values are "open", "closed", or "filtered"
85
85
  @host["ports"].last["state"] = attributes["state"]
86
86
  when "service"
87
- # Store any service info with the associated port. There shouldn't
87
+ # Store any service and script info with the associated port. There shouldn't
88
88
  # be any collisions on attribute names here, so just merge them.
89
89
  @host["ports"].last.merge!(attributes)
90
+ when "script"
91
+ @host["ports"].last["scripts"] ||= {}
92
+ @host["ports"].last["scripts"][attributes["id"]] = attributes["output"]
90
93
  when "trace"
91
94
  @host["trace"] = {"port" => attributes["port"], "proto" => attributes["proto"], "hops" => [] }
92
95
  when "hop"
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__)))
2
+ require 'railgun/api_constants.rb.ut'
3
+ require 'railgun/buffer_item.rb.ut'
4
+ require 'railgun/dll_function.rb.ut'
5
+ require 'railgun/dll_helper.rb.ut'
6
+ require 'railgun/win_const_manager.rb.ut'
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..','..','..','..','..', 'lib'))
4
+
5
+ require 'rex/post/meterpreter/extensions/stdapi/railgun/api_constants'
6
+ require 'rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager'
7
+ require 'rex/text'
8
+ require 'test/unit'
9
+
10
+ module Rex
11
+ module Post
12
+ module Meterpreter
13
+ module Extensions
14
+ module Stdapi
15
+ module Railgun
16
+ class ApiConstants::UnitTest < Test::Unit::TestCase
17
+ def test_add_constants
18
+ const_manager = WinConstManager.new
19
+
20
+ ApiConstants.add_constants(const_manager)
21
+
22
+ assert_equal(0, const_manager.parse('SUCCESS'),
23
+ "ApiConstants.add_constants should have added WinAPI constants to given constant manager")
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,47 @@
1
+ # Copyright (c) 2010, patrickHVE@googlemail.com
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ # * Redistributions of source code must retain the above copyright
7
+ # notice, this list of conditions and the following disclaimer.
8
+ # * Redistributions in binary form must reproduce the above copyright
9
+ # notice, this list of conditions and the following disclaimer in the
10
+ # documentation and/or other materials provided with the distribution.
11
+ # * The names of the author may not be used to endorse or promote products
12
+ # derived from this software without specific prior written permission.
13
+ #
14
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ # DISCLAIMED. IN NO EVENT SHALL patrickHVE@googlemail.com BE LIABLE FOR ANY
18
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+
25
+ module Rex
26
+ module Post
27
+ module Meterpreter
28
+ module Extensions
29
+ module Stdapi
30
+ module Railgun
31
+
32
+ #
33
+ #
34
+ #
35
+ class BufferItem
36
+
37
+ attr_reader :belongs_to_param_n, :addr, :length_in_bytes, :datatype
38
+
39
+ def initialize(belongs_to_param_n, addr, length_in_bytes, datatype)
40
+ @belongs_to_param_n = belongs_to_param_n
41
+ @addr = addr
42
+ @length_in_bytes = length_in_bytes
43
+ @datatype = datatype
44
+ end
45
+ end
46
+
47
+ end; end; end; end; end; end
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..','..','..','..','..', 'lib'))
4
+
5
+ require 'rex/post/meterpreter/extensions/stdapi/railgun/buffer_item'
6
+ require 'test/unit'
7
+
8
+ module Rex
9
+ module Post
10
+ module Meterpreter
11
+ module Extensions
12
+ module Stdapi
13
+ module Railgun
14
+ class BufferItem::UnitTest < Test::Unit::TestCase
15
+
16
+ def test_initialization
17
+ target_belongs_to_param_n = 1
18
+ target_addr = 232323
19
+ target_length_in_bytes = 4
20
+ target_datatype = "DWORD"
21
+
22
+ item = BufferItem.new(target_belongs_to_param_n, target_addr,
23
+ target_length_in_bytes, target_datatype)
24
+
25
+ assert_equal(target_belongs_to_param_n, item.belongs_to_param_n)
26
+ assert_equal(target_addr, item.addr)
27
+ assert_equal(target_length_in_bytes, item.length_in_bytes)
28
+ assert_equal(target_datatype, item.datatype)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -22,8 +22,9 @@
22
22
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
23
  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
24
 
25
- require 'pp'
26
- require 'enumerator'
25
+ require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_helper'
26
+ require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_function'
27
+ require 'rex/post/meterpreter/extensions/stdapi/railgun/buffer_item'
27
28
 
28
29
  module Rex
29
30
  module Post
@@ -32,229 +33,6 @@ module Extensions
32
33
  module Stdapi
33
34
  module Railgun
34
35
 
35
- #
36
- # Manages our library of windows constants
37
- #
38
- class WinConstManager
39
-
40
- def initialize()
41
- @consts = {}
42
- end
43
-
44
- def add_const(name, value)
45
- @consts[name] = value
46
- end
47
-
48
- # parses a string constaining constants and returns an integer
49
- # the string can be either "CONST" or "CONST1 | CONST2"
50
- #
51
- # this function will NOT throw an exception but return "nil" if it can't parse a string
52
- def parse(s)
53
- if s.class != String
54
- return nil # it's not even a string'
55
- end
56
- return_value = 0
57
- for one_const in s.split('|')
58
- one_const = one_const.strip()
59
- if not @consts.has_key? one_const
60
- return nil # at least one "Constant" is unknown to us
61
- end
62
- return_value |= @consts[one_const]
63
- end
64
- return return_value
65
- end
66
-
67
- def is_parseable(s)
68
- return parse(s) != nil
69
- end
70
- end
71
-
72
- #
73
- # represents one function, e.g. MessageBoxW
74
- #
75
- class DLLFunction
76
- attr_reader :return_type, :params, :windows_name
77
-
78
- def initialize(return_type, params, windows_name)
79
- check_return_type(return_type) # we do error checking as early as possible so the library is easier to use
80
- check_params(params)
81
- @return_type = return_type
82
- @params = params
83
- @windows_name = windows_name
84
- end
85
-
86
- @@directions = ["in", "out", "inout", "return"]
87
-
88
- @@allowed_datatypes = {
89
- "VOID" => ["return"],
90
- "BOOL" => ["in", "return"],
91
- "DWORD" => ["in", "return"],
92
- "WORD" => ["in", "return"],
93
- "BYTE" => ["in", "return"],
94
- "LPVOID" => ["in", "return"], # sf: for specifying a memory address (e.g. VirtualAlloc/HeapAlloc/...) where we dont want ot back it up with actuall mem ala PBLOB
95
- "HANDLE" => ["in", "return"],
96
- "PDWORD" => ["in", "out", "inout"], # todo: support for functions that return pointers to strings
97
- "PWCHAR" => ["in", "out", "inout"],
98
- "PCHAR" => ["in", "out", "inout"],
99
- "PBLOB" => ["in", "out", "inout"],
100
- }
101
-
102
- private
103
-
104
- def check_type_exists (type)
105
- if not @@allowed_datatypes.has_key?(type)
106
- raise "Type unknown: #{type}. Allowed types: #{PP.pp(@@allowed_datatypes.keys, "")}"
107
- end
108
- end
109
-
110
- def check_return_type (type)
111
- check_type_exists(type)
112
- if not @@allowed_datatypes[type].include?("return")
113
- raise "#{type} is not allowed as a return type"
114
- end
115
- end
116
-
117
- def check_params (params)
118
- params.each do |param|
119
- throw "each param must be descriped by a three-tuple [type,name,direction]" unless param.length == 3
120
- type = param[0]
121
- direction = param[2]
122
- check_type_exists(type)
123
- throw "invalid direction: #{direction}" unless @@directions.include?(direction)
124
- throw "direction 'return' is only for the return value of the function." unless direction != "return"
125
- end
126
- end
127
-
128
- end
129
-
130
- #
131
- #
132
- #
133
- class BufferItem
134
-
135
- attr_reader :belongs_to_param_n, :addr, :length_in_bytes, :datatype
136
-
137
- def initialize(belongs_to_param_n, addr, length_in_bytes, datatype)
138
- @belongs_to_param_n = belongs_to_param_n
139
- @addr = addr
140
- @length_in_bytes = length_in_bytes
141
- @datatype = datatype
142
- end
143
- end
144
-
145
- #
146
- # shared functions
147
- #
148
- module DLLHelper
149
-
150
- # converts ruby string to zero-terminated ASCII string
151
- def str_to_ascii_z(str)
152
- return str+"\x00"
153
- end
154
-
155
- # converts 0-terminated ASCII string to ruby string
156
- def asciiz_to_str(asciiz)
157
- zero_byte_idx = asciiz.index("\x00")
158
- if zero_byte_idx != nil
159
- return asciiz[0, zero_byte_idx]
160
- else
161
- return asciiz
162
- end
163
- end
164
-
165
- # converts ruby string to zero-terminated WCHAR string
166
- def str_to_uni_z(str)
167
- enc = str.unpack("C*").pack("v*")
168
- enc += "\x00\x00"
169
- return enc
170
- end
171
-
172
- # converts 0-terminated UTF16 to ruby string
173
- def uniz_to_str(uniz)
174
- uniz.unpack("v*").pack("C*").unpack("A*")[0]
175
- end
176
-
177
- # parses a number param and returns the value
178
- # raises an exception if the param cannot be converted to a number
179
- # examples:
180
- # nil => 0
181
- # 3 => 3
182
- # "MB_OK" => 0
183
- # "SOME_CONSTANT | OTHER_CONSTANT" => 17
184
- # "tuna" => !!!!!!!!!!Exception
185
- def param_to_number(v)
186
- if v.class == NilClass then
187
- return 0
188
- elsif v.class == Fixnum then
189
- return v # ok, it's already a number
190
- elsif v.class == Bignum then
191
- return v # ok, it's already a number
192
- elsif v.class == String then
193
- dw = @win_consts.parse(v) # might raise an exception
194
- if dw != nil
195
- return dw
196
- else
197
- raise "Param #{v} (class #{v.class}) cannot be converted to a number. It's a string but matches no constants I know."
198
- end
199
- else
200
- raise "Param #{v} (class #{v.class}) should be a number but isn't"
201
- end
202
- end
203
-
204
- # assembles the buffers "in" and "inout"
205
- def assemble_buffer(direction, function, args)
206
- layout = {} # paramName => BufferItem
207
- blob = ""
208
- #puts " building buffer: #{direction}"
209
- function.params.each_with_index do |param_desc, param_idx|
210
- #puts " processing #{param_desc[0]} #{param_desc[1]} #{param_desc[2]}"
211
- # we care only about inout buffers
212
- if param_desc[2] == direction
213
- buffer = nil
214
- # Special case:
215
- # The user can choose to supply a Null pointer instead of a buffer
216
- # in this case we don't need space in any heap buffer
217
- if param_desc[0][0,1] == 'P' # type is a pointer
218
- if args[param_idx] == nil
219
- next
220
- end
221
- end
222
-
223
- case param_desc[0] # required argument type
224
- when "PDWORD"
225
- dw = param_to_number(args[param_idx])
226
- buffer = [dw].pack('V')
227
- when "PWCHAR"
228
- raise "param #{param_desc[1]}: string expected" unless args[param_idx].class == String
229
- buffer = str_to_uni_z(args[param_idx])
230
- when "PCHAR"
231
- raise "param #{param_desc[1]}: string expected" unless args[param_idx].class == String
232
- buffer = str_to_ascii_z(args[param_idx])
233
- when "PBLOB"
234
- raise "param #{param_desc[1]}: please supply your BLOB as string!" unless args[param_idx].class == String
235
- buffer = args[param_idx]
236
- # other types (non-pointers) don't reference buffers
237
- # and don't need any treatment here
238
- end
239
-
240
- if buffer != nil
241
- #puts " adding #{buffer.length} bytes to heap blob"
242
- layout[param_desc[1]] = BufferItem.new(param_idx, blob.length, buffer.length, param_desc[0])
243
- blob += buffer
244
- # sf: force 8 byte alignment to satisfy x64, wont matter on x86.
245
- while( blob.length % 8 != 0 )
246
- blob += "\x00"
247
- end
248
- #puts " heap blob size now #{blob.length}"
249
- end
250
- end
251
- end
252
- #puts " built buffer: #{direction}"
253
- return [layout, blob]
254
- end
255
-
256
- end
257
-
258
36
  #
259
37
  # represents a DLL, e.g. kernel32.dll
260
38
  #
@@ -537,4 +315,4 @@ class DLL
537
315
  end
538
316
  end
539
317
 
540
- end; end; end; end; end; end
318
+ end; end; end; end; end; end;
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2010, patrickHVE@googlemail.com
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ # * Redistributions of source code must retain the above copyright
7
+ # notice, this list of conditions and the following disclaimer.
8
+ # * Redistributions in binary form must reproduce the above copyright
9
+ # notice, this list of conditions and the following disclaimer in the
10
+ # documentation and/or other materials provided with the distribution.
11
+ # * The names of the author may not be used to endorse or promote products
12
+ # derived from this software without specific prior written permission.
13
+ #
14
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ # DISCLAIMED. IN NO EVENT SHALL patrickHVE@googlemail.com BE LIABLE FOR ANY
18
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+
25
+ module Rex
26
+ module Post
27
+ module Meterpreter
28
+ module Extensions
29
+ module Stdapi
30
+ module Railgun
31
+
32
+ #
33
+ # represents one function, e.g. MessageBoxW
34
+ #
35
+ class DLLFunction
36
+ @@allowed_datatypes = {
37
+ "VOID" => ["return"],
38
+ "BOOL" => ["in", "return"],
39
+ "DWORD" => ["in", "return"],
40
+ "WORD" => ["in", "return"],
41
+ "BYTE" => ["in", "return"],
42
+ "LPVOID" => ["in", "return"], # sf: for specifying a memory address (e.g. VirtualAlloc/HeapAlloc/...) where we dont want ot back it up with actuall mem ala PBLOB
43
+ "HANDLE" => ["in", "return"],
44
+ "PDWORD" => ["in", "out", "inout"], # todo: support for functions that return pointers to strings
45
+ "PWCHAR" => ["in", "out", "inout"],
46
+ "PCHAR" => ["in", "out", "inout"],
47
+ "PBLOB" => ["in", "out", "inout"],
48
+ }.freeze
49
+
50
+ @@directions = ["in", "out", "inout", "return"].freeze
51
+
52
+ attr_reader :return_type, :params, :windows_name
53
+
54
+ def initialize(return_type, params, windows_name)
55
+ check_return_type(return_type) # we do error checking as early as possible so the library is easier to use
56
+ check_params(params)
57
+ @return_type = return_type
58
+ @params = params
59
+ @windows_name = windows_name
60
+ end
61
+
62
+ private
63
+
64
+ def check_type_exists (type)
65
+ if not @@allowed_datatypes.has_key?(type)
66
+ raise ArgumentError, "Type unknown: #{type}. Allowed types: #{PP.pp(@@allowed_datatypes.keys, "")}"
67
+ end
68
+ end
69
+
70
+ def check_return_type (type)
71
+ check_type_exists(type)
72
+ if not @@allowed_datatypes[type].include?("return")
73
+ raise ArgumentError, "#{type} is not allowed as a return type"
74
+ end
75
+ end
76
+
77
+ def check_params (params)
78
+ params.each do |param|
79
+ raise ArgumentError, "each param must be descriped by a three-tuple [type,name,direction]" unless param.length == 3
80
+ type = param[0]
81
+ direction = param[2]
82
+
83
+ # Assert a valid type
84
+ check_type_exists(type)
85
+
86
+ # Only our set of predefined directions are valid
87
+ unless @@directions.include?(direction)
88
+ raise ArgumentError, "invalid direction: #{direction}"
89
+ end
90
+
91
+ # 'return' is not a valid direction in this context
92
+ unless direction != "return"
93
+ raise "direction 'return' is only for the return value of the function."
94
+ end
95
+ end
96
+ end
97
+
98
+ end
99
+
100
+ end; end; end; end; end; end