ruby_smb 1.0.3 → 2.0.1
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/enum_registry_key.rb +28 -0
- data/examples/enum_registry_values.rb +30 -0
- data/examples/negotiate.rb +51 -8
- data/examples/pipes.rb +2 -1
- data/examples/read_file_encryption.rb +56 -0
- data/examples/read_registry_key_value.rb +32 -0
- data/lib/ruby_smb.rb +4 -1
- data/lib/ruby_smb/client.rb +233 -22
- data/lib/ruby_smb/client/authentication.rb +70 -33
- data/lib/ruby_smb/client/echo.rb +20 -2
- data/lib/ruby_smb/client/encryption.rb +62 -0
- data/lib/ruby_smb/client/negotiation.rb +172 -24
- data/lib/ruby_smb/client/signing.rb +19 -0
- data/lib/ruby_smb/client/tree_connect.rb +24 -18
- 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 +38 -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 +3 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +95 -16
- data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
- data/lib/ruby_smb/dcerpc/request.rb +28 -9
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +35 -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/winreg.rb +340 -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/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 +39 -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/dispatcher/socket.rb +4 -3
- data/lib/ruby_smb/error.rb +68 -2
- data/lib/ruby_smb/generic_packet.rb +33 -4
- data/lib/ruby_smb/smb1/commands.rb +1 -1
- data/lib/ruby_smb/smb1/file.rb +66 -15
- data/lib/ruby_smb/smb1/packet/close_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/close_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/echo_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/echo_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/empty_packet.rb +10 -1
- data/lib/ruby_smb/smb1/packet/logoff_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/logoff_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/negotiate_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/negotiate_response.rb +3 -7
- data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +4 -4
- data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/read_andx_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/read_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/session_setup_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_request.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/trans/request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/trans/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +13 -3
- data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/write_andx_request.rb +3 -6
- data/lib/ruby_smb/smb1/packet/write_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/pipe.rb +87 -6
- data/lib/ruby_smb/smb1/tree.rb +50 -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 +103 -25
- 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/close_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/close_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +41 -0
- data/lib/ruby_smb/smb2/packet/create_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/create_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/echo_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/echo_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -3
- data/lib/ruby_smb/smb2/packet/ioctl_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/ioctl_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/logoff_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/logoff_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +51 -17
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +52 -5
- data/lib/ruby_smb/smb2/packet/query_directory_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/query_directory_response.rb +8 -2
- data/lib/ruby_smb/smb2/packet/read_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/read_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/set_info_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/set_info_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/transform_header.rb +84 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +93 -10
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +10 -22
- data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/write_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/write_response.rb +2 -1
- data/lib/ruby_smb/smb2/pipe.rb +86 -12
- data/lib/ruby_smb/smb2/smb2_header.rb +1 -1
- data/lib/ruby_smb/smb2/tree.rb +65 -21
- data/lib/ruby_smb/version.rb +1 -1
- data/ruby_smb.gemspec +5 -3
- data/spec/lib/ruby_smb/client_spec.rb +1612 -108
- 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 +410 -0
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +98 -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/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/enum_key_request_spec.rb +108 -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 +90 -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 +39 -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 +150 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +710 -0
- data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +2 -2
- data/spec/lib/ruby_smb/error_spec.rb +59 -0
- data/spec/lib/ruby_smb/generic_packet_spec.rb +52 -4
- data/spec/lib/ruby_smb/smb1/file_spec.rb +191 -2
- data/spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb +68 -0
- 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/packet/trans2/find_first2_response_spec.rb +11 -2
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +11 -2
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +272 -149
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +44 -7
- 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 +323 -6
- 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 +78 -0
- 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/query_directory_response_spec.rb +8 -0
- 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 -22
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +286 -149
- data/spec/lib/ruby_smb/smb2/smb2_header_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +261 -2
- metadata +191 -83
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/smb1/dcerpc.rb +0 -67
- data/lib/ruby_smb/smb2/dcerpc.rb +0 -70
- data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +0 -37
@@ -4,6 +4,8 @@ module RubySMB
|
|
4
4
|
# An SMB2 Query Directory Request Packet as defined in
|
5
5
|
# [2.2.33 SMB2 QUERY_DIRECTORY Request](https://msdn.microsoft.com/en-us/library/cc246551.aspx)
|
6
6
|
class QueryDirectoryRequest < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::QUERY_DIRECTORY
|
8
|
+
|
7
9
|
endian :little
|
8
10
|
smb2_header :smb2_header
|
9
11
|
uint16 :structure_size, label: 'Structure Size', initial_value: 33
|
@@ -25,10 +27,6 @@ module RubySMB
|
|
25
27
|
uint32 :output_length, label: 'Output Buffer Length'
|
26
28
|
string16 :name, label: 'Name/Search Pattern'
|
27
29
|
|
28
|
-
def initialize_instance
|
29
|
-
super
|
30
|
-
smb2_header.command = RubySMB::SMB2::Commands::QUERY_DIRECTORY
|
31
|
-
end
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
@@ -4,6 +4,8 @@ module RubySMB
|
|
4
4
|
# An SMB2 Query Directory Response Packet as defined in
|
5
5
|
# [2.2.34 SMB2 QUERY_DIRECTORY Response](https://msdn.microsoft.com/en-us/library/cc246552.aspx)
|
6
6
|
class QueryDirectoryResponse < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::QUERY_DIRECTORY
|
8
|
+
|
7
9
|
endian :little
|
8
10
|
smb2_header :smb2_header
|
9
11
|
uint16 :structure_size, label: 'Structure Size', initial_value: 9
|
@@ -13,7 +15,6 @@ module RubySMB
|
|
13
15
|
|
14
16
|
def initialize_instance
|
15
17
|
super
|
16
|
-
smb2_header.command = RubySMB::SMB2::Commands::QUERY_DIRECTORY
|
17
18
|
smb2_header.flags.reply = 1
|
18
19
|
end
|
19
20
|
|
@@ -23,6 +24,7 @@ module RubySMB
|
|
23
24
|
#
|
24
25
|
# @param klass [Class] the FileInformationClass class to read the data as
|
25
26
|
# @return [array<BinData::Record>] An array of structs holding the requested information
|
27
|
+
# @raise [RubySMB::Error::InvalidPacket] if the string buffer is not a valid File Information
|
26
28
|
def results(klass)
|
27
29
|
information_classes = []
|
28
30
|
blob = buffer.to_binary_s.dup
|
@@ -35,7 +37,11 @@ module RubySMB
|
|
35
37
|
blob.slice!(0, length)
|
36
38
|
end
|
37
39
|
|
38
|
-
|
40
|
+
begin
|
41
|
+
information_classes << klass.read(data)
|
42
|
+
rescue IOError
|
43
|
+
raise RubySMB::Error::InvalidPacket, "Invalid #{klass} File Information in the string buffer"
|
44
|
+
end
|
39
45
|
end
|
40
46
|
information_classes
|
41
47
|
end
|
@@ -4,6 +4,8 @@ module RubySMB
|
|
4
4
|
# An SMB2 Read Request Packet as defined in
|
5
5
|
# [2.2.19 SMB2 READ Request](https://msdn.microsoft.com/en-us/library/cc246527.aspx)
|
6
6
|
class ReadRequest < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::READ
|
8
|
+
|
7
9
|
endian :little
|
8
10
|
|
9
11
|
smb2_header :smb2_header
|
@@ -20,10 +22,6 @@ module RubySMB
|
|
20
22
|
uint16 :channel_length, label: 'Read Channel Info Length'
|
21
23
|
string :buffer, label: 'Read Channel info Buffer', initial_value: 0x00
|
22
24
|
|
23
|
-
def initialize_instance
|
24
|
-
super
|
25
|
-
smb2_header.command = RubySMB::SMB2::Commands::READ
|
26
|
-
end
|
27
25
|
end
|
28
26
|
end
|
29
27
|
end
|
@@ -4,6 +4,8 @@ module RubySMB
|
|
4
4
|
# An SMB2 Read Response Packet as defined in
|
5
5
|
# [2.2.20 SMB2 READ Response](https://msdn.microsoft.com/en-us/library/cc246531.aspx)
|
6
6
|
class ReadResponse < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::READ
|
8
|
+
|
7
9
|
endian :little
|
8
10
|
|
9
11
|
smb2_header :smb2_header
|
@@ -17,7 +19,6 @@ module RubySMB
|
|
17
19
|
|
18
20
|
def initialize_instance
|
19
21
|
super
|
20
|
-
smb2_header.command = RubySMB::SMB2::Commands::READ
|
21
22
|
smb2_header.flags.reply = 1
|
22
23
|
end
|
23
24
|
end
|
@@ -4,6 +4,8 @@ module RubySMB
|
|
4
4
|
# An SMB2 SessionSetupRequest Packet as defined in
|
5
5
|
# [2.2.5 SMB2 SESSION_SETUP Request](https://msdn.microsoft.com/en-us/library/cc246563.aspx)
|
6
6
|
class SessionSetupRequest < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::SESSION_SETUP
|
8
|
+
|
7
9
|
endian :little
|
8
10
|
smb2_header :smb2_header
|
9
11
|
uint16 :structure_size, label: 'Structure Size', initial_value: 25
|
@@ -16,11 +18,6 @@ module RubySMB
|
|
16
18
|
uint64 :previous_session_id, label: 'Previous Session ID'
|
17
19
|
string :buffer, label: 'Security Buffer', length: -> { security_buffer_length }
|
18
20
|
|
19
|
-
def initialize_instance
|
20
|
-
super
|
21
|
-
smb2_header.command = RubySMB::SMB2::Commands::SESSION_SETUP
|
22
|
-
end
|
23
|
-
|
24
21
|
# Takes a serialized NTLM Type 1 message and wraps it in the GSS ASN1 encoding
|
25
22
|
# and inserts it into the {RubySMB::SMB2::Packet::SessionSetupRequest#buffer}
|
26
23
|
# as well as updating the {RubySMB::SMB2::Packet::SessionSetupRequest#security_buffer_length}
|
@@ -4,6 +4,8 @@ module RubySMB
|
|
4
4
|
# An SMB2 SessionSetupResponse Packet as defined in
|
5
5
|
# [2.2.6 SMB2 SESSION_SETUP Response](https://msdn.microsoft.com/en-us/library/cc246564.aspx)
|
6
6
|
class SessionSetupResponse < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::SESSION_SETUP
|
8
|
+
|
7
9
|
endian :little
|
8
10
|
smb2_header :smb2_header
|
9
11
|
uint16 :structure_size, label: 'Structure Size', initial_value: 9
|
@@ -14,7 +16,6 @@ module RubySMB
|
|
14
16
|
|
15
17
|
def initialize_instance
|
16
18
|
super
|
17
|
-
smb2_header.command = RubySMB::SMB2::Commands::SESSION_SETUP
|
18
19
|
smb2_header.flags.reply = 1
|
19
20
|
end
|
20
21
|
|
@@ -4,6 +4,8 @@ module RubySMB
|
|
4
4
|
# An SMB2 Set Info Request Packet as defined in
|
5
5
|
# [2.2.39 SMB2 SET_INFO Request](https://msdn.microsoft.com/en-us/library/cc246560.aspx)
|
6
6
|
class SetInfoRequest < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::SET_INFO
|
8
|
+
|
7
9
|
include RubySMB::Fscc::FileInformation
|
8
10
|
|
9
11
|
endian :little
|
@@ -48,10 +50,6 @@ module RubySMB
|
|
48
50
|
file_id_full_directory_information FILE_ID_FULL_DIRECTORY_INFORMATION, label: 'File Id Full Directory Information'
|
49
51
|
end
|
50
52
|
|
51
|
-
def initialize_instance
|
52
|
-
super
|
53
|
-
smb2_header.command = RubySMB::SMB2::Commands::SET_INFO
|
54
|
-
end
|
55
53
|
end
|
56
54
|
end
|
57
55
|
end
|
@@ -4,6 +4,8 @@ module RubySMB
|
|
4
4
|
# An SMB2 Read Response Packet as defined in
|
5
5
|
# [2.2.40 SMB2 SET_INFO Response](https://msdn.microsoft.com/en-us/library/cc246562.aspx)
|
6
6
|
class SetInfoResponse < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::SET_INFO
|
8
|
+
|
7
9
|
endian :little
|
8
10
|
|
9
11
|
smb2_header :smb2_header
|
@@ -11,7 +13,6 @@ module RubySMB
|
|
11
13
|
|
12
14
|
def initialize_instance
|
13
15
|
super
|
14
|
-
smb2_header.command = RubySMB::SMB2::Commands::SET_INFO
|
15
16
|
smb2_header.flags.reply = 1
|
16
17
|
end
|
17
18
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB2
|
3
|
+
module Packet
|
4
|
+
# An SMB2 TRANSFORM_HEADER Packet as defined in
|
5
|
+
# [2.2.41 SMB2 TRANSFORM_HEADER](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/d6ce2327-a4c9-4793-be66-7b5bad2175fa)
|
6
|
+
class TransformHeader < BinData::Record
|
7
|
+
endian :little
|
8
|
+
hide :reserved0
|
9
|
+
|
10
|
+
endian :little
|
11
|
+
bit32 :protocol, label: 'Protocol ID Field', initial_value: 0xFD534D42
|
12
|
+
string :signature, label: 'Signature', length: 16
|
13
|
+
string :nonce, label: 'Nonce', length: 16
|
14
|
+
uint32 :original_message_size, label: 'Original Message Size'
|
15
|
+
uint16 :reserved0
|
16
|
+
uint16 :flags, label: 'Flags / Encryption Algorithm'
|
17
|
+
uint64 :session_id, label: 'Session ID'
|
18
|
+
array :encrypted_data, label: 'Encrypted Data', type: :uint8, read_until: :eof
|
19
|
+
|
20
|
+
def decrypt(key, algorithm: 'AES-128-GCM')
|
21
|
+
auth_data = self.to_binary_s[20...52]
|
22
|
+
encrypted_data = self.encrypted_data.to_ary.pack('C*')
|
23
|
+
|
24
|
+
case algorithm
|
25
|
+
when 'AES-128-CCM'
|
26
|
+
cipher = OpenSSL::CCM.new('AES', key, 16)
|
27
|
+
unencrypted_data = cipher.decrypt(encrypted_data + self.signature, self.nonce[0...11], auth_data)
|
28
|
+
unless unencrypted_data.length > 0
|
29
|
+
raise OpenSSL::Cipher::CipherError # raised for consistency with GCM mode
|
30
|
+
end
|
31
|
+
when 'AES-128-GCM'
|
32
|
+
cipher = OpenSSL::Cipher.new(algorithm).decrypt
|
33
|
+
cipher.key = key
|
34
|
+
cipher.iv = self.nonce[0...12]
|
35
|
+
cipher.auth_data = auth_data
|
36
|
+
cipher.auth_tag = self.signature
|
37
|
+
unencrypted_data = cipher.update(encrypted_data)
|
38
|
+
cipher.final # raises OpenSSL::Cipher::CipherError on signature failure
|
39
|
+
else
|
40
|
+
raise ArgumentError.new('Invalid algorithm, must be either AES-128-CCM or AES-128-GCM')
|
41
|
+
end
|
42
|
+
|
43
|
+
unencrypted_data[0...self.original_message_size]
|
44
|
+
rescue Exception => e
|
45
|
+
raise RubySMB::Error::EncryptionError, "Error while decrypting with '#{algorithm}' (#{e.class}: #{e})"
|
46
|
+
end
|
47
|
+
|
48
|
+
def encrypt(unencrypted_data, key, algorithm: 'AES-128-GCM')
|
49
|
+
if unencrypted_data.is_a? BinData::Record
|
50
|
+
unencrypted_data = unencrypted_data.to_binary_s
|
51
|
+
end
|
52
|
+
|
53
|
+
self.original_message_size.assign(unencrypted_data.length)
|
54
|
+
|
55
|
+
case algorithm
|
56
|
+
when 'AES-128-CCM'
|
57
|
+
cipher = OpenSSL::CCM.new('AES', key, 16)
|
58
|
+
random_iv = OpenSSL::Random.random_bytes(11)
|
59
|
+
self.nonce.assign(random_iv)
|
60
|
+
result = cipher.encrypt(unencrypted_data, random_iv, self.to_binary_s[20...52])
|
61
|
+
encrypted_data = result[0...-16]
|
62
|
+
auth_tag = result[-16..-1]
|
63
|
+
when 'AES-128-GCM'
|
64
|
+
cipher = OpenSSL::Cipher.new(algorithm).encrypt
|
65
|
+
cipher.iv_len = 12
|
66
|
+
cipher.key = key
|
67
|
+
self.nonce.assign(cipher.random_iv)
|
68
|
+
cipher.auth_data = self.to_binary_s[20...52]
|
69
|
+
encrypted_data = cipher.update(unencrypted_data) + cipher.final
|
70
|
+
auth_tag = cipher.auth_tag
|
71
|
+
else
|
72
|
+
raise ArgumentError.new('Invalid algorithm, must be either AES-128-CCM or AES-128-GCM')
|
73
|
+
end
|
74
|
+
|
75
|
+
self.encrypted_data.assign(encrypted_data.bytes)
|
76
|
+
self.signature.assign(auth_tag)
|
77
|
+
nil
|
78
|
+
rescue Exception => e
|
79
|
+
raise RubySMB::Error::EncryptionError, "Error while encrypting with '#{algorithm}' (#{e.class}: #{e})"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -1,25 +1,108 @@
|
|
1
1
|
module RubySMB
|
2
2
|
module SMB2
|
3
3
|
module Packet
|
4
|
+
|
5
|
+
|
6
|
+
# An SMB2 RemotedIdentityTreeConnectContext Packet as defined in
|
7
|
+
# [2.2.9.2.1 SMB2_REMOTED_IDENTITY_TREE_CONNECT Context](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/ee7ff411-93e0-484f-9f73-31916fee4cb8)
|
8
|
+
# TODO: implement helper methods to add each Remote Identity element
|
9
|
+
class RemotedIdentityTreeConnectContext < BinData::Record
|
10
|
+
endian :little
|
11
|
+
uint16 :ticket_type, label: 'Ticket Type', initial_value: 0x0001
|
12
|
+
uint16 :ticket_size, label: 'Ticket Size', initial_value: -> { num_bytes }
|
13
|
+
uint16 :user, label: 'User'
|
14
|
+
uint16 :user_name, label: 'User Name'
|
15
|
+
uint16 :domain, label: 'Domain'
|
16
|
+
uint16 :groups, label: 'Groups'
|
17
|
+
uint16 :restricted_groups, label: 'Restricted Groups'
|
18
|
+
uint16 :privileges, label: 'Privileges'
|
19
|
+
uint16 :primary_group, label: 'Primary Group'
|
20
|
+
uint16 :owner, label: 'Owner'
|
21
|
+
uint16 :default_dacl, label: 'Default DACL'
|
22
|
+
uint16 :device_groups, label: 'Device Groups'
|
23
|
+
uint16 :user_claims, label: 'User Claims'
|
24
|
+
uint16 :device_claims, label: 'Device Claims'
|
25
|
+
string :ticket_info, label: 'Ticket Info', read_length: -> { ticket_size - ticket_info.rel_offset}
|
26
|
+
end
|
27
|
+
|
28
|
+
# An SMB2 TreeConnectContext Packet as defined in
|
29
|
+
# [2.2.9.2 SMB2 TREE_CONNECT_CONTEXT Request Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/06eaaabc-caca-4776-9daf-82439e90dacd)
|
30
|
+
class TreeConnectContext < BinData::Record
|
31
|
+
|
32
|
+
# Context Types
|
33
|
+
|
34
|
+
# This value is reserved.
|
35
|
+
SMB2_RESERVED_TREE_CONNECT_CONTEXT_ID = 0x0000
|
36
|
+
# The Data field contains remoted identity tree connect context data as
|
37
|
+
# specified in section [2.2.9.2.1](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/ee7ff411-93e0-484f-9f73-31916fee4cb8)
|
38
|
+
SMB2_REMOTED_IDENTITY_TREE_CONNECT_CONTEXT_ID = 0x0001
|
39
|
+
|
40
|
+
endian :little
|
41
|
+
uint16 :context_type, label: 'Context Type'
|
42
|
+
uint16 :data_length, label: 'Data Length', initial_value: -> { data.to_binary_s.size }
|
43
|
+
uint32 :reserved, label: 'Reserved'
|
44
|
+
choice :data, label: 'Data', selection: -> { context_type } do
|
45
|
+
remoted_identity_tree_connect_context SMB2_REMOTED_IDENTITY_TREE_CONNECT_CONTEXT_ID, label: 'Remoted Identity Tree Connect Context'
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
# An SMB2 TreeConnectRequestExtension Packet as defined in
|
51
|
+
# [2.2.9.1 SMB2 TREE_CONNECT Request Extension](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/9ca7328b-b6ca-41a7-9773-0fa237261b76)
|
52
|
+
class TreeConnectRequestExtension < BinData::Record
|
53
|
+
endian :little
|
54
|
+
uint32 :tree_connect_context_offset, label: 'Tree Connect Context Offset', initial_value: -> { tree_connect_contexts.rel_offset }
|
55
|
+
uint16 :tree_connect_context_count, label: 'Tree Connect Context Count', initial_value: -> { tree_connect_contexts.size }
|
56
|
+
string :reserved, label: 'Reserved', length: 10
|
57
|
+
string16 :path, label: 'Path Buffer'
|
58
|
+
array :tree_connect_contexts, label: 'Tree Connect Contexts', type: :tree_connect_context, initial_length: -> { tree_connect_context_count }
|
59
|
+
end
|
60
|
+
|
4
61
|
# An SMB2 TreeConnectRequest Packet as defined in
|
5
62
|
# [2.2.9 SMB2 TREE_CONNECT Request](https://msdn.microsoft.com/en-us/library/cc246567.aspx)
|
6
63
|
class TreeConnectRequest < RubySMB::GenericPacket
|
64
|
+
COMMAND = RubySMB::SMB2::Commands::TREE_CONNECT
|
65
|
+
|
66
|
+
# Flags (SMB 3.1.1 only)
|
67
|
+
|
68
|
+
# The client has previously connected to the specified cluster share
|
69
|
+
# using the SMB dialect of the connection on which the request is received.
|
70
|
+
SMB2_TREE_CONNECT_FLAG_CLUSTER_RECONNECT = 0x0001
|
71
|
+
# The client can handle synchronous share redirects via a Share Redirect
|
72
|
+
# error context response as specified in section [2.2.2.2.2](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/f3073a8b-9f0f-47c0-91e5-ec3be9a49f37).
|
73
|
+
SMB2_TREE_CONNECT_FLAG_REDIRECT_TO_OWNER = 0x0002
|
74
|
+
# A tree connect request extension, as specified in section
|
75
|
+
# [2.2.9.1](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/9ca7328b-b6ca-41a7-9773-0fa237261b76),
|
76
|
+
# is present, starting at the Buffer field of this tree connect request.
|
77
|
+
SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT = 0x0003
|
78
|
+
|
7
79
|
endian :little
|
8
80
|
smb2_header :smb2_header
|
9
81
|
uint16 :structure_size, label: 'Structure Size', initial_value: 9
|
82
|
+
# The flags field is only used by SMB 3.1.1, it must be 0 for other versions
|
10
83
|
uint16 :flags, label: 'Flags', initial_value: 0x00
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
84
|
+
# if SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT flag is set, #path_offset
|
85
|
+
# will have to be updated with the correct offset of the path name,
|
86
|
+
# which is located in the TreeConnect Context.
|
87
|
+
uint16 :path_offset, label: 'Path Offset', initial_value: -> do
|
88
|
+
if flags == SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT
|
89
|
+
tree_connect_request_extension.path.abs_offset
|
90
|
+
else
|
91
|
+
path.abs_offset
|
92
|
+
end
|
18
93
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
94
|
+
# if SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT flag is set, #path_length
|
95
|
+
# will have to be updated with the correct full share path name,
|
96
|
+
# which is located in the TreeConnect Context.
|
97
|
+
uint16 :path_length, label: 'Path Length', initial_value: -> do
|
98
|
+
if flags == SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT
|
99
|
+
tree_connect_request_extension.path.to_binary_s.length
|
100
|
+
else
|
101
|
+
path.to_binary_s.length
|
102
|
+
end
|
22
103
|
end
|
104
|
+
string16 :path, label: 'Path Buffer', onlyif: -> { flags != SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT }
|
105
|
+
tree_connect_request_extension :tree_connect_request_extension, label: 'Tree Connect Request Extension', onlyif: -> { flags == SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT }
|
23
106
|
end
|
24
107
|
end
|
25
108
|
end
|
@@ -4,6 +4,16 @@ module RubySMB
|
|
4
4
|
# An SMB2 TreeConnectResponse Packet as defined in
|
5
5
|
# [2.2.10 SMB2 TREE_CONNECT Response](https://msdn.microsoft.com/en-us/library/cc246499.aspx)
|
6
6
|
class TreeConnectResponse < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::TREE_CONNECT
|
8
|
+
|
9
|
+
# Share Types
|
10
|
+
# Physical disk share
|
11
|
+
SMB2_SHARE_TYPE_DISK = 0x01
|
12
|
+
# Named pipe share
|
13
|
+
SMB2_SHARE_TYPE_PIPE = 0x02
|
14
|
+
# Printer share
|
15
|
+
SMB2_SHARE_TYPE_PRINT = 0x03
|
16
|
+
|
7
17
|
endian :little
|
8
18
|
smb2_header :smb2_header
|
9
19
|
uint16 :structure_size, label: 'Structure Size', initial_value: 16
|
@@ -15,31 +25,9 @@ module RubySMB
|
|
15
25
|
|
16
26
|
def initialize_instance
|
17
27
|
super
|
18
|
-
smb2_header.command = RubySMB::SMB2::Commands::TREE_CONNECT
|
19
28
|
smb2_header.flags.reply = 1
|
20
29
|
end
|
21
30
|
|
22
|
-
# Returns the ACCESS_MASK for the Maximal Share Access Rights. The packet
|
23
|
-
# defaults this to a {RubySMB::SMB2::BitField::DirectoryAccessMask}. If it is anything other than
|
24
|
-
# a directory that has been connected to, it will re-cast it as a {RubySMB::SMB2::BitField::FileAccessMask}
|
25
|
-
#
|
26
|
-
# @return [RubySMB::SMB2::BitField::DirectoryAccessMask] if a directory was connected to
|
27
|
-
# @return [RubySMB::SMB2::BitField::FileAccessMask] if anything else was connected to
|
28
|
-
def access_rights
|
29
|
-
if is_directory?
|
30
|
-
maximal_access
|
31
|
-
else
|
32
|
-
mask = maximal_access.to_binary_s
|
33
|
-
RubySMB::SMB2::BitField::FileAccessMask.read(mask)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Checks if the remote Tree is a directory
|
38
|
-
#
|
39
|
-
# @return [Boolean]
|
40
|
-
def is_directory?
|
41
|
-
share_type == 0x01
|
42
|
-
end
|
43
31
|
end
|
44
32
|
end
|
45
33
|
end
|
@@ -4,15 +4,13 @@ module RubySMB
|
|
4
4
|
# An SMB2 TreeDisconnectRequest Packet as defined in
|
5
5
|
# [2.2.11 SMB2 TREE_DISCONNECT Request](https://msdn.microsoft.com/en-us/library/cc246500.aspx)
|
6
6
|
class TreeDisconnectRequest < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::TREE_DISCONNECT
|
8
|
+
|
7
9
|
endian :little
|
8
10
|
smb2_header :smb2_header
|
9
11
|
uint16 :structure_size, label: 'Structure Size', initial_value: 4
|
10
12
|
uint16 :reserved, label: 'Reserved', initial_value: 0
|
11
13
|
|
12
|
-
def initialize_instance
|
13
|
-
super
|
14
|
-
smb2_header.command = RubySMB::SMB2::Commands::TREE_DISCONNECT
|
15
|
-
end
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -4,13 +4,14 @@ module RubySMB
|
|
4
4
|
# An SMB2 TreeDisconnectResponse Packet as defined in
|
5
5
|
# [2.2.12 SMB2 TREE_DISCONNECT Response](https://msdn.microsoft.com/en-us/library/cc246501.aspx)
|
6
6
|
class TreeDisconnectResponse < RubySMB::GenericPacket
|
7
|
+
COMMAND = RubySMB::SMB2::Commands::TREE_DISCONNECT
|
8
|
+
|
7
9
|
endian :little
|
8
10
|
smb2_header :smb2_header
|
9
11
|
uint16 :structure_size, label: 'Structure Size', initial_value: 4
|
10
12
|
|
11
13
|
def initialize_instance
|
12
14
|
super
|
13
|
-
smb2_header.command = RubySMB::SMB2::Commands::TREE_DISCONNECT
|
14
15
|
smb2_header.flags.reply = 1
|
15
16
|
end
|
16
17
|
end
|