ruby_smb 2.0.1 → 2.0.6
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 +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
@@ -13,9 +13,10 @@ module RubySMB
|
|
13
13
|
|
14
14
|
rpc_hkey :hkey
|
15
15
|
rrp_unicode_string :lp_value_name
|
16
|
-
string :
|
16
|
+
string :pad1, length: -> { pad_length(self.lp_value_name) }
|
17
17
|
ndr_lp_dword :lp_type
|
18
|
-
|
18
|
+
ndr_lp_byte_array :lp_data
|
19
|
+
string :pad2, length: -> { pad_length(self.lp_data) }
|
19
20
|
ndr_lp_dword :lpcb_data
|
20
21
|
ndr_lp_dword :lpcb_len
|
21
22
|
|
@@ -24,10 +25,10 @@ module RubySMB
|
|
24
25
|
@opnum = REG_QUERY_VALUE
|
25
26
|
end
|
26
27
|
|
27
|
-
# Determines the correct length for the padding
|
28
|
-
#
|
29
|
-
def pad_length
|
30
|
-
offset = (
|
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
|
31
32
|
(4 - offset) % 4
|
32
33
|
end
|
33
34
|
end
|
@@ -9,22 +9,22 @@ module RubySMB
|
|
9
9
|
|
10
10
|
endian :little
|
11
11
|
|
12
|
-
ndr_lp_dword
|
13
|
-
|
14
|
-
string
|
15
|
-
ndr_lp_dword
|
16
|
-
ndr_lp_dword
|
17
|
-
uint32
|
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
18
|
|
19
19
|
def initialize_instance
|
20
20
|
super
|
21
21
|
@opnum = REG_QUERY_VALUE
|
22
22
|
end
|
23
23
|
|
24
|
-
# Determines the correct length for the padding
|
25
|
-
#
|
26
|
-
def pad_length
|
27
|
-
offset = (
|
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
28
|
(4 - offset) % 4
|
29
29
|
end
|
30
30
|
|
@@ -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
|
|
@@ -74,7 +74,7 @@ module RubySMB
|
|
74
74
|
raise ::RubySMB::Error::NetBiosSessionService, 'NBSS Header is missing'
|
75
75
|
end
|
76
76
|
|
77
|
-
length = nbss_header.
|
77
|
+
length = nbss_header.stream_protocol_length
|
78
78
|
data = full_response ? nbss_header.to_binary_s : ''
|
79
79
|
if length > 0
|
80
80
|
if IO.select([@tcp_socket], nil, nil, @read_timeout).nil?
|
data/lib/ruby_smb/error.rb
CHANGED
@@ -16,23 +16,26 @@ module RubySMB
|
|
16
16
|
# Raised when trying to parse raw binary into a Packet and the data
|
17
17
|
# is invalid.
|
18
18
|
class InvalidPacket < RubySMBError
|
19
|
+
attr_reader :status_code
|
19
20
|
def initialize(args = nil)
|
20
21
|
if args.nil?
|
21
22
|
super
|
22
23
|
elsif args.is_a? String
|
23
24
|
super(args)
|
24
25
|
elsif args.is_a? Hash
|
25
|
-
expected_proto = args[:expected_proto] ? translate_protocol(args[:expected_proto]) :
|
26
|
-
expected_cmd = args[:expected_cmd] ||
|
27
|
-
received_proto = args[:
|
28
|
-
received_cmd = args[:
|
26
|
+
expected_proto = args[:expected_proto] ? translate_protocol(args[:expected_proto]) : '???'
|
27
|
+
expected_cmd = args[:expected_cmd] || '???'
|
28
|
+
received_proto = args[:packet]&.packet_smb_version || '???'
|
29
|
+
received_cmd = get_cmd(args[:packet]) || '???'
|
30
|
+
@status_code = args[:packet]&.status_code
|
29
31
|
super(
|
30
32
|
"Expecting #{expected_proto} protocol "\
|
31
33
|
"with command=#{expected_cmd}"\
|
32
34
|
"#{(" (" + args[:expected_custom] + ")") if args[:expected_custom]}, "\
|
33
35
|
"got #{received_proto} protocol "\
|
34
36
|
"with command=#{received_cmd}"\
|
35
|
-
"#{(" (" + args[:received_custom] + ")") if args[:received_custom]}"
|
37
|
+
"#{(" (" + args[:received_custom] + ")") if args[:received_custom]}"\
|
38
|
+
"#{(", Status: #{@status_code}") if @status_code}"
|
36
39
|
)
|
37
40
|
else
|
38
41
|
raise ArgumentError, "InvalidPacket expects a String or a Hash, got a #{args.class}"
|
@@ -50,6 +53,19 @@ module RubySMB
|
|
50
53
|
end
|
51
54
|
end
|
52
55
|
private :translate_protocol
|
56
|
+
|
57
|
+
def get_cmd(packet)
|
58
|
+
return nil unless packet
|
59
|
+
case packet.packet_smb_version
|
60
|
+
when 'SMB1'
|
61
|
+
packet.smb_header.command
|
62
|
+
when 'SMB2'
|
63
|
+
packet.smb2_header.command
|
64
|
+
else
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
private :get_cmd
|
53
69
|
end
|
54
70
|
|
55
71
|
# Raised when a response packet has a NTStatus code that was unexpected.
|
@@ -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
|
@@ -49,7 +49,17 @@ module RubySMB
|
|
49
49
|
when /SMB1/
|
50
50
|
packet = RubySMB::SMB1::Packet::EmptyPacket.read(val)
|
51
51
|
when /SMB2/
|
52
|
-
|
52
|
+
begin
|
53
|
+
packet = RubySMB::SMB2::Packet::ErrorPacket.read(val)
|
54
|
+
rescue RubySMB::Error::InvalidPacket
|
55
|
+
# Handle the case where an SMB2 error packet is expected, but the
|
56
|
+
# server sent an SMB1 empty packet instead. This behavior has been
|
57
|
+
# observed with older versions of Samba when something goes wrong
|
58
|
+
# on the server side. We just want to give it a chance and try to
|
59
|
+
# parse it as an SMB1 empty packet to keep information and avoid
|
60
|
+
# failing as much as possible.
|
61
|
+
packet = RubySMB::SMB1::Packet::EmptyPacket.read(val)
|
62
|
+
end
|
53
63
|
else
|
54
64
|
raise RubySMB::Error::InvalidPacket, 'Not a valid SMB packet'
|
55
65
|
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
|
data/lib/ruby_smb/smb1/file.rb
CHANGED
@@ -86,8 +86,7 @@ module RubySMB
|
|
86
86
|
raise RubySMB::Error::InvalidPacket.new(
|
87
87
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
88
88
|
expected_cmd: RubySMB::SMB1::Packet::CloseResponse::COMMAND,
|
89
|
-
|
90
|
-
received_cmd: response.smb_header.command
|
89
|
+
packet: response
|
91
90
|
)
|
92
91
|
end
|
93
92
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
@@ -106,11 +105,7 @@ module RubySMB
|
|
106
105
|
# @raise [RubySMB::Error::InvalidPacket] if the response packet is not valid
|
107
106
|
# @raise [RubySMB::Error::UnexpectedStatusCode] if the response NTStatus is not STATUS_SUCCESS
|
108
107
|
def read(bytes: @size, offset: 0)
|
109
|
-
atomic_read_size =
|
110
|
-
@tree.client.max_buffer_size
|
111
|
-
else
|
112
|
-
bytes
|
113
|
-
end
|
108
|
+
atomic_read_size = [bytes, @tree.client.max_buffer_size].min
|
114
109
|
remaining_bytes = bytes
|
115
110
|
data = ''
|
116
111
|
|
@@ -122,8 +117,7 @@ module RubySMB
|
|
122
117
|
raise RubySMB::Error::InvalidPacket.new(
|
123
118
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
124
119
|
expected_cmd: RubySMB::SMB1::Packet::ReadAndxResponse::COMMAND,
|
125
|
-
|
126
|
-
received_cmd: response.smb_header.command
|
120
|
+
packet: response
|
127
121
|
)
|
128
122
|
end
|
129
123
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
@@ -171,8 +165,7 @@ module RubySMB
|
|
171
165
|
raise RubySMB::Error::InvalidPacket.new(
|
172
166
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
173
167
|
expected_cmd: RubySMB::SMB1::Packet::ReadAndxResponse::COMMAND,
|
174
|
-
|
175
|
-
received_cmd: response.smb_header.command
|
168
|
+
packet: response
|
176
169
|
)
|
177
170
|
end
|
178
171
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
@@ -193,8 +186,7 @@ module RubySMB
|
|
193
186
|
raise RubySMB::Error::InvalidPacket.new(
|
194
187
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
195
188
|
expected_cmd: RubySMB::SMB1::Packet::Trans2::SetFileInformationResponse::COMMAND,
|
196
|
-
|
197
|
-
received_cmd: response.smb_header.command
|
189
|
+
packet: response
|
198
190
|
)
|
199
191
|
end
|
200
192
|
response.status_code
|
@@ -227,11 +219,7 @@ module RubySMB
|
|
227
219
|
total_bytes_written = 0
|
228
220
|
|
229
221
|
loop do
|
230
|
-
atomic_write_size =
|
231
|
-
@tree.client.max_buffer_size
|
232
|
-
else
|
233
|
-
bytes
|
234
|
-
end
|
222
|
+
atomic_write_size = [bytes, @tree.client.max_buffer_size].min
|
235
223
|
write_request = write_packet(data: buffer.slice!(0, atomic_write_size), offset: offset)
|
236
224
|
raw_response = @tree.client.send_recv(write_request)
|
237
225
|
response = RubySMB::SMB1::Packet::WriteAndxResponse.read(raw_response)
|
@@ -239,8 +227,7 @@ module RubySMB
|
|
239
227
|
raise RubySMB::Error::InvalidPacket.new(
|
240
228
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
241
229
|
expected_cmd: RubySMB::SMB1::Packet::WriteAndxResponse::COMMAND,
|
242
|
-
|
243
|
-
received_cmd: response.smb_header.command
|
230
|
+
packet: response
|
244
231
|
)
|
245
232
|
end
|
246
233
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
@@ -279,8 +266,7 @@ module RubySMB
|
|
279
266
|
raise RubySMB::Error::InvalidPacket.new(
|
280
267
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
281
268
|
expected_cmd: RubySMB::SMB1::Packet::WriteAndxResponse::COMMAND,
|
282
|
-
|
283
|
-
received_cmd: response.smb_header.command
|
269
|
+
packet: response
|
284
270
|
)
|
285
271
|
end
|
286
272
|
response.parameter_block.count_low
|
@@ -298,8 +284,7 @@ module RubySMB
|
|
298
284
|
raise RubySMB::Error::InvalidPacket.new(
|
299
285
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
300
286
|
expected_cmd: RubySMB::SMB1::Packet::Trans2::SetFileInformationResponse::COMMAND,
|
301
|
-
|
302
|
-
received_cmd: response.smb_header.command
|
287
|
+
packet: response
|
303
288
|
)
|
304
289
|
end
|
305
290
|
response.status_code
|
@@ -316,7 +301,7 @@ module RubySMB
|
|
316
301
|
passthrough_info_level = RubySMB::Fscc::FileInformation::FILE_RENAME_INFORMATION +
|
317
302
|
RubySMB::Fscc::FileInformation::SMB_INFO_PASSTHROUGH
|
318
303
|
rename_request.data_block.trans2_parameters.information_level = passthrough_info_level
|
319
|
-
rename_request.data_block.trans2_data.info_level_struct.file_name = new_file_name
|
304
|
+
rename_request.data_block.trans2_data.info_level_struct.file_name = new_file_name
|
320
305
|
set_trans2_params(rename_request)
|
321
306
|
end
|
322
307
|
|
@@ -40,7 +40,6 @@ module RubySMB
|
|
40
40
|
|
41
41
|
# The {RubySMB::SMB1::DataBlock} specific to this packet type.
|
42
42
|
class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
43
|
-
uint8 :name, label: 'Name', initial_value: 0x00
|
44
43
|
string :pad1, length: -> { pad1_length }
|
45
44
|
trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
46
45
|
string :pad2, length: -> { pad2_length }
|
@@ -39,7 +39,6 @@ module RubySMB
|
|
39
39
|
|
40
40
|
# The {RubySMB::SMB1::DataBlock} specific to this packet type.
|
41
41
|
class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
42
|
-
uint8 :name, label: 'Name', initial_value: 0x00
|
43
42
|
string :pad1, length: -> { pad1_length }
|
44
43
|
trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
45
44
|
string :pad2, length: -> { pad2_length }
|
@@ -44,8 +44,7 @@ module RubySMB
|
|
44
44
|
class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
45
45
|
string :pad1, length: -> { pad1_length }
|
46
46
|
trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
47
|
-
|
48
|
-
string :trans2_data, label: 'Trans2 Data', length: 0
|
47
|
+
# trans2_data: No data is sent by this message.
|
49
48
|
end
|
50
49
|
|
51
50
|
smb_header :smb_header
|
@@ -23,23 +23,11 @@ module RubySMB
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
# The Trans2 Data Block for this particular Subcommand
|
27
|
-
class Trans2Data < BinData::Record
|
28
|
-
|
29
|
-
# Returns the length of the Trans2Data struct
|
30
|
-
# in number of bytes
|
31
|
-
def length
|
32
|
-
do_num_bytes
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
26
|
# The {RubySMB::SMB1::DataBlock} specific to this packet type.
|
37
27
|
class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
38
|
-
uint8 :name, label: 'Name', initial_value: 0x00
|
39
28
|
string :pad1, length: -> { pad1_length }
|
40
29
|
trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
41
|
-
|
42
|
-
trans2_data :trans2_data, label: 'Trans2 Data'
|
30
|
+
# trans2_data: No data is sent by this message.
|
43
31
|
end
|
44
32
|
|
45
33
|
smb_header :smb_header
|
data/lib/ruby_smb/smb1/pipe.rb
CHANGED
@@ -16,9 +16,13 @@ module RubySMB
|
|
16
16
|
def initialize(tree:, response:, name:)
|
17
17
|
raise ArgumentError, 'No Name Provided' if name.nil?
|
18
18
|
case name
|
19
|
-
when '
|
19
|
+
when 'netlogon', '\\netlogon'
|
20
|
+
extend RubySMB::Dcerpc::Netlogon
|
21
|
+
when 'srvsvc', '\\srvsvc'
|
20
22
|
extend RubySMB::Dcerpc::Srvsvc
|
21
|
-
when '
|
23
|
+
when 'svcctl', '\\svcctl'
|
24
|
+
extend RubySMB::Dcerpc::Svcctl
|
25
|
+
when 'winreg', '\\winreg'
|
22
26
|
extend RubySMB::Dcerpc::Winreg
|
23
27
|
end
|
24
28
|
super(tree: tree, response: response, name: name)
|
@@ -41,8 +45,7 @@ module RubySMB
|
|
41
45
|
raise RubySMB::Error::InvalidPacket.new(
|
42
46
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
43
47
|
expected_cmd: RubySMB::SMB1::Packet::Trans::PeekNmpipeRequest::COMMAND,
|
44
|
-
|
45
|
-
received_cmd: response.smb_header.command
|
48
|
+
packet: response
|
46
49
|
)
|
47
50
|
end
|
48
51
|
|
@@ -100,8 +103,7 @@ module RubySMB
|
|
100
103
|
raise RubySMB::Error::InvalidPacket.new(
|
101
104
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
102
105
|
expected_cmd: RubySMB::SMB1::Packet::Trans::TransactNmpipeResponse::COMMAND,
|
103
|
-
|
104
|
-
received_cmd: trans_nmpipe_response.smb_header.command
|
106
|
+
packet: trans_nmpipe_response
|
105
107
|
)
|
106
108
|
end
|
107
109
|
unless [WindowsError::NTStatus::STATUS_SUCCESS,
|