rex 2.0.8 → 2.0.9

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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rex.rb +1 -0
  3. data/lib/rex/arch.rb +5 -0
  4. data/lib/rex/arch/x86.rb +19 -5
  5. data/lib/rex/arch/zarch.rb +17 -0
  6. data/lib/rex/compat.rb +5 -4
  7. data/lib/rex/constants.rb +3 -1
  8. data/lib/rex/encoder/alpha2/alpha_mixed.rb +70 -9
  9. data/lib/rex/encoder/alpha2/alpha_upper.rb +67 -8
  10. data/lib/rex/exploitation/cmdstager.rb +1 -0
  11. data/lib/rex/exploitation/cmdstager/certutil.rb +115 -0
  12. data/lib/rex/exploitation/cmdstager/echo.rb +6 -3
  13. data/lib/rex/exploitation/egghunter.rb +1 -1
  14. data/lib/rex/google/geolocation.rb +68 -0
  15. data/lib/rex/io/bidirectional_pipe.rb +0 -4
  16. data/lib/rex/java/serialization.rb +2 -0
  17. data/lib/rex/java/serialization/decode_error.rb +11 -0
  18. data/lib/rex/java/serialization/encode_error.rb +11 -0
  19. data/lib/rex/java/serialization/model.rb +2 -0
  20. data/lib/rex/java/serialization/model/annotation.rb +3 -3
  21. data/lib/rex/java/serialization/model/block_data.rb +3 -3
  22. data/lib/rex/java/serialization/model/block_data_long.rb +3 -3
  23. data/lib/rex/java/serialization/model/class_desc.rb +6 -6
  24. data/lib/rex/java/serialization/model/contents.rb +17 -10
  25. data/lib/rex/java/serialization/model/field.rb +12 -11
  26. data/lib/rex/java/serialization/model/long_utf.rb +3 -3
  27. data/lib/rex/java/serialization/model/new_array.rb +22 -23
  28. data/lib/rex/java/serialization/model/new_class.rb +57 -0
  29. data/lib/rex/java/serialization/model/new_class_desc.rb +15 -16
  30. data/lib/rex/java/serialization/model/new_enum.rb +5 -5
  31. data/lib/rex/java/serialization/model/new_object.rb +22 -17
  32. data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
  33. data/lib/rex/java/serialization/model/reference.rb +4 -4
  34. data/lib/rex/java/serialization/model/stream.rb +7 -7
  35. data/lib/rex/java/serialization/model/utf.rb +3 -3
  36. data/lib/rex/json_hash_file.rb +94 -0
  37. data/lib/rex/logging/log_sink.rb +1 -0
  38. data/lib/rex/logging/sinks/timestamp_flatfile.rb +21 -0
  39. data/lib/rex/parser/appscan_nokogiri.rb +13 -23
  40. data/lib/rex/parser/fs/ntfs.rb +10 -5
  41. data/lib/rex/parser/nmap_nokogiri.rb +3 -1
  42. data/lib/rex/parser/openvas_nokogiri.rb +70 -73
  43. data/lib/rex/parser/winscp.rb +108 -0
  44. data/lib/rex/parser/x509_certificate.rb +92 -0
  45. data/lib/rex/payloads.rb +0 -1
  46. data/lib/rex/payloads/meterpreter/config.rb +154 -0
  47. data/lib/rex/payloads/meterpreter/uri_checksum.rb +136 -0
  48. data/lib/rex/post/meterpreter.rb +1 -1
  49. data/lib/rex/post/meterpreter/client.rb +26 -3
  50. data/lib/rex/post/meterpreter/client_core.rb +387 -75
  51. data/lib/rex/post/meterpreter/extensions/android/android.rb +127 -37
  52. data/lib/rex/post/meterpreter/extensions/android/tlv.rb +46 -25
  53. data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +4 -0
  54. data/lib/rex/post/meterpreter/extensions/extapi/ntds/ntds.rb +39 -0
  55. data/lib/rex/post/meterpreter/extensions/extapi/pageant/pageant.rb +44 -0
  56. data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +9 -0
  57. data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +16 -1
  58. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +1 -1
  59. data/lib/rex/post/meterpreter/extensions/python/python.rb +114 -0
  60. data/lib/rex/post/meterpreter/extensions/python/tlv.rb +21 -0
  61. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +17 -14
  62. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +33 -12
  63. data/lib/rex/post/meterpreter/extensions/stdapi/fs/mount.rb +57 -0
  64. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3 -3
  65. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +3 -1
  66. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +2 -0
  67. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -3
  68. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +29 -6
  69. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +5 -1
  70. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +18 -6
  71. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +2 -2
  72. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +34 -36
  73. data/lib/rex/post/meterpreter/packet.rb +29 -0
  74. data/lib/rex/post/meterpreter/packet_dispatcher.rb +20 -7
  75. data/lib/rex/post/meterpreter/ui/console.rb +1 -0
  76. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +230 -72
  77. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +544 -34
  78. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +188 -57
  79. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +115 -93
  80. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +1 -1
  81. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +1 -1
  82. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +49 -15
  83. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +11 -2
  84. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/python.rb +187 -0
  85. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +324 -133
  86. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +52 -2
  87. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +68 -65
  88. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +9 -1
  89. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +113 -118
  90. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
  91. data/lib/rex/powershell.rb +62 -0
  92. data/lib/rex/powershell/command.rb +359 -0
  93. data/lib/rex/{exploitation/powershell → powershell}/function.rb +0 -2
  94. data/lib/rex/{exploitation/powershell → powershell}/obfu.rb +0 -2
  95. data/lib/rex/{exploitation/powershell → powershell}/output.rb +11 -5
  96. data/lib/rex/{exploitation/powershell → powershell}/param.rb +0 -2
  97. data/lib/rex/powershell/parser.rb +182 -0
  98. data/lib/rex/powershell/payload.rb +78 -0
  99. data/lib/rex/{exploitation/powershell → powershell}/psh_methods.rb +16 -2
  100. data/lib/rex/{exploitation/powershell → powershell}/script.rb +2 -4
  101. data/lib/rex/proto/dcerpc/client.rb +6 -6
  102. data/lib/rex/proto/dcerpc/exceptions.rb +26 -0
  103. data/lib/rex/proto/http/client.rb +3 -3
  104. data/lib/rex/proto/http/client_request.rb +0 -5
  105. data/lib/rex/proto/http/response.rb +86 -0
  106. data/lib/rex/proto/ipmi/utils.rb +30 -26
  107. data/lib/rex/proto/kerberos/client.rb +1 -1
  108. data/lib/rex/proto/kerberos/model/kdc_request.rb +2 -2
  109. data/lib/rex/proto/rfb/client.rb +8 -3
  110. data/lib/rex/proto/rfb/constants.rb +1 -1
  111. data/lib/rex/proto/rmi.rb +2 -0
  112. data/lib/rex/proto/rmi/decode_error.rb +10 -0
  113. data/lib/rex/proto/rmi/exception.rb +10 -0
  114. data/lib/rex/proto/rmi/model.rb +5 -0
  115. data/lib/rex/proto/rmi/model/call.rb +4 -4
  116. data/lib/rex/proto/rmi/model/call_data.rb +137 -0
  117. data/lib/rex/proto/rmi/model/dgc_ack.rb +2 -2
  118. data/lib/rex/proto/rmi/model/element.rb +26 -11
  119. data/lib/rex/proto/rmi/model/output_header.rb +4 -4
  120. data/lib/rex/proto/rmi/model/ping.rb +2 -2
  121. data/lib/rex/proto/rmi/model/ping_ack.rb +2 -2
  122. data/lib/rex/proto/rmi/model/protocol_ack.rb +2 -2
  123. data/lib/rex/proto/rmi/model/return_data.rb +5 -5
  124. data/lib/rex/proto/rmi/model/return_value.rb +124 -0
  125. data/lib/rex/proto/rmi/model/unique_identifier.rb +77 -0
  126. data/lib/rex/proto/steam.rb +3 -0
  127. data/lib/rex/proto/steam/message.rb +125 -0
  128. data/lib/rex/proto/tftp/client.rb +35 -14
  129. data/lib/rex/random_identifier_generator.rb +2 -0
  130. data/lib/rex/ropbuilder.rb +1 -1
  131. data/lib/rex/socket/parameters.rb +9 -0
  132. data/lib/rex/socket/ssl_tcp.rb +25 -41
  133. data/lib/rex/socket/ssl_tcp_server.rb +10 -21
  134. data/lib/rex/sslscan/result.rb +20 -1
  135. data/lib/rex/text.rb +241 -55
  136. data/lib/rex/ui/output.rb +0 -3
  137. data/lib/rex/ui/subscriber.rb +0 -10
  138. data/lib/rex/ui/text/color.rb +9 -0
  139. data/lib/rex/ui/text/dispatcher_shell.rb +1 -0
  140. data/lib/rex/ui/text/output.rb +15 -4
  141. data/lib/rex/ui/text/output/file.rb +1 -0
  142. data/lib/rex/ui/text/output/stdio.rb +0 -16
  143. data/lib/rex/ui/text/shell.rb +3 -0
  144. data/lib/rex/ui/text/table.rb +85 -19
  145. data/lib/rex/user_agent.rb +118 -0
  146. data/rex.gemspec +2 -2
  147. metadata +41 -14
  148. data/lib/rex/exploitation/powershell.rb +0 -62
  149. data/lib/rex/exploitation/powershell/parser.rb +0 -183
  150. data/lib/rex/payloads/meterpreter.rb +0 -2
  151. data/lib/rex/payloads/meterpreter/patch.rb +0 -136
@@ -45,7 +45,7 @@ class Priv < Extension
45
45
 
46
46
  elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
47
47
 
48
- elevator_path = MeterpreterBinaries.path('elevator', client.binary_suffix)
48
+ elevator_path = MetasploitPayloads.meterpreter_path('elevator', client.binary_suffix)
49
49
  if elevator_path.nil?
50
50
  raise RuntimeError, "elevator.#{binary_suffix} not found", caller
51
51
  end
@@ -0,0 +1,114 @@
1
+ # -*- coding: binary -*-
2
+
3
+ require 'rex/post/meterpreter/extensions/python/tlv'
4
+ require 'set'
5
+
6
+ module Rex
7
+ module Post
8
+ module Meterpreter
9
+ module Extensions
10
+ module Python
11
+
12
+ ###
13
+ #
14
+ # Python extension - gives remote python scripting capabilities on the target.
15
+ #
16
+ ###
17
+
18
+ class Python < Extension
19
+
20
+ PY_CODE_TYPE_STRING = 0
21
+ PY_CODE_TYPE_PY = 1
22
+ PY_CODE_TYPE_PYC = 2
23
+
24
+ PY_CODE_FILE_TYPES = [ '.py', '.pyc' ]
25
+
26
+ PY_CODE_FILE_TYPE_MAP = {
27
+ '.py' => PY_CODE_TYPE_PY,
28
+ '.pyc' => PY_CODE_TYPE_PYC
29
+ }
30
+
31
+ #
32
+ # Typical extension initialization routine.
33
+ #
34
+ # @param client (see Extension#initialize)
35
+ def initialize(client)
36
+ super(client, 'python')
37
+
38
+ client.register_extension_aliases(
39
+ [
40
+ {
41
+ 'name' => 'python',
42
+ 'ext' => self
43
+ }
44
+ ])
45
+ end
46
+
47
+ def reset
48
+ request = Packet.create_request('python_reset')
49
+ client.send_request(request)
50
+
51
+ return true
52
+ end
53
+
54
+ def import(file, mod_name, result_var)
55
+ unless ::File.file?(file)
56
+ raise ArgumentError, "File not found: #{file}"
57
+ end
58
+
59
+ ext = ::File.extname(file).downcase
60
+ unless PY_CODE_FILE_TYPES.include?(ext)
61
+ raise ArgumentError, "File not a valid type: #{file}"
62
+ end
63
+
64
+ code = ::File.read(file)
65
+
66
+ request = Packet.create_request('python_execute')
67
+ request.add_tlv(TLV_TYPE_PYTHON_CODE, code)
68
+ request.add_tlv(TLV_TYPE_PYTHON_CODE_LEN, code.length)
69
+ request.add_tlv(TLV_TYPE_PYTHON_CODE_TYPE, PY_CODE_FILE_TYPE_MAP[ext])
70
+ request.add_tlv(TLV_TYPE_PYTHON_NAME, mod_name) if mod_name
71
+ request.add_tlv(TLV_TYPE_PYTHON_RESULT_VAR, result_var) if result_var
72
+
73
+ run_exec_request(request)
74
+ end
75
+
76
+ #
77
+ # Dump the LSA secrets from the target machine.
78
+ #
79
+ # @return [Hash<Symbol,Object>]
80
+ def execute_string(code, result_var)
81
+ request = Packet.create_request('python_execute')
82
+ request.add_tlv(TLV_TYPE_PYTHON_CODE, code)
83
+ request.add_tlv(TLV_TYPE_PYTHON_CODE_TYPE, PY_CODE_TYPE_STRING)
84
+ request.add_tlv(TLV_TYPE_PYTHON_RESULT_VAR, result_var) if result_var
85
+
86
+ run_exec_request(request)
87
+ end
88
+
89
+ private
90
+
91
+ def run_exec_request(request)
92
+ response = client.send_request(request)
93
+
94
+ result = {
95
+ result: response.get_tlv_value(TLV_TYPE_PYTHON_RESULT),
96
+ stdout: "",
97
+ stderr: ""
98
+ }
99
+
100
+ response.each(TLV_TYPE_PYTHON_STDOUT) do |o|
101
+ result[:stdout] << o.value
102
+ end
103
+
104
+ response.each(TLV_TYPE_PYTHON_STDERR) do |e|
105
+ result[:stderr] << e.value
106
+ end
107
+
108
+ result
109
+ end
110
+
111
+ end
112
+
113
+ end; end; end; end; end
114
+
@@ -0,0 +1,21 @@
1
+ # -*- coding: binary -*-
2
+ module Rex
3
+ module Post
4
+ module Meterpreter
5
+ module Extensions
6
+ module Python
7
+
8
+ TLV_TYPE_PYTHON_STDOUT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 1)
9
+ TLV_TYPE_PYTHON_STDERR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 2)
10
+ TLV_TYPE_PYTHON_CODE = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 3)
11
+ TLV_TYPE_PYTHON_CODE_LEN = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 4)
12
+ TLV_TYPE_PYTHON_CODE_TYPE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 5)
13
+ TLV_TYPE_PYTHON_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 6)
14
+ TLV_TYPE_PYTHON_RESULT_VAR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 7)
15
+ TLV_TYPE_PYTHON_RESULT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 8)
16
+
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -52,16 +52,17 @@ class Dir < Rex::Post::Dir
52
52
  #
53
53
  # Enumerates all of the files/folders in a given directory.
54
54
  #
55
- def Dir.entries(name = getwd)
55
+ def Dir.entries(name = getwd, glob = nil)
56
56
  request = Packet.create_request('stdapi_fs_ls')
57
57
  files = []
58
+ name = name + ::File::SEPARATOR + glob if glob
58
59
 
59
60
  request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode(name))
60
61
 
61
62
  response = client.send_request(request)
62
63
 
63
64
  response.each(TLV_TYPE_FILE_NAME) { |file_name|
64
- files << client.unicode_filter_encode( file_name.value )
65
+ files << client.unicode_filter_encode(file_name.value)
65
66
  }
66
67
 
67
68
  return files
@@ -79,6 +80,7 @@ class Dir < Rex::Post::Dir
79
80
  response = client.send_request(request)
80
81
 
81
82
  fname = response.get_tlvs(TLV_TYPE_FILE_NAME)
83
+ fsname = response.get_tlvs(TLV_TYPE_FILE_SHORT_NAME)
82
84
  fpath = response.get_tlvs(TLV_TYPE_FILE_PATH)
83
85
  sbuf = response.get_tlvs(TLV_TYPE_STAT_BUF)
84
86
 
@@ -96,8 +98,9 @@ class Dir < Rex::Post::Dir
96
98
 
97
99
  files <<
98
100
  {
99
- 'FileName' => client.unicode_filter_encode( file_name.value ),
100
- 'FilePath' => client.unicode_filter_encode( fpath[idx].value ),
101
+ 'FileName' => client.unicode_filter_encode(file_name.value),
102
+ 'FilePath' => client.unicode_filter_encode(fpath[idx].value),
103
+ 'FileShortName' => fsname[idx] ? fsname[idx].value : nil,
101
104
  'StatBuf' => st,
102
105
  }
103
106
  }
@@ -145,7 +148,7 @@ class Dir < Rex::Post::Dir
145
148
 
146
149
  response = client.send_request(request)
147
150
 
148
- return client.unicode_filter_encode( response.get_tlv(TLV_TYPE_DIRECTORY_PATH).value )
151
+ return client.unicode_filter_encode(response.get_tlv(TLV_TYPE_DIRECTORY_PATH).value)
149
152
  end
150
153
 
151
154
  #
@@ -192,11 +195,11 @@ class Dir < Rex::Post::Dir
192
195
  # Downloads the contents of a remote directory a
193
196
  # local directory, optionally in a recursive fashion.
194
197
  #
195
- def Dir.download(dst, src, recursive = false, force = true, &stat)
198
+ def Dir.download(dst, src, recursive = false, force = true, glob = nil, &stat)
196
199
 
197
- self.entries(src).each { |src_sub|
198
- dst_item = dst + ::File::SEPARATOR + client.unicode_filter_encode( src_sub )
199
- src_item = src + client.fs.file.separator + client.unicode_filter_encode( src_sub )
200
+ self.entries(src, glob).each { |src_sub|
201
+ dst_item = dst + ::File::SEPARATOR + client.unicode_filter_encode(src_sub)
202
+ src_item = src + client.fs.file.separator + client.unicode_filter_encode(src_sub)
200
203
 
201
204
  if (src_sub == '.' or src_sub == '..')
202
205
  next
@@ -207,8 +210,8 @@ class Dir < Rex::Post::Dir
207
210
  if (src_stat.file?)
208
211
  stat.call('downloading', src_item, dst_item) if (stat)
209
212
  begin
210
- client.fs.file.download(dst_item, src_item)
211
- stat.call('downloaded', src_item, dst_item) if (stat)
213
+ result = client.fs.file.download_file(dst_item, src_item)
214
+ stat.call(result, src_item, dst_item) if (stat)
212
215
  rescue ::Rex::Post::Meterpreter::RequestError => e
213
216
  if force
214
217
  stat.call('failed', src_item, dst_item) if (stat)
@@ -228,7 +231,7 @@ class Dir < Rex::Post::Dir
228
231
  end
229
232
 
230
233
  stat.call('mirroring', src_item, dst_item) if (stat)
231
- download(dst_item, src_item, recursive, force, &stat)
234
+ download(dst_item, src_item, recursive, force, glob, &stat)
232
235
  stat.call('mirrored', src_item, dst_item) if (stat)
233
236
  end
234
237
  }
@@ -240,8 +243,8 @@ class Dir < Rex::Post::Dir
240
243
  #
241
244
  def Dir.upload(dst, src, recursive = false, &stat)
242
245
  ::Dir.entries(src).each { |src_sub|
243
- dst_item = dst + client.fs.file.separator + client.unicode_filter_encode( src_sub )
244
- src_item = src + ::File::SEPARATOR + client.unicode_filter_encode( src_sub )
246
+ dst_item = dst + client.fs.file.separator + client.unicode_filter_encode(src_sub)
247
+ src_item = src + ::File::SEPARATOR + client.unicode_filter_encode(src_sub)
245
248
 
246
249
  if (src_sub == '.' or src_sub == '..')
247
250
  next
@@ -91,9 +91,9 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
91
91
  if( response.result == 0 )
92
92
  response.each( TLV_TYPE_SEARCH_RESULTS ) do | results |
93
93
  files << {
94
- 'path' => client.unicode_filter_encode( results.get_tlv_value( TLV_TYPE_FILE_PATH ).chomp( '\\' ) ),
95
- 'name' => client.unicode_filter_encode( results.get_tlv_value( TLV_TYPE_FILE_NAME ) ),
96
- 'size' => results.get_tlv_value( TLV_TYPE_FILE_SIZE )
94
+ 'path' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_PATH).chomp( '\\' )),
95
+ 'name' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_NAME)),
96
+ 'size' => results.get_tlv_value(TLV_TYPE_FILE_SIZE)
97
97
  }
98
98
  end
99
99
  end
@@ -138,7 +138,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
138
138
 
139
139
  response = client.send_request(request)
140
140
 
141
- return client.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_FILE_PATH) )
141
+ return client.unicode_filter_encode(response.get_tlv_value(TLV_TYPE_FILE_PATH))
142
142
  end
143
143
 
144
144
 
@@ -152,8 +152,10 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
152
152
 
153
153
  response = client.send_request(request)
154
154
 
155
- # This is not really a file name, but a raw hash in bytes
156
- return response.get_tlv_value(TLV_TYPE_FILE_NAME)
155
+ # older meterpreter binaries will send FILE_NAME containing the hash
156
+ hash = response.get_tlv_value(TLV_TYPE_FILE_HASH) ||
157
+ response.get_tlv_value(TLV_TYPE_FILE_NAME)
158
+ return hash
157
159
  end
158
160
 
159
161
  #
@@ -166,8 +168,10 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
166
168
 
167
169
  response = client.send_request(request)
168
170
 
169
- # This is not really a file name, but a raw hash in bytes
170
- return response.get_tlv_value(TLV_TYPE_FILE_NAME)
171
+ # older meterpreter binaries will send FILE_NAME containing the hash
172
+ hash = response.get_tlv_value(TLV_TYPE_FILE_HASH) ||
173
+ response.get_tlv_value(TLV_TYPE_FILE_NAME)
174
+ return hash
171
175
  end
172
176
 
173
177
  #
@@ -265,6 +269,10 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
265
269
  stat.call('uploaded', src_file, dest_file) if (stat)
266
270
  end
267
271
 
272
+ def File.is_glob?(name)
273
+ /\*|\[|\?/ === name
274
+ end
275
+
268
276
  #
269
277
  # Download one or more files from the remote computer to the local
270
278
  # directory supplied in destination.
@@ -281,10 +289,8 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
281
289
  end
282
290
 
283
291
  stat.call('downloading', src, dest) if (stat)
284
-
285
- download_file(dest, src)
286
-
287
- stat.call('downloaded', src, dest) if (stat)
292
+ result = download_file(dest, src)
293
+ stat.call(result, src, dest) if (stat)
288
294
  }
289
295
  end
290
296
 
@@ -293,6 +299,17 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
293
299
  #
294
300
  def File.download_file(dest_file, src_file)
295
301
  src_fd = client.fs.file.new(src_file, "rb")
302
+
303
+ # Check for changes
304
+ src_stat = client.fs.filestat.new(src_file)
305
+ if ::File.exists?(dest_file)
306
+ dst_stat = ::File.stat(dest_file)
307
+ if src_stat.size == dst_stat.size && src_stat.mtime == dst_stat.mtime
308
+ return 'skipped'
309
+ end
310
+ end
311
+
312
+ # Make the destination path if necessary
296
313
  dir = ::File.dirname(dest_file)
297
314
  ::FileUtils.mkdir_p(dir) if dir and not ::File.directory?(dir)
298
315
 
@@ -308,6 +325,10 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
308
325
  src_fd.close
309
326
  dst_fd.close
310
327
  end
328
+
329
+ # Clone the times from the remote file
330
+ ::File.utime(src_stat.atime, src_stat.mtime, dest_file)
331
+ return 'download'
311
332
  end
312
333
 
313
334
  #
@@ -0,0 +1,57 @@
1
+ # -*- coding: binary -*-
2
+
3
+ require 'rex/post/meterpreter/extensions/stdapi/stdapi'
4
+
5
+ module Rex
6
+ module Post
7
+ module Meterpreter
8
+ module Extensions
9
+ module Stdapi
10
+ module Fs
11
+
12
+ class Mount
13
+
14
+ # Used when matching against windows drive types
15
+ DRIVE_TYPES = [
16
+ :unknown,
17
+ :no_root,
18
+ :removable,
19
+ :fixed,
20
+ :remote,
21
+ :cdrom,
22
+ :ramdisk
23
+ ]
24
+
25
+ def initialize(client)
26
+ self.client = client
27
+ end
28
+
29
+ def show_mount
30
+ request = Packet.create_request('stdapi_fs_mount_show')
31
+
32
+ response = client.send_request(request)
33
+
34
+ results = []
35
+
36
+ response.each(TLV_TYPE_MOUNT) do |d|
37
+ results << {
38
+ name: d.get_tlv_value(TLV_TYPE_MOUNT_NAME),
39
+ type: DRIVE_TYPES[d.get_tlv_value(TLV_TYPE_MOUNT_TYPE)],
40
+ user_space: d.get_tlv_value(TLV_TYPE_MOUNT_SPACE_USER),
41
+ total_space: d.get_tlv_value(TLV_TYPE_MOUNT_SPACE_TOTAL),
42
+ free_space: d.get_tlv_value(TLV_TYPE_MOUNT_SPACE_FREE),
43
+ unc: d.get_tlv_value(TLV_TYPE_MOUNT_UNCPATH)
44
+ }
45
+ end
46
+
47
+ results
48
+ end
49
+
50
+ protected
51
+ attr_accessor :client # :nodoc:
52
+
53
+ end
54
+
55
+ end; end; end; end; end; end
56
+
57
+
@@ -2159,13 +2159,13 @@ class Def_kernel32
2159
2159
  ])
2160
2160
 
2161
2161
  dll.add_function( 'InterlockedCompareExchange', 'DWORD',[
2162
- ["PDWORD","Destination","inout"],
2162
+ ["PDWORD","Destination","in"],
2163
2163
  ["DWORD","ExChange","in"],
2164
2164
  ["DWORD","Comperand","in"],
2165
2165
  ])
2166
2166
 
2167
2167
  dll.add_function( 'InterlockedCompareExchange64', 'LPVOID',[
2168
- ["PBLOB","Destination","inout"],
2168
+ ["PBLOB","Destination","in"],
2169
2169
  ["PBLOB","ExChange","in"],
2170
2170
  ["PBLOB","Comperand","in"],
2171
2171
  ])
@@ -2175,7 +2175,7 @@ class Def_kernel32
2175
2175
  ])
2176
2176
 
2177
2177
  dll.add_function( 'InterlockedExchange', 'DWORD',[
2178
- ["PDWORD","Target","inout"],
2178
+ ["PDWORD","Target","in"],
2179
2179
  ["DWORD","Value","in"],
2180
2180
  ])
2181
2181
 
@@ -7,6 +7,7 @@ require 'rex/post/meterpreter/extensions/stdapi/tlv'
7
7
  require 'rex/post/meterpreter/extensions/stdapi/fs/dir'
8
8
  require 'rex/post/meterpreter/extensions/stdapi/fs/file'
9
9
  require 'rex/post/meterpreter/extensions/stdapi/fs/file_stat'
10
+ require 'rex/post/meterpreter/extensions/stdapi/fs/mount'
10
11
  require 'rex/post/meterpreter/extensions/stdapi/net/resolve'
11
12
  require 'rex/post/meterpreter/extensions/stdapi/net/config'
12
13
  require 'rex/post/meterpreter/extensions/stdapi/net/socket'
@@ -50,7 +51,8 @@ class Stdapi < Extension
50
51
  {
51
52
  'dir' => self.dir,
52
53
  'file' => self.file,
53
- 'filestat' => self.filestat
54
+ 'filestat' => self.filestat,
55
+ 'mount' => Fs::Mount.new(client)
54
56
  })
55
57
  },
56
58
  {
@@ -94,6 +94,8 @@ class Config
94
94
  'OS' => response.get_tlv_value(TLV_TYPE_OS_NAME),
95
95
  'Architecture' => response.get_tlv_value(TLV_TYPE_ARCHITECTURE),
96
96
  'System Language' => response.get_tlv_value(TLV_TYPE_LANG_SYSTEM),
97
+ 'Domain' => response.get_tlv_value(TLV_TYPE_DOMAIN),
98
+ 'Logged On Users' => response.get_tlv_value(TLV_TYPE_LOGGED_ON_USER_COUNT)
97
99
  }
98
100
  end
99
101