ruby_smb 0.0.8 → 0.0.9
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 +0 -0
- data/examples/tree_connect.rb +27 -0
- data/lib/ruby_smb/client.rb +25 -2
- data/lib/ruby_smb/client/authentication.rb +5 -6
- data/lib/ruby_smb/client/negotiation.rb +2 -3
- data/lib/ruby_smb/client/signing.rb +6 -2
- data/lib/ruby_smb/client/tree_connect.rb +86 -0
- data/lib/ruby_smb/generic_packet.rb +1 -1
- data/lib/ruby_smb/smb1.rb +1 -1
- data/lib/ruby_smb/smb1/bit_field.rb +4 -0
- data/lib/ruby_smb/smb1/bit_field/directory_access_mask.rb +38 -0
- data/lib/ruby_smb/smb1/bit_field/file_access_mask.rb +38 -0
- data/lib/ruby_smb/smb1/bit_field/optional_support.rb +19 -0
- data/lib/ruby_smb/smb1/bit_field/tree_connect_flags.rb +18 -0
- data/lib/ruby_smb/smb1/commands.rb +2 -0
- data/lib/ruby_smb/smb1/packet.rb +4 -0
- data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +34 -0
- data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +74 -0
- data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +29 -0
- data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +30 -0
- data/lib/ruby_smb/smb1/tree.rb +55 -0
- data/lib/ruby_smb/smb2.rb +1 -0
- data/lib/ruby_smb/smb2/bit_field.rb +4 -0
- data/lib/ruby_smb/smb2/bit_field/directory_access_mask.rb +38 -0
- data/lib/ruby_smb/smb2/bit_field/file_access_mask.rb +38 -0
- data/lib/ruby_smb/smb2/bit_field/share_capabailities.rb +21 -0
- data/lib/ruby_smb/smb2/bit_field/share_flags.rb +75 -0
- data/lib/ruby_smb/smb2/packet.rb +5 -0
- data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +27 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +50 -0
- data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +21 -0
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +22 -0
- data/lib/ruby_smb/smb2/smb2_header.rb +3 -3
- data/lib/ruby_smb/smb2/tree.rb +51 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/ruby_smb.gemspec +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +114 -4
- data/spec/lib/ruby_smb/smb1/bit_field/directory_access_mask_spec.rb +190 -0
- data/spec/lib/ruby_smb/smb1/bit_field/file_access_mask_spec.rb +190 -0
- data/spec/lib/ruby_smb/smb1/bit_field/optional_support_spec.rb +52 -0
- data/spec/lib/ruby_smb/smb1/bit_field/tree_connect_flags_spec.rb +37 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_request_spec.rb +53 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +86 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_request_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_response_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +55 -0
- data/spec/lib/ruby_smb/smb2/bit_field/directory_access_mask_spec.rb +190 -0
- data/spec/lib/ruby_smb/smb2/bit_field/file_access_mask_spec.rb +190 -0
- data/spec/lib/ruby_smb/smb2/bit_field/share_capabilities_spec.rb +54 -0
- data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +184 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +49 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +57 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +54 -0
- metadata +63 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4447c748fa5ae3b4bade1f7da2f90b05e98f90e3
|
4
|
+
data.tar.gz: 0a077bd853a42f08210f527475965459347570a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0284a70fde3ac94578b232fb30cfd0a2a579947104a700371cd04f78b9b29ff295ac4f90423fbb280848fc35f1095b42c9f3caa0c229dbee02a1f8480466b28e
|
7
|
+
data.tar.gz: 94ba89646185e15f2c2a945849948287fb01734523c092fbe410f0e8d42d31b518c53eb2689192d64358fda5493fbf791d12e3cd0e3ce2102828f0345910ad13
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# This example script is used for testing TreeConnect functionality
|
4
|
+
# It will attempt to connect to a specific share and then disconnect.
|
5
|
+
# Example usage: ruby tree_connect.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE
|
6
|
+
# This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials
|
7
|
+
|
8
|
+
require 'bundler/setup'
|
9
|
+
require 'ruby_smb'
|
10
|
+
|
11
|
+
address = ARGV[0]
|
12
|
+
username = ARGV[1]
|
13
|
+
password = ARGV[2]
|
14
|
+
share = ARGV[3]
|
15
|
+
path = "\\\\#{address}\\#{share}"
|
16
|
+
|
17
|
+
sock = TCPSocket.new address, 445
|
18
|
+
dispatcher = RubySMB::Dispatcher::Socket.new(sock)
|
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
|
+
|
26
|
+
tree = client.smb2_tree_connect(path)
|
27
|
+
tree.disconnect!
|
data/lib/ruby_smb/client.rb
CHANGED
@@ -6,10 +6,12 @@ module RubySMB
|
|
6
6
|
require 'ruby_smb/client/negotiation'
|
7
7
|
require 'ruby_smb/client/authentication'
|
8
8
|
require 'ruby_smb/client/signing'
|
9
|
+
require 'ruby_smb/client/tree_connect'
|
9
10
|
|
10
11
|
include RubySMB::Client::Negotiation
|
11
12
|
include RubySMB::Client::Authentication
|
12
13
|
include RubySMB::Client::Signing
|
14
|
+
include RubySMB::Client::TreeConnect
|
13
15
|
|
14
16
|
# The Default SMB1 Dialect string used in an SMB1 Negotiate Request
|
15
17
|
SMB1_DIALECT_SMB1_DEFAULT = "NT LM 0.12"
|
@@ -116,6 +118,20 @@ module RubySMB
|
|
116
118
|
@smb2_message_id = 0
|
117
119
|
end
|
118
120
|
|
121
|
+
# Sets the message id field in an SMB2 packet's
|
122
|
+
# header to the one tracked by the client. It then increments
|
123
|
+
# the counter on the client.
|
124
|
+
#
|
125
|
+
# @param packet [RubySMB::GenericPacket] the packet to set the message id for
|
126
|
+
# @return [RubySMB::GenericPacket] the modified packet
|
127
|
+
def increment_smb_message_id(packet)
|
128
|
+
if packet.smb2_header.message_id == 0 && self.smb2_message_id != 0
|
129
|
+
packet.smb2_header.message_id = self.smb2_message_id
|
130
|
+
self.smb2_message_id += 1
|
131
|
+
end
|
132
|
+
packet
|
133
|
+
end
|
134
|
+
|
119
135
|
def login(username: self.username, password: self.password, domain: self.domain, local_workstation: self.local_workstation )
|
120
136
|
@domain = domain
|
121
137
|
@local_workstation = local_workstation
|
@@ -141,15 +157,22 @@ module RubySMB
|
|
141
157
|
def send_recv(packet)
|
142
158
|
case packet.packet_smb_version
|
143
159
|
when 'SMB1'
|
160
|
+
if self.user_id
|
161
|
+
packet.smb_header.uid = self.user_id
|
162
|
+
end
|
144
163
|
packet = smb1_sign(packet)
|
145
164
|
when 'SMB2'
|
146
|
-
packet =
|
165
|
+
packet = increment_smb_message_id(packet)
|
166
|
+
packet.smb2_header.session_id = self.session_id
|
167
|
+
unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest)
|
168
|
+
packet = smb2_sign(packet)
|
169
|
+
end
|
147
170
|
else
|
148
171
|
packet = packet
|
149
172
|
end
|
150
173
|
dispatcher.send_packet(packet)
|
151
174
|
raw_response = dispatcher.recv_packet
|
152
|
-
if self.
|
175
|
+
if self.signing_required && !self.session_key.empty?
|
153
176
|
self.sequence_counter += 1
|
154
177
|
end
|
155
178
|
raw_response
|
@@ -136,12 +136,11 @@ module RubySMB
|
|
136
136
|
response = smb2_ntlmssp_negotiate
|
137
137
|
challenge_packet = smb2_ntlmssp_challenge_packet(response)
|
138
138
|
session_id = challenge_packet.smb2_header.session_id
|
139
|
+
self.session_id = session_id
|
139
140
|
challenge_message = smb2_type2_message(challenge_packet)
|
140
141
|
raw = smb2_ntlmssp_authenticate(challenge_message, session_id)
|
141
142
|
response = smb2_ntlmssp_final_packet(raw)
|
142
|
-
|
143
|
-
self.session_id = response.smb2_header.session_id if response_code.name == "STATUS_SUCCESS"
|
144
|
-
response_code
|
143
|
+
response.status_code
|
145
144
|
end
|
146
145
|
|
147
146
|
# Takes the raw binary string and returns a {RubySMB::SMB2::Packet::SessionSetupResponse}
|
@@ -185,7 +184,9 @@ module RubySMB
|
|
185
184
|
type1_message = ntlm_client.init_context
|
186
185
|
packet = RubySMB::SMB2::Packet::SessionSetupRequest.new
|
187
186
|
packet.set_type1_blob(type1_message.serialize)
|
188
|
-
|
187
|
+
# This Message ID should always be 1, but thanks to Multi-Protocol Negotiation
|
188
|
+
# the Message ID can be out of sync at this point so we re-synch it here.
|
189
|
+
packet.smb2_header.message_id = 1
|
189
190
|
self.smb2_message_id = 2
|
190
191
|
packet
|
191
192
|
end
|
@@ -225,8 +226,6 @@ module RubySMB
|
|
225
226
|
packet = RubySMB::SMB2::Packet::SessionSetupRequest.new
|
226
227
|
packet.smb2_header.session_id = session_id
|
227
228
|
packet.set_type3_blob(type3_message.serialize)
|
228
|
-
packet.smb2_header.message_id = self.smb2_message_id
|
229
|
-
self.smb2_message_id += 1
|
230
229
|
packet
|
231
230
|
end
|
232
231
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'securerandom'
|
1
2
|
module RubySMB
|
2
3
|
class Client
|
3
4
|
# This module holds all of the methods backing the {RubySMB::Client#negotiate} method
|
@@ -114,11 +115,9 @@ module RubySMB
|
|
114
115
|
# @ return [RubySMB::SMB2::Packet::NegotiateRequest] a completed SMB2 Negotiate Request packet
|
115
116
|
def smb2_negotiate_request
|
116
117
|
packet = RubySMB::SMB2::Packet::NegotiateRequest.new
|
117
|
-
packet.smb2_header.message_id = self.smb2_message_id
|
118
|
-
# Increment the message id when doing SMB2
|
119
|
-
self.smb2_message_id += 1
|
120
118
|
packet.security_mode.signing_enabled = 1
|
121
119
|
packet.add_dialect(SMB2_DIALECT_DEFAULT)
|
120
|
+
packet.client_guid = SecureRandom.random_bytes(16)
|
122
121
|
packet
|
123
122
|
end
|
124
123
|
end
|
@@ -17,7 +17,9 @@ module RubySMB
|
|
17
17
|
# @return [RubySMB::GenericPacket] the packet, signed if needed
|
18
18
|
def smb1_sign(packet)
|
19
19
|
if self.signing_required && !self.session_key.empty?
|
20
|
-
|
20
|
+
# Pack the Sequence counter into a int64le
|
21
|
+
packed_sequence_counter = [self.sequence_counter].pack('Q<')
|
22
|
+
packet.smb_header.security_features = packed_sequence_counter
|
21
23
|
signature = OpenSSL::Digest::MD5.digest(self.session_key + packet.to_binary_s)[0,8]
|
22
24
|
packet.smb_header.security_features = signature
|
23
25
|
self.sequence_counter += 1
|
@@ -35,8 +37,10 @@ module RubySMB
|
|
35
37
|
# @return [RubySMB::GenericPacket] the packet, signed if needed
|
36
38
|
def smb2_sign(packet)
|
37
39
|
if self.signing_required && !self.session_key.empty?
|
40
|
+
packet.smb2_header.flags.signed = 1
|
41
|
+
packet.smb2_header.signature = "\x00" * 16
|
38
42
|
hmac = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, self.session_key, packet.to_binary_s)
|
39
|
-
packet.smb2_header.signature = hmac
|
43
|
+
packet.smb2_header.signature = hmac[0,16]
|
40
44
|
packet
|
41
45
|
else
|
42
46
|
packet
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module RubySMB
|
2
|
+
class Client
|
3
|
+
|
4
|
+
# This module contains all of the methods for a client to connect to a
|
5
|
+
# remote share or named pipe.
|
6
|
+
module TreeConnect
|
7
|
+
|
8
|
+
#
|
9
|
+
# SMB 1 Methods
|
10
|
+
#
|
11
|
+
|
12
|
+
# Sends a request to connect to a remote Tree and returns the
|
13
|
+
# {RubySMB::SMB1::Tree}
|
14
|
+
#
|
15
|
+
# @param share [String] the share path to connect to
|
16
|
+
# @return [RubySMB::SMB1::Tree] the connected Tree
|
17
|
+
def smb1_tree_connect(share)
|
18
|
+
request = RubySMB::SMB1::Packet::TreeConnectRequest.new
|
19
|
+
request.smb_header.tid = 65535
|
20
|
+
request.data_block.path = share
|
21
|
+
raw_response = send_recv(request)
|
22
|
+
begin
|
23
|
+
response = RubySMB::SMB1::Packet::TreeConnectResponse.read(raw_response)
|
24
|
+
rescue EOFError
|
25
|
+
response = RubySMB::SMB1::Packet::ErrorPacket.read(raw_response)
|
26
|
+
end
|
27
|
+
smb1_tree_from_response(share, response)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Parses a Tree structure from a Tree Connect Response
|
31
|
+
#
|
32
|
+
# @param share [String] the share path to connect to
|
33
|
+
# @param response [RubySMB::SMB1::Packet::TreeConnectResponse] the response packet to parse into our Tree
|
34
|
+
# @return [RubySMB::SMB1::Tree]
|
35
|
+
def smb1_tree_from_response(share,response)
|
36
|
+
unless response.smb_header.command == RubySMB::SMB1::Commands::SMB_COM_TREE_CONNECT
|
37
|
+
raise RubySMB::Error::InvalidPacket, "Not a TreeConnectResponse"
|
38
|
+
end
|
39
|
+
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
40
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code.name
|
41
|
+
end
|
42
|
+
RubySMB::SMB1::Tree.new(client: self, share: share, response: response)
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# SMB2 Methods
|
47
|
+
#
|
48
|
+
|
49
|
+
# Sends a request to connect to a remote Tree and returns the
|
50
|
+
# {RubySMB::SMB2::Tree}
|
51
|
+
#
|
52
|
+
# @param share [String] the share path to connect to
|
53
|
+
# @return [RubySMB::SMB2::Tree] the connected Tree
|
54
|
+
def smb2_tree_connect(share)
|
55
|
+
request = RubySMB::SMB2::Packet::TreeConnectRequest.new
|
56
|
+
request.smb2_header.tree_id = 65535
|
57
|
+
request.encode_path(share)
|
58
|
+
raw_response = send_recv(request)
|
59
|
+
begin
|
60
|
+
response = RubySMB::SMB2::Packet::TreeConnectResponse.read(raw_response)
|
61
|
+
rescue EOFError
|
62
|
+
response = RubySMB::SMB2::Packet::ErrorPacket.read(raw_response)
|
63
|
+
end
|
64
|
+
smb2_tree_from_response(share, response)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Parses a Tree structure from a Tree Connect Response
|
68
|
+
#
|
69
|
+
# @param share [String] the share path to connect to
|
70
|
+
# @param response [RubySMB::SMB2::Packet::TreeConnectResponse] the response packet to parse into our Tree
|
71
|
+
# @return [RubySMB::SMB2::Tree]
|
72
|
+
def smb2_tree_from_response(share,response)
|
73
|
+
unless response.smb2_header.command == RubySMB::SMB2::Commands::TREE_CONNECT
|
74
|
+
raise RubySMB::Error::InvalidPacket, "Not a TreeConnectResponse"
|
75
|
+
end
|
76
|
+
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
77
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code.name
|
78
|
+
end
|
79
|
+
RubySMB::SMB2::Tree.new(client: self, share: share, response: response)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -161,7 +161,7 @@ module RubySMB
|
|
161
161
|
def process_array_field(array_field, depth)
|
162
162
|
array_field_str = ''
|
163
163
|
array_field.each do |sub_field|
|
164
|
-
fields = sub_field.class.fields.
|
164
|
+
fields = sub_field.class.fields.raw_fields
|
165
165
|
sub_field_hashes = self.class.walk_fields(fields)
|
166
166
|
sub_field_hashes.each do |sub_field_hash|
|
167
167
|
name = sub_field_hash[:name]
|
data/lib/ruby_smb/smb1.rb
CHANGED
@@ -5,6 +5,10 @@ module RubySMB
|
|
5
5
|
require 'ruby_smb/smb1/bit_field/header_flags2'
|
6
6
|
require 'ruby_smb/smb1/bit_field/security_mode'
|
7
7
|
require 'ruby_smb/smb1/bit_field/capabilities'
|
8
|
+
require 'ruby_smb/smb1/bit_field/tree_connect_flags'
|
9
|
+
require 'ruby_smb/smb1/bit_field/optional_support'
|
10
|
+
require 'ruby_smb/smb1/bit_field/directory_access_mask'
|
11
|
+
require 'ruby_smb/smb1/bit_field/file_access_mask'
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB1
|
3
|
+
module BitField
|
4
|
+
# An Access Mask bit field used to describe the permissions on a Directory, as defined in
|
5
|
+
# [2.2.1.4.2 Directory_Access_Mask](https://msdn.microsoft.com/en-us/library/ff470234.aspx)
|
6
|
+
class DirectoryAccessMask < BinData::Record
|
7
|
+
endian :little
|
8
|
+
bit1 :read_attr, label: 'Read Attributes'
|
9
|
+
bit1 :delete_child, label: 'Delete Child'
|
10
|
+
bit1 :traverse, label: 'Traverse'
|
11
|
+
bit1 :write_ea, label: 'Write Extended Attributes'
|
12
|
+
bit1 :read_ea, label: 'Read Extended Attributes'
|
13
|
+
bit1 :add_subdir, label: 'Add Subdirectory'
|
14
|
+
bit1 :add_file, label: 'Add File'
|
15
|
+
bit1 :list, label: 'List Directory'
|
16
|
+
# byte boundary
|
17
|
+
bit7 :reserved, label: 'Reserved Space'
|
18
|
+
bit1 :write_attr, label: 'Write Attributes'
|
19
|
+
|
20
|
+
# byte boundary
|
21
|
+
bit3 :reserved2, label: 'Reserved Space'
|
22
|
+
bit1 :synchronize, label: 'Synchronize'
|
23
|
+
bit1 :write_owner, label: 'Write Owner'
|
24
|
+
bit1 :write_dac, label: 'Write DAC'
|
25
|
+
bit1 :read_control, label: 'Read Control'
|
26
|
+
bit1 :delete_access, label: 'Delete'
|
27
|
+
# byte boundary
|
28
|
+
bit1 :generic_read, label: 'Generic Read'
|
29
|
+
bit1 :generic_write, label: 'Generic Write'
|
30
|
+
bit1 :generic_execute, label: 'Generic Execute'
|
31
|
+
bit1 :generic_all, label: 'Generic All'
|
32
|
+
bit2 :reserved3
|
33
|
+
bit1 :maximum, label: 'Maximum Allowed'
|
34
|
+
bit1 :system_security, label: 'System Security'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB1
|
3
|
+
module BitField
|
4
|
+
# An Access Mask bit field used to describe the permissions on a File, Printer, or named Pipe. As defined in
|
5
|
+
# [2.2.1.4.1 File_Pipe_Printer_Access_Mask](https://msdn.microsoft.com/en-us/library/ff469915.aspx)
|
6
|
+
class FileAccessMask < BinData::Record
|
7
|
+
endian :little
|
8
|
+
bit1 :read_attr, label: 'Read Attributes'
|
9
|
+
bit1 :delete_child, label: 'Delete Child'
|
10
|
+
bit1 :execute, label: 'Traverse'
|
11
|
+
bit1 :write_ea, label: 'Write Extended Attributes'
|
12
|
+
bit1 :read_ea, label: 'Read Extended Attributes'
|
13
|
+
bit1 :append_data, label: 'Append Data'
|
14
|
+
bit1 :write_data, label: 'Write Data'
|
15
|
+
bit1 :read_data, label: 'Read Data'
|
16
|
+
# byte boundary
|
17
|
+
bit7 :reserved, label: 'Reserved Space'
|
18
|
+
bit1 :write_attr, label: 'Write Attributes'
|
19
|
+
|
20
|
+
# byte boundary
|
21
|
+
bit3 :reserved2, label: 'Reserved Space'
|
22
|
+
bit1 :synchronize, label: 'Synchronize'
|
23
|
+
bit1 :write_owner, label: 'Write Owner'
|
24
|
+
bit1 :write_dac, label: 'Write DAC'
|
25
|
+
bit1 :read_control, label: 'Read Control'
|
26
|
+
bit1 :delete_access, label: 'Delete'
|
27
|
+
# byte boundary
|
28
|
+
bit1 :generic_read, label: 'Generic Read'
|
29
|
+
bit1 :generic_write, label: 'Generic Write'
|
30
|
+
bit1 :generic_execute, label: 'Generic Execute'
|
31
|
+
bit1 :generic_all, label: 'Generic All'
|
32
|
+
bit2 :reserved3
|
33
|
+
bit1 :maximum, label: 'Maximum Allowed'
|
34
|
+
bit1 :system_security, label: 'System Security'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB1
|
3
|
+
module BitField
|
4
|
+
# The OptionalSupport bit-field for an SMB1 TreeConnect Response Packet
|
5
|
+
# [2.2.4.7.2 Server Response Extensions](https://msdn.microsoft.com/en-us/library/cc246331.aspx)
|
6
|
+
class OptionalSupport < BinData::Record
|
7
|
+
endian :little
|
8
|
+
bit2 :reserved, label: 'Reserved Space', initial_value: 0
|
9
|
+
bit1 :extended_signature, label: 'Extended Signature', initial_value: 0
|
10
|
+
bit1 :unique_filename, label: 'Unique Filename', initial_value: 0
|
11
|
+
bit2 :csc_mask, label: 'CSC Mask', initial_value: 0
|
12
|
+
bit1 :dfs, label: 'DFS Share', initial_value: 0
|
13
|
+
bit1 :search, label: 'Exclusive Search Bits', initial_value: 1
|
14
|
+
bit8 :reserved2, label: 'Reserved Space', initial_value: 0
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB1
|
3
|
+
module BitField
|
4
|
+
# The Flags bit-field for an SMB1 TreeConnect Request Packet
|
5
|
+
# [2.2.4.7.1 Client Request Extensions](https://msdn.microsoft.com/en-us/library/cc246330.aspx)
|
6
|
+
class TreeConnectFlags < BinData::Record
|
7
|
+
endian :little
|
8
|
+
bit4 :reserved, label: 'Reserved Space', initial_value: 0
|
9
|
+
bit1 :extended_response, label: 'Extended Response', initial_value: 1
|
10
|
+
bit1 :extended_signature, label: 'Extended Signature', initial_value: 0
|
11
|
+
bit1 :reserved2, label: 'Reserved Space', initial_value: 0
|
12
|
+
bit1 :disconnect, label: 'Disconnect Tree', initial_value: 0
|
13
|
+
bit4 :reserved3, label: 'Reserved Space', initial_value: 0
|
14
|
+
bit4 :reserved4, label: 'Reserved Space', initial_value: 0
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/ruby_smb/smb1/packet.rb
CHANGED
@@ -7,6 +7,10 @@ module RubySMB
|
|
7
7
|
require 'ruby_smb/smb1/packet/negotiate_response_extended'
|
8
8
|
require 'ruby_smb/smb1/packet/session_setup_request'
|
9
9
|
require 'ruby_smb/smb1/packet/session_setup_response'
|
10
|
+
require 'ruby_smb/smb1/packet/tree_connect_request'
|
11
|
+
require 'ruby_smb/smb1/packet/tree_connect_response'
|
12
|
+
require 'ruby_smb/smb1/packet/tree_disconnect_request'
|
13
|
+
require 'ruby_smb/smb1/packet/tree_disconnect_response'
|
10
14
|
end
|
11
15
|
end
|
12
16
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB1
|
3
|
+
module Packet
|
4
|
+
|
5
|
+
# This class represents an SMB1 TreeConnect Request Packet as defined in
|
6
|
+
# [2.2.4.7.1 Client Request Extensions](https://msdn.microsoft.com/en-us/library/cc246330.aspx)
|
7
|
+
class TreeConnectRequest < RubySMB::GenericPacket
|
8
|
+
|
9
|
+
# A SMB1 Parameter Block as defined by the {TreeConnectRequest}
|
10
|
+
class ParameterBlock < RubySMB::SMB1::ParameterBlock
|
11
|
+
and_x_block :andx_block
|
12
|
+
tree_connect_flags :flags
|
13
|
+
uint16 :password_length, label: 'Password Length', initial_value: 0x01
|
14
|
+
end
|
15
|
+
|
16
|
+
class DataBlock < RubySMB::SMB1::DataBlock
|
17
|
+
stringz :password, label: 'Password Field', initial_value: '', length: lambda { self.parent.parameter_block.password_length }
|
18
|
+
stringz :path, label: 'Resource Path'
|
19
|
+
stringz :service, label: 'Resource Type', initial_value: '?????'
|
20
|
+
end
|
21
|
+
|
22
|
+
smb_header :smb_header
|
23
|
+
parameter_block :parameter_block
|
24
|
+
data_block :data_block
|
25
|
+
|
26
|
+
def initialize_instance
|
27
|
+
super
|
28
|
+
smb_header.command = RubySMB::SMB1::Commands::SMB_COM_TREE_CONNECT
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|