Class: RubySMB::Client
- Inherits:
-
Object
show all
- Includes:
- Authentication, Echo, Encryption, Negotiation, TreeConnect, Utils, Winreg, Signing
- Defined in:
- lib/ruby_smb/client.rb,
lib/ruby_smb/client/echo.rb,
lib/ruby_smb/client/utils.rb,
lib/ruby_smb/client/winreg.rb,
lib/ruby_smb/client/encryption.rb,
lib/ruby_smb/client/negotiation.rb,
lib/ruby_smb/client/tree_connect.rb,
lib/ruby_smb/client/authentication.rb
Overview
This module holds all of the methods backing the #open_file method
Defined Under Namespace
Modules: Authentication, Echo, Encryption, Negotiation, TreeConnect, Utils, Winreg
Constant Summary
collapse
- SMB1_DIALECT_SMB1_DEFAULT =
The Default SMB1 Dialect string used in an SMB1 Negotiate Request
'NT LM 0.12'.freeze
- SMB1_DIALECT_SMB2_DEFAULT =
The Default SMB2 Dialect string used in an SMB1 Negotiate Request
'SMB 2.002'.freeze
- SMB1_DIALECT_SMB2_WILDCARD =
The SMB2 wildcard revision number Dialect string used in an SMB1 Negotiate Request
It indicates that the server implements SMB 2.1 or future dialect revisions
Note that this must be used for SMB3
'SMB 2.???'.freeze
- SMB2_DIALECT_0202 =
'0x0202'.freeze
- SMB2_DIALECT_0210 =
'0x0210'.freeze
- SMB2_DIALECT_0300 =
'0x0300'.freeze
- SMB2_DIALECT_0302 =
'0x0302'.freeze
- SMB2_DIALECT_0311 =
'0x0311'.freeze
- SMB2_DIALECT_DEFAULT =
[
SMB2_DIALECT_0202,
SMB2_DIALECT_0210,
].freeze
- SMB3_DIALECT_DEFAULT =
[
SMB2_DIALECT_0300,
SMB2_DIALECT_0302,
SMB2_DIALECT_0311
].freeze
- MAX_BUFFER_SIZE =
The default maximum size of a SMB message that the Client accepts (in bytes)
64512
- SERVER_MAX_BUFFER_SIZE =
The default maximum size of a SMB message that the Server accepts (in bytes)
4356
Instance Attribute Summary collapse
Attributes included from Utils
#auth_user, #evasion_opts, #last_file_id, #native_lm, #native_os, #open_files, #send_lm, #send_ntlm, #spnopt, #tree_connects, #use_lanman_key, #use_ntlmv2, #usentlm2_session, #verify_signature
Attributes included from Signing
#session_key
Instance Method Summary
collapse
-
#can_be_encrypted?(packet) ⇒ Boolean
Check if the request packet can be encrypted.
-
#disconnect! ⇒ void
Logs off any currently open session on the server and closes the TCP socket connection.
-
#echo(count: 1, data: '') ⇒ WindowsError::ErrorCode
Sends an Echo request to the server and returns the NTStatus of the last response packet received.
-
#encryption_supported? ⇒ Boolean
Check if the current dialect supports encryption.
-
#increment_smb_message_id(packet) ⇒ RubySMB::GenericPacket
Sets the message id field in an SMB2 packet's header to the one tracked by the client.
-
#initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.', local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS) ⇒ Client
constructor
A new instance of Client.
-
#is_status_pending?(smb2_header) ⇒ Boolean
Check if the response is an asynchronous operation with STATUS_PENDING status code.
-
#login(username: self.username, password: self.password, domain: self.domain, local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS) ⇒ Object
Performs protocol negotiation and session setup.
-
#logoff! ⇒ WindowsError::ErrorCode
Sends a LOGOFF command to the remote server to terminate the session.
-
#net_share_enum_all(host) ⇒ Array
-
#recv_packet(encrypt: false) ⇒ String
Receives the raw response through the Dispatcher and decrypt the packet (if required).
-
#send_packet(packet, encrypt: false) ⇒ Object
Encrypt (if required) and send a packet.
-
#send_recv(packet, encrypt: false) ⇒ String
Sends a packet and receives the raw response through the Dispatcher.
-
#session_request(name = '*SMBSERVER') ⇒ TrueClass
Requests a NetBIOS Session Service using the provided name.
-
#session_request_packet(name = '*SMBSERVER') ⇒ RubySMB::Nbss::SessionRequest
Crafts the NetBIOS SessionRequest packet to be sent for session request operations.
-
#session_setup(user, pass, domain, do_recv = true, local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS) ⇒ Object
-
#tree_connect(share) ⇒ RubySMB::SMB1::Tree, RubySMB::SMB2::Tree
Connects to the supplied share.
-
#update_preauth_hash(data) ⇒ Object
-
#wipe_state! ⇒ void
Resets all of the session state on the client, setting it back to scratch.
Methods included from Encryption
#smb3_decrypt, #smb3_encrypt
Methods included from Winreg
#connect_to_winreg, #enum_registry_key, #enum_registry_values, #has_registry_key?, #read_registry_key_value
Methods included from Utils
#close, #create_pipe, #delete, #last_file, #last_tree, #last_tree_id, #open, #read, #tree_disconnect, #write
Methods included from Echo
#smb1_echo, #smb2_echo
#smb1_tree_connect, #smb1_tree_from_response, #smb2_tree_connect, #smb2_tree_from_response
#authenticate, #smb1_anonymous_auth, #smb1_anonymous_auth_request, #smb1_anonymous_auth_response, #smb1_authenticate, #smb1_ntlmssp_auth_packet, #smb1_ntlmssp_authenticate, #smb1_ntlmssp_challenge_packet, #smb1_ntlmssp_final_packet, #smb1_ntlmssp_negotiate, #smb1_ntlmssp_negotiate_packet, #smb1_session_setup_response, #smb1_type2_message, #smb2_authenticate, #smb2_ntlmssp_auth_packet, #smb2_ntlmssp_authenticate, #smb2_ntlmssp_challenge_packet, #smb2_ntlmssp_final_packet, #smb2_ntlmssp_negotiate, #smb2_ntlmssp_negotiate_packet, #smb2_session_setup_response, #smb2_type2_message
Methods included from PeerInfo
#extract_os_version, #store_target_info
#add_smb3_to_negotiate_request, #negotiate, #negotiate_request, #negotiate_response, #parse_negotiate_response, #parse_smb3_capabilities, #smb1_negotiate_request, #smb2_3_negotiate_request
Methods included from Signing
#smb1_sign, smb1_sign, #smb2_sign, smb2_sign, #smb3_sign, smb3_sign
Constructor Details
#initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.', local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS) ⇒ Client
Returns a new instance of Client.
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
|
# File 'lib/ruby_smb/client.rb', line 315
def initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.',
local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
raise ArgumentError, 'No Dispatcher provided' unless dispatcher.is_a? RubySMB::Dispatcher::Base
if smb1 == false && smb2 == false && smb3 == false
raise ArgumentError, 'You must enable at least one Protocol'
end
@dispatcher = dispatcher
@pid = rand(0xFFFF)
@domain = domain
@local_workstation = local_workstation
@password = password.encode('utf-8') || ''.encode('utf-8')
@sequence_counter = 0
@session_id = 0x00
@session_key = ''
@application_key = ''
@session_is_guest = false
@signing_required = false
@smb1 = smb1
@smb2 = smb2
@smb3 = smb3
@username = username.encode('utf-8') || ''.encode('utf-8')
@max_buffer_size = MAX_BUFFER_SIZE
@server_max_buffer_size = SERVER_MAX_BUFFER_SIZE
@server_max_read_size = RubySMB::SMB2::File::MAX_PACKET_SIZE
@server_max_write_size = RubySMB::SMB2::File::MAX_PACKET_SIZE
@server_max_transact_size = RubySMB::SMB2::File::MAX_PACKET_SIZE
@server_supports_multi_credit = false
@session_encrypt_data = always_encrypt
@ntlm_client = RubySMB::NTLM::Client.new(
@username,
@password,
workstation: @local_workstation,
domain: @domain,
flags: ntlm_flags
)
@tree_connects = []
@open_files = {}
@smb2_message_id = 0
end
|
Instance Attribute Details
#application_key ⇒ String
62
63
64
|
# File 'lib/ruby_smb/client.rb', line 62
def application_key
@application_key
end
|
#client_encryption_key ⇒ String
248
249
250
|
# File 'lib/ruby_smb/client.rb', line 248
def client_encryption_key
@client_encryption_key
end
|
#default_domain ⇒ String
116
117
118
|
# File 'lib/ruby_smb/client.rb', line 116
def default_domain
@default_domain
end
|
#default_name ⇒ String
111
112
113
|
# File 'lib/ruby_smb/client.rb', line 111
def default_name
@default_name
end
|
#dialect ⇒ Integer
141
142
143
|
# File 'lib/ruby_smb/client.rb', line 141
def dialect
@dialect
end
|
67
68
69
|
# File 'lib/ruby_smb/client.rb', line 67
def dispatcher
@dispatcher
end
|
#dns_domain_name ⇒ String
126
127
128
|
# File 'lib/ruby_smb/client.rb', line 126
def dns_domain_name
@dns_domain_name
end
|
#dns_host_name ⇒ String
121
122
123
|
# File 'lib/ruby_smb/client.rb', line 121
def dns_host_name
@dns_host_name
end
|
#dns_tree_name ⇒ String
131
132
133
|
# File 'lib/ruby_smb/client.rb', line 131
def dns_tree_name
@dns_tree_name
end
|
#domain ⇒ String
72
73
74
|
# File 'lib/ruby_smb/client.rb', line 72
def domain
@domain
end
|
#encryption_algorithm ⇒ String
243
244
245
|
# File 'lib/ruby_smb/client.rb', line 243
def encryption_algorithm
@encryption_algorithm
end
|
#local_workstation ⇒ String
77
78
79
|
# File 'lib/ruby_smb/client.rb', line 77
def local_workstation
@local_workstation
end
|
#max_buffer_size ⇒ Integer
206
207
208
|
# File 'lib/ruby_smb/client.rb', line 206
def max_buffer_size
@max_buffer_size
end
|
#negotiated_smb_version ⇒ Integer
295
296
297
|
# File 'lib/ruby_smb/client.rb', line 295
def negotiated_smb_version
@negotiated_smb_version
end
|
#negotiation_security_buffer ⇒ String
309
310
311
|
# File 'lib/ruby_smb/client.rb', line 309
def negotiation_security_buffer
@negotiation_security_buffer
end
|
#ntlm_client ⇒ String
82
83
84
|
# File 'lib/ruby_smb/client.rb', line 82
def ntlm_client
@ntlm_client
end
|
#os_version ⇒ String
136
137
138
|
# File 'lib/ruby_smb/client.rb', line 136
def os_version
@os_version
end
|
#password ⇒ String
87
88
89
|
# File 'lib/ruby_smb/client.rb', line 87
def password
@password
end
|
#peer_native_lm ⇒ String
99
100
101
|
# File 'lib/ruby_smb/client.rb', line 99
def peer_native_lm
@peer_native_lm
end
|
#peer_native_os ⇒ String
93
94
95
|
# File 'lib/ruby_smb/client.rb', line 93
def peer_native_os
@peer_native_os
end
|
#pid ⇒ Integer
200
201
202
|
# File 'lib/ruby_smb/client.rb', line 200
def pid
@pid
end
|
#preauth_integrity_hash_algorithm ⇒ String
233
234
235
|
# File 'lib/ruby_smb/client.rb', line 233
def preauth_integrity_hash_algorithm
@preauth_integrity_hash_algorithm
end
|
#preauth_integrity_hash_value ⇒ String
238
239
240
|
# File 'lib/ruby_smb/client.rb', line 238
def preauth_integrity_hash_value
@preauth_integrity_hash_value
end
|
#primary_domain ⇒ String
106
107
108
|
# File 'lib/ruby_smb/client.rb', line 106
def primary_domain
@primary_domain
end
|
#sequence_counter ⇒ Integer
148
149
150
|
# File 'lib/ruby_smb/client.rb', line 148
def sequence_counter
@sequence_counter
end
|
#server_compression_algorithms ⇒ Array<Integer>
270
271
272
|
# File 'lib/ruby_smb/client.rb', line 270
def server_compression_algorithms
@server_compression_algorithms
end
|
#server_encryption_algorithms ⇒ Array<Integer>
264
265
266
|
# File 'lib/ruby_smb/client.rb', line 264
def server_encryption_algorithms
@server_encryption_algorithms
end
|
#server_encryption_key ⇒ String
253
254
255
|
# File 'lib/ruby_smb/client.rb', line 253
def server_encryption_key
@server_encryption_key
end
|
#server_guid ⇒ String
275
276
277
|
# File 'lib/ruby_smb/client.rb', line 275
def server_guid
@server_guid
end
|
#server_max_buffer_size ⇒ Object
The maximum size SMB message that the Server accepts (in bytes)
The default value is small by default
212
213
214
|
# File 'lib/ruby_smb/client.rb', line 212
def server_max_buffer_size
@server_max_buffer_size
end
|
#server_max_read_size ⇒ Integer
222
223
224
|
# File 'lib/ruby_smb/client.rb', line 222
def server_max_read_size
@server_max_read_size
end
|
#server_max_transact_size ⇒ Integer
228
229
230
|
# File 'lib/ruby_smb/client.rb', line 228
def server_max_transact_size
@server_max_transact_size
end
|
#server_max_write_size ⇒ Integer
217
218
219
|
# File 'lib/ruby_smb/client.rb', line 217
def server_max_write_size
@server_max_write_size
end
|
#server_start_time ⇒ Time
282
283
284
|
# File 'lib/ruby_smb/client.rb', line 282
def server_start_time
@server_start_time
end
|
#server_supports_multi_credit ⇒ Boolean
303
304
305
|
# File 'lib/ruby_smb/client.rb', line 303
def server_supports_multi_credit
@server_supports_multi_credit
end
|
#server_system_time ⇒ Time
289
290
291
|
# File 'lib/ruby_smb/client.rb', line 289
def server_system_time
@server_system_time
end
|
#session_encrypt_data ⇒ Boolean
258
259
260
|
# File 'lib/ruby_smb/client.rb', line 258
def session_encrypt_data
@session_encrypt_data
end
|
#session_id ⇒ Integer
153
154
155
|
# File 'lib/ruby_smb/client.rb', line 153
def session_id
@session_id
end
|
#session_is_guest ⇒ Boolean
158
159
160
|
# File 'lib/ruby_smb/client.rb', line 158
def session_is_guest
@session_is_guest
end
|
#signing_enabled ⇒ Boolean
163
|
# File 'lib/ruby_smb/client.rb', line 163
attr_accessor :signing_required
|
#signing_required ⇒ Object
Whether or not the Server requires signing
163
164
165
|
# File 'lib/ruby_smb/client.rb', line 163
def signing_required
@signing_required
end
|
#smb1 ⇒ Boolean
168
169
170
|
# File 'lib/ruby_smb/client.rb', line 168
def smb1
@smb1
end
|
#smb2 ⇒ Boolean
173
174
175
|
# File 'lib/ruby_smb/client.rb', line 173
def smb2
@smb2
end
|
#smb2_message_id ⇒ Integer
183
184
185
|
# File 'lib/ruby_smb/client.rb', line 183
def smb2_message_id
@smb2_message_id
end
|
#smb3 ⇒ Boolean
178
179
180
|
# File 'lib/ruby_smb/client.rb', line 178
def smb3
@smb3
end
|
#user_id ⇒ Integer
193
194
195
|
# File 'lib/ruby_smb/client.rb', line 193
def user_id
@user_id
end
|
#username ⇒ String
188
189
190
|
# File 'lib/ruby_smb/client.rb', line 188
def username
@username
end
|
Instance Method Details
#can_be_encrypted?(packet) ⇒ Boolean
Check if the request packet can be encrypted. Per the SMB2 spec,
SessionSetupRequest and NegotiateRequest must not be encrypted.
541
542
543
544
545
546
|
# File 'lib/ruby_smb/client.rb', line 541
def can_be_encrypted?(packet)
return false if packet.packet_smb_version == 'SMB1'
[RubySMB::SMB2::Packet::SessionSetupRequest, RubySMB::SMB2::Packet::NegotiateRequest].none? do |klass|
packet.is_a?(klass)
end
end
|
#disconnect! ⇒ void
This method returns an undefined value.
Logs off any currently open session on the server
and closes the TCP socket connection.
367
368
369
370
371
372
373
374
|
# File 'lib/ruby_smb/client.rb', line 367
def disconnect!
begin
logoff!
rescue
wipe_state!
end
dispatcher.tcp_socket.close
end
|
#echo(count: 1, data: '') ⇒ WindowsError::ErrorCode
Sends an Echo request to the server and returns the
NTStatus of the last response packet received.
382
383
384
385
386
387
388
389
|
# File 'lib/ruby_smb/client.rb', line 382
def echo(count: 1, data: '')
response = if smb2 || smb3
smb2_echo
else
smb1_echo(count: count, data: data)
end
response.status_code
end
|
#encryption_supported? ⇒ Boolean
Check if the current dialect supports encryption.
551
552
553
|
# File 'lib/ruby_smb/client.rb', line 551
def encryption_supported?
['0x0300', '0x0302', '0x0311'].include?(@dialect)
end
|
Sets the message id field in an SMB2 packet's
header to the one tracked by the client. It then increments
the counter on the client.
397
398
399
400
401
|
# File 'lib/ruby_smb/client.rb', line 397
def increment_smb_message_id(packet)
packet..message_id = self.smb2_message_id
self.smb2_message_id += 1
packet
end
|
#is_status_pending?(smb2_header) ⇒ Boolean
Check if the response is an asynchronous operation with STATUS_PENDING
status code.
529
530
531
532
533
534
|
# File 'lib/ruby_smb/client.rb', line 529
def is_status_pending?()
value = .nt_status.value
status_code = WindowsError::NTStatus.find_by_retval(value).first
status_code == WindowsError::NTStatus::STATUS_PENDING &&
.flags.async_command == 1
end
|
#login(username: self.username, password: self.password, domain: self.domain, local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS) ⇒ Object
Performs protocol negotiation and session setup. It defaults to using
the credentials supplied during initialization, but can take a new set of credentials if needed.
405
406
407
408
409
410
411
412
|
# File 'lib/ruby_smb/client.rb', line 405
def login(username: self.username, password: self.password,
domain: self.domain, local_workstation: self.local_workstation,
ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
negotiate
session_setup(username, password, domain,
local_workstation: local_workstation,
ntlm_flags: ntlm_flags)
end
|
#logoff! ⇒ WindowsError::ErrorCode
Sends a LOGOFF command to the remote server to terminate the session
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
|
# File 'lib/ruby_smb/client.rb', line 436
def logoff!
if smb2 || smb3
request = RubySMB::SMB2::Packet::LogoffRequest.new
raw_response = send_recv(request)
response = RubySMB::SMB2::Packet::LogoffResponse.read(raw_response)
unless response.valid?
raise RubySMB::Error::InvalidPacket.new(
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
expected_cmd: RubySMB::SMB2::Packet::LogoffResponse::COMMAND,
packet: response
)
end
else
request = RubySMB::SMB1::Packet::LogoffRequest.new
raw_response = send_recv(request)
response = RubySMB::SMB1::Packet::LogoffResponse.read(raw_response)
unless response.valid?
raise RubySMB::Error::InvalidPacket.new(
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
expected_cmd: RubySMB::SMB1::Packet::LogoffResponse::COMMAND,
packet: response
)
end
end
wipe_state!
response.status_code
end
|
#net_share_enum_all(host) ⇒ Array
620
621
622
623
624
|
# File 'lib/ruby_smb/client.rb', line 620
def net_share_enum_all(host)
tree = tree_connect("\\\\#{host}\\IPC$")
named_pipe = tree.open_pipe(filename: "srvsvc", write: true, read: true)
named_pipe.net_share_enum_all(host)
end
|
#recv_packet(encrypt: false) ⇒ String
Receives the raw response through the Dispatcher and decrypt the packet (if required).
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
|
# File 'lib/ruby_smb/client.rb', line 574
def recv_packet(encrypt: false)
begin
raw_response = dispatcher.recv_packet
rescue RubySMB::Error::CommunicationError => e
if encrypt
raise RubySMB::Error::EncryptionError, "Communication error with the "\
"remote host: #{e.message}. The server supports encryption but was "\
"not able to handle the encrypted request."
else
raise e
end
end
if encrypt
begin
transform_response = RubySMB::SMB2::Packet::.read(raw_response)
rescue IOError
raise RubySMB::Error::InvalidPacket, 'Not a SMB2 TransformHeader packet'
end
begin
raw_response = smb3_decrypt(transform_response)
rescue RubySMB::Error::RubySMBError => e
raise RubySMB::Error::EncryptionError, "Error while decrypting #{transform_response.class.name} packet (SMB #@dialect}): #{e}"
end
end
raw_response
end
|
#send_packet(packet, encrypt: false) ⇒ Object
Encrypt (if required) and send a packet.
559
560
561
562
563
564
565
566
567
568
|
# File 'lib/ruby_smb/client.rb', line 559
def send_packet(packet, encrypt: false)
if encrypt
begin
packet = smb3_encrypt(packet.to_binary_s)
rescue RubySMB::Error::RubySMBError => e
raise RubySMB::Error::EncryptionError, "Error while encrypting #{packet.class.name} packet (SMB #{@dialect}): #{e}"
end
end
dispatcher.send_packet(packet)
end
|
#send_recv(packet, encrypt: false) ⇒ String
Sends a packet and receives the raw response through the Dispatcher.
It will also sign the packet if necessary.
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
|
# File 'lib/ruby_smb/client.rb', line 472
def send_recv(packet, encrypt: false)
version = packet.packet_smb_version
case version
when 'SMB1'
packet..uid = self.user_id if self.user_id
packet..pid_low = self.pid if self.pid
packet = smb1_sign(packet) if signing_required && !session_key.empty?
when 'SMB2'
packet = increment_smb_message_id(packet)
packet..session_id = session_id
unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest) || session_key.empty?
if self.smb2 && signing_required
packet = smb2_sign(packet)
elsif self.smb3
if @dialect == '0x0311' && (signing_required || (!@session_is_guest && packet.is_a?(RubySMB::SMB2::Packet::TreeConnectRequest)))
packet = smb3_sign(packet)
elsif signing_required
packet = smb3_sign(packet)
end
end
end
else
packet = packet
end
encrypt_data = false
if can_be_encrypted?(packet) && encryption_supported? && (@session_encrypt_data || encrypt)
encrypt_data = true
end
send_packet(packet, encrypt: encrypt_data)
raw_response = recv_packet(encrypt: encrypt_data)
= nil
loop do
= RubySMB::SMB2::.read(raw_response)
break unless is_status_pending?()
sleep 1
raw_response = recv_packet(encrypt: encrypt_data)
rescue IOError
break
end unless version == 'SMB1'
self.sequence_counter += 1 if signing_required && !session_key.empty?
self.smb2_message_id += .credit_charge - 1 if && self.server_supports_multi_credit
raw_response
end
|
#session_request(name = '*SMBSERVER') ⇒ TrueClass
Requests a NetBIOS Session Service using the provided name.
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
|
# File 'lib/ruby_smb/client.rb', line 650
def session_request(name = '*SMBSERVER')
session_request = session_request_packet(name)
dispatcher.send_packet(session_request, nbss_header: false)
raw_response = dispatcher.recv_packet(full_response: true)
begin
= RubySMB::Nbss::.read(raw_response)
if .session_packet_type == RubySMB::Nbss::NEGATIVE_SESSION_RESPONSE
negative_session_response = RubySMB::Nbss::NegativeSessionResponse.read(raw_response)
raise RubySMB::Error::NetBiosSessionService, "Session Request failed: #{negative_session_response.error_msg}"
end
rescue IOError
raise RubySMB::Error::InvalidPacket, 'Not a NBSS packet'
end
return true
end
|
Crafts the NetBIOS SessionRequest packet to be sent for session request operations.
671
672
673
674
675
676
677
678
679
680
681
682
|
# File 'lib/ruby_smb/client.rb', line 671
def session_request_packet(name = '*SMBSERVER')
called_name = "#{name.upcase.ljust(15)}\x20"
calling_name = "#{''.ljust(15)}\x00"
session_request = RubySMB::Nbss::SessionRequest.new
session_request..session_packet_type = RubySMB::Nbss::SESSION_REQUEST
session_request.called_name = called_name
session_request.calling_name = calling_name
session_request..stream_protocol_length =
session_request.num_bytes - session_request..num_bytes
session_request
end
|
#session_setup(user, pass, domain, do_recv = true, local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS) ⇒ Object
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
|
# File 'lib/ruby_smb/client.rb', line 414
def session_setup(user, pass, domain, do_recv=true,
local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
@domain = domain
@local_workstation = local_workstation
@password = pass.encode('utf-8') || ''.encode('utf-8')
@username = user.encode('utf-8') || ''.encode('utf-8')
@ntlm_client = RubySMB::NTLM::Client.new(
@username,
@password,
workstation: @local_workstation,
domain: @domain,
flags: ntlm_flags
)
authenticate
end
|
Connects to the supplied share
606
607
608
609
610
611
612
613
614
|
# File 'lib/ruby_smb/client.rb', line 606
def tree_connect(share)
connected_tree = if smb2 || smb3
smb2_tree_connect(share)
else
smb1_tree_connect(share)
end
@tree_connects << connected_tree
connected_tree
end
|
#update_preauth_hash(data) ⇒ Object
684
685
686
687
688
689
690
691
692
693
694
|
# File 'lib/ruby_smb/client.rb', line 684
def update_preauth_hash(data)
unless @preauth_integrity_hash_algorithm
raise RubySMB::Error::EncryptionError.new(
'Cannot compute the Preauth Integrity Hash value: Preauth Integrity Hash Algorithm is nil'
)
end
@preauth_integrity_hash_value = OpenSSL::Digest.digest(
@preauth_integrity_hash_algorithm,
@preauth_integrity_hash_value + data.to_binary_s
)
end
|
#wipe_state! ⇒ void
This method returns an undefined value.
Resets all of the session state on the client, setting it
back to scratch. Should only be called when a session is no longer
valid.
631
632
633
634
635
636
637
638
639
640
641
642
|
# File 'lib/ruby_smb/client.rb', line 631
def wipe_state!
self.session_id = 0x00
self.user_id = 0x00
self.application_key = ''
self.session_key = ''
self.session_is_guest = false
self.sequence_counter = 0
self.smb2_message_id = 0
self.client_encryption_key = nil
self.server_encryption_key = nil
self.server_supports_multi_credit = false
end
|