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, #extract_os_version, #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, #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.
308
309
310
311
312
313
314
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
|
# File 'lib/ruby_smb/client.rb', line 308
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 = ''
@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
#client_encryption_key ⇒ String
241
242
243
|
# File 'lib/ruby_smb/client.rb', line 241
def client_encryption_key
@client_encryption_key
end
|
#default_domain ⇒ String
109
110
111
|
# File 'lib/ruby_smb/client.rb', line 109
def default_domain
@default_domain
end
|
#default_name ⇒ String
104
105
106
|
# File 'lib/ruby_smb/client.rb', line 104
def default_name
@default_name
end
|
#dialect ⇒ Integer
134
135
136
|
# File 'lib/ruby_smb/client.rb', line 134
def dialect
@dialect
end
|
60
61
62
|
# File 'lib/ruby_smb/client.rb', line 60
def dispatcher
@dispatcher
end
|
#dns_domain_name ⇒ String
119
120
121
|
# File 'lib/ruby_smb/client.rb', line 119
def dns_domain_name
@dns_domain_name
end
|
#dns_host_name ⇒ String
114
115
116
|
# File 'lib/ruby_smb/client.rb', line 114
def dns_host_name
@dns_host_name
end
|
#dns_tree_name ⇒ String
124
125
126
|
# File 'lib/ruby_smb/client.rb', line 124
def dns_tree_name
@dns_tree_name
end
|
#domain ⇒ String
65
66
67
|
# File 'lib/ruby_smb/client.rb', line 65
def domain
@domain
end
|
#encryption_algorithm ⇒ String
236
237
238
|
# File 'lib/ruby_smb/client.rb', line 236
def encryption_algorithm
@encryption_algorithm
end
|
#local_workstation ⇒ String
70
71
72
|
# File 'lib/ruby_smb/client.rb', line 70
def local_workstation
@local_workstation
end
|
#max_buffer_size ⇒ Integer
199
200
201
|
# File 'lib/ruby_smb/client.rb', line 199
def max_buffer_size
@max_buffer_size
end
|
#negotiated_smb_version ⇒ Integer
288
289
290
|
# File 'lib/ruby_smb/client.rb', line 288
def negotiated_smb_version
@negotiated_smb_version
end
|
#negotiation_security_buffer ⇒ String
302
303
304
|
# File 'lib/ruby_smb/client.rb', line 302
def negotiation_security_buffer
@negotiation_security_buffer
end
|
#ntlm_client ⇒ String
75
76
77
|
# File 'lib/ruby_smb/client.rb', line 75
def ntlm_client
@ntlm_client
end
|
#os_version ⇒ String
129
130
131
|
# File 'lib/ruby_smb/client.rb', line 129
def os_version
@os_version
end
|
#password ⇒ String
80
81
82
|
# File 'lib/ruby_smb/client.rb', line 80
def password
@password
end
|
#peer_native_lm ⇒ String
92
93
94
|
# File 'lib/ruby_smb/client.rb', line 92
def peer_native_lm
@peer_native_lm
end
|
#peer_native_os ⇒ String
86
87
88
|
# File 'lib/ruby_smb/client.rb', line 86
def peer_native_os
@peer_native_os
end
|
#pid ⇒ Integer
193
194
195
|
# File 'lib/ruby_smb/client.rb', line 193
def pid
@pid
end
|
#preauth_integrity_hash_algorithm ⇒ String
226
227
228
|
# File 'lib/ruby_smb/client.rb', line 226
def preauth_integrity_hash_algorithm
@preauth_integrity_hash_algorithm
end
|
#preauth_integrity_hash_value ⇒ String
231
232
233
|
# File 'lib/ruby_smb/client.rb', line 231
def preauth_integrity_hash_value
@preauth_integrity_hash_value
end
|
#primary_domain ⇒ String
99
100
101
|
# File 'lib/ruby_smb/client.rb', line 99
def primary_domain
@primary_domain
end
|
#sequence_counter ⇒ Integer
141
142
143
|
# File 'lib/ruby_smb/client.rb', line 141
def sequence_counter
@sequence_counter
end
|
#server_compression_algorithms ⇒ Array<Integer>
263
264
265
|
# File 'lib/ruby_smb/client.rb', line 263
def server_compression_algorithms
@server_compression_algorithms
end
|
#server_encryption_algorithms ⇒ Array<Integer>
257
258
259
|
# File 'lib/ruby_smb/client.rb', line 257
def server_encryption_algorithms
@server_encryption_algorithms
end
|
#server_encryption_key ⇒ String
246
247
248
|
# File 'lib/ruby_smb/client.rb', line 246
def server_encryption_key
@server_encryption_key
end
|
#server_guid ⇒ String
268
269
270
|
# File 'lib/ruby_smb/client.rb', line 268
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
205
206
207
|
# File 'lib/ruby_smb/client.rb', line 205
def server_max_buffer_size
@server_max_buffer_size
end
|
#server_max_read_size ⇒ Integer
215
216
217
|
# File 'lib/ruby_smb/client.rb', line 215
def server_max_read_size
@server_max_read_size
end
|
#server_max_transact_size ⇒ Integer
221
222
223
|
# File 'lib/ruby_smb/client.rb', line 221
def server_max_transact_size
@server_max_transact_size
end
|
#server_max_write_size ⇒ Integer
210
211
212
|
# File 'lib/ruby_smb/client.rb', line 210
def server_max_write_size
@server_max_write_size
end
|
#server_start_time ⇒ Time
275
276
277
|
# File 'lib/ruby_smb/client.rb', line 275
def server_start_time
@server_start_time
end
|
#server_supports_multi_credit ⇒ Boolean
296
297
298
|
# File 'lib/ruby_smb/client.rb', line 296
def server_supports_multi_credit
@server_supports_multi_credit
end
|
#server_system_time ⇒ Time
282
283
284
|
# File 'lib/ruby_smb/client.rb', line 282
def server_system_time
@server_system_time
end
|
#session_encrypt_data ⇒ Boolean
251
252
253
|
# File 'lib/ruby_smb/client.rb', line 251
def session_encrypt_data
@session_encrypt_data
end
|
#session_id ⇒ Integer
146
147
148
|
# File 'lib/ruby_smb/client.rb', line 146
def session_id
@session_id
end
|
#session_is_guest ⇒ Boolean
151
152
153
|
# File 'lib/ruby_smb/client.rb', line 151
def session_is_guest
@session_is_guest
end
|
#signing_enabled ⇒ Boolean
156
|
# File 'lib/ruby_smb/client.rb', line 156
attr_accessor :signing_required
|
#signing_required ⇒ Object
Whether or not the Server requires signing
156
157
158
|
# File 'lib/ruby_smb/client.rb', line 156
def signing_required
@signing_required
end
|
#smb1 ⇒ Boolean
161
162
163
|
# File 'lib/ruby_smb/client.rb', line 161
def smb1
@smb1
end
|
#smb2 ⇒ Boolean
166
167
168
|
# File 'lib/ruby_smb/client.rb', line 166
def smb2
@smb2
end
|
#smb2_message_id ⇒ Integer
176
177
178
|
# File 'lib/ruby_smb/client.rb', line 176
def smb2_message_id
@smb2_message_id
end
|
#smb3 ⇒ Boolean
171
172
173
|
# File 'lib/ruby_smb/client.rb', line 171
def smb3
@smb3
end
|
#user_id ⇒ Integer
186
187
188
|
# File 'lib/ruby_smb/client.rb', line 186
def user_id
@user_id
end
|
#username ⇒ String
181
182
183
|
# File 'lib/ruby_smb/client.rb', line 181
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.
533
534
535
536
537
538
|
# File 'lib/ruby_smb/client.rb', line 533
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.
359
360
361
362
363
364
365
366
|
# File 'lib/ruby_smb/client.rb', line 359
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.
374
375
376
377
378
379
380
381
|
# File 'lib/ruby_smb/client.rb', line 374
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.
543
544
545
|
# File 'lib/ruby_smb/client.rb', line 543
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.
389
390
391
392
393
|
# File 'lib/ruby_smb/client.rb', line 389
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.
521
522
523
524
525
526
|
# File 'lib/ruby_smb/client.rb', line 521
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.
397
398
399
400
401
402
403
404
|
# File 'lib/ruby_smb/client.rb', line 397
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
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
|
# File 'lib/ruby_smb/client.rb', line 428
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
612
613
614
615
616
|
# File 'lib/ruby_smb/client.rb', line 612
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).
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
|
# File 'lib/ruby_smb/client.rb', line 566
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.
551
552
553
554
555
556
557
558
559
560
|
# File 'lib/ruby_smb/client.rb', line 551
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.
464
465
466
467
468
469
470
471
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
|
# File 'lib/ruby_smb/client.rb', line 464
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.
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
|
# File 'lib/ruby_smb/client.rb', line 641
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.
662
663
664
665
666
667
668
669
670
671
672
673
|
# File 'lib/ruby_smb/client.rb', line 662
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
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
|
# File 'lib/ruby_smb/client.rb', line 406
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
598
599
600
601
602
603
604
605
606
|
# File 'lib/ruby_smb/client.rb', line 598
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
675
676
677
678
679
680
681
682
683
684
685
|
# File 'lib/ruby_smb/client.rb', line 675
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.
623
624
625
626
627
628
629
630
631
632
633
|
# File 'lib/ruby_smb/client.rb', line 623
def wipe_state!
self.session_id = 0x00
self.user_id = 0x00
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
|