ruby_smb 3.3.5 → 3.3.7
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/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
|
|