ruby_smb 3.3.14 → 3.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0e82037a7cede300c72e18aca227e16dd6f6c67c46e739aae546ff990562a20
4
- data.tar.gz: ac24976008cf479989fbea0edc88ceafec163c998a7d5a87ea4b085ae1f6fcd6
3
+ metadata.gz: c750cc33b1b323d9f28b7ad65702e26758d1341d419ae3271c0cb900b0e254de
4
+ data.tar.gz: 6d62d69876566ea5fc087104da49ca598ad2705cb9bb99723ac8b22d43cb63ab
5
5
  SHA512:
6
- metadata.gz: c9f2bae08d955e0a977b5614a577ff1801f8b977a675f21a70ec7dac2b695d6215d91cd3f69b37b354022aba93494be64687b90e96c8a7b75390384eb7dd0b99
7
- data.tar.gz: de80907d4e9d1d91de05ca1b363ba94da81f2f39fd089bad724d1b6c2b5fae8ed8048b66ac84238174f573dbb362e49d809734446e5381b1914bc5cd9b8286ce
6
+ metadata.gz: a52b76ed65ba8112c3a8232d8568cfda030007d56e7b982623735b57b0515b6e0a13aab897ba56213a62c83e42132ce5f7d6c2946bee06f641029257c8681cd4
7
+ data.tar.gz: 87d493f9c4e6380d22f39debbce248e0b7f3c9eb9d8f39a93d5bb5db620fb2b47035ad3cafad6d1ba8bd1aa1d52d88ae3195daf43e5e840c7e11f38f2581ffcc
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'ruby_smb'
5
+
6
+ require 'optparse'
7
+ require 'pp'
8
+
9
+ options = {
10
+ major_version: 1,
11
+ minor_version: 0,
12
+ max_towers: 1,
13
+ }
14
+
15
+ parser = OptionParser.new do |opts|
16
+ opts.banner = "Usage: script.rb [options] TARGET PROTOCOL UUID"
17
+
18
+ opts.on("--major-version N", Integer, "Specify major version number (default: #{options[:major_version]})") do |v|
19
+ options[:major_version] = v
20
+ end
21
+
22
+ opts.on("--minor-version N", Integer, "Specify minor version number ((default: #{options[:minor_version]})") do |v|
23
+ options[:minor_version] = v
24
+ end
25
+
26
+ opts.on("--max-towers N", Integer, "Set the maximum number of towers (default: #{options[:max_towers]})") do |v|
27
+ options[:max_towers] = v
28
+ end
29
+
30
+ opts.on("-h", "--help", "Prints this help") do
31
+ puts opts
32
+ exit
33
+ end
34
+ end
35
+
36
+ # Parse and extract positional arguments
37
+ begin
38
+ parser.order!(ARGV)
39
+ if ARGV.size != 3
40
+ raise OptionParser::MissingArgument, "TARGET, PROTOCOL, and UUID are required"
41
+ end
42
+
43
+ options[:target], options[:protocol], options[:uuid] = ARGV
44
+ rescue OptionParser::ParseError => e
45
+ puts e.message
46
+ puts parser
47
+ exit 1
48
+ end
49
+
50
+ dcerpc_client = RubySMB::Dcerpc::Client.new(options[:target], RubySMB::Dcerpc::Epm)
51
+ dcerpc_client.connect
52
+ dcerpc_client.bind
53
+ dcerpc_client.ept_map(
54
+ uuid: options[:uuid],
55
+ maj_ver: options[:major_version],
56
+ min_ver: options[:minor_version],
57
+ protocol: options[:protocol].to_sym,
58
+ max_towers: options[:max_towers]
59
+ ).each do |tower|
60
+ puts "Tower: #{tower[:endpoint]}"
61
+ tower.each do |key, value|
62
+ next if key == :endpoint
63
+ puts " #{key}: #{value}"
64
+ end
65
+ end
@@ -11,7 +11,6 @@ module RubySMB
11
11
  require 'ruby_smb/peer_info'
12
12
 
13
13
  include Dcerpc
14
- include Epm
15
14
  include PeerInfo
16
15
 
17
16
  # The default maximum size of a RPC message that the Client accepts (in bytes)
@@ -146,27 +145,31 @@ module RubySMB
146
145
  # @return [TcpSocket] The connected TCP socket
147
146
  def connect(port: nil)
148
147
  return if @tcp_socket
148
+
149
149
  unless port
150
- @tcp_socket = TCPSocket.new(@host, ENDPOINT_MAPPER_PORT)
151
- bind(endpoint: Epm)
152
- begin
153
- host_port = get_host_port_from_ept_mapper(
154
- uuid: @endpoint::UUID,
155
- maj_ver: @endpoint::VER_MAJOR,
156
- min_ver: @endpoint::VER_MINOR
157
- )
158
- rescue RubySMB::Dcerpc::Error::DcerpcError => e
159
- e.message.prepend(
160
- "Cannot resolve the remote port number for endpoint #{@endpoint::UUID}. "\
161
- "Set @tcp_socket parameter to specify the service port number and bypass "\
162
- "EPM port resolution. Error: "
163
- )
164
- raise e
150
+ if @endpoint == Epm
151
+ port = ENDPOINT_MAPPER_PORT
152
+ else
153
+ epm_client = Client.new(@host, Epm, read_timeout: @read_timeout)
154
+ epm_client.connect
155
+ begin
156
+ epm_client.bind
157
+ towers = epm_client.ept_map_endpoint(@endpoint)
158
+ rescue RubySMB::Dcerpc::Error::DcerpcError => e
159
+ e.message.prepend(
160
+ "Cannot resolve the remote port number for endpoint #{@endpoint::UUID}. "\
161
+ "Set @tcp_socket parameter to specify the service port number and bypass "\
162
+ "EPM port resolution. Error: "
163
+ )
164
+ raise e
165
+ ensure
166
+ epm_client.close
167
+ end
168
+
169
+ port = towers.first[:port]
165
170
  end
166
- port = host_port[:port]
167
- @tcp_socket.close
168
- @tcp_socket = nil
169
171
  end
172
+
170
173
  @tcp_socket = TCPSocket.new(@host, port)
171
174
  end
172
175
 
@@ -27,39 +27,39 @@ module RubySMB
27
27
 
28
28
  uint16 :lhs_bytecount, byte_align: 1, initial_value: -> {prot_identifier.num_bytes}
29
29
  # Protocol Identifiers:
30
- # 0x00: "OSI Object Identifier [OID]"
31
- # 0x02: "DNA Session Control Phase 4"
32
- # 0x03: "DNA Session Control V3 Phase 5"
33
- # 0x04: "DNA NSP Transport"
34
- # 0x05: "OSI TP4 [T-Selector]"
35
- # 0x06: "OSI CLNS [NSAP]"
36
- # 0x07: "DOD TCP port"
37
- # 0x08: "DOD UDP port"
38
- # 0x09: "DOD IP v4 big-endian"
39
- # 0x0a: "RPC Connectionless v4"
40
- # 0x0b: "RPC Connection-oriented v5"
41
- # 0x0c: "MS Named Pipes"
42
- # 0x0d: "UUID"
43
- # 0x0e: "ncadg_ipx"
44
- # 0x0f: "NetBIOS Named Pipes"
45
- # 0x10: "MS Named Pipe Name" or "Local InterProcess Communication (LRPC)")
46
- # 0x11: "MS NetBIOS"
47
- # 0x12: "MS NetBEUI"
48
- # 0x13: "Netware SPX"
49
- # 0x14: "Netware IPX"
50
- # 0x15: "NMP_TOWER_ID"
51
- # 0x16: "Appletalk Stream [endpoint]"
52
- # 0x17: "Appletalk Datagram [endpoint]"
53
- # 0x18: "Appletalk [NBP-style Name]"
54
- # 0x19: "NetBIOS [CL on all protocols]"
55
- # 0x1a: "VINES SPP"
56
- # 0x1b: "VINES IPC"
57
- # 0x1c: "StreetTalk [name]"
58
- # 0x1d: "MSMQ"
59
- # 0x1f: "MS IIS (http)"
60
- # 0x20: "Unix Domain socket [pathname]"
61
- # 0x21: "null"
62
- # 0x22: "NetBIOS name"
30
+ # 0x00: "OSI Object Identifier [OID]"
31
+ # 0x02: "DNA Session Control Phase 4"
32
+ # 0x03: "DNA Session Control V3 Phase 5"
33
+ # 0x04: "DNA NSP Transport"
34
+ # 0x05: "OSI TP4 [T-Selector]"
35
+ # 0x06: "OSI CLNS [NSAP]"
36
+ # 0x07: "DOD TCP port"
37
+ # 0x08: "DOD UDP port"
38
+ # 0x09: "DOD IP v4 big-endian"
39
+ # 0x0a: "RPC Connectionless v4"
40
+ # 0x0b: "RPC Connection-oriented v5"
41
+ # 0x0c: "MS Named Pipes"
42
+ # 0x0d: "UUID"
43
+ # 0x0e: "ncadg_ipx"
44
+ # 0x0f: "NetBIOS Named Pipes"
45
+ # 0x10: "MS Named Pipe Name" or "Local InterProcess Communication (LRPC)")
46
+ # 0x11: "MS NetBIOS"
47
+ # 0x12: "MS NetBEUI"
48
+ # 0x13: "Netware SPX"
49
+ # 0x14: "Netware IPX"
50
+ # 0x15: "NMP_TOWER_ID"
51
+ # 0x16: "Appletalk Stream [endpoint]"
52
+ # 0x17: "Appletalk Datagram [endpoint]"
53
+ # 0x18: "Appletalk [NBP-style Name]"
54
+ # 0x19: "NetBIOS [CL on all protocols]"
55
+ # 0x1a: "VINES SPP"
56
+ # 0x1b: "VINES IPC"
57
+ # 0x1c: "StreetTalk [name]"
58
+ # 0x1d: "MSMQ"
59
+ # 0x1f: "MS IIS (http)"
60
+ # 0x20: "Unix Domain socket [pathname]"
61
+ # 0x21: "null"
62
+ # 0x22: "NetBIOS name"
63
63
  uint8 :prot_identifier, byte_align: 1, initial_value: 0x0b
64
64
  uint16 :rhs_bytecount, byte_align: 1, initial_value: 2
65
65
  uint16 :minor_version, byte_align: 1
@@ -77,7 +77,7 @@ module RubySMB
77
77
  # default: Host name
78
78
  uint8 :identifier, byte_align: 1
79
79
  uint16 :rhs_bytecount, byte_align: 1, initial_value: -> { name.length }
80
- ndr_fixed_byte_array :name, initial_length: :rhs_bytecount
80
+ uint8_array :name, initial_length: :rhs_bytecount, byte_align: 1
81
81
  end
82
82
 
83
83
  class EpmFloorPipeOrPort < Ndr::NdrStruct
@@ -100,9 +100,9 @@ module RubySMB
100
100
  uint8 :identifier, byte_align: 1, initial_value: 0x07
101
101
  uint16 :rhs_bytecount, byte_align: 1, initial_value: -> { pipe_or_port.num_bytes }
102
102
  choice :pipe_or_port, selection: :identifier, byte_align: 1 do
103
- ndr_fixed_byte_array 0x10, initial_length: :rhs_bytecount
104
- ndr_fixed_byte_array 0x0c, initial_length: :rhs_bytecount
105
- ndr_fixed_byte_array 0x0f, initial_length: :rhs_bytecount
103
+ uint8_array 0x10, initial_length: :rhs_bytecount, byte_align: 1
104
+ uint8_array 0x0c, initial_length: :rhs_bytecount, byte_align: 1
105
+ uint8_array 0x0f, initial_length: :rhs_bytecount, byte_align: 1
106
106
  uint16be 0x07
107
107
  uint16be 0x08
108
108
  uint16be 0x13
@@ -110,7 +110,7 @@ module RubySMB
110
110
  uint16be 0x1a
111
111
  uint16be 0x1b
112
112
  uint16be 0x1f
113
- ndr_fixed_byte_array :default, initial_length: :rhs_bytecount
113
+ uint8_array :default, initial_length: :rhs_bytecount, byte_align: 1
114
114
  end
115
115
  end
116
116
 
@@ -143,17 +143,17 @@ module RubySMB
143
143
  uint8 :identifier, byte_align: 1, initial_value: 0x09
144
144
  uint16 :rhs_bytecount, byte_align: 1, initial_value: -> { host_or_addr.num_bytes }
145
145
  choice :host_or_addr, selection: :identifier, byte_align: 1 do
146
- ndr_fixed_byte_array 0x11, initial_length: :rhs_bytecount
147
- ndr_fixed_byte_array 0x12, initial_length: :rhs_bytecount
148
- ndr_fixed_byte_array 0x22, initial_length: :rhs_bytecount
146
+ uint8_array 0x11, initial_length: :rhs_bytecount, byte_align: 1
147
+ uint8_array 0x12, initial_length: :rhs_bytecount, byte_align: 1
148
+ uint8_array 0x22, initial_length: :rhs_bytecount, byte_align: 1
149
149
  epm_ipv4_address 0x09
150
150
  epm_ipx_spx_address 0x13
151
151
  epm_ipx_spx_address 0x14
152
- choice 0x00, selection: -> {rhs_bytecount.num_bytes} do
153
- ndr_fixed_byte_array 16, initial_length: 16
154
- ndr_fixed_byte_array :default, initial_length: :rhs_bytecount
152
+ choice 0x00, selection: -> { rhs_bytecount.num_bytes } do
153
+ uint8_array 16, initial_length: 16, byte_align: 1
154
+ uint8_array :default, initial_length: :rhs_bytecount, byte_align: 1
155
155
  end
156
- ndr_fixed_byte_array :default, initial_length: :rhs_bytecount
156
+ uint8_array :default, initial_length: :rhs_bytecount, byte_align: 1
157
157
  end
158
158
  end
159
159
 
@@ -9,37 +9,91 @@ module RubySMB
9
9
  # Operation numbers
10
10
  EPT_MAP = 0x0003
11
11
 
12
+ # MS-RPCE specific error codes
13
+ STATUS_NO_ELEMENTS = 0x16C9A0D6
14
+
12
15
  require 'ruby_smb/dcerpc/epm/epm_twrt'
13
16
  require 'ruby_smb/dcerpc/epm/epm_ept_map_request'
14
17
  require 'ruby_smb/dcerpc/epm/epm_ept_map_response'
15
18
 
16
- # Retrieve the service port number given a DCERPC interface UUID
17
- # See:
18
- # [2.2.1.2.5 ept_map Method](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/ab744583-430e-4055-8901-3c6bc007e791)
19
- # [https://pubs.opengroup.org/onlinepubs/9629399/apdxo.htm](https://pubs.opengroup.org/onlinepubs/9629399/apdxo.htm)
19
+ # Map a service to a connection end point.
20
20
  #
21
- # @param uuid [String] The interface UUID
22
- # @param maj_ver [Integer] The interface Major version
23
- # @param min_ver [Integer] The interface Minor version
24
- # @param max_towers [Integer] The maximum number of elements to be returned
25
- # @return [Hash] A hash with the host and port
26
- # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
27
- # EpmEptMap packet
28
- # @raise [RubySMB::Dcerpc::Error::EpmError] if the response error status
29
- # is not STATUS_SUCCESS
30
- def get_host_port_from_ept_mapper(uuid:, maj_ver:, min_ver:, max_towers: 1)
31
- decoded_tower = EpmDecodedTowerOctetString.new(
32
- interface_identifier: {
33
- interface: uuid,
34
- major_version: maj_ver,
35
- minor_version: min_ver
36
- },
37
- data_representation: {
38
- interface: Ndr::UUID,
39
- major_version: Ndr::VER_MAJOR,
40
- minor_version: Ndr::VER_MINOR
41
- }
42
- )
21
+ # @param uuid [String] The object UUID of the interface.
22
+ # @param maj_ver [Integer] The major version number of the interface.
23
+ # @param min_ver [Integer] The minor version number of the interface.
24
+ # @param max_towers [Integer] The maximum number of results to obtain.
25
+ # @param protocol [Symbol] The protocol of endpoint to obtain.
26
+ #
27
+ # @return [Array<Hash<Symbol,>>] The mapped endpoints. The hash keys will
28
+ # depend on the protocol that was selected but an endpoint key will
29
+ # always be present.
30
+ # @raise [NotImplementedError] Raised if the *protocol* argument is not
31
+ # supported.
32
+ def ept_map(uuid:, maj_ver:, min_ver: 0, max_towers: 1, protocol: :ncacn_ip_tcp)
33
+ interface_identifier = {
34
+ interface: uuid,
35
+ major_version: maj_ver,
36
+ minor_version: min_ver
37
+ }
38
+ data_representation = {
39
+ interface: Ndr::UUID,
40
+ major_version: Ndr::VER_MAJOR,
41
+ minor_version: Ndr::VER_MINOR
42
+ }
43
+
44
+ case protocol
45
+ when :ncacn_ip_tcp
46
+ decoded_tower = EpmDecodedTowerOctetString.new(
47
+ interface_identifier: interface_identifier,
48
+ data_representation: data_representation,
49
+ pipe_or_port: {
50
+ identifier: 7, # 0x07: DOD TCP port
51
+ pipe_or_port: 0
52
+ },
53
+ host_or_addr: {
54
+ identifier: 9, # 0x09: DOD IP v4 address (big-endian)
55
+ host_or_addr: 0
56
+ }
57
+ )
58
+
59
+ process_tower = lambda do |tower|
60
+ port = tower.pipe_or_port.pipe_or_port.value
61
+ address = IPAddr.new(tower.host_or_addr.host_or_addr.value, Socket::AF_INET)
62
+ {
63
+ port: port,
64
+ address: address,
65
+ # https://learn.microsoft.com/en-us/windows/win32/midl/ncacn-ip-tcp
66
+ endpoint: "ncacn_ip_tcp:#{address}[#{port}]"
67
+ }
68
+ end
69
+ when :ncacn_np
70
+ decoded_tower = EpmDecodedTowerOctetString.new(
71
+ interface_identifier: interface_identifier,
72
+ data_representation: data_representation,
73
+ pipe_or_port: {
74
+ identifier: 0x0f, # 0x0f: NetBIOS pipe name
75
+ pipe_or_port: [0]
76
+ },
77
+ host_or_addr: {
78
+ identifier: 0x11, # 0x11: MS NetBIOS host name
79
+ host_or_addr: [0]
80
+ }
81
+ )
82
+
83
+ process_tower = lambda do |tower|
84
+ pipe = tower.pipe_or_port.pipe_or_port[...-1].pack('C*')
85
+ host = tower.host_or_addr.host_or_addr[...-1].pack('C*')
86
+ {
87
+ pipe: pipe,
88
+ host: host,
89
+ # https://learn.microsoft.com/en-us/windows/win32/midl/ncacn-nb-nb
90
+ endpoint: "ncacn_np:#{host}[#{pipe}]"
91
+ }
92
+ end
93
+ else
94
+ raise NotImplementedError, "Unsupported protocol: #{protocol}"
95
+ end
96
+
43
97
  tower = EpmTwrt.new(decoded_tower)
44
98
  ept_map_request = EpmEptMapRequest.new(
45
99
  obj: Uuid.new,
@@ -53,21 +107,31 @@ module RubySMB
53
107
  rescue IOError
54
108
  raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading EptMapResponse'
55
109
  end
56
- unless ept_map_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
110
+
111
+ if ept_map_response.error_status == STATUS_NO_ELEMENTS
112
+ raise RubySMB::Dcerpc::Error::EpmError,
113
+ "Error returned with ept_map: "\
114
+ "(0x16c9a0d6) STATUS_NO_ELEMENTS: There are no elements that satisfy the specified search criteria."
115
+ elsif ept_map_response.error_status != WindowsError::NTStatus::STATUS_SUCCESS
57
116
  raise RubySMB::Dcerpc::Error::EpmError,
58
117
  "Error returned with ept_map: "\
59
118
  "#{WindowsError::NTStatus.find_by_retval(ept_map_response.error_status.value).join(',')}"
60
119
  end
61
- tower_binary = ept_map_response.towers[0].tower_octet_string.to_binary_s
62
- begin
63
- decoded_tower = EpmDecodedTowerOctetString.read(tower_binary)
64
- rescue IOError
65
- raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading EpmDecodedTowerOctetString'
120
+
121
+ ept_map_response.towers.map do |tower|
122
+ tower_binary = tower.tower_octet_string.to_binary_s
123
+ begin
124
+ decoded_tower = EpmDecodedTowerOctetString.read(tower_binary)
125
+ rescue IOError
126
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading EpmDecodedTowerOctetString'
127
+ end
128
+
129
+ process_tower.(decoded_tower)
66
130
  end
67
- {
68
- port: decoded_tower.pipe_or_port.pipe_or_port.to_i,
69
- host: decoded_tower.host_or_addr.host_or_addr.to_i
70
- }
131
+ end
132
+
133
+ def ept_map_endpoint(endpoint, **kwargs)
134
+ ept_map(uuid: endpoint::UUID, maj_ver: endpoint::VER_MAJOR, min_ver: endpoint::VER_MINOR, **kwargs)
71
135
  end
72
136
  end
73
137
  end
@@ -28,6 +28,7 @@ module RubySMB
28
28
  DCE_C_AUTHZ_DCE = 2
29
29
 
30
30
  require 'windows_error/win32'
31
+ require 'ruby_smb/dcerpc/client'
31
32
  require 'ruby_smb/dcerpc/error'
32
33
  require 'ruby_smb/dcerpc/fault'
33
34
  require 'ruby_smb/dcerpc/uuid'
@@ -190,6 +191,8 @@ module RubySMB
190
191
  # @raise [ArgumentError] if `:auth_type` is unknown
191
192
  # @raise [NotImplementedError] if `:auth_type` is not implemented (yet)
192
193
  def bind(options={})
194
+ options = options.merge(endpoint: @endpoint) if !options[:endpoint] && defined?(:@endpoint) && @endpoint
195
+
193
196
  @call_id ||= 1
194
197
  bind_req = Bind.new(options)
195
198
  bind_req.pdu_header.call_id = @call_id
@@ -1,3 +1,3 @@
1
1
  module RubySMB
2
- VERSION = '3.3.14'.freeze
2
+ VERSION = '3.3.15'.freeze
3
3
  end
@@ -1,8 +1,9 @@
1
1
  require 'ruby_smb/dcerpc/client'
2
+ require 'ipaddr'
2
3
 
3
4
  RSpec.describe RubySMB::Dcerpc::Client do
4
- it 'includes the RubySMB::Dcerpc::Epm class' do
5
- expect(described_class < RubySMB::Dcerpc::Epm).to be true
5
+ it 'includes the RubySMB::PeerInfo class' do
6
+ expect(described_class < RubySMB::PeerInfo).to be true
6
7
  end
7
8
 
8
9
  let(:host) { '1.2.3.4' }
@@ -75,42 +76,38 @@ RSpec.describe RubySMB::Dcerpc::Client do
75
76
  end
76
77
 
77
78
  context 'without TCP port' do
78
- let(:host_port) { {host: '0.9.8.7', port: 999} }
79
+ let(:host_port) { {host: '192.0.2.1', port: 999} }
80
+ let(:epm_client) { double('EPM DCERPC Client') }
79
81
  let(:epm_tcp_socket) { double('EPM TcpSocket') }
80
82
  before :example do
81
- allow(TCPSocket).to receive(:new).with(host, 135).and_return(epm_tcp_socket)
82
- allow(client).to receive(:bind)
83
- allow(client).to receive(:get_host_port_from_ept_mapper).and_return(host_port)
84
- allow(epm_tcp_socket).to receive(:close)
85
- end
86
-
87
- it 'connects to port 135' do
88
- client.connect
89
- expect(TCPSocket).to have_received(:new).with(host, 135)
83
+ allow(described_class).to receive(:new).with(host, endpoint).and_call_original
84
+ allow(described_class).to receive(:new).with(host, RubySMB::Dcerpc::Epm, {:read_timeout => 30}).and_return(epm_client)
85
+ allow(epm_client).to receive(:connect)
86
+ allow(epm_client).to receive(:bind)
87
+ allow(epm_client).to receive(:ept_map_endpoint).with(endpoint).and_return(
88
+ [{address: IPAddr.new(host_port[:host], Socket::AF_INET), port: host_port[:port]}]
89
+ )
90
+ allow(epm_client).to receive(:close)
90
91
  end
91
92
 
92
- it 'binds to the Endpoint Mapper endpoint' do
93
+ it 'creates a new client bound to the Endpoint Mapper endpoint' do
93
94
  client.connect
94
- expect(client).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Epm)
95
+ expect(described_class).to have_received(:new).with(host, RubySMB::Dcerpc::Epm, {:read_timeout => 30})
95
96
  end
96
97
 
97
98
  it 'gets host and port information from the Endpoint Mapper' do
98
99
  client.connect
99
- expect(client).to have_received(:get_host_port_from_ept_mapper).with(
100
- uuid: endpoint::UUID,
101
- maj_ver: endpoint::VER_MAJOR,
102
- min_ver: endpoint::VER_MINOR
103
- )
100
+ expect(epm_client).to have_received(:ept_map_endpoint).with(endpoint)
104
101
  end
105
102
 
106
- it 'closes the EPM socket' do
103
+ it 'closes the EPM client socket' do
107
104
  client.connect
108
- expect(epm_tcp_socket).to have_received(:close)
105
+ expect(epm_client).to have_received(:close)
109
106
  end
110
107
 
111
108
  it 'connects to the endpoint and returns the socket' do
112
109
  expect(client.connect).to eq(tcp_socket)
113
- expect(TCPSocket).to have_received(:new).with(host, 999)
110
+ expect(TCPSocket).to have_received(:new).with(host, host_port[:port])
114
111
  end
115
112
  end
116
113
  end
@@ -330,7 +327,7 @@ RSpec.describe RubySMB::Dcerpc::Client do
330
327
 
331
328
  it 'sends an auth3 request' do
332
329
  client.bind(**kwargs)
333
- expect(client).to have_received(:auth_provider_complete_handshake).with(bindack_response, auth_type: kwargs[:auth_type], auth_level: kwargs[:auth_level])
330
+ expect(client).to have_received(:auth_provider_complete_handshake).with(bindack_response, auth_type: kwargs[:auth_type], auth_level: kwargs[:auth_level], endpoint: endpoint)
334
331
  end
335
332
  end
336
333
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_smb
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.14
4
+ version: 3.3.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -183,6 +183,7 @@ files:
183
183
  - examples/enum_domain_users.rb
184
184
  - examples/enum_registry_key.rb
185
185
  - examples/enum_registry_values.rb
186
+ - examples/epm_client.rb
186
187
  - examples/file_server.rb
187
188
  - examples/get_computer_info.rb
188
189
  - examples/list_directory.rb