ruby_smb 1.0.5 → 2.0.3

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.
Files changed (191) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.travis.yml +3 -2
  5. data/Gemfile +6 -2
  6. data/README.md +35 -47
  7. data/examples/anonymous_auth.rb +3 -3
  8. data/examples/append_file.rb +10 -8
  9. data/examples/authenticate.rb +9 -5
  10. data/examples/delete_file.rb +8 -6
  11. data/examples/enum_registry_key.rb +29 -0
  12. data/examples/enum_registry_values.rb +31 -0
  13. data/examples/list_directory.rb +8 -6
  14. data/examples/negotiate.rb +51 -8
  15. data/examples/negotiate_with_netbios_service.rb +9 -5
  16. data/examples/net_share_enum_all.rb +6 -4
  17. data/examples/pipes.rb +13 -13
  18. data/examples/query_service_status.rb +64 -0
  19. data/examples/read_file.rb +8 -6
  20. data/examples/read_file_encryption.rb +56 -0
  21. data/examples/read_registry_key_value.rb +33 -0
  22. data/examples/rename_file.rb +9 -7
  23. data/examples/tree_connect.rb +7 -5
  24. data/examples/write_file.rb +9 -7
  25. data/lib/ruby_smb.rb +4 -1
  26. data/lib/ruby_smb/client.rb +239 -21
  27. data/lib/ruby_smb/client/authentication.rb +27 -8
  28. data/lib/ruby_smb/client/encryption.rb +62 -0
  29. data/lib/ruby_smb/client/negotiation.rb +154 -12
  30. data/lib/ruby_smb/client/signing.rb +19 -0
  31. data/lib/ruby_smb/client/tree_connect.rb +4 -4
  32. data/lib/ruby_smb/client/utils.rb +8 -7
  33. data/lib/ruby_smb/client/winreg.rb +46 -0
  34. data/lib/ruby_smb/crypto.rb +30 -0
  35. data/lib/ruby_smb/dcerpc.rb +40 -0
  36. data/lib/ruby_smb/dcerpc/bind.rb +2 -2
  37. data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
  38. data/lib/ruby_smb/dcerpc/error.rb +6 -0
  39. data/lib/ruby_smb/dcerpc/ndr.rb +260 -16
  40. data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
  41. data/lib/ruby_smb/dcerpc/request.rb +41 -9
  42. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
  43. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +38 -0
  44. data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
  45. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
  46. data/lib/ruby_smb/dcerpc/svcctl.rb +479 -0
  47. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +48 -0
  48. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
  49. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
  50. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
  51. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
  52. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
  53. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +35 -0
  54. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
  55. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +31 -0
  56. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
  57. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
  58. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +44 -0
  59. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
  60. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
  61. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +25 -0
  62. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
  63. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
  64. data/lib/ruby_smb/dcerpc/winreg.rb +421 -0
  65. data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
  66. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
  67. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +73 -0
  68. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -0
  69. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +45 -0
  70. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
  71. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
  72. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
  73. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
  74. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
  75. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
  76. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
  77. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
  78. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
  79. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +40 -0
  80. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
  81. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
  82. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +37 -0
  83. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
  84. data/lib/ruby_smb/dispatcher/base.rb +1 -1
  85. data/lib/ruby_smb/dispatcher/socket.rb +5 -4
  86. data/lib/ruby_smb/error.rb +28 -1
  87. data/lib/ruby_smb/field/stringz16.rb +17 -1
  88. data/lib/ruby_smb/nbss/session_header.rb +4 -4
  89. data/lib/ruby_smb/smb1/commands.rb +1 -1
  90. data/lib/ruby_smb/smb1/file.rb +8 -14
  91. data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +1 -1
  92. data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +2 -2
  93. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
  94. data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -2
  95. data/lib/ruby_smb/smb1/packet/write_andx_request.rb +1 -1
  96. data/lib/ruby_smb/smb1/pipe.rb +81 -3
  97. data/lib/ruby_smb/smb1/tree.rb +12 -3
  98. data/lib/ruby_smb/smb2/bit_field/session_flags.rb +2 -1
  99. data/lib/ruby_smb/smb2/bit_field/share_flags.rb +6 -4
  100. data/lib/ruby_smb/smb2/file.rb +51 -61
  101. data/lib/ruby_smb/smb2/negotiate_context.rb +108 -0
  102. data/lib/ruby_smb/smb2/packet.rb +2 -0
  103. data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +41 -0
  104. data/lib/ruby_smb/smb2/packet/error_packet.rb +2 -4
  105. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +51 -14
  106. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +50 -4
  107. data/lib/ruby_smb/smb2/packet/transform_header.rb +84 -0
  108. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +92 -6
  109. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +8 -26
  110. data/lib/ruby_smb/smb2/pipe.rb +80 -3
  111. data/lib/ruby_smb/smb2/smb2_header.rb +1 -1
  112. data/lib/ruby_smb/smb2/tree.rb +32 -20
  113. data/lib/ruby_smb/version.rb +1 -1
  114. data/ruby_smb.gemspec +5 -3
  115. data/spec/lib/ruby_smb/client_spec.rb +1583 -102
  116. data/spec/lib/ruby_smb/crypto_spec.rb +25 -0
  117. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
  118. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
  119. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +1729 -0
  120. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
  121. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +161 -0
  122. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +135 -0
  123. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
  124. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
  125. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +191 -0
  126. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
  127. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
  128. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
  129. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
  130. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
  131. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +78 -0
  132. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
  133. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +59 -0
  134. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
  135. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
  136. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
  137. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
  138. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
  139. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +72 -0
  140. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +46 -0
  141. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
  142. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +512 -0
  143. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb +28 -0
  144. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -0
  145. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +110 -0
  146. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
  147. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +104 -0
  148. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
  149. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
  150. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
  151. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
  152. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
  153. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +95 -0
  154. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
  155. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +35 -0
  156. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
  157. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
  158. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +138 -0
  159. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
  160. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +57 -0
  161. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
  162. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +884 -0
  163. data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
  164. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +12 -12
  165. data/spec/lib/ruby_smb/error_spec.rb +59 -0
  166. data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
  167. data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
  168. data/spec/lib/ruby_smb/smb1/file_spec.rb +9 -1
  169. data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_request_spec.rb +2 -2
  170. data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_response_spec.rb +2 -2
  171. data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +2 -2
  172. data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +1 -1
  173. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +216 -147
  174. data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +9 -0
  175. data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +27 -0
  176. data/spec/lib/ruby_smb/smb2/file_spec.rb +146 -68
  177. data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +332 -0
  178. data/spec/lib/ruby_smb/smb2/packet/compression_transform_header_spec.rb +108 -0
  179. data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +3 -24
  180. data/spec/lib/ruby_smb/smb2/packet/negotiate_request_spec.rb +138 -3
  181. data/spec/lib/ruby_smb/smb2/packet/negotiate_response_spec.rb +120 -2
  182. data/spec/lib/ruby_smb/smb2/packet/transform_header_spec.rb +220 -0
  183. data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +339 -9
  184. data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +3 -30
  185. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +226 -148
  186. data/spec/lib/ruby_smb/smb2/smb2_header_spec.rb +2 -2
  187. data/spec/lib/ruby_smb/smb2/tree_spec.rb +88 -9
  188. metadata +257 -81
  189. metadata.gz.sig +0 -0
  190. data/lib/ruby_smb/smb1/dcerpc.rb +0 -72
  191. data/lib/ruby_smb/smb2/dcerpc.rb +0 -75
@@ -69,11 +69,51 @@ RSpec.describe RubySMB::Dcerpc::Request do
69
69
  expect(packet.stub).to be_a BinData::Choice
70
70
  end
71
71
 
72
- context 'with a NetShareEnumAll stub' do
72
+ context 'with a Srvsvc endpoint' do
73
+ let(:host) { '1.2.3.4' }
74
+ let(:packet) do
75
+ described_class.new(
76
+ { :opnum => RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL },
77
+ { :endpoint => 'Srvsvc', :host => host }
78
+ )
79
+ end
80
+
81
+ it 'uses endpoint parameter to select a Srvsvc stub packet' do
82
+ expect(packet.stub.selection).to eq('Srvsvc')
83
+ end
84
+
85
+ it 'selects the expected packet structure' do
86
+ expect(packet.stub).to eq(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.new(host: host))
87
+ end
88
+ end
89
+
90
+ context 'with a Winreg endpoint' do
91
+ let(:opnum) { RubySMB::Dcerpc::Winreg::OPEN_HKCR }
92
+ let(:packet) do
93
+ described_class.new(
94
+ { :opnum => opnum },
95
+ { :endpoint => 'Winreg' }
96
+ )
97
+ end
73
98
 
74
- it 'uses opnum as a selector' do
75
- packet = described_class.new({ :opnum => RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL }, host: '1.2.3.4')
76
- expect(packet.stub.selection).to eq(packet.opnum)
99
+ it 'uses endpoint parameter to select a Winreg stub packet' do
100
+ expect(packet.stub.selection).to eq('Winreg')
101
+ end
102
+
103
+ it 'selects the expected packet structure' do
104
+ expect(packet.stub).to eq(RubySMB::Dcerpc::Winreg::OpenRootKeyRequest.new(opnum: opnum))
105
+ end
106
+ end
107
+
108
+ context 'with an unknown endpoint' do
109
+ let(:packet) do
110
+ described_class.new(
111
+ { :endpoint => 'Unknown' }
112
+ )
113
+ end
114
+
115
+ it 'sets #stub to an empty string' do
116
+ expect(packet.stub).to eq('')
77
117
  end
78
118
  end
79
119
  end
@@ -102,13 +142,16 @@ RSpec.describe RubySMB::Dcerpc::Request do
102
142
  end
103
143
 
104
144
  it 'reads its own binary representation and output the same packet' do
105
- packet = described_class.new({ :opnum => RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL }, host: '1.2.3.4')
145
+ packet = described_class.new(
146
+ { :opnum => RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL },
147
+ { :endpoint => 'Srvsvc', :host => '1.2.3.4' }
148
+ )
106
149
  packet.pdu_header.pfc_flags.object_uuid = 1
107
150
  packet.object = '8a885d04-1ceb-11c9-9fe8-08002b104860'
108
151
  packet.auth_verifier = '123456'
109
152
  packet.pdu_header.auth_length = 6
110
153
  binary = packet.to_binary_s
111
- expect(described_class.read(binary)).to eq(packet)
154
+ packet2 = described_class.new( { :endpoint => 'Srvsvc' } )
155
+ expect(packet2.read(binary)).to eq(packet)
112
156
  end
113
157
  end
114
-
@@ -0,0 +1,161 @@
1
+ RSpec.describe RubySMB::Dcerpc::RpcSecurityDescriptor do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :lp_security_descriptor }
5
+ it { is_expected.to respond_to :cb_in_security_descriptor }
6
+ it { is_expected.to respond_to :cb_out_security_descriptor }
7
+
8
+ it 'is little endian' do
9
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
10
+ end
11
+
12
+ describe '#lp_security_descriptor' do
13
+ it 'should be a NdrLpByteArray structure' do
14
+ expect(packet.lp_security_descriptor).to be_a RubySMB::Dcerpc::Ndr::NdrLpByteArray
15
+ end
16
+ end
17
+
18
+ describe '#cb_in_security_descriptor' do
19
+ it 'should be a 32-bit unsigned integer' do
20
+ expect(packet.cb_in_security_descriptor).to be_a BinData::Uint32le
21
+ end
22
+ end
23
+
24
+ describe '#cb_out_security_descriptor' do
25
+ it 'should be a 32-bit unsigned integer' do
26
+ expect(packet.cb_out_security_descriptor).to be_a BinData::Uint32le
27
+ end
28
+ end
29
+
30
+ describe '#read' do
31
+ context 'with a null pointer' do
32
+ it 'reads its own binary representation' do
33
+ raw = packet.to_binary_s
34
+ expect(described_class.read(raw)).to eq(packet)
35
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
36
+ end
37
+ end
38
+
39
+ context 'with a normal RpcSecurityAttributes structure' do
40
+ it 'reads its own binary representation' do
41
+ packet.lp_security_descriptor = RubySMB::Dcerpc::Ndr::NdrLpByteArray.new([1, 2, 3])
42
+ packet.cb_in_security_descriptor = 90
43
+ packet.cb_out_security_descriptor = 33
44
+ raw = packet.to_binary_s
45
+ expect(described_class.read(raw)).to eq(packet)
46
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ RSpec.describe RubySMB::Dcerpc::RpcSecurityAttributes do
53
+ subject(:packet) { described_class.new }
54
+
55
+ it { is_expected.to respond_to :n_length }
56
+ it { is_expected.to respond_to :rpc_security_descriptor }
57
+ it { is_expected.to respond_to :b_inheritHandle }
58
+
59
+ it 'is little endian' do
60
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
61
+ end
62
+
63
+ describe '#n_length' do
64
+ it 'should be a 32-bit unsigned integer' do
65
+ expect(packet.n_length).to be_a BinData::Uint32le
66
+ end
67
+ end
68
+
69
+ describe '#rpc_security_descriptor' do
70
+ it 'should be a RpcSecurityDescriptor structure' do
71
+ expect(packet.rpc_security_descriptor).to be_a RubySMB::Dcerpc::RpcSecurityDescriptor
72
+ end
73
+ end
74
+
75
+ describe '#b_inheritHandle' do
76
+ it 'should be a 8-bit unsigned integer' do
77
+ expect(packet.b_inheritHandle).to be_a BinData::Uint8
78
+ end
79
+ end
80
+
81
+ describe '#read' do
82
+ context 'with a null pointer' do
83
+ it 'reads its own binary representation' do
84
+ raw = packet.to_binary_s
85
+ expect(described_class.read(raw)).to eq(packet)
86
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
87
+ end
88
+ end
89
+
90
+ context 'with a normal RpcSecurityAttributes structure' do
91
+ it 'reads its own binary representation' do
92
+ packet.n_length = 3
93
+ packet.rpc_security_descriptor = RubySMB::Dcerpc::RpcSecurityDescriptor.new
94
+ packet.rpc_security_descriptor.lp_security_descriptor = [1, 2, 3]
95
+ packet.rpc_security_descriptor.cb_in_security_descriptor = 33
96
+ packet.rpc_security_descriptor.cb_out_security_descriptor = 22
97
+ packet.b_inheritHandle = 90
98
+ raw = packet.to_binary_s
99
+ expect(described_class.read(raw)).to eq(packet)
100
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ RSpec.describe RubySMB::Dcerpc::PrpcSecurityAttributes do
107
+ it 'is NdrPointer subclass' do
108
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrPointer
109
+ end
110
+
111
+ subject(:packet) { described_class.new }
112
+
113
+ it { is_expected.to respond_to :referent }
114
+
115
+ it 'is little endian' do
116
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
117
+ end
118
+
119
+ describe '#referent' do
120
+ it 'should be a RpcSecurityAttributes structure' do
121
+ expect(packet.referent).to be_a RubySMB::Dcerpc::RpcSecurityAttributes
122
+ end
123
+
124
+ it 'exists if superclass #referent_id is not zero' do
125
+ packet.referent_id = 0xCCCC
126
+ expect(packet.referent?).to be true
127
+ end
128
+
129
+ it 'does not exist if superclass #referent_id is zero' do
130
+ packet.referent_id = 0
131
+ expect(packet.referent?).to be false
132
+ end
133
+ end
134
+
135
+ describe '#read' do
136
+ context 'with a null pointer' do
137
+ it 'reads its own binary representation' do
138
+ raw = packet.to_binary_s
139
+ expect(described_class.read(raw)).to eq(packet)
140
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
141
+ end
142
+ end
143
+
144
+ context 'with a normal RpcSecurityAttributes structure' do
145
+ it 'reads its own binary representation' do
146
+ struct = RubySMB::Dcerpc::RpcSecurityAttributes.new
147
+ struct.n_length = 5
148
+ struct.rpc_security_descriptor = RubySMB::Dcerpc::RpcSecurityDescriptor.new
149
+ struct.rpc_security_descriptor.lp_security_descriptor = [1, 2, 3]
150
+ struct.rpc_security_descriptor.cb_in_security_descriptor = 33
151
+ struct.rpc_security_descriptor.cb_out_security_descriptor = 22
152
+ struct.b_inheritHandle = 4
153
+ packet.set(struct)
154
+ raw = packet.to_binary_s
155
+ expect(described_class.read(raw)).to eq(packet)
156
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
157
+ end
158
+ end
159
+ end
160
+ end
161
+
@@ -0,0 +1,135 @@
1
+ RSpec.describe RubySMB::Dcerpc::RrpUnicodeString do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :buffer_length }
5
+ it { is_expected.to respond_to :maximum_length }
6
+ it { is_expected.to respond_to :buffer }
7
+
8
+ it 'is little endian' do
9
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
10
+ end
11
+
12
+ describe '#buffer_length' do
13
+ it 'should be a 16-bit unsigned integer' do
14
+ expect(packet.buffer_length).to be_a BinData::Uint16le
15
+ end
16
+ end
17
+
18
+ describe '#maximum_length' do
19
+ it 'should be a 16-bit unsigned integer' do
20
+ expect(packet.maximum_length).to be_a BinData::Uint16le
21
+ end
22
+ end
23
+
24
+ describe '#buffer' do
25
+ it 'should be a NdrLpStr' do
26
+ expect(packet.buffer).to be_a RubySMB::Dcerpc::Ndr::NdrLpStr
27
+ end
28
+ end
29
+
30
+ describe '#get' do
31
+ it 'returns #buffer' do
32
+ packet.buffer = 'spec_test'
33
+ expect(packet.get).to eq(RubySMB::Dcerpc::Ndr::NdrLpStr.new('spec_test'))
34
+ end
35
+ end
36
+
37
+ describe '#set' do
38
+ it 'sets #buffer to the expected value' do
39
+ packet.set('spec_test')
40
+ expect(packet.buffer).to eq(RubySMB::Dcerpc::Ndr::NdrLpStr.new('spec_test'))
41
+ end
42
+
43
+ it 'sets #buffer_length to the expected value' do
44
+ packet.set('spec_test')
45
+ expect(packet.buffer_length).to eq(('spec_test'.size + 1) * 2)
46
+ end
47
+
48
+ it 'sets #maximum_length to the expected value' do
49
+ packet.set('spec_test')
50
+ expect(packet.maximum_length).to eq(('spec_test'.size + 1) * 2)
51
+ end
52
+
53
+ context 'when the value is :null' do
54
+ it 'sets #buffer_length to 0' do
55
+ packet.buffer_length = 33
56
+ packet.set(:null)
57
+ expect(packet.buffer_length).to eq(0)
58
+ end
59
+
60
+ it 'does not set #maximum_length if it has already been set' do
61
+ packet.maximum_length = 33
62
+ packet.set(:null)
63
+ expect(packet.maximum_length).to eq(33)
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '#read' do
69
+ context 'with a null pointer' do
70
+ it 'reads its own binary representation' do
71
+ raw = packet.to_binary_s
72
+ expect(described_class.read(raw)).to eq(packet)
73
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
74
+ end
75
+ end
76
+
77
+ context 'with a normal string' do
78
+ it 'reads its own binary representation' do
79
+ packet.assign('my_test')
80
+ raw = packet.to_binary_s
81
+ expect(described_class.read(raw)).to eq(packet)
82
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ RSpec.describe RubySMB::Dcerpc::PrrpUnicodeString do
89
+ it 'is NdrPointer subclass' do
90
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrPointer
91
+ end
92
+
93
+ subject(:packet) { described_class.new }
94
+
95
+ it { is_expected.to respond_to :referent }
96
+
97
+ it 'is little endian' do
98
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
99
+ end
100
+
101
+ describe '#referent' do
102
+ it 'is a RrpUnicodeString' do
103
+ expect(packet.referent).to be_a RubySMB::Dcerpc::RrpUnicodeString
104
+ end
105
+
106
+ it 'exists if superclass #referent_identifier is not zero' do
107
+ packet.referent_id = 0xCCCC
108
+ expect(packet.referent?).to be true
109
+ end
110
+
111
+ it 'does not exist if superclass #referent_identifier is zero' do
112
+ packet.referent_id = 0
113
+ expect(packet.referent?).to be false
114
+ end
115
+ end
116
+
117
+ describe '#read' do
118
+ context 'with a null pointer' do
119
+ it 'reads its own binary representation' do
120
+ raw = packet.to_binary_s
121
+ expect(described_class.read(raw)).to eq(packet)
122
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
123
+ end
124
+ end
125
+
126
+ context 'with a normal string' do
127
+ it 'reads its own binary representation' do
128
+ packet.assign('my_test')
129
+ raw = packet.to_binary_s
130
+ expect(described_class.read(raw)).to eq(packet)
131
+ expect(described_class.read(raw).to_binary_s).to eq(raw)
132
+ end
133
+ end
134
+ end
135
+ end
@@ -15,11 +15,18 @@ RSpec.describe RubySMB::Dcerpc::Srvsvc::NetShareEnumAll do
15
15
  it { is_expected.to respond_to :max_buffer }
16
16
  it { is_expected.to respond_to :resume_referent_id }
17
17
  it { is_expected.to respond_to :resume_handle }
18
+ it { is_expected.to respond_to :opnum }
18
19
 
19
20
  it 'is little endian' do
20
21
  expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
21
22
  end
22
23
 
24
+ context 'when \'host\' parameter is not provided' do
25
+ it 'raises an ArgumentError' do
26
+ expect { described_class.new }.to raise_error(ArgumentError)
27
+ end
28
+ end
29
+
23
30
  describe '#referent_id' do
24
31
  it 'should be a 32-bit unsigned integer' do
25
32
  expect(packet.referent_id).to be_a BinData::Uint32le
@@ -156,6 +163,12 @@ RSpec.describe RubySMB::Dcerpc::Srvsvc::NetShareEnumAll do
156
163
  end
157
164
  end
158
165
 
166
+ describe '#initialize_instance' do
167
+ it 'sets #opnum to REG_CLOSE_KEY constant' do
168
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL)
169
+ end
170
+ end
171
+
159
172
  describe '#pad_length' do
160
173
  it 'returns 0 when #level is already 4-byte aligned' do
161
174
  expect(packet.pad_length).to eq 0
@@ -0,0 +1,60 @@
1
+ RSpec.describe RubySMB::Dcerpc::Srvsvc do
2
+ let(:srvsvc) do
3
+ RubySMB::SMB1::Pipe.new(
4
+ tree: double('Tree'),
5
+ response: RubySMB::SMB1::Packet::NtCreateAndxResponse.new,
6
+ name: 'srvsvc'
7
+ )
8
+ end
9
+
10
+ describe '#net_share_enum_all' do
11
+ let(:host) { '1.2.3.4' }
12
+ let(:request_packet) { double('NetShareEnumAll request packet') }
13
+ let(:dcerpc_response) { double('DCERPC response') }
14
+ let(:shares) do
15
+ [
16
+ ["C$", "DISK", "Default share"],
17
+ ["Shared", "DISK", ""],
18
+ ["IPC$", "IPC", "Remote IPC"],
19
+ ["ADMIN$", "DISK", "Remote Admin"]
20
+ ]
21
+ end
22
+
23
+ before :example do
24
+ allow(srvsvc).to receive(:bind)
25
+ allow(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll).to receive(:new).and_return(request_packet)
26
+ allow(srvsvc).to receive(:dcerpc_request).and_return(dcerpc_response)
27
+ allow(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll).to receive(:parse_response).and_return(shares)
28
+ end
29
+
30
+ it 'calls #bind with the expected arguments' do
31
+ srvsvc.net_share_enum_all(host)
32
+ expect(srvsvc).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Srvsvc)
33
+ end
34
+
35
+ it 'creates the expected NetShareEnumAll packet' do
36
+ srvsvc.net_share_enum_all(host)
37
+ expect(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll).to have_received(:new).with(host: host)
38
+ end
39
+
40
+ it 'calls #request with the expected arguments' do
41
+ srvsvc.net_share_enum_all(host)
42
+ expect(srvsvc).to have_received(:dcerpc_request).with(request_packet)
43
+ end
44
+
45
+ it 'parse the response with NetShareEnumAll #parse_response method' do
46
+ srvsvc.net_share_enum_all(host)
47
+ expect(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll).to have_received(:parse_response).with(dcerpc_response)
48
+ end
49
+
50
+ it 'returns the remote shares' do
51
+ output = [
52
+ {:name=>"C$", :type=>"DISK", :comment=>"Default share"},
53
+ {:name=>"Shared", :type=>"DISK", :comment=>""},
54
+ {:name=>"IPC$", :type=>"IPC", :comment=>"Remote IPC"},
55
+ {:name=>"ADMIN$", :type=>"DISK", :comment=>"Remote Admin"},
56
+ ]
57
+ expect(srvsvc.net_share_enum_all(host)).to eq(output)
58
+ end
59
+ end
60
+ end