librex 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
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