ruby_smb 3.3.5 → 3.3.7
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/examples/registry_key_security_descriptor.rb +109 -0
- data/lib/ruby_smb/client/winreg.rb +12 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +16 -6
- data/lib/ruby_smb/dcerpc/request.rb +19 -16
- data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +1 -1
- data/lib/ruby_smb/dcerpc/samr/sampr_domain_info_buffer.rb +151 -0
- data/lib/ruby_smb/dcerpc/samr/samr_query_information_domain_request.rb +22 -0
- data/lib/ruby_smb/dcerpc/samr/samr_query_information_domain_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr.rb +42 -1
- data/lib/ruby_smb/dcerpc/winreg/get_key_security_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/winreg/get_key_security_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +2 -0
- data/lib/ruby_smb/dcerpc/winreg/set_key_security_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/winreg/set_key_security_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/winreg.rb +121 -9
- data/lib/ruby_smb/field/security_descriptor.rb +17 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +80 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +267 -18
- data.tar.gz.sig +0 -0
- metadata +10 -2
- metadata.gz.sig +0 -0
@@ -16,10 +16,12 @@ module RubySMB
|
|
16
16
|
REG_CREATE_KEY = 0x06
|
17
17
|
REG_ENUM_KEY = 0x09
|
18
18
|
REG_ENUM_VALUE = 0x0a
|
19
|
+
REG_GET_KEY_SECURITY = 0x0c
|
19
20
|
REG_OPEN_KEY = 0x0f
|
20
21
|
REG_QUERY_INFO_KEY = 0x10
|
21
22
|
REG_QUERY_VALUE = 0x11
|
22
23
|
REG_SAVE_KEY = 0x14
|
24
|
+
REG_SET_KEY_SECURITY = 0x15
|
23
25
|
OPEN_HKCC = 0x1b
|
24
26
|
OPEN_HKPT = 0x20
|
25
27
|
OPEN_HKPN = 0x21
|
@@ -43,6 +45,10 @@ module RubySMB
|
|
43
45
|
require 'ruby_smb/dcerpc/winreg/create_key_response'
|
44
46
|
require 'ruby_smb/dcerpc/winreg/save_key_request'
|
45
47
|
require 'ruby_smb/dcerpc/winreg/save_key_response'
|
48
|
+
require 'ruby_smb/dcerpc/winreg/get_key_security_request'
|
49
|
+
require 'ruby_smb/dcerpc/winreg/get_key_security_response'
|
50
|
+
require 'ruby_smb/dcerpc/winreg/set_key_security_request'
|
51
|
+
require 'ruby_smb/dcerpc/winreg/set_key_security_response'
|
46
52
|
|
47
53
|
ROOT_KEY_MAP = {
|
48
54
|
"HKEY_CLASSES_ROOT" => OPEN_HKCR,
|
@@ -65,6 +71,8 @@ module RubySMB
|
|
65
71
|
|
66
72
|
BUFFER_SIZE = 1024
|
67
73
|
|
74
|
+
RegValue = Struct.new(:type, :data)
|
75
|
+
|
68
76
|
# Open the registry root key and return a handle for it. The key can be
|
69
77
|
# either a long format (e.g. HKEY_LOCAL_MACHINE) or a short format
|
70
78
|
# (e.g. HKLM)
|
@@ -105,10 +113,7 @@ module RubySMB
|
|
105
113
|
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
106
114
|
def open_key(handle, sub_key)
|
107
115
|
openkey_request_packet = RubySMB::Dcerpc::Winreg::OpenKeyRequest.new(hkey: handle, lp_sub_key: sub_key)
|
108
|
-
openkey_request_packet.sam_desired.
|
109
|
-
openkey_request_packet.sam_desired.key_query_value = 1
|
110
|
-
openkey_request_packet.sam_desired.key_enumerate_sub_keys = 1
|
111
|
-
openkey_request_packet.sam_desired.key_notify = 1
|
116
|
+
openkey_request_packet.sam_desired.maximum_allowed = 1
|
112
117
|
response = dcerpc_request(openkey_request_packet)
|
113
118
|
begin
|
114
119
|
open_key_response = RubySMB::Dcerpc::Winreg::OpenKeyResponse.read(response)
|
@@ -124,11 +129,12 @@ module RubySMB
|
|
124
129
|
end
|
125
130
|
|
126
131
|
# Retrieve the data associated with the named value of a specified
|
127
|
-
# registry open key.
|
132
|
+
# registry open key. This will also return the type if required.
|
128
133
|
#
|
129
134
|
# @param handle [Ndr::NdrContextHandle] the handle for the key
|
130
135
|
# @param value_name [String] the name of the value
|
131
|
-
# @
|
136
|
+
# @param value_name [Boolean] also return the data type if set to true
|
137
|
+
# @return [RegValue] a RegValue struct containing the data type and the actual data of the value entry
|
132
138
|
# @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a QueryValueResponse packet
|
133
139
|
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
134
140
|
def query_value(handle, value_name)
|
@@ -161,7 +167,7 @@ module RubySMB
|
|
161
167
|
"#{WindowsError::Win32.find_by_retval(query_value_response.error_status.value).join(',')}"
|
162
168
|
end
|
163
169
|
|
164
|
-
query_value_response.data
|
170
|
+
RegValue.new(query_value_response.lp_type, query_value_response.data)
|
165
171
|
end
|
166
172
|
|
167
173
|
# Close the handle to the registry key.
|
@@ -323,6 +329,7 @@ module RubySMB
|
|
323
329
|
# exists, false otherwise.
|
324
330
|
#
|
325
331
|
# @param key [String] the registry key to check
|
332
|
+
# @param bind [Boolean] Bind to the winreg endpoint if true (default)
|
326
333
|
# @return [Boolean]
|
327
334
|
def has_registry_key?(key, bind: true)
|
328
335
|
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
@@ -345,6 +352,7 @@ module RubySMB
|
|
345
352
|
#
|
346
353
|
# @param key [String] the registry key
|
347
354
|
# @param value_name [String] the name of the value to read
|
355
|
+
# @param bind [Boolean] Bind to the winreg endpoint if true (default)
|
348
356
|
# @return [String] the data of the value entry
|
349
357
|
def read_registry_key_value(key, value_name, bind: true)
|
350
358
|
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
@@ -352,8 +360,8 @@ module RubySMB
|
|
352
360
|
root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
|
353
361
|
root_key_handle = open_root_key(root_key)
|
354
362
|
subkey_handle = open_key(root_key_handle, sub_key)
|
355
|
-
|
356
|
-
|
363
|
+
reg_value = query_value(subkey_handle, value_name)
|
364
|
+
reg_value.data
|
357
365
|
ensure
|
358
366
|
close_key(subkey_handle) if subkey_handle
|
359
367
|
close_key(root_key_handle) if root_key_handle
|
@@ -363,6 +371,7 @@ module RubySMB
|
|
363
371
|
# is provided, it enumerates its subkeys.
|
364
372
|
#
|
365
373
|
# @param key [String] the registry key
|
374
|
+
# @param bind [Boolean] Bind to the winreg endpoint if true (default)
|
366
375
|
# @return [Array<String>] the subkeys
|
367
376
|
def enum_registry_key(key, bind: true)
|
368
377
|
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
@@ -389,6 +398,7 @@ module RubySMB
|
|
389
398
|
# Enumerate the values for the specified registry key.
|
390
399
|
#
|
391
400
|
# @param key [String] the registry key
|
401
|
+
# @param bind [Boolean] Bind to the winreg endpoint if true (default)
|
392
402
|
# @return [Array<String>] the values
|
393
403
|
def enum_registry_values(key, bind: true)
|
394
404
|
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
@@ -412,6 +422,108 @@ module RubySMB
|
|
412
422
|
close_key(root_key_handle) if root_key_handle && root_key_handle != subkey_handle
|
413
423
|
end
|
414
424
|
|
425
|
+
|
426
|
+
# Retrieve the security descriptor for the given registry key handle.
|
427
|
+
#
|
428
|
+
# @param handle [String] the handle to the registry key
|
429
|
+
# @param security_information [] the security information to query (see https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/23e75ca3-98fd-4396-84e5-86cd9d40d343). These constants are defined in the `RubySMB::Field::SecurityDescriptor` class
|
430
|
+
# @return [String] The security descriptor as a byte stream
|
431
|
+
# @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a GetKeySecurityResponse packet
|
432
|
+
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
433
|
+
def get_key_security(handle, security_information = RubySMB::Field::SecurityDescriptor::OWNER_SECURITY_INFORMATION)
|
434
|
+
get_key_security_request = RubySMB::Dcerpc::Winreg::GetKeySecurityRequest.new(
|
435
|
+
hkey: handle,
|
436
|
+
security_information: security_information,
|
437
|
+
prpc_security_descriptor_in: { cb_in_security_descriptor: 4096 }
|
438
|
+
)
|
439
|
+
response = dcerpc_request(get_key_security_request)
|
440
|
+
begin
|
441
|
+
get_key_security_response = RubySMB::Dcerpc::Winreg::GetKeySecurityResponse.read(response)
|
442
|
+
rescue IOError
|
443
|
+
raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the GetKeySecurity response"
|
444
|
+
end
|
445
|
+
unless get_key_security_response.error_status == WindowsError::Win32::ERROR_SUCCESS
|
446
|
+
raise RubySMB::Dcerpc::Error::WinregError, "Error returned when querying information: "\
|
447
|
+
"#{WindowsError::Win32.find_by_retval(get_key_security_response.error_status.value).join(',')}"
|
448
|
+
end
|
449
|
+
|
450
|
+
get_key_security_response.prpc_security_descriptor_out.lp_security_descriptor.to_a.pack('C*')
|
451
|
+
end
|
452
|
+
|
453
|
+
# Retrieve the security descriptor for the given key.
|
454
|
+
#
|
455
|
+
# @param key [String] the registry key
|
456
|
+
# @param security_information [] the security information to query (see https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/23e75ca3-98fd-4396-84e5-86cd9d40d343). These constants are defined in the `RubySMB::Field::SecurityDescriptor` class
|
457
|
+
# @param bind [Boolean] Bind to the winreg endpoint if true (default)
|
458
|
+
# @return [String] The security descriptor as a byte stream
|
459
|
+
# @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a GetKeySecurityResponse packet
|
460
|
+
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
461
|
+
def get_key_security_descriptor(key, security_information = RubySMB::Field::SecurityDescriptor::OWNER_SECURITY_INFORMATION, bind: true)
|
462
|
+
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
463
|
+
|
464
|
+
root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
|
465
|
+
root_key_handle = open_root_key(root_key)
|
466
|
+
subkey_handle = open_key(root_key_handle, sub_key)
|
467
|
+
get_key_security(subkey_handle, security_information)
|
468
|
+
ensure
|
469
|
+
close_key(subkey_handle) if subkey_handle
|
470
|
+
close_key(root_key_handle) if root_key_handle
|
471
|
+
end
|
472
|
+
|
473
|
+
# Set the security descriptor for the given registry key handle.
|
474
|
+
#
|
475
|
+
# @param handle [String] the handle to the registry key
|
476
|
+
# @param security_descriptor [String] the new security descriptor to set as a byte stream
|
477
|
+
# @param security_information [] the security information to query (see https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/23e75ca3-98fd-4396-84e5-86cd9d40d343). These constants are defined in the `RubySMB::Field::SecurityDescriptor` class
|
478
|
+
# @param bind [Boolean] Bind to the winreg endpoint if true (default)
|
479
|
+
# @return [Integer] The error status returned by the DCERPC call
|
480
|
+
# @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a SetKeySecurityResponse packet
|
481
|
+
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
482
|
+
def set_key_security(handle, security_descriptor, security_information = RubySMB::Field::SecurityDescriptor::OWNER_SECURITY_INFORMATION)
|
483
|
+
set_key_security_request = RubySMB::Dcerpc::Winreg::SetKeySecurityRequest.new(
|
484
|
+
hkey: handle,
|
485
|
+
security_information: security_information,
|
486
|
+
prpc_security_descriptor: {
|
487
|
+
lp_security_descriptor: security_descriptor.bytes,
|
488
|
+
cb_in_security_descriptor: security_descriptor.b.size,
|
489
|
+
cb_out_security_descriptor: security_descriptor.b.size
|
490
|
+
}
|
491
|
+
)
|
492
|
+
response = dcerpc_request(set_key_security_request)
|
493
|
+
begin
|
494
|
+
set_key_security_response = RubySMB::Dcerpc::Winreg::SetKeySecurityResponse.read(response)
|
495
|
+
rescue IOError
|
496
|
+
raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the SetKeySecurity response"
|
497
|
+
end
|
498
|
+
unless set_key_security_response.error_status == WindowsError::Win32::ERROR_SUCCESS
|
499
|
+
raise RubySMB::Dcerpc::Error::WinregError, "Error returned when setting the registry key: "\
|
500
|
+
"#{WindowsError::Win32.find_by_retval(set_key_security_response.error_status.value).join(',')}"
|
501
|
+
end
|
502
|
+
|
503
|
+
set_key_security_response.error_status
|
504
|
+
end
|
505
|
+
|
506
|
+
# Set the security descriptor for the given key.
|
507
|
+
#
|
508
|
+
# @param key [String] the registry key
|
509
|
+
# @param security_descriptor [String] the new security descriptor to set as a byte stream
|
510
|
+
# @param security_information [] the security information to query (see https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/23e75ca3-98fd-4396-84e5-86cd9d40d343). These constants are defined in the `RubySMB::Field::SecurityDescriptor` class
|
511
|
+
# @param bind [Boolean] Bind to the winreg endpoint if true (default)
|
512
|
+
# @return [Integer] The error status returned by the DCERPC call
|
513
|
+
# @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a SetKeySecurityResponse packet
|
514
|
+
# @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
|
515
|
+
def set_key_security_descriptor(key, security_descriptor, security_information = RubySMB::Field::SecurityDescriptor::OWNER_SECURITY_INFORMATION, bind: true)
|
516
|
+
bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
|
517
|
+
|
518
|
+
root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
|
519
|
+
root_key_handle = open_root_key(root_key)
|
520
|
+
subkey_handle = open_key(root_key_handle, sub_key)
|
521
|
+
set_key_security(subkey_handle, security_descriptor, security_information)
|
522
|
+
ensure
|
523
|
+
close_key(subkey_handle) if subkey_handle
|
524
|
+
close_key(root_key_handle) if root_key_handle
|
525
|
+
end
|
526
|
+
|
415
527
|
end
|
416
528
|
end
|
417
529
|
end
|
@@ -3,6 +3,23 @@ module RubySMB
|
|
3
3
|
# Class representing a SECURITY_DESCRIPTOR as defined in
|
4
4
|
# [2.4.6 SECURITY_DESCRIPTOR](https://msdn.microsoft.com/en-us/library/cc230366.aspx)
|
5
5
|
class SecurityDescriptor < BinData::Record
|
6
|
+
|
7
|
+
# Security Information as defined in
|
8
|
+
# [2.4.7 SECURITY_INFORMATION](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/23e75ca3-98fd-4396-84e5-86cd9d40d343)
|
9
|
+
OWNER_SECURITY_INFORMATION = 0x00000001
|
10
|
+
GROUP_SECURITY_INFORMATION = 0x00000002
|
11
|
+
DACL_SECURITY_INFORMATION = 0x00000004
|
12
|
+
SACL_SECURITY_INFORMATION = 0x00000008
|
13
|
+
LABEL_SECURITY_INFORMATION = 0x00000010
|
14
|
+
UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000
|
15
|
+
UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
|
16
|
+
PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000
|
17
|
+
PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
|
18
|
+
ATTRIBUTE_SECURITY_INFORMATION = 0x00000020
|
19
|
+
SCOPE_SECURITY_INFORMATION = 0x00000040
|
20
|
+
PROCESS_TRUST_LABEL_SECURITY_INFORMATION = 0x00000080
|
21
|
+
BACKUP_SECURITY_INFORMATION = 0x00010000
|
22
|
+
|
6
23
|
endian :little
|
7
24
|
uint8 :revision, label: 'Revision', initial_value: 0x01
|
8
25
|
uint8 :sbz1, label: 'Resource Manager Control Bits'
|
data/lib/ruby_smb/version.rb
CHANGED
@@ -1352,6 +1352,15 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarString do
|
|
1352
1352
|
}
|
1353
1353
|
let(:value) { 'ABCD' }
|
1354
1354
|
end
|
1355
|
+
context 'with an empty string' do
|
1356
|
+
it_behaves_like 'a NDR String', conformant: false, char_size: 1, null_terminated: false do
|
1357
|
+
let(:binary_stream) {
|
1358
|
+
"\x00\x00\x00\x00"\
|
1359
|
+
"\x00\x00\x00\x00".b
|
1360
|
+
}
|
1361
|
+
let(:value) { '' }
|
1362
|
+
end
|
1363
|
+
end
|
1355
1364
|
end
|
1356
1365
|
|
1357
1366
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarStringz do
|
@@ -1368,6 +1377,16 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarStringz do
|
|
1368
1377
|
}
|
1369
1378
|
let(:value) { 'ABCD' }
|
1370
1379
|
end
|
1380
|
+
context 'with an empty string' do
|
1381
|
+
it_behaves_like 'a NDR String', conformant: false, char_size: 1, null_terminated: true do
|
1382
|
+
let(:binary_stream) {
|
1383
|
+
"\x00\x00\x00\x00"\
|
1384
|
+
"\x01\x00\x00\x00"\
|
1385
|
+
"\x00".b
|
1386
|
+
}
|
1387
|
+
let(:value) { '' }
|
1388
|
+
end
|
1389
|
+
end
|
1371
1390
|
end
|
1372
1391
|
|
1373
1392
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarWideString do
|
@@ -1383,6 +1402,15 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarWideString do
|
|
1383
1402
|
}
|
1384
1403
|
let(:value) { 'ABCD'.encode('utf-16le') }
|
1385
1404
|
end
|
1405
|
+
context 'with an empty string' do
|
1406
|
+
it_behaves_like 'a NDR String', conformant: false, char_size: 2, null_terminated: false do
|
1407
|
+
let(:binary_stream) {
|
1408
|
+
"\x00\x00\x00\x00"\
|
1409
|
+
"\x00\x00\x00\x00".b
|
1410
|
+
}
|
1411
|
+
let(:value) { '' }
|
1412
|
+
end
|
1413
|
+
end
|
1386
1414
|
end
|
1387
1415
|
|
1388
1416
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarWideStringz do
|
@@ -1398,6 +1426,16 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarWideStringz do
|
|
1398
1426
|
}
|
1399
1427
|
let(:value) { 'ABCD'.encode('utf-16le') }
|
1400
1428
|
end
|
1429
|
+
context 'with an empty string' do
|
1430
|
+
it_behaves_like 'a NDR String', conformant: false, char_size: 2, null_terminated: true do
|
1431
|
+
let(:binary_stream) {
|
1432
|
+
"\x00\x00\x00\x00"\
|
1433
|
+
"\x01\x00\x00\x00"\
|
1434
|
+
"\x00\x00".b
|
1435
|
+
}
|
1436
|
+
let(:value) { '' }
|
1437
|
+
end
|
1438
|
+
end
|
1401
1439
|
end
|
1402
1440
|
|
1403
1441
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarString do
|
@@ -1415,6 +1453,16 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarString do
|
|
1415
1453
|
}
|
1416
1454
|
let(:value) { 'ABCD' }
|
1417
1455
|
end
|
1456
|
+
context 'with an empty string' do
|
1457
|
+
it_behaves_like 'a NDR String', conformant: true, char_size: 1, null_terminated: false do
|
1458
|
+
let(:binary_stream) {
|
1459
|
+
"\x00\x00\x00\x00"\
|
1460
|
+
"\x00\x00\x00\x00"\
|
1461
|
+
"\x00\x00\x00\x00".b
|
1462
|
+
}
|
1463
|
+
let(:value) { '' }
|
1464
|
+
end
|
1465
|
+
end
|
1418
1466
|
end
|
1419
1467
|
|
1420
1468
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarStringz do
|
@@ -1432,6 +1480,17 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarStringz do
|
|
1432
1480
|
}
|
1433
1481
|
let(:value) { 'ABCD' }
|
1434
1482
|
end
|
1483
|
+
context 'with an empty string' do
|
1484
|
+
it_behaves_like 'a NDR String', conformant: true, char_size: 1, null_terminated: true do
|
1485
|
+
let(:binary_stream) {
|
1486
|
+
"\x01\x00\x00\x00"\
|
1487
|
+
"\x00\x00\x00\x00"\
|
1488
|
+
"\x01\x00\x00\x00"\
|
1489
|
+
"\x00".b
|
1490
|
+
}
|
1491
|
+
let(:value) { '' }
|
1492
|
+
end
|
1493
|
+
end
|
1435
1494
|
end
|
1436
1495
|
|
1437
1496
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarWideString do
|
@@ -1448,6 +1507,16 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarWideString do
|
|
1448
1507
|
}
|
1449
1508
|
let(:value) { 'ABCD'.encode('utf-16le') }
|
1450
1509
|
end
|
1510
|
+
context 'with an empty string' do
|
1511
|
+
it_behaves_like 'a NDR String', conformant: true, char_size: 2, null_terminated: false do
|
1512
|
+
let(:binary_stream) {
|
1513
|
+
"\x00\x00\x00\x00"\
|
1514
|
+
"\x00\x00\x00\x00"\
|
1515
|
+
"\x00\x00\x00\x00".b
|
1516
|
+
}
|
1517
|
+
let(:value) { '' }
|
1518
|
+
end
|
1519
|
+
end
|
1451
1520
|
end
|
1452
1521
|
|
1453
1522
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarWideStringz do
|
@@ -1464,6 +1533,17 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarWideStringz do
|
|
1464
1533
|
}
|
1465
1534
|
let(:value) { 'ABCD'.encode('utf-16le') }
|
1466
1535
|
end
|
1536
|
+
context 'with an empty string' do
|
1537
|
+
it_behaves_like 'a NDR String', conformant: true, char_size: 1, null_terminated: true do
|
1538
|
+
let(:binary_stream) {
|
1539
|
+
"\x01\x00\x00\x00"\
|
1540
|
+
"\x00\x00\x00\x00"\
|
1541
|
+
"\x01\x00\x00\x00"\
|
1542
|
+
"\x00\x00".b
|
1543
|
+
}
|
1544
|
+
let(:value) { '' }
|
1545
|
+
end
|
1546
|
+
end
|
1467
1547
|
end
|
1468
1548
|
|
1469
1549
|
|