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 +4 -4
- data/examples/epm_client.rb +65 -0
- data/lib/ruby_smb/dcerpc/client.rb +22 -19
- data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +45 -45
- data/lib/ruby_smb/dcerpc/epm.rb +100 -36
- data/lib/ruby_smb/dcerpc.rb +3 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/dcerpc/client_spec.rb +20 -23
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c750cc33b1b323d9f28b7ad65702e26758d1341d419ae3271c0cb900b0e254de
|
4
|
+
data.tar.gz: 6d62d69876566ea5fc087104da49ca598ad2705cb9bb99723ac8b22d43cb63ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
@
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
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
|
-
|
147
|
-
|
148
|
-
|
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
|
-
|
154
|
-
|
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
|
-
|
156
|
+
uint8_array :default, initial_length: :rhs_bytecount, byte_align: 1
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
data/lib/ruby_smb/dcerpc/epm.rb
CHANGED
@@ -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
|
-
#
|
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
|
22
|
-
# @param maj_ver [Integer] The
|
23
|
-
# @param min_ver [Integer] The
|
24
|
-
# @param max_towers [Integer] The maximum number of
|
25
|
-
# @
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
69
|
-
|
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
|
data/lib/ruby_smb/dcerpc.rb
CHANGED
@@ -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
|
data/lib/ruby_smb/version.rb
CHANGED
@@ -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::
|
5
|
-
expect(described_class < RubySMB::
|
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.
|
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(
|
82
|
-
allow(
|
83
|
-
allow(
|
84
|
-
allow(
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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 '
|
93
|
+
it 'creates a new client bound to the Endpoint Mapper endpoint' do
|
93
94
|
client.connect
|
94
|
-
expect(
|
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(
|
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(
|
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,
|
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.
|
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
|