ruby_smb 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|