ruby_smb 2.0.2 → 2.0.3
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/examples/anonymous_auth.rb +3 -3
- data/examples/append_file.rb +10 -8
- data/examples/authenticate.rb +9 -5
- data/examples/delete_file.rb +8 -6
- data/examples/enum_registry_key.rb +5 -4
- data/examples/enum_registry_values.rb +5 -4
- data/examples/list_directory.rb +8 -6
- data/examples/negotiate_with_netbios_service.rb +9 -5
- data/examples/net_share_enum_all.rb +6 -4
- data/examples/pipes.rb +11 -12
- data/examples/query_service_status.rb +64 -0
- data/examples/read_file.rb +8 -6
- data/examples/read_registry_key_value.rb +6 -5
- data/examples/rename_file.rb +9 -7
- data/examples/tree_connect.rb +7 -5
- data/examples/write_file.rb +9 -7
- data/lib/ruby_smb/client.rb +72 -43
- data/lib/ruby_smb/client/negotiation.rb +1 -0
- data/lib/ruby_smb/dcerpc.rb +2 -0
- data/lib/ruby_smb/dcerpc/error.rb +3 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +209 -44
- data/lib/ruby_smb/dcerpc/request.rb +13 -0
- data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +9 -6
- data/lib/ruby_smb/dcerpc/svcctl.rb +479 -0
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +48 -0
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +35 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +31 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +44 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/winreg.rb +98 -17
- data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +73 -0
- data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +4 -4
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +7 -6
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +10 -10
- data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +37 -0
- data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
- data/lib/ruby_smb/dispatcher/base.rb +1 -1
- data/lib/ruby_smb/dispatcher/socket.rb +1 -1
- data/lib/ruby_smb/field/stringz16.rb +17 -1
- data/lib/ruby_smb/nbss/session_header.rb +4 -4
- data/lib/ruby_smb/smb1/file.rb +2 -10
- data/lib/ruby_smb/smb1/pipe.rb +2 -0
- data/lib/ruby_smb/smb2/file.rb +25 -17
- data/lib/ruby_smb/smb2/pipe.rb +3 -0
- data/lib/ruby_smb/smb2/tree.rb +9 -3
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +161 -60
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +1396 -77
- data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +161 -0
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +49 -12
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +191 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +78 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +59 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +72 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +46 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +512 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +110 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +0 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +9 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +0 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +17 -17
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +11 -23
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +57 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +215 -41
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +10 -10
- data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
- data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +7 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +60 -6
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +7 -0
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +35 -1
- metadata +72 -2
- metadata.gz.sig +0 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'ruby_smb/dcerpc/ndr'
|
2
|
+
|
3
|
+
module RubySMB
|
4
|
+
module Dcerpc
|
5
|
+
module Svcctl
|
6
|
+
|
7
|
+
# [3.1.4.19 RStartServiceW (Opnum 19)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-scmr/d9be95a2-cf01-4bdc-b30f-6fe4b37ada16)
|
8
|
+
class StartServiceWRequest < BinData::Record
|
9
|
+
attr_reader :opnum
|
10
|
+
|
11
|
+
endian :little
|
12
|
+
|
13
|
+
sc_rpc_handle :h_service
|
14
|
+
uint32 :argc
|
15
|
+
ndr_lp_string_ptrsw :argv
|
16
|
+
|
17
|
+
def initialize_instance
|
18
|
+
super
|
19
|
+
@opnum = START_SERVICE_W
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'ruby_smb/dcerpc/ndr'
|
2
|
+
|
3
|
+
module RubySMB
|
4
|
+
module Dcerpc
|
5
|
+
module Svcctl
|
6
|
+
|
7
|
+
# [3.1.4.19 RStartServiceW (Opnum 19)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-scmr/d9be95a2-cf01-4bdc-b30f-6fe4b37ada16)
|
8
|
+
class StartServiceWResponse < BinData::Record
|
9
|
+
attr_reader :opnum
|
10
|
+
|
11
|
+
endian :little
|
12
|
+
|
13
|
+
uint32 :error_status
|
14
|
+
|
15
|
+
def initialize_instance
|
16
|
+
super
|
17
|
+
@opnum = START_SERVICE_W
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
|
@@ -13,11 +13,13 @@ module RubySMB
|
|
13
13
|
OPEN_HKPD = 0x03
|
14
14
|
OPEN_HKU = 0x04
|
15
15
|
REG_CLOSE_KEY = 0x05
|
16
|
+
REG_CREATE_KEY = 0x06
|
16
17
|
REG_ENUM_KEY = 0x09
|
17
18
|
REG_ENUM_VALUE = 0x0a
|
18
19
|
REG_OPEN_KEY = 0x0f
|
19
20
|
REG_QUERY_INFO_KEY = 0x10
|
20
21
|
REG_QUERY_VALUE = 0x11
|
22
|
+
REG_SAVE_KEY = 0x14
|
21
23
|
OPEN_HKCC = 0x1b
|
22
24
|
OPEN_HKPT = 0x20
|
23
25
|
OPEN_HKPN = 0x21
|
@@ -37,6 +39,10 @@ module RubySMB
|
|
37
39
|
require 'ruby_smb/dcerpc/winreg/query_info_key_response'
|
38
40
|
require 'ruby_smb/dcerpc/winreg/query_value_request'
|
39
41
|
require 'ruby_smb/dcerpc/winreg/query_value_response'
|
42
|
+
require 'ruby_smb/dcerpc/winreg/create_key_request'
|
43
|
+
require 'ruby_smb/dcerpc/winreg/create_key_response'
|
44
|
+
require 'ruby_smb/dcerpc/winreg/save_key_request'
|
45
|
+
require 'ruby_smb/dcerpc/winreg/save_key_response'
|
40
46
|
|
41
47
|
ROOT_KEY_MAP = {
|
42
48
|
"HKEY_CLASSES_ROOT" => OPEN_HKCR,
|
@@ -125,7 +131,9 @@ module RubySMB
|
|
125
131
|
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
126
132
|
def query_value(handle, value_name)
|
127
133
|
query_value_request_packet = RubySMB::Dcerpc::Winreg::QueryValueRequest.new(hkey: handle, lp_value_name: value_name)
|
128
|
-
query_value_request_packet.
|
134
|
+
query_value_request_packet.lp_type = 0
|
135
|
+
query_value_request_packet.lpcb_data = 0
|
136
|
+
query_value_request_packet.lpcb_len = 0
|
129
137
|
response = dcerpc_request(query_value_request_packet)
|
130
138
|
begin
|
131
139
|
query_value_response = RubySMB::Dcerpc::Winreg::QueryValueResponse.read(response)
|
@@ -137,9 +145,9 @@ module RubySMB
|
|
137
145
|
"#{WindowsError::Win32.find_by_retval(query_value_response.error_status.value).join(',')}"
|
138
146
|
end
|
139
147
|
|
140
|
-
query_value_request_packet = RubySMB::Dcerpc::Winreg::QueryValueRequest.new(hkey: handle, lp_value_name: value_name)
|
141
148
|
query_value_request_packet.lpcb_data = query_value_response.lpcb_data
|
142
|
-
query_value_request_packet.lp_data
|
149
|
+
query_value_request_packet.lp_data = []
|
150
|
+
query_value_request_packet.lp_data.referent.max_count = query_value_response.lpcb_data.referent
|
143
151
|
response = dcerpc_request(query_value_request_packet)
|
144
152
|
begin
|
145
153
|
query_value_response = RubySMB::Dcerpc::Winreg::QueryValueResponse.read(response)
|
@@ -185,6 +193,10 @@ module RubySMB
|
|
185
193
|
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
186
194
|
def query_info_key(handle)
|
187
195
|
query_info_key_request_packet = RubySMB::Dcerpc::Winreg::QueryInfoKeyRequest.new(hkey: handle)
|
196
|
+
query_info_key_request_packet.lp_class = ''
|
197
|
+
query_info_key_request_packet.lp_class.referent.actual_count = 0
|
198
|
+
query_info_key_request_packet.lp_class.maximum_length = 1024
|
199
|
+
query_info_key_request_packet.lp_class.buffer.referent.max_count = 1024 / 2
|
188
200
|
response = dcerpc_request(query_info_key_request_packet)
|
189
201
|
begin
|
190
202
|
query_info_key_response = RubySMB::Dcerpc::Winreg::QueryInfoKeyResponse.read(response)
|
@@ -209,7 +221,9 @@ module RubySMB
|
|
209
221
|
def enum_key(handle, index)
|
210
222
|
enum_key_request_packet = RubySMB::Dcerpc::Winreg::EnumKeyRequest.new(hkey: handle, dw_index: index)
|
211
223
|
enum_key_request_packet.lpft_last_write_time = 0
|
212
|
-
enum_key_request_packet.lp_class
|
224
|
+
enum_key_request_packet.lp_class = ''
|
225
|
+
enum_key_request_packet.lp_class.referent.buffer = :null
|
226
|
+
enum_key_request_packet.lp_name.buffer = ''
|
213
227
|
enum_key_request_packet.lp_name.buffer.referent.max_count = 256
|
214
228
|
response = dcerpc_request(enum_key_request_packet)
|
215
229
|
begin
|
@@ -234,7 +248,7 @@ module RubySMB
|
|
234
248
|
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
235
249
|
def enum_value(handle, index)
|
236
250
|
enum_value_request_packet = RubySMB::Dcerpc::Winreg::EnumValueRequest.new(hkey: handle, dw_index: index)
|
237
|
-
enum_value_request_packet.
|
251
|
+
enum_value_request_packet.lp_value_name.buffer = ''
|
238
252
|
enum_value_request_packet.lp_value_name.buffer.referent.max_count = 256
|
239
253
|
response = dcerpc_request(enum_value_request_packet)
|
240
254
|
begin
|
@@ -250,13 +264,72 @@ module RubySMB
|
|
250
264
|
enum_value_response.lp_value_name.to_s
|
251
265
|
end
|
252
266
|
|
267
|
+
# Creates the specified registry key and returns a handle to the newly created key
|
268
|
+
#
|
269
|
+
# @param handle [Ndr::NdrContextHandle] the handle for the key
|
270
|
+
# @param sub_key [String] the name of the key
|
271
|
+
# @param opts [Hash] options for the CreateKeyRequest
|
272
|
+
# @return [RubySMB::Dcerpc::Winreg::PrpcHkey] the handle to the opened or created key
|
273
|
+
# @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a CreateKeyResponse packet
|
274
|
+
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
275
|
+
def create_key(handle, sub_key, opts = {})
|
276
|
+
opts = {
|
277
|
+
hkey: handle,
|
278
|
+
lp_sub_key: sub_key,
|
279
|
+
lp_class: opts[:lp_class] || :null,
|
280
|
+
dw_options: opts[:dw_options] || RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_KEY_TYPE_VOLATILE,
|
281
|
+
sam_desired: opts[:sam_desired] || RubySMB::Dcerpc::Winreg::Regsam.new(maximum: 1),
|
282
|
+
lp_security_attributes: opts[:lp_security_attributes] || RubySMB::Dcerpc::RpcSecurityAttributes.new,
|
283
|
+
lpdw_disposition: opts[:lpdw_disposition] || RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_CREATED_NEW_KEY,
|
284
|
+
}
|
285
|
+
create_key_request_packet = RubySMB::Dcerpc::Winreg::CreateKeyRequest.new(opts)
|
286
|
+
response = dcerpc_request(create_key_request_packet)
|
287
|
+
begin
|
288
|
+
create_key_response = RubySMB::Dcerpc::Winreg::CreateKeyResponse.read(response)
|
289
|
+
rescue IOError
|
290
|
+
raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the CreateKey response"
|
291
|
+
end
|
292
|
+
unless create_key_response.error_status == WindowsError::Win32::ERROR_SUCCESS
|
293
|
+
raise RubySMB::Dcerpc::Error::WinregError, "Error returned when creating key #{sub_key}: "\
|
294
|
+
"#{WindowsError::Win32.find_by_retval(create_key_response.error_status.value).join(',')}"
|
295
|
+
end
|
296
|
+
|
297
|
+
create_key_response.hkey
|
298
|
+
end
|
299
|
+
|
300
|
+
# Saves the specified key, subkeys, and values to a new file
|
301
|
+
#
|
302
|
+
# @param handle [Ndr::NdrContextHandle] the handle for the key
|
303
|
+
# @param file_name [String] the name of the registry file in which the specified key and subkeys are to be saved
|
304
|
+
# @param opts [Hash] options for the SaveKeyRequest
|
305
|
+
# @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a SaveKeyResponse packet
|
306
|
+
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
307
|
+
def save_key(handle, file_name, opts = {})
|
308
|
+
opts = {
|
309
|
+
hkey: handle,
|
310
|
+
lp_file: file_name,
|
311
|
+
lp_security_attributes: opts[:lp_security_attributes] || :null,
|
312
|
+
}
|
313
|
+
save_key_request_packet = RubySMB::Dcerpc::Winreg::SaveKeyRequest.new(opts)
|
314
|
+
response = dcerpc_request(save_key_request_packet)
|
315
|
+
begin
|
316
|
+
save_key_response = RubySMB::Dcerpc::Winreg::SaveKeyResponse.read(response)
|
317
|
+
rescue IOError
|
318
|
+
raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the SaveKeyResponse response"
|
319
|
+
end
|
320
|
+
unless save_key_response.error_status == WindowsError::Win32::ERROR_SUCCESS
|
321
|
+
raise RubySMB::Dcerpc::Error::WinregError, "Error returned when saving key to #{file_name}: "\
|
322
|
+
"#{WindowsError::Win32.find_by_retval(save_key_response.error_status.value).join(',')}"
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
253
326
|
# Checks if the specified registry key exists. It returns true if it
|
254
327
|
# exists, false otherwise.
|
255
328
|
#
|
256
329
|
# @param key [String] the registry key to check
|
257
330
|
# @return [Boolean]
|
258
|
-
def has_registry_key?(key)
|
259
|
-
bind(endpoint: RubySMB::Dcerpc::Winreg)
|
331
|
+
def has_registry_key?(key, bind: true)
|
332
|
+
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
260
333
|
|
261
334
|
root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
|
262
335
|
begin
|
@@ -265,8 +338,10 @@ module RubySMB
|
|
265
338
|
rescue RubySMB::Dcerpc::Error::WinregError
|
266
339
|
return false
|
267
340
|
end
|
268
|
-
close_key(subkey_handle)
|
269
341
|
return true
|
342
|
+
ensure
|
343
|
+
close_key(subkey_handle) if subkey_handle
|
344
|
+
close_key(root_key_handle) if root_key_handle
|
270
345
|
end
|
271
346
|
|
272
347
|
# Retrieve the data associated with the named value of a specified
|
@@ -275,15 +350,17 @@ module RubySMB
|
|
275
350
|
# @param key [String] the registry key
|
276
351
|
# @param value_name [String] the name of the value to read
|
277
352
|
# @return [String] the data of the value entry
|
278
|
-
def read_registry_key_value(key, value_name)
|
279
|
-
bind(endpoint: RubySMB::Dcerpc::Winreg)
|
353
|
+
def read_registry_key_value(key, value_name, bind: true)
|
354
|
+
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
280
355
|
|
281
356
|
root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
|
282
357
|
root_key_handle = open_root_key(root_key)
|
283
358
|
subkey_handle = open_key(root_key_handle, sub_key)
|
284
359
|
value = query_value(subkey_handle, value_name)
|
285
|
-
close_key(subkey_handle)
|
286
360
|
value
|
361
|
+
ensure
|
362
|
+
close_key(subkey_handle) if subkey_handle
|
363
|
+
close_key(root_key_handle) if root_key_handle
|
287
364
|
end
|
288
365
|
|
289
366
|
# Enumerate the subkeys of a specified registry key. If only a root key
|
@@ -291,8 +368,8 @@ module RubySMB
|
|
291
368
|
#
|
292
369
|
# @param key [String] the registry key
|
293
370
|
# @return [Array<String>] the subkeys
|
294
|
-
def enum_registry_key(key)
|
295
|
-
bind(endpoint: RubySMB::Dcerpc::Winreg)
|
371
|
+
def enum_registry_key(key, bind: true)
|
372
|
+
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
296
373
|
|
297
374
|
root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
|
298
375
|
root_key_handle = open_root_key(root_key)
|
@@ -307,16 +384,18 @@ module RubySMB
|
|
307
384
|
key_count.times do |i|
|
308
385
|
enum_result << enum_key(subkey_handle, i)
|
309
386
|
end
|
310
|
-
close_key(subkey_handle)
|
311
387
|
enum_result
|
388
|
+
ensure
|
389
|
+
close_key(subkey_handle) if subkey_handle
|
390
|
+
close_key(root_key_handle) if root_key_handle
|
312
391
|
end
|
313
392
|
|
314
393
|
# Enumerate the values for the specified registry key.
|
315
394
|
#
|
316
395
|
# @param key [String] the registry key
|
317
396
|
# @return [Array<String>] the values
|
318
|
-
def enum_registry_values(key)
|
319
|
-
bind(endpoint: RubySMB::Dcerpc::Winreg)
|
397
|
+
def enum_registry_values(key, bind: true)
|
398
|
+
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
320
399
|
|
321
400
|
root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
|
322
401
|
root_key_handle = open_root_key(root_key)
|
@@ -331,8 +410,10 @@ module RubySMB
|
|
331
410
|
value_count.times do |i|
|
332
411
|
enum_result << enum_value(subkey_handle, i)
|
333
412
|
end
|
334
|
-
close_key(subkey_handle)
|
335
413
|
enum_result
|
414
|
+
ensure
|
415
|
+
close_key(subkey_handle) if subkey_handle
|
416
|
+
close_key(root_key_handle) if root_key_handle
|
336
417
|
end
|
337
418
|
|
338
419
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Winreg
|
4
|
+
|
5
|
+
class RpcHkey < Ndr::NdrContextHandle; end
|
6
|
+
|
7
|
+
# This class represents a BaseRegCreateKey Request Packet as defined in
|
8
|
+
# [3.1.5.7 BaseRegCreateKey (Opnum 6)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/c7186ae2-1c82-45e9-933b-97d9873657e8)
|
9
|
+
class CreateKeyRequest < BinData::Record
|
10
|
+
# Options:
|
11
|
+
# bitwise OR of one of the key types (REG_KEY_TYPE_*), and any or none
|
12
|
+
# of the other options:
|
13
|
+
#
|
14
|
+
# This key is not volatile. The key and all its values MUST be
|
15
|
+
# persisted to the backing store and is preserved when the registry
|
16
|
+
# server loses context due to a computer restart, reboot, or shut down
|
17
|
+
# process.
|
18
|
+
REG_KEY_TYPE_NON_VOLATILE = 0x00000000
|
19
|
+
# This key is volatile. The key with all its subkeys and values MUST
|
20
|
+
# NOT be preserved when the registry server loses context due to a
|
21
|
+
# computer restart, reboot, or shut down process.
|
22
|
+
REG_KEY_TYPE_VOLATILE = 0x00000001
|
23
|
+
# This key is a symbolic link to another key.
|
24
|
+
REG_KEY_TYPE_SYMLINK = 0x00000002
|
25
|
+
# Indicates that the caller wishes to assert its backup and/or restore
|
26
|
+
# privileges.
|
27
|
+
REG_OPTION_BACKUP_RESTORE = 0x00000004
|
28
|
+
# Indicates that the caller wishes to open the targeted symlink source
|
29
|
+
# rather than the symlink target.
|
30
|
+
REG_OPTION_OPEN_LINK = 0x00000008
|
31
|
+
# Indicates that the caller wishes to disable limited user access
|
32
|
+
# virtualization for this operation.
|
33
|
+
REG_OPTION_DONT_VIRTUALIZE = 0x00000010
|
34
|
+
|
35
|
+
|
36
|
+
# Create disposition:
|
37
|
+
# The key did not exist and was created.
|
38
|
+
REG_CREATED_NEW_KEY = 0x00000001
|
39
|
+
# The key already existed and was opened without being changed.
|
40
|
+
REG_OPENED_EXISTING_KEY = 0x00000002
|
41
|
+
|
42
|
+
attr_reader :opnum
|
43
|
+
|
44
|
+
endian :little
|
45
|
+
|
46
|
+
rpc_hkey :hkey
|
47
|
+
rrp_unicode_string :lp_sub_key
|
48
|
+
string :pad1, length: -> { pad_length(self.lp_sub_key) }
|
49
|
+
rrp_unicode_string :lp_class
|
50
|
+
string :pad2, length: -> { pad_length(self.lp_class) }
|
51
|
+
uint32 :dw_options
|
52
|
+
regsam :sam_desired
|
53
|
+
prpc_security_attributes :lp_security_attributes
|
54
|
+
string :pad3, length: -> { pad_length(self.lp_security_attributes) }
|
55
|
+
ndr_lp_dword :lpdw_disposition
|
56
|
+
|
57
|
+
def initialize_instance
|
58
|
+
super
|
59
|
+
@opnum = REG_CREATE_KEY
|
60
|
+
end
|
61
|
+
|
62
|
+
# Determines the correct length for the padding, so that the next
|
63
|
+
# field is 4-byte aligned.
|
64
|
+
def pad_length(prev_element)
|
65
|
+
offset = (prev_element.abs_offset + prev_element.to_binary_s.length) % 4
|
66
|
+
(4 - offset) % 4
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Winreg
|
4
|
+
|
5
|
+
class PrpcHkey < Ndr::NdrContextHandle; end
|
6
|
+
|
7
|
+
# This class represents a BaseRegCreateKey Response Packet as defined in
|
8
|
+
# [3.1.5.7 BaseRegCreateKey (Opnum 6)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/c7186ae2-1c82-45e9-933b-97d9873657e8)
|
9
|
+
class CreateKeyResponse < BinData::Record
|
10
|
+
# Create disposition
|
11
|
+
# The key did not exist and was created.
|
12
|
+
REG_CREATED_NEW_KEY = 0x00000001
|
13
|
+
# The key already existed and was opened without being changed.
|
14
|
+
REG_OPENED_EXISTING_KEY = 0x00000002
|
15
|
+
|
16
|
+
attr_reader :opnum
|
17
|
+
|
18
|
+
endian :little
|
19
|
+
|
20
|
+
prpc_hkey :hkey
|
21
|
+
ndr_lp_dword :lpdw_disposition
|
22
|
+
uint32 :error_status
|
23
|
+
|
24
|
+
def initialize_instance
|
25
|
+
super
|
26
|
+
@opnum = REG_CREATE_KEY
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
|
@@ -4,10 +4,10 @@ module RubySMB
|
|
4
4
|
|
5
5
|
# This class represents a PREGISTRY_SERVER_NAME structure as defined in
|
6
6
|
# [2.2.2 PREGISTRY_SERVER_NAME](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/8bcd15fd-1aa5-44e2-8662-112ec3e9817b)
|
7
|
-
class PRegistryServerName < Ndr::
|
7
|
+
class PRegistryServerName < Ndr::NdrPointer
|
8
8
|
endian :little
|
9
9
|
|
10
|
-
string16 :referent, read_length: -> { 4 }
|
10
|
+
string16 :referent, onlyif: -> { self.referent_id != 0 }, read_length: -> { 4 }
|
11
11
|
end
|
12
12
|
|
13
13
|
# This class is a generic class that represents OpenXXX Request packet,
|
@@ -33,8 +33,8 @@ module RubySMB
|
|
33
33
|
def initialize_instance
|
34
34
|
super
|
35
35
|
@opnum = get_parameter(:opnum) if has_parameter?(:opnum)
|
36
|
-
p_registry_server_name
|
37
|
-
sam_desired.maximum = 1 unless [OPEN_HKPD, OPEN_HKPT, OPEN_HKPN].include?(@opnum)
|
36
|
+
self.p_registry_server_name = :null
|
37
|
+
self.sam_desired.maximum = 1 unless [OPEN_HKPD, OPEN_HKPT, OPEN_HKPN].include?(@opnum)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|