ruby_smb 2.0.1 → 2.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -1
- 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 +81 -48
- data/lib/ruby_smb/client/authentication.rb +5 -10
- data/lib/ruby_smb/client/echo.rb +2 -4
- data/lib/ruby_smb/client/negotiation.rb +21 -14
- data/lib/ruby_smb/client/tree_connect.rb +2 -4
- data/lib/ruby_smb/client/utils.rb +16 -10
- data/lib/ruby_smb/client/winreg.rb +1 -1
- data/lib/ruby_smb/dcerpc.rb +4 -0
- data/lib/ruby_smb/dcerpc/error.rb +3 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +306 -44
- data/lib/ruby_smb/dcerpc/netlogon.rb +101 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +28 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/request.rb +19 -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/error.rb +21 -5
- data/lib/ruby_smb/field/stringz16.rb +17 -1
- data/lib/ruby_smb/generic_packet.rb +11 -1
- data/lib/ruby_smb/nbss/session_header.rb +4 -4
- data/lib/ruby_smb/smb1/file.rb +10 -25
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +1 -2
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +1 -13
- data/lib/ruby_smb/smb1/pipe.rb +8 -6
- data/lib/ruby_smb/smb1/tree.rb +13 -9
- data/lib/ruby_smb/smb2/file.rb +33 -33
- data/lib/ruby_smb/smb2/pipe.rb +9 -6
- data/lib/ruby_smb/smb2/tree.rb +21 -11
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +195 -101
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +1396 -77
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +69 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response_spec.rb +53 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +69 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response_spec.rb +37 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +45 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +37 -0
- 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 +227 -41
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +10 -10
- data/spec/lib/ruby_smb/error_spec.rb +34 -5
- data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
- data/spec/lib/ruby_smb/generic_packet_spec.rb +7 -0
- data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
- data/spec/lib/ruby_smb/smb1/file_spec.rb +2 -4
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +0 -5
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +0 -6
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +30 -5
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +22 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +61 -9
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +9 -5
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +58 -1
- metadata +91 -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 && root_key_handle != subkey_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 && root_key_handle != subkey_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
|
|