ruby_smb 3.3.6 → 3.3.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +14 -0
  4. data/examples/registry_key_security_descriptor.rb +109 -0
  5. data/lib/ruby_smb/client/winreg.rb +12 -0
  6. data/lib/ruby_smb/dcerpc/error.rb +3 -0
  7. data/lib/ruby_smb/dcerpc/lsarpc/lsar_close_handle_request.rb +22 -0
  8. data/lib/ruby_smb/dcerpc/lsarpc/lsar_close_handle_response.rb +23 -0
  9. data/lib/ruby_smb/dcerpc/lsarpc/lsar_lookup_sids_request.rb +26 -0
  10. data/lib/ruby_smb/dcerpc/lsarpc/lsar_lookup_sids_response.rb +25 -0
  11. data/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy2_request.rb +24 -0
  12. data/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy2_response.rb +23 -0
  13. data/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy_request.rb +24 -0
  14. data/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy_response.rb +23 -0
  15. data/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy2_request.rb +23 -0
  16. data/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy2_response.rb +23 -0
  17. data/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy_request.rb +23 -0
  18. data/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy_response.rb +23 -0
  19. data/lib/ruby_smb/dcerpc/lsarpc.rb +634 -2
  20. data/lib/ruby_smb/dcerpc/ndr.rb +10 -4
  21. data/lib/ruby_smb/dcerpc/request.rb +26 -16
  22. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +1 -1
  23. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +1 -1
  24. data/lib/ruby_smb/dcerpc/winreg/get_key_security_request.rb +26 -0
  25. data/lib/ruby_smb/dcerpc/winreg/get_key_security_response.rb +26 -0
  26. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +2 -0
  27. data/lib/ruby_smb/dcerpc/winreg/set_key_security_request.rb +26 -0
  28. data/lib/ruby_smb/dcerpc/winreg/set_key_security_response.rb +25 -0
  29. data/lib/ruby_smb/dcerpc/winreg.rb +121 -9
  30. data/lib/ruby_smb/field/security_descriptor.rb +17 -0
  31. data/lib/ruby_smb/version.rb +1 -1
  32. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_close_handle_request_spec.rb +40 -0
  33. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_close_handle_response_spec.rb +46 -0
  34. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_lookup_sids_request_spec.rb +69 -0
  35. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_lookup_sids_response_spec.rb +56 -0
  36. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy2_request_spec.rb +68 -0
  37. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy2_response_spec.rb +46 -0
  38. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy_request_spec.rb +68 -0
  39. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy_response_spec.rb +45 -0
  40. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy2_request_spec.rb +47 -0
  41. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy2_response_spec.rb +54 -0
  42. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy_request_spec.rb +46 -0
  43. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy_response_spec.rb +53 -0
  44. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +80 -0
  45. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +267 -18
  46. data.tar.gz.sig +0 -0
  47. metadata +44 -3
  48. metadata.gz.sig +0 -0
@@ -0,0 +1,68 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarOpenPolicy2Request do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :system_name }
7
+ it { is_expected.to respond_to :object_attributes }
8
+ it { is_expected.to respond_to :access_mask }
9
+ it { is_expected.to respond_to :opnum }
10
+
11
+ it 'is little endian' do
12
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
13
+ end
14
+ it 'is a BinData::Record' do
15
+ expect(packet).to be_a(BinData::Record)
16
+ end
17
+ describe '#system_name' do
18
+ it 'is an NdrWideStringzPtr structure' do
19
+ expect(packet.system_name).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
20
+ end
21
+ end
22
+ describe '#object_attributes' do
23
+ it 'is an LsaprObjectAttributes structure' do
24
+ expect(packet.object_attributes).to be_a RubySMB::Dcerpc::Lsarpc::LsaprObjectAttributes
25
+ end
26
+ end
27
+ describe '#access_mask' do
28
+ it 'is an NdrUint32 structure' do
29
+ expect(packet.access_mask).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
30
+ end
31
+ end
32
+ describe '#initialize_instance' do
33
+ it 'sets #opnum to LSAR_OPEN_POLICY2 constant' do
34
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_OPEN_POLICY2)
35
+ end
36
+ end
37
+ it 'reads itself' do
38
+ new_class = described_class.new(
39
+ system_name: 'Example_System',
40
+ object_attributes: {
41
+ security_quality_of_service: {
42
+ impersonation_level: 0,
43
+ security_context_tracking_mode: 0
44
+ }
45
+ },
46
+ access_mask: 0
47
+ )
48
+ expect(packet.read(new_class.to_binary_s)).to eq(
49
+ {
50
+ system_name: 'Example_System'.encode('UTF-16LE'),
51
+ object_attributes: {
52
+ len: 24,
53
+ root_directory: :null,
54
+ object_name: :null,
55
+ attributes: 0,
56
+ security_descriptor: :null,
57
+ security_quality_of_service: {
58
+ len: 12,
59
+ impersonation_level: 0,
60
+ security_context_tracking_mode: 0,
61
+ effective_only: 0
62
+ }
63
+ },
64
+ access_mask: 0
65
+ }
66
+ )
67
+ end
68
+ end
@@ -0,0 +1,46 @@
1
+
2
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarOpenPolicy2Response do
3
+ subject(:packet) { described_class.new }
4
+
5
+ it { is_expected.to respond_to :policy_handle }
6
+ it { is_expected.to respond_to :error_status }
7
+ it { is_expected.to respond_to :opnum }
8
+
9
+ it 'is little endian' do
10
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
11
+ end
12
+ it 'is a BinData::Record' do
13
+ expect(packet).to be_a(BinData::Record)
14
+ end
15
+ describe '#policy_handle' do
16
+ it 'is an LsaprHandle structure' do
17
+ expect(packet.policy_handle).to be_a RubySMB::Dcerpc::Lsarpc::LsaprHandle
18
+ end
19
+ end
20
+ describe '#error_status' do
21
+ it 'is a NdrUint32' do
22
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
23
+ end
24
+ end
25
+ describe '#initialize_instance' do
26
+ it 'sets #opnum to LSAR_OPEN_POLICY2 constant' do
27
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_OPEN_POLICY2)
28
+ end
29
+ end
30
+ it 'reads itself' do
31
+ new_class = described_class.new(
32
+ policy_handle: {
33
+ context_handle_attributes: 0,
34
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
35
+ },
36
+ error_status: 0
37
+ )
38
+ expect(packet.read(new_class.to_binary_s)).to eq(
39
+ policy_handle: {
40
+ context_handle_attributes: 0,
41
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
42
+ },
43
+ error_status: 0
44
+ )
45
+ end
46
+ end
@@ -0,0 +1,68 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarOpenPolicyRequest do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :system_name }
7
+ it { is_expected.to respond_to :object_attributes }
8
+ it { is_expected.to respond_to :access_mask }
9
+ it { is_expected.to respond_to :opnum }
10
+
11
+ it 'is little endian' do
12
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
13
+ end
14
+ it 'is a BinData::Record' do
15
+ expect(packet).to be_a(BinData::Record)
16
+ end
17
+ describe '#system_name' do
18
+ it 'is an NdrWideStringPtr structure' do
19
+ expect(packet.system_name).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringPtr
20
+ end
21
+ end
22
+ describe '#object_attributes' do
23
+ it 'is an LsaprObjectAttributes structure' do
24
+ expect(packet.object_attributes).to be_a RubySMB::Dcerpc::Lsarpc::LsaprObjectAttributes
25
+ end
26
+ end
27
+ describe '#access_mask' do
28
+ it 'is an NdrUint32 structure' do
29
+ expect(packet.access_mask).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
30
+ end
31
+ end
32
+ describe '#initialize_instance' do
33
+ it 'sets #opnum to LSAR_OPEN_POLICY constant' do
34
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_OPEN_POLICY)
35
+ end
36
+ end
37
+ it 'reads itself' do
38
+ new_class = described_class.new(
39
+ system_name: 'Example_System',
40
+ object_attributes: {
41
+ security_quality_of_service: {
42
+ impersonation_level: 0,
43
+ security_context_tracking_mode: 0
44
+ }
45
+ },
46
+ access_mask: 0
47
+ )
48
+ expect(packet.read(new_class.to_binary_s)).to eq(
49
+ {
50
+ system_name: 'Example_System'.encode('UTF-16LE'),
51
+ object_attributes: {
52
+ len: 24,
53
+ root_directory: :null,
54
+ object_name: :null,
55
+ attributes: 0,
56
+ security_descriptor: :null,
57
+ security_quality_of_service: {
58
+ len: 12,
59
+ impersonation_level: 0,
60
+ security_context_tracking_mode: 0,
61
+ effective_only: 0
62
+ }
63
+ },
64
+ access_mask: 0
65
+ }
66
+ )
67
+ end
68
+ end
@@ -0,0 +1,45 @@
1
+
2
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarOpenPolicyResponse do
3
+ subject(:packet) { described_class.new }
4
+
5
+ it { is_expected.to respond_to :policy_handle }
6
+ it { is_expected.to respond_to :error_status }
7
+ it { is_expected.to respond_to :opnum }
8
+
9
+ it 'is little endian' do
10
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
11
+ end
12
+ it 'is a BinData::Record' do
13
+ expect(packet).to be_a(BinData::Record)
14
+ end
15
+ describe '#policy_handle' do
16
+ it 'is an LsaprHandle structure' do
17
+ expect(packet.policy_handle).to be_a RubySMB::Dcerpc::Lsarpc::LsaprHandle
18
+ end
19
+ end
20
+ describe '#error_status' do
21
+ it 'is a NdrUint32' do
22
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
23
+ end
24
+ end
25
+ describe '#initialize_instance' do
26
+ it 'sets #opnum to LSAR_OPEN_POLICY constant' do
27
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_OPEN_POLICY)
28
+ end
29
+ end
30
+ it 'reads itself' do
31
+ new_class = described_class.new(
32
+ policy_handle: {
33
+ context_handle_attributes: 0,
34
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
35
+ }
36
+ )
37
+ expect(packet.read(new_class.to_binary_s)).to eq(
38
+ policy_handle: {
39
+ context_handle_attributes: 0,
40
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
41
+ },
42
+ error_status: 0
43
+ )
44
+ end
45
+ end
@@ -0,0 +1,47 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarQueryInformationPolicy2Request do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :policy_handle }
7
+ it { is_expected.to respond_to :information_class }
8
+ it { is_expected.to respond_to :opnum }
9
+
10
+ it 'is little endian' do
11
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
12
+ end
13
+ it 'is a BinData::Record' do
14
+ expect(packet).to be_a(BinData::Record)
15
+ end
16
+ describe '#policy_handle' do
17
+ it 'is an LsaprHandle structure' do
18
+ expect(packet.policy_handle).to be_a RubySMB::Dcerpc::Lsarpc::LsaprHandle
19
+ end
20
+ end
21
+ describe '#information_class' do
22
+ it 'is an NdrUint32 structure' do
23
+ expect(packet.information_class).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
24
+ end
25
+ end
26
+ describe '#initialize_instance' do
27
+ it 'sets #opnum to LSAR_QUERY_INFORMATION_POLICY2 constant' do
28
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_QUERY_INFORMATION_POLICY2)
29
+ end
30
+ end
31
+ it 'reads itself' do
32
+ new_class = described_class.new(
33
+ policy_handle: {
34
+ context_handle_attributes: 0,
35
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
36
+ },
37
+ information_class: 0
38
+ )
39
+ expect(packet.read(new_class.to_binary_s)).to eq(
40
+ policy_handle: {
41
+ context_handle_attributes: 0,
42
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
43
+ },
44
+ information_class: 0
45
+ )
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+ require 'ruby_smb/dcerpc/lsarpc'
3
+
4
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarQueryInformationPolicy2Response do
5
+ subject(:packet) { described_class.new }
6
+
7
+ it { is_expected.to respond_to :policy_information }
8
+ it { is_expected.to respond_to :error_status }
9
+ it { is_expected.to respond_to :opnum }
10
+
11
+ it 'is little endian' do
12
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
13
+ end
14
+ it 'is a BinData::Record' do
15
+ expect(packet).to be_a(BinData::Record)
16
+ end
17
+ describe '#policy_information' do
18
+ it 'is an LsaprPolicyInformationPtr structure' do
19
+ expect(packet.policy_information).to be_a RubySMB::Dcerpc::Lsarpc::LsaprPolicyInformationPtr
20
+ end
21
+ end
22
+ describe '#error_status' do
23
+ it 'is an NdrUint32 structure' do
24
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
25
+ end
26
+ end
27
+ describe '#initialize_instance' do
28
+ it 'sets #opnum to LSAR_QUERY_INFORMATION_POLICY2 constant' do
29
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_QUERY_INFORMATION_POLICY2)
30
+ end
31
+ end
32
+ it 'reads itself' do
33
+ new_class = described_class.new(
34
+ policy_information: {
35
+ policy_information_class: 1,
36
+ policy_information: {}
37
+ }
38
+ )
39
+ expect(packet.read(new_class.to_binary_s)).to eq(
40
+ policy_information: {
41
+ policy_information_class: 1,
42
+ policy_information: {
43
+ audit_log_percent_full: 0,
44
+ maximum_log_size: 0,
45
+ audit_retention_period: 0,
46
+ audit_log_full_shutdown_in_progress: 0,
47
+ time_to_shutdown: 0,
48
+ next_audit_record_id: 0
49
+ }
50
+ },
51
+ error_status: 0
52
+ )
53
+ end
54
+ end
@@ -0,0 +1,46 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarQueryInformationPolicyRequest do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :policy_handle }
7
+ it { is_expected.to respond_to :information_class }
8
+ it { is_expected.to respond_to :opnum }
9
+
10
+ it 'is little endian' do
11
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
12
+ end
13
+ it 'is a BinData::Record' do
14
+ expect(packet).to be_a(BinData::Record)
15
+ end
16
+ describe '#policy_handle' do
17
+ it 'is an LsaprHandle structure' do
18
+ expect(packet.policy_handle).to be_a RubySMB::Dcerpc::Lsarpc::LsaprHandle
19
+ end
20
+ end
21
+ describe '#information_class' do
22
+ it 'is an NdrUint32 structure' do
23
+ expect(packet.information_class).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
24
+ end
25
+ end
26
+ describe '#initialize_instance' do
27
+ it 'sets #opnum to LSAR_QUERY_INFORMATION_POLICY constant' do
28
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_QUERY_INFORMATION_POLICY)
29
+ end
30
+ end
31
+ it 'reads itself' do
32
+ new_class = described_class.new(
33
+ policy_handle: {
34
+ context_handle_attributes: 0,
35
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
36
+ }
37
+ )
38
+ expect(packet.read(new_class.to_binary_s)).to eq(
39
+ policy_handle: {
40
+ context_handle_attributes: 0,
41
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
42
+ },
43
+ information_class: 0
44
+ )
45
+ end
46
+ end
@@ -0,0 +1,53 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarQueryInformationPolicyResponse do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :policy_information }
7
+ it { is_expected.to respond_to :error_status }
8
+ it { is_expected.to respond_to :opnum }
9
+
10
+ it 'is little endian' do
11
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
12
+ end
13
+ it 'is a BinData::Record' do
14
+ expect(packet).to be_a(BinData::Record)
15
+ end
16
+ describe '#policy_information' do
17
+ it 'is an LsaprPolicyInformationPtr structure' do
18
+ expect(packet.policy_information).to be_a RubySMB::Dcerpc::Lsarpc::LsaprPolicyInformationPtr
19
+ end
20
+ end
21
+ describe '#error_status' do
22
+ it 'is an NdrUint32 structure' do
23
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
24
+ end
25
+ end
26
+ describe '#initialize_instance' do
27
+ it 'sets #opnum to LSAR_QUERY_INFORMATION_POLICY constant' do
28
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_QUERY_INFORMATION_POLICY)
29
+ end
30
+ end
31
+ it 'reads itself' do
32
+ new_class = described_class.new(
33
+ policy_information: {
34
+ policy_information_class: 1,
35
+ policy_information: {}
36
+ }
37
+ )
38
+ expect(packet.read(new_class.to_binary_s)).to eq(
39
+ policy_information: {
40
+ policy_information_class: 1,
41
+ policy_information: {
42
+ audit_log_percent_full: 0,
43
+ maximum_log_size: 0,
44
+ audit_retention_period: 0,
45
+ audit_log_full_shutdown_in_progress: 0,
46
+ time_to_shutdown: 0,
47
+ next_audit_record_id: 0
48
+ }
49
+ },
50
+ error_status: 0
51
+ )
52
+ end
53
+ end
@@ -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