ruby_smb 1.0.5 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
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