ruby_smb 1.0.0 → 1.1.0

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 (171) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.travis.yml +4 -1
  4. data/README.md +35 -47
  5. data/examples/enum_registry_key.rb +28 -0
  6. data/examples/enum_registry_values.rb +30 -0
  7. data/examples/pipes.rb +2 -1
  8. data/examples/read_registry_key_value.rb +32 -0
  9. data/lib/ruby_smb/client/authentication.rb +43 -25
  10. data/lib/ruby_smb/client/echo.rb +20 -2
  11. data/lib/ruby_smb/client/negotiation.rb +27 -12
  12. data/lib/ruby_smb/client/tree_connect.rb +20 -14
  13. data/lib/ruby_smb/client/utils.rb +2 -2
  14. data/lib/ruby_smb/client/winreg.rb +46 -0
  15. data/lib/ruby_smb/client.rb +28 -4
  16. data/lib/ruby_smb/dcerpc/bind.rb +2 -2
  17. data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
  18. data/lib/ruby_smb/dcerpc/error.rb +3 -0
  19. data/lib/ruby_smb/dcerpc/ndr.rb +95 -16
  20. data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
  21. data/lib/ruby_smb/dcerpc/request.rb +28 -9
  22. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +35 -0
  23. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
  24. data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
  25. data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
  26. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
  27. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +45 -0
  28. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
  29. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
  30. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
  31. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
  32. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
  33. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
  34. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
  35. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
  36. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
  37. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +39 -0
  38. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
  39. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
  40. data/lib/ruby_smb/dcerpc/winreg.rb +340 -0
  41. data/lib/ruby_smb/dcerpc.rb +38 -0
  42. data/lib/ruby_smb/dispatcher/socket.rb +3 -1
  43. data/lib/ruby_smb/error.rb +40 -1
  44. data/lib/ruby_smb/generic_packet.rb +33 -4
  45. data/lib/ruby_smb/smb1/file.rb +67 -11
  46. data/lib/ruby_smb/smb1/packet/close_request.rb +2 -5
  47. data/lib/ruby_smb/smb1/packet/close_response.rb +2 -1
  48. data/lib/ruby_smb/smb1/packet/echo_request.rb +2 -4
  49. data/lib/ruby_smb/smb1/packet/echo_response.rb +2 -1
  50. data/lib/ruby_smb/smb1/packet/empty_packet.rb +10 -1
  51. data/lib/ruby_smb/smb1/packet/logoff_request.rb +2 -4
  52. data/lib/ruby_smb/smb1/packet/logoff_response.rb +2 -1
  53. data/lib/ruby_smb/smb1/packet/negotiate_request.rb +2 -5
  54. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +3 -7
  55. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +4 -4
  56. data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +2 -4
  57. data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +2 -1
  58. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +2 -1
  59. data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +2 -1
  60. data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +2 -4
  61. data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +2 -1
  62. data/lib/ruby_smb/smb1/packet/read_andx_request.rb +2 -5
  63. data/lib/ruby_smb/smb1/packet/read_andx_response.rb +2 -1
  64. data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -1
  65. data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +2 -1
  66. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +2 -5
  67. data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -1
  68. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_request.rb +0 -1
  69. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_response.rb +3 -2
  70. data/lib/ruby_smb/smb1/packet/trans/request.rb +2 -5
  71. data/lib/ruby_smb/smb1/packet/trans/response.rb +2 -1
  72. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +1 -1
  73. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +1 -1
  74. data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +2 -1
  75. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +8 -2
  76. data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +2 -1
  77. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +8 -2
  78. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +2 -1
  79. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +2 -1
  80. data/lib/ruby_smb/smb1/packet/trans2/request.rb +2 -4
  81. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +2 -4
  82. data/lib/ruby_smb/smb1/packet/trans2/response.rb +2 -1
  83. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +2 -1
  84. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +2 -1
  85. data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +2 -4
  86. data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +13 -3
  87. data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
  88. data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -1
  89. data/lib/ruby_smb/smb1/packet/write_andx_request.rb +2 -5
  90. data/lib/ruby_smb/smb1/packet/write_andx_response.rb +2 -1
  91. data/lib/ruby_smb/smb1/pipe.rb +86 -5
  92. data/lib/ruby_smb/smb1/tree.rb +40 -2
  93. data/lib/ruby_smb/smb2/file.rb +97 -1
  94. data/lib/ruby_smb/smb2/packet/close_request.rb +2 -4
  95. data/lib/ruby_smb/smb2/packet/close_response.rb +2 -1
  96. data/lib/ruby_smb/smb2/packet/create_request.rb +2 -4
  97. data/lib/ruby_smb/smb2/packet/create_response.rb +2 -1
  98. data/lib/ruby_smb/smb2/packet/echo_request.rb +2 -4
  99. data/lib/ruby_smb/smb2/packet/echo_response.rb +2 -1
  100. data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -3
  101. data/lib/ruby_smb/smb2/packet/ioctl_request.rb +2 -5
  102. data/lib/ruby_smb/smb2/packet/ioctl_response.rb +2 -1
  103. data/lib/ruby_smb/smb2/packet/logoff_request.rb +2 -4
  104. data/lib/ruby_smb/smb2/packet/logoff_response.rb +2 -1
  105. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +2 -5
  106. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +2 -1
  107. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +2 -4
  108. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +8 -2
  109. data/lib/ruby_smb/smb2/packet/read_request.rb +2 -4
  110. data/lib/ruby_smb/smb2/packet/read_response.rb +2 -1
  111. data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
  112. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -1
  113. data/lib/ruby_smb/smb2/packet/set_info_request.rb +2 -4
  114. data/lib/ruby_smb/smb2/packet/set_info_response.rb +2 -1
  115. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +2 -5
  116. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +8 -2
  117. data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +2 -4
  118. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +2 -1
  119. data/lib/ruby_smb/smb2/packet/write_request.rb +2 -4
  120. data/lib/ruby_smb/smb2/packet/write_response.rb +2 -1
  121. data/lib/ruby_smb/smb2/pipe.rb +98 -11
  122. data/lib/ruby_smb/smb2/tree.rb +44 -6
  123. data/lib/ruby_smb/version.rb +1 -1
  124. data/lib/ruby_smb.rb +0 -1
  125. data/ruby_smb.gemspec +3 -3
  126. data/spec/lib/ruby_smb/client_spec.rb +271 -11
  127. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
  128. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
  129. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +410 -0
  130. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
  131. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +98 -0
  132. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
  133. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
  134. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb +28 -0
  135. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -0
  136. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +108 -0
  137. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
  138. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
  139. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
  140. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
  141. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
  142. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +90 -0
  143. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
  144. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +39 -0
  145. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
  146. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
  147. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +150 -0
  148. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
  149. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +710 -0
  150. data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
  151. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +3 -1
  152. data/spec/lib/ruby_smb/generic_packet_spec.rb +52 -4
  153. data/spec/lib/ruby_smb/smb1/file_spec.rb +191 -2
  154. data/spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb +68 -0
  155. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +11 -2
  156. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +11 -2
  157. data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +40 -0
  158. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +272 -149
  159. data/spec/lib/ruby_smb/smb1/tree_spec.rb +44 -7
  160. data/spec/lib/ruby_smb/smb2/file_spec.rb +295 -2
  161. data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +78 -0
  162. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +8 -0
  163. data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +8 -0
  164. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +322 -145
  165. data/spec/lib/ruby_smb/smb2/tree_spec.rb +214 -0
  166. data.tar.gz.sig +0 -0
  167. metadata +70 -11
  168. metadata.gz.sig +0 -0
  169. data/lib/ruby_smb/smb1/dcerpc.rb +0 -67
  170. data/lib/ruby_smb/smb2/dcerpc.rb +0 -70
  171. data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +0 -37
@@ -48,6 +48,13 @@ RSpec.describe RubySMB::SMB2::Tree do
48
48
  tree.disconnect!
49
49
  end
50
50
 
51
+ it 'raises an InvalidPacket exception if the response is not valid' do
52
+ allow(client).to receive(:send_recv)
53
+ allow(RubySMB::SMB2::Packet::TreeDisconnectResponse).to receive(:read).and_return(disco_resp)
54
+ allow(disco_resp).to receive(:valid?).and_return(false)
55
+ expect { tree.disconnect! }.to raise_error(RubySMB::Error::InvalidPacket)
56
+ end
57
+
51
58
  it 'returns the NTStatus code from the response' do
52
59
  allow(client).to receive(:send_recv).and_return(disco_resp.to_binary_s)
53
60
  expect(tree.disconnect!).to eq disco_resp.status_code
@@ -129,6 +136,15 @@ RSpec.describe RubySMB::SMB2::Tree do
129
136
  expect(client).to receive(:send_recv).with(create_req).and_return(create_response.to_binary_s)
130
137
  tree.open_directory
131
138
  end
139
+
140
+ context 'when the response is not a valid packet' do
141
+ it 'raises an InvalidPacket exception' do
142
+ allow(client).to receive(:send_recv)
143
+ allow(RubySMB::SMB2::Packet::CreateResponse).to receive(:read).and_return(create_response)
144
+ create_response.smb2_header.command = RubySMB::SMB2::Commands::LOGOFF
145
+ expect { tree.open_directory }.to raise_error(RubySMB::Error::InvalidPacket)
146
+ end
147
+ end
132
148
  end
133
149
 
134
150
  describe '#list' do
@@ -202,6 +218,13 @@ RSpec.describe RubySMB::SMB2::Tree do
202
218
  expect(tree.list).to eq([file1])
203
219
  end
204
220
 
221
+ context 'when the response is not a valid packet' do
222
+ it 'raises an InvalidPacket exception' do
223
+ query_dir_res.smb2_header.command = RubySMB::SMB2::Commands::LOGOFF
224
+ expect { tree.list }.to raise_error(RubySMB::Error::InvalidPacket)
225
+ end
226
+ end
227
+
205
228
  context 'when multiple requests are needed to retrieve the full directory list' do
206
229
  before :example do
207
230
  query_dir_res.smb2_header.nt_status = WindowsError::NTStatus::STATUS_SUCCESS.value
@@ -238,4 +261,195 @@ RSpec.describe RubySMB::SMB2::Tree do
238
261
  end
239
262
 
240
263
  end
264
+
265
+ describe '#open_file' do
266
+ let(:create_request) { RubySMB::SMB2::Packet::CreateRequest.new }
267
+ let(:create_response) { RubySMB::SMB2::Packet::CreateResponse.new }
268
+ let(:filename) { "test_file\x00".encode('UTF-16LE') }
269
+
270
+ before :each do
271
+ allow(RubySMB::SMB2::Packet::CreateRequest).to receive(:new).and_return(create_request)
272
+ allow(RubySMB::SMB2::Packet::CreateResponse).to receive(:read).and_return(create_response)
273
+ end
274
+
275
+ it 'calls #set_header_fields' do
276
+ allow(client).to receive(:send_recv).and_return(create_response.to_binary_s)
277
+ expect(tree).to receive(:set_header_fields).with(create_request).and_call_original
278
+ tree.open_file(filename: filename)
279
+ end
280
+
281
+ describe 'filename' do
282
+ it 'takes the filename as an argument' do
283
+ allow(client).to receive(:send_recv) do |packet|
284
+ expect(packet.name).to eq(filename)
285
+ create_response.to_binary_s
286
+ end
287
+ tree.open_file(filename: filename)
288
+ end
289
+ end
290
+
291
+ describe 'attributes' do
292
+ it 'has the correct default fields set' do
293
+ allow(client).to receive(:send_recv) do |packet|
294
+ expect(packet.file_attributes.directory).to eq(0)
295
+ expect(packet.file_attributes.normal).to eq(1)
296
+ create_response.to_binary_s
297
+ end
298
+ tree.open_file(filename: filename)
299
+ end
300
+
301
+ it 'can take the Attributes as an argument' do
302
+ attributes = { normal: 0 }
303
+ allow(client).to receive(:send_recv) do |packet|
304
+ expect(packet.file_attributes.normal).to eq(0)
305
+ create_response.to_binary_s
306
+ end
307
+ tree.open_file(filename: filename, attributes: attributes)
308
+ end
309
+ end
310
+
311
+ describe 'options' do
312
+ it 'has the correct default fields set' do
313
+ allow(client).to receive(:send_recv) do |packet|
314
+ expect(packet.create_options.directory_file).to eq(0)
315
+ expect(packet.create_options.non_directory_file).to eq(1)
316
+ create_response.to_binary_s
317
+ end
318
+ tree.open_file(filename: filename)
319
+ end
320
+
321
+ it 'can take the Create Options as an argument' do
322
+ options = RubySMB::SMB1::BitField::CreateOptions.new(directory_file: 1)
323
+ allow(client).to receive(:send_recv) do |packet|
324
+ expect(packet.create_options.directory_file).to eq(1)
325
+ expect(packet.create_options.non_directory_file).to eq(0)
326
+ create_response.to_binary_s
327
+ end
328
+ tree.open_file(filename: filename, options: options)
329
+ end
330
+ end
331
+
332
+ describe 'disposition' do
333
+ it 'defaults to FILE_OPEN' do
334
+ allow(client).to receive(:send_recv) do |packet|
335
+ expect(packet.create_disposition).to eq(RubySMB::Dispositions::FILE_OPEN)
336
+ create_response.to_binary_s
337
+ end
338
+ tree.open_file(filename: filename)
339
+ end
340
+
341
+ it 'can take the Disposition as an argument' do
342
+ allow(client).to receive(:send_recv) do |packet|
343
+ expect(packet.create_disposition).to eq(RubySMB::Dispositions::FILE_OPEN_IF)
344
+ create_response.to_binary_s
345
+ end
346
+ tree.open_file(filename: filename, disposition: RubySMB::Dispositions::FILE_OPEN_IF)
347
+ end
348
+ end
349
+
350
+ describe 'impersonation level' do
351
+ it 'defaults to SEC_IMPERSONATE' do
352
+ allow(client).to receive(:send_recv) do |packet|
353
+ expect(packet.impersonation_level).to eq(RubySMB::ImpersonationLevels::SEC_IMPERSONATE)
354
+ create_response.to_binary_s
355
+ end
356
+ tree.open_file(filename: filename)
357
+ end
358
+
359
+ it 'can take the Impersonation Level as an argument' do
360
+ allow(client).to receive(:send_recv) do |packet|
361
+ expect(packet.impersonation_level).to eq(RubySMB::ImpersonationLevels::SEC_DELEGATE)
362
+ create_response.to_binary_s
363
+ end
364
+ tree.open_file(filename: filename, impersonation: RubySMB::ImpersonationLevels::SEC_DELEGATE)
365
+ end
366
+ end
367
+
368
+ describe 'RWD access permissions' do
369
+ it 'will set the read permission from the parameters' do
370
+ allow(client).to receive(:send_recv) do |packet|
371
+ expect(packet.share_access.read_access).to eq(1)
372
+ expect(packet.desired_access.read_data).to eq(1)
373
+ create_response.to_binary_s
374
+ end
375
+ tree.open_file(filename: filename, read: true)
376
+ end
377
+
378
+ it 'will set the write permission from the parameters' do
379
+ allow(client).to receive(:send_recv) do |packet|
380
+ expect(packet.share_access.write_access).to eq(1)
381
+ expect(packet.desired_access.write_data).to eq(1)
382
+ expect(packet.desired_access.append_data).to eq(1)
383
+ create_response.to_binary_s
384
+ end
385
+ tree.open_file(filename: filename, write: true)
386
+ end
387
+
388
+ it 'will set the delete permission from the parameters' do
389
+ allow(client).to receive(:send_recv) do |packet|
390
+ expect(packet.share_access.delete_access).to eq(1)
391
+ expect(packet.desired_access.delete_access).to eq(1)
392
+ create_response.to_binary_s
393
+ end
394
+ tree.open_file(filename: filename, delete: true)
395
+ end
396
+ end
397
+
398
+ it 'sets #requested_oplock to 0xFF' do
399
+ allow(client).to receive(:send_recv) do |packet|
400
+ expect(packet.requested_oplock).to eq(0xFF)
401
+ create_response.to_binary_s
402
+ end
403
+ tree.open_file(filename: filename, delete: true)
404
+ end
405
+
406
+ it 'sends the CreateRequest request packet and gets the expected CreateResponse response back' do
407
+ expect(client).to receive(:send_recv).with(create_request).and_return(create_response.to_binary_s)
408
+ tree.open_file(filename: filename)
409
+ end
410
+
411
+ context 'when sending the request packet and gets a response back' do
412
+ before :example do
413
+ allow(client).to receive(:send_recv).with(create_request).and_return(create_response.to_binary_s)
414
+ end
415
+
416
+ context 'when it is a file' do
417
+ it 'returns the expected RubySMB::SMB2::File object' do
418
+ file_obj = RubySMB::SMB2::File.new(name: filename, tree: tree, response: create_response)
419
+ expect(RubySMB::SMB2::File).to receive(:new).with(name: filename, tree: tree, response: create_response).and_return(file_obj)
420
+ expect(tree.open_file(filename: filename)).to eq(file_obj)
421
+ end
422
+ end
423
+
424
+ context 'when it is a pipe' do
425
+ it 'returns the expected RubySMB::SMB2::Pipe object' do
426
+ response.share_type = 0x02
427
+ pipe_obj = RubySMB::SMB2::Pipe.new(name: filename, tree: tree, response: create_response)
428
+ expect(RubySMB::SMB2::Pipe).to receive(:new).with(name: filename, tree: tree, response: create_response).and_return(pipe_obj)
429
+ expect(tree.open_file(filename: filename)).to eq(pipe_obj)
430
+ end
431
+ end
432
+
433
+ context 'when it is an unsupported share type' do
434
+ it 'raises a RubySMBError exception' do
435
+ response.share_type = 0x03
436
+ expect { tree.open_file(filename: filename) }.to raise_error(RubySMB::Error::RubySMBError)
437
+ end
438
+ end
439
+
440
+ context 'when the response is not a CreateResponse packet' do
441
+ it 'raises an InvalidPacket exception' do
442
+ create_response.smb2_header.command = RubySMB::SMB2::Commands::LOGOFF
443
+ expect { tree.open_file(filename: filename) }.to raise_error(RubySMB::Error::InvalidPacket)
444
+ end
445
+ end
446
+
447
+ context 'when the response status code is not STATUS_SUCCESS' do
448
+ it 'raises an UnexpectedStatusCode exception' do
449
+ create_response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_INVALID_HANDLE.value
450
+ expect { tree.open_file(filename: filename) }.to raise_error(RubySMB::Error::UnexpectedStatusCode)
451
+ end
452
+ end
453
+ end
454
+ end
241
455
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,9 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_smb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
+ - Metasploit Hackers
7
8
  - David Maloney
8
9
  - James Lee
9
10
  - Dev Mohanty
@@ -91,7 +92,7 @@ cert_chain:
91
92
  G+Hmcg1v810agasPdoydE0RTVZgEOOMoQ07qu7JFXVWZ9ZQpHT7qJATWL/b2csFG
92
93
  8mVuTXnyJOKRJA==
93
94
  -----END CERTIFICATE-----
94
- date: 2018-06-25 00:00:00.000000000 Z
95
+ date: 2019-06-27 00:00:00.000000000 Z
95
96
  dependencies:
96
97
  - !ruby/object:Gem::Dependency
97
98
  name: redcarpet
@@ -207,10 +208,7 @@ dependencies:
207
208
  version: '0'
208
209
  description: ''
209
210
  email:
210
- - DMaloney@rapid7.com
211
- - egypt@metasploit.com
212
- - dev_mohanty@rapid7.com
213
- - paristvinternet-github@yahoo.com
211
+ - msfdev@metasploit.com
214
212
  executables: []
215
213
  extensions: []
216
214
  extra_rdoc_files: []
@@ -229,12 +227,15 @@ files:
229
227
  - examples/append_file.rb
230
228
  - examples/authenticate.rb
231
229
  - examples/delete_file.rb
230
+ - examples/enum_registry_key.rb
231
+ - examples/enum_registry_values.rb
232
232
  - examples/list_directory.rb
233
233
  - examples/negotiate.rb
234
234
  - examples/negotiate_with_netbios_service.rb
235
235
  - examples/net_share_enum_all.rb
236
236
  - examples/pipes.rb
237
237
  - examples/read_file.rb
238
+ - examples/read_registry_key_value.rb
238
239
  - examples/rename_file.rb
239
240
  - examples/tree_connect.rb
240
241
  - examples/write_file.rb
@@ -246,6 +247,7 @@ files:
246
247
  - lib/ruby_smb/client/signing.rb
247
248
  - lib/ruby_smb/client/tree_connect.rb
248
249
  - lib/ruby_smb/client/utils.rb
250
+ - lib/ruby_smb/client/winreg.rb
249
251
  - lib/ruby_smb/dcerpc.rb
250
252
  - lib/ruby_smb/dcerpc/bind.rb
251
253
  - lib/ruby_smb/dcerpc/bind_ack.rb
@@ -256,9 +258,26 @@ files:
256
258
  - lib/ruby_smb/dcerpc/ptypes.rb
257
259
  - lib/ruby_smb/dcerpc/request.rb
258
260
  - lib/ruby_smb/dcerpc/response.rb
261
+ - lib/ruby_smb/dcerpc/rrp_unicode_string.rb
259
262
  - lib/ruby_smb/dcerpc/srvsvc.rb
260
263
  - lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb
261
264
  - lib/ruby_smb/dcerpc/uuid.rb
265
+ - lib/ruby_smb/dcerpc/winreg.rb
266
+ - lib/ruby_smb/dcerpc/winreg/close_key_request.rb
267
+ - lib/ruby_smb/dcerpc/winreg/close_key_response.rb
268
+ - lib/ruby_smb/dcerpc/winreg/enum_key_request.rb
269
+ - lib/ruby_smb/dcerpc/winreg/enum_key_response.rb
270
+ - lib/ruby_smb/dcerpc/winreg/enum_value_request.rb
271
+ - lib/ruby_smb/dcerpc/winreg/enum_value_response.rb
272
+ - lib/ruby_smb/dcerpc/winreg/open_key_request.rb
273
+ - lib/ruby_smb/dcerpc/winreg/open_key_response.rb
274
+ - lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb
275
+ - lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb
276
+ - lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb
277
+ - lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb
278
+ - lib/ruby_smb/dcerpc/winreg/query_value_request.rb
279
+ - lib/ruby_smb/dcerpc/winreg/query_value_response.rb
280
+ - lib/ruby_smb/dcerpc/winreg/regsam.rb
262
281
  - lib/ruby_smb/dispatcher.rb
263
282
  - lib/ruby_smb/dispatcher/base.rb
264
283
  - lib/ruby_smb/dispatcher/socket.rb
@@ -324,7 +343,6 @@ files:
324
343
  - lib/ruby_smb/smb1/commands.rb
325
344
  - lib/ruby_smb/smb1/create_actions.rb
326
345
  - lib/ruby_smb/smb1/data_block.rb
327
- - lib/ruby_smb/smb1/dcerpc.rb
328
346
  - lib/ruby_smb/smb1/dialect.rb
329
347
  - lib/ruby_smb/smb1/file.rb
330
348
  - lib/ruby_smb/smb1/oplock_levels.rb
@@ -402,7 +420,6 @@ files:
402
420
  - lib/ruby_smb/smb2/bit_field/smb2_security_mode_single.rb
403
421
  - lib/ruby_smb/smb2/commands.rb
404
422
  - lib/ruby_smb/smb2/create_context.rb
405
- - lib/ruby_smb/smb2/dcerpc.rb
406
423
  - lib/ruby_smb/smb2/file.rb
407
424
  - lib/ruby_smb/smb2/info_type.rb
408
425
  - lib/ruby_smb/smb2/packet.rb
@@ -441,12 +458,32 @@ files:
441
458
  - spec/lib/ruby_smb/client_spec.rb
442
459
  - spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb
443
460
  - spec/lib/ruby_smb/dcerpc/bind_spec.rb
461
+ - spec/lib/ruby_smb/dcerpc/ndr_spec.rb
444
462
  - spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb
445
463
  - spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb
446
464
  - spec/lib/ruby_smb/dcerpc/request_spec.rb
447
465
  - spec/lib/ruby_smb/dcerpc/response_spec.rb
466
+ - spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb
448
467
  - spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb
468
+ - spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb
449
469
  - spec/lib/ruby_smb/dcerpc/uuid_spec.rb
470
+ - spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb
471
+ - spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb
472
+ - spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb
473
+ - spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb
474
+ - spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb
475
+ - spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb
476
+ - spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb
477
+ - spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb
478
+ - spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb
479
+ - spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb
480
+ - spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb
481
+ - spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb
482
+ - spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb
483
+ - spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb
484
+ - spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb
485
+ - spec/lib/ruby_smb/dcerpc/winreg_spec.rb
486
+ - spec/lib/ruby_smb/dcerpc_spec.rb
450
487
  - spec/lib/ruby_smb/dispatcher/base_spec.rb
451
488
  - spec/lib/ruby_smb/dispatcher/socket_spec.rb
452
489
  - spec/lib/ruby_smb/field/extended_attribute_flag_spec.rb
@@ -503,7 +540,7 @@ files:
503
540
  - spec/lib/ruby_smb/smb1/packet/close_response_spec.rb
504
541
  - spec/lib/ruby_smb/smb1/packet/echo_request_spec.rb
505
542
  - spec/lib/ruby_smb/smb1/packet/echo_response_spec.rb
506
- - spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb
543
+ - spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb
507
544
  - spec/lib/ruby_smb/smb1/packet/logoff_request_spec.rb
508
545
  - spec/lib/ruby_smb/smb1/packet/logoff_response_spec.rb
509
546
  - spec/lib/ruby_smb/smb1/packet/negotiate_request_spec.rb
@@ -566,6 +603,7 @@ files:
566
603
  - spec/lib/ruby_smb/smb2/packet/create_response_spec.rb
567
604
  - spec/lib/ruby_smb/smb2/packet/echo_request_spec.rb
568
605
  - spec/lib/ruby_smb/smb2/packet/echo_response_spec.rb
606
+ - spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb
569
607
  - spec/lib/ruby_smb/smb2/packet/ioctl_request_spec.rb
570
608
  - spec/lib/ruby_smb/smb2/packet/logoff_request_spec.rb
571
609
  - spec/lib/ruby_smb/smb2/packet/logoff_response_spec.rb
@@ -604,7 +642,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
604
642
  requirements:
605
643
  - - ">="
606
644
  - !ruby/object:Gem::Version
607
- version: 2.2.0
645
+ version: 2.3.0
608
646
  required_rubygems_version: !ruby/object:Gem::Requirement
609
647
  requirements:
610
648
  - - ">="
@@ -620,12 +658,32 @@ test_files:
620
658
  - spec/lib/ruby_smb/client_spec.rb
621
659
  - spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb
622
660
  - spec/lib/ruby_smb/dcerpc/bind_spec.rb
661
+ - spec/lib/ruby_smb/dcerpc/ndr_spec.rb
623
662
  - spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb
624
663
  - spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb
625
664
  - spec/lib/ruby_smb/dcerpc/request_spec.rb
626
665
  - spec/lib/ruby_smb/dcerpc/response_spec.rb
666
+ - spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb
627
667
  - spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb
668
+ - spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb
628
669
  - spec/lib/ruby_smb/dcerpc/uuid_spec.rb
670
+ - spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb
671
+ - spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb
672
+ - spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb
673
+ - spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb
674
+ - spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb
675
+ - spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb
676
+ - spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb
677
+ - spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb
678
+ - spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb
679
+ - spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb
680
+ - spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb
681
+ - spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb
682
+ - spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb
683
+ - spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb
684
+ - spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb
685
+ - spec/lib/ruby_smb/dcerpc/winreg_spec.rb
686
+ - spec/lib/ruby_smb/dcerpc_spec.rb
629
687
  - spec/lib/ruby_smb/dispatcher/base_spec.rb
630
688
  - spec/lib/ruby_smb/dispatcher/socket_spec.rb
631
689
  - spec/lib/ruby_smb/field/extended_attribute_flag_spec.rb
@@ -682,7 +740,7 @@ test_files:
682
740
  - spec/lib/ruby_smb/smb1/packet/close_response_spec.rb
683
741
  - spec/lib/ruby_smb/smb1/packet/echo_request_spec.rb
684
742
  - spec/lib/ruby_smb/smb1/packet/echo_response_spec.rb
685
- - spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb
743
+ - spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb
686
744
  - spec/lib/ruby_smb/smb1/packet/logoff_request_spec.rb
687
745
  - spec/lib/ruby_smb/smb1/packet/logoff_response_spec.rb
688
746
  - spec/lib/ruby_smb/smb1/packet/negotiate_request_spec.rb
@@ -745,6 +803,7 @@ test_files:
745
803
  - spec/lib/ruby_smb/smb2/packet/create_response_spec.rb
746
804
  - spec/lib/ruby_smb/smb2/packet/echo_request_spec.rb
747
805
  - spec/lib/ruby_smb/smb2/packet/echo_response_spec.rb
806
+ - spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb
748
807
  - spec/lib/ruby_smb/smb2/packet/ioctl_request_spec.rb
749
808
  - spec/lib/ruby_smb/smb2/packet/logoff_request_spec.rb
750
809
  - spec/lib/ruby_smb/smb2/packet/logoff_response_spec.rb
metadata.gz.sig CHANGED
Binary file
@@ -1,67 +0,0 @@
1
- module RubySMB
2
- module SMB1
3
- module Dcerpc
4
-
5
- def net_share_enum_all(host)
6
- bind(endpoint: RubySMB::Dcerpc::Srvsvc)
7
-
8
- response = request(RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL, host: host)
9
-
10
- shares = RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.parse_response(response.stub.to_binary_s)
11
- shares.map{|s|{name: s[0], type: s[1], comment: s[2]}}
12
- end
13
-
14
- def bind(options={})
15
- bind_req = RubySMB::Dcerpc::Bind.new(options)
16
- write(data: bind_req.to_binary_s)
17
- @size = 1024
18
- dcerpc_raw_response = read()
19
- begin
20
- dcerpc_response = RubySMB::Dcerpc::BindAck.read(dcerpc_raw_response)
21
- rescue IOError
22
- raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the DCERPC response"
23
- end
24
- unless dcerpc_response.pdu_header.ptype == RubySMB::Dcerpc::PTypes::BIND_ACK
25
- raise RubySMB::Dcerpc::Error::BindError, "Not a BindAck packet"
26
- end
27
-
28
- res_list = dcerpc_response.p_result_list
29
- if res_list.n_results == 0 ||
30
- res_list.p_results[0].result != RubySMB::Dcerpc::BindAck::ACCEPTANCE
31
- raise RubySMB::Dcerpc::Error::BindError,
32
- "Bind Failed (Result: #{res_list.p_results[0].result}, Reason: #{res_list.p_results[0].reason})"
33
- end
34
- dcerpc_response
35
- end
36
-
37
- def request(opnum, options={})
38
- dcerpc_request = RubySMB::Dcerpc::Request.new({ :opnum => opnum }, options)
39
- request = RubySMB::SMB1::Packet::Trans::TransactNmpipeRequest.new(options)
40
- @tree.set_header_fields(request)
41
- request.set_fid(@fid)
42
- request.data_block.trans_data.write_data = dcerpc_request.to_binary_s
43
-
44
- trans_nmpipe_raw_response = @tree.client.send_recv(request)
45
- trans_nmpipe_response = RubySMB::SMB1::Packet::Trans::TransactNmpipeResponse.read(trans_nmpipe_raw_response)
46
- unless trans_nmpipe_response.smb_header.command == RubySMB::SMB1::Commands::SMB_COM_TRANSACTION
47
- raise RubySMB::Error::InvalidPacket, 'Not a Trans packet'
48
- end
49
- unless trans_nmpipe_response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
50
- raise RubySMB::Error::UnexpectedStatusCode, trans_nmpipe_response.status_code.name
51
- end
52
-
53
- begin
54
- dcerpc_response = RubySMB::Dcerpc::Response.read(trans_nmpipe_response.data_block.trans_data.read_data)
55
- rescue IOError
56
- raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the DCERPC response"
57
- end
58
- unless dcerpc_response.pdu_header.ptype == RubySMB::Dcerpc::PTypes::RESPONSE
59
- raise RubySMB::Dcerpc::Error::InvalidPacket, "Not a Response packet"
60
- end
61
- dcerpc_response
62
- end
63
-
64
- end
65
- end
66
- end
67
-
@@ -1,70 +0,0 @@
1
- module RubySMB
2
- module SMB2
3
- module Dcerpc
4
-
5
- def net_share_enum_all(host)
6
- bind(endpoint: RubySMB::Dcerpc::Srvsvc)
7
-
8
- response = request(RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL, host: host)
9
-
10
- shares = RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.parse_response(response.stub.to_binary_s)
11
- shares.map{|s|{name: s[0], type: s[1], comment: s[2]}}
12
- end
13
-
14
- def bind(options={})
15
- bind_req = RubySMB::Dcerpc::Bind.new(options)
16
- write(data: bind_req.to_binary_s)
17
- @size = 1024
18
- dcerpc_raw_response = read()
19
- begin
20
- dcerpc_response = RubySMB::Dcerpc::BindAck.read(dcerpc_raw_response)
21
- rescue IOError
22
- raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the DCERPC response"
23
- end
24
- unless dcerpc_response.pdu_header.ptype == RubySMB::Dcerpc::PTypes::BIND_ACK
25
- raise RubySMB::Dcerpc::Error::BindError, "Not a BindAck packet"
26
- end
27
-
28
- res_list = dcerpc_response.p_result_list
29
- if res_list.n_results == 0 ||
30
- res_list.p_results[0].result != RubySMB::Dcerpc::BindAck::ACCEPTANCE
31
- raise RubySMB::Dcerpc::Error::BindError,
32
- "Bind Failed (Result: #{res_list.p_results[0].result}, Reason: #{res_list.p_results[0].reason})"
33
- end
34
- dcerpc_response
35
- end
36
-
37
- def request(opnum, options={})
38
- dcerpc_request = RubySMB::Dcerpc::Request.new({ :opnum => opnum }, options)
39
- ioctl_response = ioctl_send_recv(dcerpc_request, options)
40
- begin
41
- dcerpc_response = RubySMB::Dcerpc::Response.read(ioctl_response.output_data)
42
- rescue IOError
43
- raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the DCERPC response"
44
- end
45
- unless dcerpc_response.pdu_header.ptype == RubySMB::Dcerpc::PTypes::RESPONSE
46
- raise RubySMB::Dcerpc::Error::InvalidPacket, "Not a Response packet"
47
- end
48
- dcerpc_response
49
- end
50
-
51
- def ioctl_send_recv(action, options={})
52
- request = set_header_fields(RubySMB::SMB2::Packet::IoctlRequest.new(options))
53
- request.ctl_code = 0x0011C017
54
- request.flags.is_fsctl = 0x00000001
55
- request.buffer = action.to_binary_s
56
- ioctl_raw_response = @tree.client.send_recv(request)
57
- ioctl_response = RubySMB::SMB2::Packet::IoctlResponse.read(ioctl_raw_response)
58
- unless ioctl_response.smb2_header.command == RubySMB::SMB2::Commands::IOCTL
59
- raise RubySMB::Error::InvalidPacket, 'Not a IoctlResponse packet'
60
- end
61
- unless ioctl_response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
62
- raise RubySMB::Error::UnexpectedStatusCode, ioctl_response.status_code.name
63
- end
64
- ioctl_response
65
- end
66
-
67
- end
68
- end
69
- end
70
-
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe RubySMB::SMB1::Packet::EmptyPacket do
4
- subject(:packet) { described_class.new }
5
-
6
- describe '#smb_header' do
7
- subject(:header) { packet.smb_header }
8
-
9
- it 'is a standard SMB Header' do
10
- expect(header).to be_a RubySMB::SMB1::SMBHeader
11
- end
12
- end
13
-
14
- describe '#parameter_block' do
15
- subject(:parameter_block) { packet.parameter_block }
16
-
17
- it 'is a standard ParameterBlock' do
18
- expect(parameter_block).to be_a RubySMB::SMB1::ParameterBlock
19
- end
20
-
21
- it 'should be empty' do
22
- expect(parameter_block.to_binary_s).to eq "\x00"
23
- end
24
- end
25
-
26
- describe '#data_block' do
27
- subject(:data_block) { packet.data_block }
28
-
29
- it 'is a standard DataBlock' do
30
- expect(data_block).to be_a RubySMB::SMB1::DataBlock
31
- end
32
-
33
- it 'should be empty' do
34
- expect(data_block.to_binary_s).to eq "\x00\x00"
35
- end
36
- end
37
- end