ruby_smb 1.0.5 → 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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +3 -2
- data/Gemfile +6 -2
- data/README.md +35 -47
- 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 +29 -0
- data/examples/enum_registry_values.rb +31 -0
- data/examples/list_directory.rb +8 -6
- data/examples/negotiate.rb +51 -8
- data/examples/negotiate_with_netbios_service.rb +9 -5
- data/examples/net_share_enum_all.rb +6 -4
- data/examples/pipes.rb +13 -13
- data/examples/query_service_status.rb +64 -0
- data/examples/read_file.rb +8 -6
- data/examples/read_file_encryption.rb +56 -0
- data/examples/read_registry_key_value.rb +33 -0
- 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.rb +4 -1
- data/lib/ruby_smb/client.rb +239 -21
- data/lib/ruby_smb/client/authentication.rb +27 -8
- data/lib/ruby_smb/client/encryption.rb +62 -0
- data/lib/ruby_smb/client/negotiation.rb +154 -12
- data/lib/ruby_smb/client/signing.rb +19 -0
- data/lib/ruby_smb/client/tree_connect.rb +4 -4
- data/lib/ruby_smb/client/utils.rb +8 -7
- data/lib/ruby_smb/client/winreg.rb +46 -0
- data/lib/ruby_smb/crypto.rb +30 -0
- data/lib/ruby_smb/dcerpc.rb +40 -0
- data/lib/ruby_smb/dcerpc/bind.rb +2 -2
- data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
- data/lib/ruby_smb/dcerpc/error.rb +6 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +260 -16
- data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
- data/lib/ruby_smb/dcerpc/request.rb +41 -9
- data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +38 -0
- data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
- data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
- 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 +421 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
- 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 +45 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
- data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
- data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +40 -0
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
- data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
- 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 +5 -4
- data/lib/ruby_smb/error.rb +28 -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/commands.rb +1 -1
- data/lib/ruby_smb/smb1/file.rb +8 -14
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +2 -2
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -2
- data/lib/ruby_smb/smb1/packet/write_andx_request.rb +1 -1
- data/lib/ruby_smb/smb1/pipe.rb +81 -3
- data/lib/ruby_smb/smb1/tree.rb +12 -3
- data/lib/ruby_smb/smb2/bit_field/session_flags.rb +2 -1
- data/lib/ruby_smb/smb2/bit_field/share_flags.rb +6 -4
- data/lib/ruby_smb/smb2/file.rb +51 -61
- data/lib/ruby_smb/smb2/negotiate_context.rb +108 -0
- data/lib/ruby_smb/smb2/packet.rb +2 -0
- data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +41 -0
- data/lib/ruby_smb/smb2/packet/error_packet.rb +2 -4
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +51 -14
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +50 -4
- data/lib/ruby_smb/smb2/packet/transform_header.rb +84 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +92 -6
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +8 -26
- data/lib/ruby_smb/smb2/pipe.rb +80 -3
- data/lib/ruby_smb/smb2/smb2_header.rb +1 -1
- data/lib/ruby_smb/smb2/tree.rb +32 -20
- data/lib/ruby_smb/version.rb +1 -1
- data/ruby_smb.gemspec +5 -3
- data/spec/lib/ruby_smb/client_spec.rb +1583 -102
- data/spec/lib/ruby_smb/crypto_spec.rb +25 -0
- data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +1729 -0
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
- data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +161 -0
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +135 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
- 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/close_key_request_spec.rb +28 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -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 +104 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +95 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +35 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +138 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
- 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 +884 -0
- data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +12 -12
- data/spec/lib/ruby_smb/error_spec.rb +59 -0
- 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/file_spec.rb +9 -1
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +216 -147
- data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +9 -0
- data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +27 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +146 -68
- data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +332 -0
- data/spec/lib/ruby_smb/smb2/packet/compression_transform_header_spec.rb +108 -0
- data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +3 -24
- data/spec/lib/ruby_smb/smb2/packet/negotiate_request_spec.rb +138 -3
- data/spec/lib/ruby_smb/smb2/packet/negotiate_response_spec.rb +120 -2
- data/spec/lib/ruby_smb/smb2/packet/transform_header_spec.rb +220 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +339 -9
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +3 -30
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +226 -148
- data/spec/lib/ruby_smb/smb2/smb2_header_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +88 -9
- metadata +257 -81
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/smb1/dcerpc.rb +0 -72
- data/lib/ruby_smb/smb2/dcerpc.rb +0 -75
@@ -0,0 +1,27 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Winreg
|
4
|
+
|
5
|
+
class RpcHkey < Ndr::NdrContextHandle; end
|
6
|
+
|
7
|
+
# This class represents a BaseRegQueryInfoKey Request Packet as defined in
|
8
|
+
# [3.1.5.16 BaseRegQueryInfoKey (Opnum 16)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/a886ba66-5c7b-4331-bacd-7c77edc95d85)
|
9
|
+
class QueryInfoKeyRequest < BinData::Record
|
10
|
+
attr_reader :opnum
|
11
|
+
|
12
|
+
endian :little
|
13
|
+
|
14
|
+
rpc_hkey :hkey
|
15
|
+
rrp_unicode_string :lp_class
|
16
|
+
|
17
|
+
def initialize_instance
|
18
|
+
super
|
19
|
+
@opnum = REG_QUERY_INFO_KEY
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Winreg
|
4
|
+
# This class represents a BaseRegQueryInfoKey Response Packet as defined in
|
5
|
+
# [3.1.5.16 BaseRegQueryInfoKey (Opnum 16)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/a886ba66-5c7b-4331-bacd-7c77edc95d85)
|
6
|
+
class QueryInfoKeyResponse < BinData::Record
|
7
|
+
attr_reader :opnum
|
8
|
+
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
rrp_unicode_string :lp_class, initial_value: 0
|
12
|
+
string :pad, length: -> { pad_length }
|
13
|
+
uint32 :lpc_sub_keys
|
14
|
+
uint32 :lpc_max_sub_key_len
|
15
|
+
uint32 :lpc_max_class_len
|
16
|
+
uint32 :lpc_values
|
17
|
+
uint32 :lpcb_max_value_name_len
|
18
|
+
uint32 :lpcb_max_value_len
|
19
|
+
uint32 :lpcb_security_descriptor
|
20
|
+
file_time :lpft_last_write_time
|
21
|
+
uint32 :error_status
|
22
|
+
|
23
|
+
def initialize_instance
|
24
|
+
super
|
25
|
+
@opnum = REG_QUERY_INFO_KEY
|
26
|
+
end
|
27
|
+
|
28
|
+
# Determines the correct length for the padding in front of
|
29
|
+
# #lpc_sub_keys. It should always force a 4-byte alignment.
|
30
|
+
def pad_length
|
31
|
+
offset = (lp_class.abs_offset + lp_class.to_binary_s.length) % 4
|
32
|
+
(4 - offset) % 4
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Winreg
|
4
|
+
|
5
|
+
class RpcHkey < Ndr::NdrContextHandle; end
|
6
|
+
|
7
|
+
# This class represents a BaseRegQueryValue Request Packet as defined in
|
8
|
+
# [3.1.5.17 BaseRegQueryValue (Opnum 17)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/8bc10aa3-2f91-44e8-aa33-b3263c49ab9d)
|
9
|
+
class QueryValueRequest < BinData::Record
|
10
|
+
attr_reader :opnum
|
11
|
+
|
12
|
+
endian :little
|
13
|
+
|
14
|
+
rpc_hkey :hkey
|
15
|
+
rrp_unicode_string :lp_value_name
|
16
|
+
string :pad1, length: -> { pad_length(self.lp_value_name) }
|
17
|
+
ndr_lp_dword :lp_type
|
18
|
+
ndr_lp_byte_array :lp_data
|
19
|
+
string :pad2, length: -> { pad_length(self.lp_data) }
|
20
|
+
ndr_lp_dword :lpcb_data
|
21
|
+
ndr_lp_dword :lpcb_len
|
22
|
+
|
23
|
+
def initialize_instance
|
24
|
+
super
|
25
|
+
@opnum = REG_QUERY_VALUE
|
26
|
+
end
|
27
|
+
|
28
|
+
# Determines the correct length for the padding, so that the next
|
29
|
+
# field is 4-byte aligned.
|
30
|
+
def pad_length(prev_element)
|
31
|
+
offset = (prev_element.abs_offset + prev_element.to_binary_s.length) % 4
|
32
|
+
(4 - offset) % 4
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Winreg
|
4
|
+
|
5
|
+
# This class represents a BaseRegQueryValue Response Packet as defined in
|
6
|
+
# [3.1.5.17 BaseRegQueryValue (Opnum 17)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/8bc10aa3-2f91-44e8-aa33-b3263c49ab9d)
|
7
|
+
class QueryValueResponse < BinData::Record
|
8
|
+
attr_reader :opnum
|
9
|
+
|
10
|
+
endian :little
|
11
|
+
|
12
|
+
ndr_lp_dword :lp_type
|
13
|
+
ndr_lp_byte_array :lp_data
|
14
|
+
string :pad, length: -> { pad_length(self.lp_data) }
|
15
|
+
ndr_lp_dword :lpcb_data
|
16
|
+
ndr_lp_dword :lpcb_len
|
17
|
+
uint32 :error_status
|
18
|
+
|
19
|
+
def initialize_instance
|
20
|
+
super
|
21
|
+
@opnum = REG_QUERY_VALUE
|
22
|
+
end
|
23
|
+
|
24
|
+
# Determines the correct length for the padding, so that the next
|
25
|
+
# field is 4-byte aligned.
|
26
|
+
def pad_length(prev_element)
|
27
|
+
offset = (prev_element.abs_offset + prev_element.to_binary_s.length) % 4
|
28
|
+
(4 - offset) % 4
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the data portion of the registry value formatted according to its type:
|
32
|
+
# [3.1.1.5 Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/3d64dbea-f016-4373-8cac-e43bf343837d)
|
33
|
+
def data
|
34
|
+
bytes = lp_data.bytes.to_a.pack('C*')
|
35
|
+
case lp_type
|
36
|
+
when 1,2
|
37
|
+
bytes.force_encoding('utf-16le').strip
|
38
|
+
when 3
|
39
|
+
bytes
|
40
|
+
when 4
|
41
|
+
bytes.unpack('V').first
|
42
|
+
when 5
|
43
|
+
bytes.unpack('N').first
|
44
|
+
when 7
|
45
|
+
str = bytes.force_encoding('utf-16le')
|
46
|
+
str.split("\0".encode('utf-16le'))
|
47
|
+
when 11
|
48
|
+
bytes.unpack('Q<').first
|
49
|
+
else
|
50
|
+
""
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Winreg
|
4
|
+
|
5
|
+
# This class represents a REGSAM structure as defined in
|
6
|
+
# [2.2.3 REGSAM](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/fefbc801-b141-4bb1-9dcb-bf366da3ae7e)
|
7
|
+
# [2.4.3 ACCESS_MASK](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b)
|
8
|
+
class Regsam < BinData::Record
|
9
|
+
endian :little
|
10
|
+
bit2 :reserved, label: 'Reserved Space'
|
11
|
+
bit1 :key_create_link, label: 'Key Create Link'
|
12
|
+
bit1 :key_notify, label: 'Key Notify'
|
13
|
+
bit1 :key_enumerate_sub_keys, label: 'Key Enumerate Sub Keys'
|
14
|
+
bit1 :key_create_sub_key, label: 'Key Create Sub Key'
|
15
|
+
bit1 :key_set_value, label: 'Key Set Value'
|
16
|
+
bit1 :key_query_value, label: 'Key Query Value'
|
17
|
+
# byte boundary
|
18
|
+
bit6 :reserved2, label: 'Reserved Space'
|
19
|
+
bit1 :key_wow64_32key, label: 'Key Wow64 32key'
|
20
|
+
bit1 :key_wow64_64key, label: 'Key Wow64 64key'
|
21
|
+
# byte boundary
|
22
|
+
bit3 :reserved3, label: 'Reserved Space'
|
23
|
+
bit1 :synchronize, label: 'Synchronize'
|
24
|
+
bit1 :write_owner, label: 'Write Owner'
|
25
|
+
bit1 :write_dac, label: 'Write DAC'
|
26
|
+
bit1 :read_control, label: 'Read Control'
|
27
|
+
bit1 :delete_access, label: 'Delete'
|
28
|
+
# byte boundary
|
29
|
+
bit1 :generic_read, label: 'Generic Read'
|
30
|
+
bit1 :generic_write, label: 'Generic Write'
|
31
|
+
bit1 :generic_execute, label: 'Generic Execute'
|
32
|
+
bit1 :generic_all, label: 'Generic All'
|
33
|
+
bit2 :reserved4, label: 'Reserved Space'
|
34
|
+
bit1 :maximum, label: 'Maximum Allowed'
|
35
|
+
bit1 :system_security, label: 'System Security'
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Winreg
|
4
|
+
|
5
|
+
class RpcHkey < Ndr::NdrContextHandle; end
|
6
|
+
|
7
|
+
# This class represents a BaseRegSaveKey Request Packet as defined in
|
8
|
+
# [3.1.5.20 BaseRegSaveKey (Opnum 20)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/f022247d-6ef1-4f46-b195-7f60654f4a0d)
|
9
|
+
class SaveKeyRequest < BinData::Record
|
10
|
+
attr_reader :opnum
|
11
|
+
|
12
|
+
endian :little
|
13
|
+
|
14
|
+
rpc_hkey :hkey
|
15
|
+
rrp_unicode_string :lp_file
|
16
|
+
string :pad, length: -> { pad_length(self.lp_file) }
|
17
|
+
prpc_security_attributes :lp_security_attributes
|
18
|
+
|
19
|
+
def initialize_instance
|
20
|
+
super
|
21
|
+
@opnum = REG_SAVE_KEY
|
22
|
+
end
|
23
|
+
|
24
|
+
# Determines the correct length for the padding, so that the next
|
25
|
+
# field is 4-byte aligned.
|
26
|
+
def pad_length(prev_element)
|
27
|
+
offset = (prev_element.abs_offset + prev_element.to_binary_s.length) % 4
|
28
|
+
(4 - offset) % 4
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Winreg
|
4
|
+
|
5
|
+
# This class represents a BaseRegSaveKey Response Packet as defined in
|
6
|
+
# [3.1.5.20 BaseRegSaveKey (Opnum 20)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/f022247d-6ef1-4f46-b195-7f60654f4a0d)
|
7
|
+
class SaveKeyResponse < BinData::Record
|
8
|
+
attr_reader :opnum
|
9
|
+
|
10
|
+
endian :little
|
11
|
+
|
12
|
+
uint32 :error_status
|
13
|
+
|
14
|
+
def initialize_instance
|
15
|
+
super
|
16
|
+
@opnum = REG_CREATE_KEY
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -9,7 +9,7 @@ module RubySMB
|
|
9
9
|
def nbss(packet)
|
10
10
|
nbss = RubySMB::Nbss::SessionHeader.new
|
11
11
|
nbss.session_packet_type = RubySMB::Nbss::SESSION_MESSAGE
|
12
|
-
nbss.
|
12
|
+
nbss.stream_protocol_length = packet.do_num_bytes
|
13
13
|
nbss.to_binary_s
|
14
14
|
end
|
15
15
|
|
@@ -48,7 +48,7 @@ module RubySMB
|
|
48
48
|
end
|
49
49
|
|
50
50
|
rescue IOError, Errno::ECONNABORTED, Errno::ECONNRESET => e
|
51
|
-
raise RubySMB::Error::CommunicationError, "An error
|
51
|
+
raise RubySMB::Error::CommunicationError, "An error occurred writing to the Socket: #{e.message}"
|
52
52
|
end
|
53
53
|
nil
|
54
54
|
end
|
@@ -61,19 +61,20 @@ module RubySMB
|
|
61
61
|
# which are assumed to be the NetBiosSessionService header.
|
62
62
|
# @raise [RubySMB::Error::CommunicationError] if the read timeout expires or an error occurs when reading the socket
|
63
63
|
def recv_packet(full_response: false)
|
64
|
+
raise RubySMB::Error::CommunicationError, 'Connection has already been closed' if @tcp_socket.closed?
|
64
65
|
if IO.select([@tcp_socket], nil, nil, @read_timeout).nil?
|
65
66
|
raise RubySMB::Error::CommunicationError, "Read timeout expired when reading from the Socket (timeout=#{@read_timeout})"
|
66
67
|
end
|
67
68
|
|
68
69
|
begin
|
69
70
|
nbss_data = @tcp_socket.read(4)
|
70
|
-
raise
|
71
|
+
raise RubySMB::Error::CommunicationError, 'Socket read returned nil' if nbss_data.nil?
|
71
72
|
nbss_header = RubySMB::Nbss::SessionHeader.read(nbss_data)
|
72
73
|
rescue IOError
|
73
74
|
raise ::RubySMB::Error::NetBiosSessionService, 'NBSS Header is missing'
|
74
75
|
end
|
75
76
|
|
76
|
-
length = nbss_header.
|
77
|
+
length = nbss_header.stream_protocol_length
|
77
78
|
data = full_response ? nbss_header.to_binary_s : ''
|
78
79
|
if length > 0
|
79
80
|
if IO.select([@tcp_socket], nil, nil, @read_timeout).nil?
|
@@ -84,7 +85,7 @@ module RubySMB
|
|
84
85
|
end
|
85
86
|
data
|
86
87
|
rescue Errno::EINVAL, Errno::ECONNABORTED, Errno::ECONNRESET, TypeError, NoMethodError => e
|
87
|
-
raise RubySMB::Error::CommunicationError, "An error
|
88
|
+
raise RubySMB::Error::CommunicationError, "An error occurred reading from the Socket #{e.message}"
|
88
89
|
end
|
89
90
|
end
|
90
91
|
end
|
data/lib/ruby_smb/error.rb
CHANGED
@@ -53,7 +53,28 @@ module RubySMB
|
|
53
53
|
end
|
54
54
|
|
55
55
|
# Raised when a response packet has a NTStatus code that was unexpected.
|
56
|
-
class UnexpectedStatusCode < RubySMBError
|
56
|
+
class UnexpectedStatusCode < RubySMBError
|
57
|
+
attr_reader :status_code
|
58
|
+
|
59
|
+
def initialize(status_code)
|
60
|
+
case status_code
|
61
|
+
when WindowsError::ErrorCode
|
62
|
+
@status_code = status_code
|
63
|
+
when Integer
|
64
|
+
@status_code = WindowsError::NTStatus.find_by_retval(status_code).first
|
65
|
+
if @status_code.nil?
|
66
|
+
@status_code = WindowsError::ErrorCode.new("0x#{status_code.to_s(16)}", status_code, "Unknown 0x#{status_code.to_s(16)}")
|
67
|
+
end
|
68
|
+
else
|
69
|
+
raise ArgumentError, "Status code must be a WindowsError::ErrorCode or an Integer, got #{status_code.class}"
|
70
|
+
end
|
71
|
+
super
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_s
|
75
|
+
"The server responded with an unexpected status code: #{status_code.name}"
|
76
|
+
end
|
77
|
+
end
|
57
78
|
|
58
79
|
# Raised when an error occurs with the underlying socket.
|
59
80
|
class CommunicationError < RubySMBError; end
|
@@ -65,5 +86,11 @@ module RubySMB
|
|
65
86
|
# Raised when trying to parse raw binary into a BitField and the data
|
66
87
|
# is invalid.
|
67
88
|
class InvalidBitField < RubySMBError; end
|
89
|
+
|
90
|
+
# Raised when an encryption operation fails
|
91
|
+
class EncryptionError < RubySMBError; end
|
92
|
+
|
93
|
+
# Raised when an signing operation fails
|
94
|
+
class SigningError < RubySMBError; end
|
68
95
|
end
|
69
96
|
end
|
@@ -25,12 +25,17 @@ module RubySMB
|
|
25
25
|
# @see BinData::Stringz
|
26
26
|
def read_and_return_value(io)
|
27
27
|
max_length = eval_parameter(:max_length)
|
28
|
+
if max_length && max_length % 2 != 0
|
29
|
+
raise ArgumentError, "[Stringz16] #max_length should be a multiple of "\
|
30
|
+
"two, since it is Unicode (got #{max_length})"
|
31
|
+
end
|
28
32
|
str = ''
|
29
33
|
i = 0
|
30
34
|
ch = nil
|
31
35
|
|
32
36
|
# read until double NULL-byte or we have read in the max number of bytes
|
33
|
-
|
37
|
+
loop do
|
38
|
+
break if ch == "\0\0" || (max_length && i == max_length)
|
34
39
|
ch = io.readbytes(2)
|
35
40
|
str << ch
|
36
41
|
i += 2
|
@@ -46,6 +51,17 @@ module RubySMB
|
|
46
51
|
def truncate_after_first_zero_byte!(str)
|
47
52
|
str.sub!(/([^\0]*\0\0\0).*/, '\1')
|
48
53
|
end
|
54
|
+
|
55
|
+
def trim_to!(str, max_length = nil)
|
56
|
+
if max_length
|
57
|
+
max_length = 2 if max_length < 2
|
58
|
+
str.slice!(max_length..-1)
|
59
|
+
if str.length == max_length && str[-2, 2] != "\0\0"
|
60
|
+
str[-2, 2] = "\0\0"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
49
65
|
end
|
50
66
|
end
|
51
67
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module RubySMB
|
2
2
|
module Nbss
|
3
3
|
# Representation of the NetBIOS Session Service Header as defined in
|
4
|
-
# [
|
4
|
+
# SMB: [2.1 Transport](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb/f906c680-330c-43ae-9a71-f854e24aeee6)
|
5
|
+
# SMB2: [2.1 Transport](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/1dfacde4-b5c7-4494-8a14-a09d3ab4cc83)
|
5
6
|
class SessionHeader < BinData::Record
|
6
7
|
endian :big
|
7
8
|
|
8
|
-
uint8
|
9
|
-
|
10
|
-
bit17 :packet_length, label: 'Packet Length'
|
9
|
+
uint8 :session_packet_type, label: 'Session Packet Type', initial_value: 0
|
10
|
+
uint24 :stream_protocol_length, label: 'Stream Protocol Length'
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -10,7 +10,7 @@ module RubySMB
|
|
10
10
|
SMB_COM_TRANSACTION2_SECONDARY = 0x33
|
11
11
|
SMB_COM_TREE_DISCONNECT = 0x71
|
12
12
|
SMB_COM_NEGOTIATE = 0x72
|
13
|
-
|
13
|
+
SMB_COM_SESSION_SETUP_ANDX = 0x73
|
14
14
|
SMB_COM_LOGOFF = 0x74
|
15
15
|
SMB_COM_TREE_CONNECT = 0x75
|
16
16
|
SMB_COM_NT_TRANSACT = 0xA0
|
data/lib/ruby_smb/smb1/file.rb
CHANGED
@@ -91,7 +91,7 @@ module RubySMB
|
|
91
91
|
)
|
92
92
|
end
|
93
93
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
94
|
-
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
94
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
95
95
|
end
|
96
96
|
response.status_code
|
97
97
|
end
|
@@ -106,11 +106,7 @@ module RubySMB
|
|
106
106
|
# @raise [RubySMB::Error::InvalidPacket] if the response packet is not valid
|
107
107
|
# @raise [RubySMB::Error::UnexpectedStatusCode] if the response NTStatus is not STATUS_SUCCESS
|
108
108
|
def read(bytes: @size, offset: 0)
|
109
|
-
atomic_read_size =
|
110
|
-
@tree.client.max_buffer_size
|
111
|
-
else
|
112
|
-
bytes
|
113
|
-
end
|
109
|
+
atomic_read_size = [bytes, @tree.client.max_buffer_size].min
|
114
110
|
remaining_bytes = bytes
|
115
111
|
data = ''
|
116
112
|
|
@@ -127,7 +123,7 @@ module RubySMB
|
|
127
123
|
)
|
128
124
|
end
|
129
125
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
130
|
-
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
126
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
131
127
|
end
|
132
128
|
|
133
129
|
if response.is_a?(RubySMB::SMB1::Packet::ReadAndxResponse)
|
@@ -156,6 +152,8 @@ module RubySMB
|
|
156
152
|
def read_packet(read_length: 0, offset: 0)
|
157
153
|
read_request = set_header_fields(RubySMB::SMB1::Packet::ReadAndxRequest.new)
|
158
154
|
read_request.parameter_block.max_count_of_bytes_to_return = read_length
|
155
|
+
read_request.parameter_block.min_count_of_bytes_to_return = read_length
|
156
|
+
read_request.parameter_block.remaining = read_length
|
159
157
|
read_request.parameter_block.offset = offset
|
160
158
|
read_request
|
161
159
|
end
|
@@ -174,7 +172,7 @@ module RubySMB
|
|
174
172
|
)
|
175
173
|
end
|
176
174
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
177
|
-
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
175
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
178
176
|
end
|
179
177
|
|
180
178
|
response.data_block.data.to_binary_s
|
@@ -225,11 +223,7 @@ module RubySMB
|
|
225
223
|
total_bytes_written = 0
|
226
224
|
|
227
225
|
loop do
|
228
|
-
atomic_write_size =
|
229
|
-
@tree.client.max_buffer_size
|
230
|
-
else
|
231
|
-
bytes
|
232
|
-
end
|
226
|
+
atomic_write_size = [bytes, @tree.client.max_buffer_size].min
|
233
227
|
write_request = write_packet(data: buffer.slice!(0, atomic_write_size), offset: offset)
|
234
228
|
raw_response = @tree.client.send_recv(write_request)
|
235
229
|
response = RubySMB::SMB1::Packet::WriteAndxResponse.read(raw_response)
|
@@ -242,7 +236,7 @@ module RubySMB
|
|
242
236
|
)
|
243
237
|
end
|
244
238
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
245
|
-
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
239
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
246
240
|
end
|
247
241
|
bytes_written = response.parameter_block.count_low + (response.parameter_block.count_high << 16)
|
248
242
|
total_bytes_written += bytes_written
|