ruby_smb 1.0.2 → 2.0.0
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 +200 -20
- 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 +160 -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 +5 -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 +41 -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 +51 -4
- 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 +1563 -104
- 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 +3 -1
- 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
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# This example script is used for testing the Winreg registry key value read functionality.
|
4
|
+
# It will attempt to connect to a host and reads the value of a specified registry key.
|
5
|
+
# Example usage: ruby enum_registry_key.rb 192.168.172.138 msfadmin msfadmin HKLM\\My\\Key ValueName
|
6
|
+
# This will try to connect to \\192.168.172.138 with the msfadmin:msfadmin credentialas and reads the ValueName data corresponding to the HKLM\\My\\Key registry key.
|
7
|
+
|
8
|
+
require 'bundler/setup'
|
9
|
+
require 'ruby_smb'
|
10
|
+
|
11
|
+
address = ARGV[0]
|
12
|
+
username = ARGV[1]
|
13
|
+
password = ARGV[2]
|
14
|
+
registry_key = ARGV[3]
|
15
|
+
value_name = ARGV[4]
|
16
|
+
|
17
|
+
sock = TCPSocket.new address, 445
|
18
|
+
dispatcher = RubySMB::Dispatcher::Socket.new(sock, read_timeout: 60)
|
19
|
+
|
20
|
+
client = RubySMB::Client.new(dispatcher, smb1: true, smb2: true, username: username, password: password)
|
21
|
+
protocol = client.negotiate
|
22
|
+
status = client.authenticate
|
23
|
+
|
24
|
+
puts "#{protocol}: #{status}"
|
25
|
+
puts "Key: #{registry_key}"
|
26
|
+
puts "Value: #{value_name}"
|
27
|
+
|
28
|
+
key_value = client.read_registry_key_value(address, registry_key, value_name)
|
29
|
+
puts key_value
|
30
|
+
|
31
|
+
client.disconnect!
|
32
|
+
|
data/lib/ruby_smb.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'bindata'
|
2
2
|
require 'net/ntlm'
|
3
3
|
require 'net/ntlm/client'
|
4
|
+
require 'openssl'
|
5
|
+
require 'openssl/ccm'
|
6
|
+
require 'openssl/cmac'
|
4
7
|
require 'windows_error'
|
5
8
|
require 'windows_error/nt_status'
|
6
9
|
# A packet parsing and manipulation library for the SMB1 and SMB2 protocols
|
@@ -15,7 +18,6 @@ module RubySMB
|
|
15
18
|
require 'ruby_smb/field'
|
16
19
|
require 'ruby_smb/nbss'
|
17
20
|
require 'ruby_smb/fscc'
|
18
|
-
require 'ruby_smb/dcerpc'
|
19
21
|
require 'ruby_smb/generic_packet'
|
20
22
|
require 'ruby_smb/dispatcher'
|
21
23
|
require 'ruby_smb/version'
|
@@ -23,4 +25,5 @@ module RubySMB
|
|
23
25
|
require 'ruby_smb/smb2'
|
24
26
|
require 'ruby_smb/smb1'
|
25
27
|
require 'ruby_smb/client'
|
28
|
+
require 'ruby_smb/crypto'
|
26
29
|
end
|
data/lib/ruby_smb/client.rb
CHANGED
@@ -8,6 +8,8 @@ module RubySMB
|
|
8
8
|
require 'ruby_smb/client/tree_connect'
|
9
9
|
require 'ruby_smb/client/echo'
|
10
10
|
require 'ruby_smb/client/utils'
|
11
|
+
require 'ruby_smb/client/winreg'
|
12
|
+
require 'ruby_smb/client/encryption'
|
11
13
|
|
12
14
|
include RubySMB::Client::Negotiation
|
13
15
|
include RubySMB::Client::Authentication
|
@@ -15,13 +17,21 @@ module RubySMB
|
|
15
17
|
include RubySMB::Client::TreeConnect
|
16
18
|
include RubySMB::Client::Echo
|
17
19
|
include RubySMB::Client::Utils
|
20
|
+
include RubySMB::Client::Winreg
|
21
|
+
include RubySMB::Client::Encryption
|
18
22
|
|
19
23
|
# The Default SMB1 Dialect string used in an SMB1 Negotiate Request
|
20
24
|
SMB1_DIALECT_SMB1_DEFAULT = 'NT LM 0.12'.freeze
|
21
25
|
# The Default SMB2 Dialect string used in an SMB1 Negotiate Request
|
22
26
|
SMB1_DIALECT_SMB2_DEFAULT = 'SMB 2.002'.freeze
|
23
|
-
# Dialect
|
24
|
-
|
27
|
+
# The SMB2 wildcard revision number Dialect string used in an SMB1 Negotiate Request
|
28
|
+
# It indicates that the server implements SMB 2.1 or future dialect revisions
|
29
|
+
# Note that this must be used for SMB3
|
30
|
+
SMB1_DIALECT_SMB2_WILDCARD = 'SMB 2.???'.freeze
|
31
|
+
# Dialect values for SMB2
|
32
|
+
SMB2_DIALECT_DEFAULT = ['0x0202', '0x0210']
|
33
|
+
# Dialect values for SMB3
|
34
|
+
SMB3_DIALECT_DEFAULT = ['0x0300', '0x0302', '0x0311']
|
25
35
|
# The default maximum size of a SMB message that the Client accepts (in bytes)
|
26
36
|
MAX_BUFFER_SIZE = 64512
|
27
37
|
# The default maximum size of a SMB message that the Server accepts (in bytes)
|
@@ -133,6 +143,11 @@ module RubySMB
|
|
133
143
|
# @return [Boolean]
|
134
144
|
attr_accessor :smb2
|
135
145
|
|
146
|
+
# Whether or not the Client should support SMB3
|
147
|
+
# @!attribute [rw] smb3
|
148
|
+
# @return [Boolean]
|
149
|
+
attr_accessor :smb3
|
150
|
+
|
136
151
|
# Tracks the current SMB2 Message ID that keeps communication in sync
|
137
152
|
# @!attribute [rw] smb2_message_id
|
138
153
|
# @return [Integer]
|
@@ -176,12 +191,61 @@ module RubySMB
|
|
176
191
|
# @return [Integer]
|
177
192
|
attr_accessor :server_max_transact_size
|
178
193
|
|
194
|
+
# The algorithm to compute the preauthentication integrity hash (SMB 3.1.1).
|
195
|
+
# @!attribute [rw] preauth_integrity_hash_algorithm
|
196
|
+
# @return [String]
|
197
|
+
attr_accessor :preauth_integrity_hash_algorithm
|
198
|
+
|
199
|
+
# The preauthentication integrity hash value (SMB 3.1.1).
|
200
|
+
# @!attribute [rw] preauth_integrity_hash_value
|
201
|
+
# @return [String]
|
202
|
+
attr_accessor :preauth_integrity_hash_value
|
203
|
+
|
204
|
+
# The algorithm for encryption (SMB 3.x).
|
205
|
+
# @!attribute [rw] encryption_algorithm
|
206
|
+
# @return [String]
|
207
|
+
attr_accessor :encryption_algorithm
|
208
|
+
|
209
|
+
# The client encryption key (SMB 3.x).
|
210
|
+
# @!attribute [rw] client_encryption_key
|
211
|
+
# @return [String]
|
212
|
+
attr_accessor :client_encryption_key
|
213
|
+
|
214
|
+
# The server encryption key (SMB 3.x).
|
215
|
+
# @!attribute [rw] server_encryption_key
|
216
|
+
# @return [String]
|
217
|
+
attr_accessor :server_encryption_key
|
218
|
+
|
219
|
+
# Whether or not encryption is required (SMB 3.x)
|
220
|
+
# @!attribute [rw] encryption_required
|
221
|
+
# @return [Boolean]
|
222
|
+
attr_accessor :encryption_required
|
223
|
+
|
224
|
+
# The encryption algorithms supported by the server (SMB 3.x).
|
225
|
+
# @!attribute [rw] server_encryption_algorithms
|
226
|
+
# @return [Array<Integer>] list of supported encryption algorithms
|
227
|
+
# (constants defined in RubySMB::SMB2::EncryptionCapabilities)
|
228
|
+
attr_accessor :server_encryption_algorithms
|
229
|
+
|
230
|
+
# The compression algorithms supported by the server (SMB 3.x).
|
231
|
+
# @!attribute [rw] server_compression_algorithms
|
232
|
+
# @return [Array<Integer>] list of supported compression algorithms
|
233
|
+
# (constants defined in RubySMB::SMB2::CompressionCapabilities)
|
234
|
+
attr_accessor :server_compression_algorithms
|
235
|
+
|
236
|
+
# The SMB version that has been successfully negotiated. This value is only
|
237
|
+
# set after the NEGOTIATE handshake has been performed.
|
238
|
+
# @!attribute [rw] negotiated_smb_version
|
239
|
+
# @return [Integer] the negotiated SMB version
|
240
|
+
attr_accessor :negotiated_smb_version
|
241
|
+
|
179
242
|
# @param dispatcher [RubySMB::Dispatcher::Socket] the packet dispatcher to use
|
180
243
|
# @param smb1 [Boolean] whether or not to enable SMB1 support
|
181
244
|
# @param smb2 [Boolean] whether or not to enable SMB2 support
|
182
|
-
|
245
|
+
# @param smb3 [Boolean] whether or not to enable SMB3 support
|
246
|
+
def initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.', local_workstation: 'WORKSTATION', always_encrypt: true)
|
183
247
|
raise ArgumentError, 'No Dispatcher provided' unless dispatcher.is_a? RubySMB::Dispatcher::Base
|
184
|
-
if smb1 == false && smb2 == false
|
248
|
+
if smb1 == false && smb2 == false && smb3 == false
|
185
249
|
raise ArgumentError, 'You must enable at least one Protocol'
|
186
250
|
end
|
187
251
|
@dispatcher = dispatcher
|
@@ -194,6 +258,7 @@ module RubySMB
|
|
194
258
|
@signing_required = false
|
195
259
|
@smb1 = smb1
|
196
260
|
@smb2 = smb2
|
261
|
+
@smb3 = smb3
|
197
262
|
@username = username.encode('utf-8') || ''.encode('utf-8')
|
198
263
|
@max_buffer_size = MAX_BUFFER_SIZE
|
199
264
|
# These sizes will be modifed during negotiation
|
@@ -202,6 +267,9 @@ module RubySMB
|
|
202
267
|
@server_max_write_size = RubySMB::SMB2::File::MAX_PACKET_SIZE
|
203
268
|
@server_max_transact_size = RubySMB::SMB2::File::MAX_PACKET_SIZE
|
204
269
|
|
270
|
+
# SMB 3.x options
|
271
|
+
@encryption_required = always_encrypt
|
272
|
+
|
205
273
|
negotiate_version_flag = 0x02000000
|
206
274
|
flags = Net::NTLM::Client::DEFAULT_FLAGS |
|
207
275
|
Net::NTLM::FLAGS[:TARGET_INFO] |
|
@@ -241,7 +309,7 @@ module RubySMB
|
|
241
309
|
# @param data [String] the data the server should echo back (ignored in SMB2)
|
242
310
|
# @return [WindowsError::ErrorCode] the NTStatus of the last response received
|
243
311
|
def echo(count: 1, data: '')
|
244
|
-
response = if smb2
|
312
|
+
response = if smb2 || smb3
|
245
313
|
smb2_echo
|
246
314
|
else
|
247
315
|
smb1_echo(count: count, data: data)
|
@@ -256,10 +324,8 @@ module RubySMB
|
|
256
324
|
# @param packet [RubySMB::GenericPacket] the packet to set the message id for
|
257
325
|
# @return [RubySMB::GenericPacket] the modified packet
|
258
326
|
def increment_smb_message_id(packet)
|
259
|
-
|
260
|
-
|
261
|
-
self.smb2_message_id += 1
|
262
|
-
end
|
327
|
+
packet.smb2_header.message_id = smb2_message_id
|
328
|
+
self.smb2_message_id += 1
|
263
329
|
packet
|
264
330
|
end
|
265
331
|
|
@@ -297,15 +363,32 @@ module RubySMB
|
|
297
363
|
# Sends a LOGOFF command to the remote server to terminate the session
|
298
364
|
#
|
299
365
|
# @return [WindowsError::ErrorCode] the NTStatus of the response
|
366
|
+
# @raise [RubySMB::Error::InvalidPacket] if the response packet is not a LogoffResponse packet
|
300
367
|
def logoff!
|
301
|
-
if smb2
|
368
|
+
if smb2 || smb3
|
302
369
|
request = RubySMB::SMB2::Packet::LogoffRequest.new
|
303
370
|
raw_response = send_recv(request)
|
304
371
|
response = RubySMB::SMB2::Packet::LogoffResponse.read(raw_response)
|
372
|
+
unless response.valid?
|
373
|
+
raise RubySMB::Error::InvalidPacket.new(
|
374
|
+
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
375
|
+
expected_cmd: RubySMB::SMB2::Packet::LogoffResponse::COMMAND,
|
376
|
+
received_proto: response.smb2_header.protocol,
|
377
|
+
received_cmd: response.smb2_header.command
|
378
|
+
)
|
379
|
+
end
|
305
380
|
else
|
306
381
|
request = RubySMB::SMB1::Packet::LogoffRequest.new
|
307
382
|
raw_response = send_recv(request)
|
308
383
|
response = RubySMB::SMB1::Packet::LogoffResponse.read(raw_response)
|
384
|
+
unless response.valid?
|
385
|
+
raise RubySMB::Error::InvalidPacket.new(
|
386
|
+
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
387
|
+
expected_cmd: RubySMB::SMB1::Packet::LogoffResponse::COMMAND,
|
388
|
+
received_proto: response.smb_header.protocol,
|
389
|
+
received_cmd: response.smb_header.command
|
390
|
+
)
|
391
|
+
end
|
309
392
|
end
|
310
393
|
wipe_state!
|
311
394
|
response.status_code
|
@@ -316,8 +399,9 @@ module RubySMB
|
|
316
399
|
#
|
317
400
|
# @param packet [RubySMB::GenericPacket] the request to be sent
|
318
401
|
# @return [String] the raw response data received
|
319
|
-
def send_recv(packet)
|
320
|
-
|
402
|
+
def send_recv(packet, encrypt: false)
|
403
|
+
version = packet.packet_smb_version
|
404
|
+
case version
|
321
405
|
when 'SMB1'
|
322
406
|
packet.smb_header.uid = user_id if user_id
|
323
407
|
packet = smb1_sign(packet)
|
@@ -325,25 +409,103 @@ module RubySMB
|
|
325
409
|
packet = increment_smb_message_id(packet)
|
326
410
|
packet.smb2_header.session_id = session_id
|
327
411
|
unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest)
|
328
|
-
|
412
|
+
if self.smb2
|
413
|
+
packet = smb2_sign(packet)
|
414
|
+
elsif self.smb3
|
415
|
+
packet = smb3_sign(packet)
|
416
|
+
end
|
329
417
|
end
|
330
418
|
else
|
331
419
|
packet = packet
|
332
420
|
end
|
333
|
-
|
334
|
-
|
421
|
+
|
422
|
+
if can_be_encrypted?(packet) && encryption_supported? && (@encryption_required || encrypt)
|
423
|
+
send_encrypt(packet)
|
424
|
+
raw_response = recv_encrypt
|
425
|
+
loop do
|
426
|
+
break unless is_status_pending?(raw_response)
|
427
|
+
sleep 1
|
428
|
+
raw_response = recv_encrypt
|
429
|
+
end
|
430
|
+
else
|
431
|
+
dispatcher.send_packet(packet)
|
432
|
+
raw_response = dispatcher.recv_packet
|
433
|
+
loop do
|
434
|
+
break unless is_status_pending?(raw_response)
|
435
|
+
sleep 1
|
436
|
+
raw_response = dispatcher.recv_packet
|
437
|
+
end unless version == 'SMB1'
|
438
|
+
end
|
335
439
|
|
336
440
|
self.sequence_counter += 1 if signing_required && !session_key.empty?
|
337
441
|
raw_response
|
338
442
|
end
|
339
443
|
|
444
|
+
# Check if the response is an asynchronous operation with STATUS_PENDING
|
445
|
+
# status code.
|
446
|
+
#
|
447
|
+
# @param raw_response [String] the raw response packet
|
448
|
+
# @return [Boolean] true if it is a status pending operation, false otherwise
|
449
|
+
def is_status_pending?(raw_response)
|
450
|
+
smb2_header = RubySMB::SMB2::SMB2Header.read(raw_response)
|
451
|
+
value = smb2_header.nt_status.value
|
452
|
+
status_code = WindowsError::NTStatus.find_by_retval(value).first
|
453
|
+
status_code == WindowsError::NTStatus::STATUS_PENDING &&
|
454
|
+
smb2_header.flags.async_command == 1
|
455
|
+
end
|
456
|
+
|
457
|
+
# Check if the request packet can be encrypted. Per the SMB spec,
|
458
|
+
# SessionSetupRequest and NegotiateRequest must not be encrypted.
|
459
|
+
#
|
460
|
+
# @param packet [RubySMB::GenericPacket] the request packet
|
461
|
+
# @return [Boolean] true if the packet can be encrypted
|
462
|
+
def can_be_encrypted?(packet)
|
463
|
+
[RubySMB::SMB2::Packet::SessionSetupRequest, RubySMB::SMB2::Packet::NegotiateRequest].none? do |klass|
|
464
|
+
packet.is_a?(klass)
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
# Check if the current dialect support encryption.
|
469
|
+
#
|
470
|
+
# @return [Boolean] true if encryption is supported
|
471
|
+
def encryption_supported?
|
472
|
+
['0x0300', '0x0302', '0x0311'].include?(@dialect)
|
473
|
+
end
|
474
|
+
|
475
|
+
# Encrypt and send a packet
|
476
|
+
def send_encrypt(packet)
|
477
|
+
begin
|
478
|
+
transform_request = smb3_encrypt(packet.to_binary_s)
|
479
|
+
rescue RubySMB::Error::RubySMBError => e
|
480
|
+
raise RubySMB::Error::EncryptionError, "Error while encrypting #{packet.class.name} packet (SMB #{@dialect}): #{e}"
|
481
|
+
end
|
482
|
+
dispatcher.send_packet(transform_request)
|
483
|
+
end
|
484
|
+
|
485
|
+
# Receives the raw response through the Dispatcher and decrypt the packet.
|
486
|
+
#
|
487
|
+
# @return [String] the raw unencrypted packet
|
488
|
+
def recv_encrypt
|
489
|
+
raw_response = dispatcher.recv_packet
|
490
|
+
begin
|
491
|
+
transform_response = RubySMB::SMB2::Packet::TransformHeader.read(raw_response)
|
492
|
+
rescue IOError
|
493
|
+
raise RubySMB::Error::InvalidPacket, 'Not a SMB2 TransformHeader packet'
|
494
|
+
end
|
495
|
+
begin
|
496
|
+
smb3_decrypt(transform_response)
|
497
|
+
rescue RubySMB::Error::RubySMBError => e
|
498
|
+
raise RubySMB::Error::EncryptionError, "Error while decrypting #{transform_response.class.name} packet (SMB #@dialect}): #{e}"
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
340
502
|
# Connects to the supplied share
|
341
503
|
#
|
342
504
|
# @param share [String] the path to the share in `\\server\share_name` format
|
343
505
|
# @return [RubySMB::SMB1::Tree] if talking over SMB1
|
344
506
|
# @return [RubySMB::SMB2::Tree] if talking over SMB2
|
345
507
|
def tree_connect(share)
|
346
|
-
connected_tree = if smb2
|
508
|
+
connected_tree = if smb2 || smb3
|
347
509
|
smb2_tree_connect(share)
|
348
510
|
else
|
349
511
|
smb1_tree_connect(share)
|
@@ -373,6 +535,8 @@ module RubySMB
|
|
373
535
|
self.session_key = ''
|
374
536
|
self.sequence_counter = 0
|
375
537
|
self.smb2_message_id = 0
|
538
|
+
self.client_encryption_key = nil
|
539
|
+
self.server_encryption_key = nil
|
376
540
|
end
|
377
541
|
|
378
542
|
# Requests a NetBIOS Session Service using the provided name.
|
@@ -380,14 +544,19 @@ module RubySMB
|
|
380
544
|
# @param name [String] the NetBIOS name to request
|
381
545
|
# @return [TrueClass] if session request is granted
|
382
546
|
# @raise [RubySMB::Error::NetBiosSessionService] if session request is refused
|
547
|
+
# @raise [RubySMB::Error::InvalidPacket] if the response packet is not a NBSS packet
|
383
548
|
def session_request(name = '*SMBSERVER')
|
384
549
|
session_request = session_request_packet(name)
|
385
550
|
dispatcher.send_packet(session_request, nbss_header: false)
|
386
551
|
raw_response = dispatcher.recv_packet(full_response: true)
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
552
|
+
begin
|
553
|
+
session_header = RubySMB::Nbss::SessionHeader.read(raw_response)
|
554
|
+
if session_header.session_packet_type == RubySMB::Nbss::NEGATIVE_SESSION_RESPONSE
|
555
|
+
negative_session_response = RubySMB::Nbss::NegativeSessionResponse.read(raw_response)
|
556
|
+
raise RubySMB::Error::NetBiosSessionService, "Session Request failed: #{negative_session_response.error_msg}"
|
557
|
+
end
|
558
|
+
rescue IOError
|
559
|
+
raise RubySMB::Error::InvalidPacket, 'Not a NBSS packet'
|
391
560
|
end
|
392
561
|
|
393
562
|
return true
|
@@ -410,5 +579,16 @@ module RubySMB
|
|
410
579
|
session_request
|
411
580
|
end
|
412
581
|
|
582
|
+
def update_preauth_hash(data)
|
583
|
+
unless @preauth_integrity_hash_algorithm
|
584
|
+
raise RubySMB::Error::EncryptionError.new(
|
585
|
+
'Cannot compute the Preauth Integrity Hash value: Preauth Integrity Hash Algorithm is nil'
|
586
|
+
)
|
587
|
+
end
|
588
|
+
@preauth_integrity_hash_value = OpenSSL::Digest.digest(
|
589
|
+
@preauth_integrity_hash_algorithm,
|
590
|
+
@preauth_integrity_hash_value + data.to_binary_s
|
591
|
+
)
|
592
|
+
end
|
413
593
|
end
|
414
594
|
end
|
@@ -54,14 +54,15 @@ module RubySMB
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def smb1_anonymous_auth_response(raw_response)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
packet = RubySMB::SMB1::Packet::SessionSetupLegacyResponse.read(raw_response)
|
58
|
+
|
59
|
+
unless packet.valid?
|
60
|
+
raise RubySMB::Error::InvalidPacket.new(
|
61
|
+
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
62
|
+
expected_cmd: RubySMB::SMB1::Packet::SessionSetupLegacyResponse::COMMAND,
|
63
|
+
received_proto: packet.smb_header.protocol,
|
64
|
+
received_cmd: packet.smb_header.command
|
65
|
+
)
|
65
66
|
end
|
66
67
|
packet
|
67
68
|
end
|
@@ -147,14 +148,15 @@ module RubySMB
|
|
147
148
|
|
148
149
|
# Takes the raw binary string and returns a {RubySMB::SMB1::Packet::SessionSetupResponse}
|
149
150
|
def smb1_ntlmssp_final_packet(raw_response)
|
150
|
-
|
151
|
-
packet = RubySMB::SMB1::Packet::SessionSetupResponse.read(raw_response)
|
152
|
-
rescue
|
153
|
-
packet = RubySMB::SMB1::Packet::EmptyPacket.read(raw_response)
|
154
|
-
end
|
151
|
+
packet = RubySMB::SMB1::Packet::SessionSetupResponse.read(raw_response)
|
155
152
|
|
156
|
-
unless packet.
|
157
|
-
raise RubySMB::Error::InvalidPacket
|
153
|
+
unless packet.valid?
|
154
|
+
raise RubySMB::Error::InvalidPacket.new(
|
155
|
+
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
156
|
+
expected_cmd: RubySMB::SMB1::Packet::SessionSetupResponse::COMMAND,
|
157
|
+
received_proto: packet.smb_header.protocol,
|
158
|
+
received_cmd: packet.smb_header.command
|
159
|
+
)
|
158
160
|
end
|
159
161
|
packet
|
160
162
|
end
|
@@ -162,15 +164,20 @@ module RubySMB
|
|
162
164
|
# Takes the raw binary string and returns a {RubySMB::SMB1::Packet::SessionSetupResponse}
|
163
165
|
def smb1_ntlmssp_challenge_packet(raw_response)
|
164
166
|
packet = RubySMB::SMB1::Packet::SessionSetupResponse.read(raw_response)
|
165
|
-
|
167
|
+
unless packet.valid?
|
168
|
+
raise RubySMB::Error::InvalidPacket.new(
|
169
|
+
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
170
|
+
expected_cmd: RubySMB::SMB1::Packet::SessionSetupResponse::COMMAND,
|
171
|
+
received_proto: packet.smb_header.protocol,
|
172
|
+
received_cmd: packet.smb_header.command
|
173
|
+
)
|
174
|
+
end
|
166
175
|
|
176
|
+
status_code = packet.status_code
|
167
177
|
unless status_code.name == 'STATUS_MORE_PROCESSING_REQUIRED'
|
168
|
-
raise RubySMB::Error::UnexpectedStatusCode, status_code
|
178
|
+
raise RubySMB::Error::UnexpectedStatusCode, status_code
|
169
179
|
end
|
170
180
|
|
171
|
-
unless packet.smb_header.command == RubySMB::SMB1::Commands::SMB_COM_SESSION_SETUP
|
172
|
-
raise RubySMB::Error::InvalidPacket, "Command was #{packet.smb_header.command} and not #{RubySMB::SMB1::Commands::SMB_COM_SESSION_SETUP}"
|
173
|
-
end
|
174
181
|
packet
|
175
182
|
end
|
176
183
|
|
@@ -194,6 +201,9 @@ module RubySMB
|
|
194
201
|
def smb2_authenticate
|
195
202
|
response = smb2_ntlmssp_negotiate
|
196
203
|
challenge_packet = smb2_ntlmssp_challenge_packet(response)
|
204
|
+
if @dialect == '0x0311'
|
205
|
+
update_preauth_hash(challenge_packet)
|
206
|
+
end
|
197
207
|
@session_id = challenge_packet.smb2_header.session_id
|
198
208
|
type2_b64_message = smb2_type2_message(challenge_packet)
|
199
209
|
type3_message = @ntlm_client.init_context(type2_b64_message)
|
@@ -206,28 +216,49 @@ module RubySMB
|
|
206
216
|
raw = smb2_ntlmssp_authenticate(type3_message, @session_id)
|
207
217
|
response = smb2_ntlmssp_final_packet(raw)
|
208
218
|
|
219
|
+
if @smb3 && !@encryption_required && response.session_flags.encrypt_data == 1
|
220
|
+
@encryption_required = true
|
221
|
+
end
|
222
|
+
######
|
223
|
+
# DEBUG
|
224
|
+
#puts "Session ID = #{@session_id.to_binary_s.each_byte.map {|e| '%02x' % e}.join}"
|
225
|
+
#puts "Session key = #{@session_key.each_byte.map {|e| '%02x' % e}.join}"
|
226
|
+
#puts "PreAuthHash = #{@preauth_integrity_hash_value.each_byte.map {|e| '%02x' % e}.join}" if @preauth_integrity_hash_value
|
227
|
+
######
|
228
|
+
|
209
229
|
response.status_code
|
210
230
|
end
|
211
231
|
|
212
232
|
# Takes the raw binary string and returns a {RubySMB::SMB2::Packet::SessionSetupResponse}
|
213
233
|
def smb2_ntlmssp_final_packet(raw_response)
|
214
234
|
packet = RubySMB::SMB2::Packet::SessionSetupResponse.read(raw_response)
|
215
|
-
unless packet.
|
216
|
-
raise RubySMB::Error::InvalidPacket
|
235
|
+
unless packet.valid?
|
236
|
+
raise RubySMB::Error::InvalidPacket.new(
|
237
|
+
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
238
|
+
expected_cmd: RubySMB::SMB2::Packet::SessionSetupResponse::COMMAND,
|
239
|
+
received_proto: packet.smb2_header.protocol,
|
240
|
+
received_cmd: packet.smb2_header.command
|
241
|
+
)
|
217
242
|
end
|
243
|
+
|
218
244
|
packet
|
219
245
|
end
|
220
246
|
|
221
247
|
# Takes the raw binary string and returns a {RubySMB::SMB2::Packet::SessionSetupResponse}
|
222
248
|
def smb2_ntlmssp_challenge_packet(raw_response)
|
223
249
|
packet = RubySMB::SMB2::Packet::SessionSetupResponse.read(raw_response)
|
224
|
-
|
225
|
-
|
226
|
-
|
250
|
+
unless packet.valid?
|
251
|
+
raise RubySMB::Error::InvalidPacket.new(
|
252
|
+
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
253
|
+
expected_cmd: RubySMB::SMB2::Packet::SessionSetupResponse::COMMAND,
|
254
|
+
received_proto: packet.smb2_header.protocol,
|
255
|
+
received_cmd: packet.smb2_header.command
|
256
|
+
)
|
227
257
|
end
|
228
258
|
|
229
|
-
|
230
|
-
|
259
|
+
status_code = packet.status_code
|
260
|
+
unless status_code.name == 'STATUS_MORE_PROCESSING_REQUIRED'
|
261
|
+
raise RubySMB::Error::UnexpectedStatusCode, status_code
|
231
262
|
end
|
232
263
|
packet
|
233
264
|
end
|
@@ -238,7 +269,11 @@ module RubySMB
|
|
238
269
|
# @return [String] the binary string response from the server
|
239
270
|
def smb2_ntlmssp_negotiate
|
240
271
|
packet = smb2_ntlmssp_negotiate_packet
|
241
|
-
send_recv(packet)
|
272
|
+
response = send_recv(packet)
|
273
|
+
if @dialect == '0x0311'
|
274
|
+
update_preauth_hash(packet)
|
275
|
+
end
|
276
|
+
response
|
242
277
|
end
|
243
278
|
|
244
279
|
# Creates the {RubySMB::SMB2::Packet::SessionSetupRequest} packet
|
@@ -250,10 +285,7 @@ module RubySMB
|
|
250
285
|
type1_message = ntlm_client.init_context
|
251
286
|
packet = RubySMB::SMB2::Packet::SessionSetupRequest.new
|
252
287
|
packet.set_type1_blob(type1_message.serialize)
|
253
|
-
|
254
|
-
# the Message ID can be out of sync at this point so we re-synch it here.
|
255
|
-
packet.smb2_header.message_id = 1
|
256
|
-
self.smb2_message_id = 2
|
288
|
+
packet.security_mode.signing_enabled = 1
|
257
289
|
packet
|
258
290
|
end
|
259
291
|
|
@@ -276,7 +308,11 @@ module RubySMB
|
|
276
308
|
# @return [String] the raw binary response from the server
|
277
309
|
def smb2_ntlmssp_authenticate(type3_message, user_id)
|
278
310
|
packet = smb2_ntlmssp_auth_packet(type3_message, user_id)
|
279
|
-
send_recv(packet)
|
311
|
+
response = send_recv(packet)
|
312
|
+
if @dialect == '0x0311'
|
313
|
+
update_preauth_hash(packet)
|
314
|
+
end
|
315
|
+
response
|
280
316
|
end
|
281
317
|
|
282
318
|
# Generates the {RubySMB::SMB2::Packet::SessionSetupRequest} packet
|
@@ -289,6 +325,7 @@ module RubySMB
|
|
289
325
|
packet = RubySMB::SMB2::Packet::SessionSetupRequest.new
|
290
326
|
packet.smb2_header.session_id = session_id
|
291
327
|
packet.set_type3_blob(type3_message.serialize)
|
328
|
+
packet.security_mode.signing_enabled = 1
|
292
329
|
packet
|
293
330
|
end
|
294
331
|
|