ruby_smb 1.0.3 → 2.0.1
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +3 -2
- data/Gemfile +6 -2
- data/README.md +35 -47
- data/examples/enum_registry_key.rb +28 -0
- data/examples/enum_registry_values.rb +30 -0
- data/examples/negotiate.rb +51 -8
- data/examples/pipes.rb +2 -1
- data/examples/read_file_encryption.rb +56 -0
- data/examples/read_registry_key_value.rb +32 -0
- data/lib/ruby_smb.rb +4 -1
- data/lib/ruby_smb/client.rb +233 -22
- data/lib/ruby_smb/client/authentication.rb +70 -33
- data/lib/ruby_smb/client/echo.rb +20 -2
- data/lib/ruby_smb/client/encryption.rb +62 -0
- data/lib/ruby_smb/client/negotiation.rb +172 -24
- data/lib/ruby_smb/client/signing.rb +19 -0
- data/lib/ruby_smb/client/tree_connect.rb +24 -18
- data/lib/ruby_smb/client/utils.rb +8 -7
- data/lib/ruby_smb/client/winreg.rb +46 -0
- data/lib/ruby_smb/crypto.rb +30 -0
- data/lib/ruby_smb/dcerpc.rb +38 -0
- data/lib/ruby_smb/dcerpc/bind.rb +2 -2
- data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
- data/lib/ruby_smb/dcerpc/error.rb +3 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +95 -16
- data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
- data/lib/ruby_smb/dcerpc/request.rb +28 -9
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +35 -0
- data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
- data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
- data/lib/ruby_smb/dcerpc/winreg.rb +340 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +45 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
- data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
- data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +39 -0
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
- data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
- data/lib/ruby_smb/dispatcher/socket.rb +4 -3
- data/lib/ruby_smb/error.rb +68 -2
- data/lib/ruby_smb/generic_packet.rb +33 -4
- data/lib/ruby_smb/smb1/commands.rb +1 -1
- data/lib/ruby_smb/smb1/file.rb +66 -15
- data/lib/ruby_smb/smb1/packet/close_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/close_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/echo_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/echo_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/empty_packet.rb +10 -1
- data/lib/ruby_smb/smb1/packet/logoff_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/logoff_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/negotiate_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/negotiate_response.rb +3 -7
- data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +4 -4
- data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/read_andx_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/read_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/session_setup_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_request.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_response.rb +3 -2
- data/lib/ruby_smb/smb1/packet/trans/request.rb +2 -5
- data/lib/ruby_smb/smb1/packet/trans/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2/response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +2 -1
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +13 -3
- data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -1
- data/lib/ruby_smb/smb1/packet/write_andx_request.rb +3 -6
- data/lib/ruby_smb/smb1/packet/write_andx_response.rb +2 -1
- data/lib/ruby_smb/smb1/pipe.rb +87 -6
- data/lib/ruby_smb/smb1/tree.rb +50 -3
- data/lib/ruby_smb/smb2/bit_field/session_flags.rb +2 -1
- data/lib/ruby_smb/smb2/bit_field/share_flags.rb +6 -4
- data/lib/ruby_smb/smb2/file.rb +103 -25
- data/lib/ruby_smb/smb2/negotiate_context.rb +108 -0
- data/lib/ruby_smb/smb2/packet.rb +2 -0
- data/lib/ruby_smb/smb2/packet/close_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/close_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +41 -0
- data/lib/ruby_smb/smb2/packet/create_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/create_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/echo_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/echo_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -3
- data/lib/ruby_smb/smb2/packet/ioctl_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/ioctl_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/logoff_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/logoff_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +51 -17
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +52 -5
- data/lib/ruby_smb/smb2/packet/query_directory_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/query_directory_response.rb +8 -2
- data/lib/ruby_smb/smb2/packet/read_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/read_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/set_info_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/set_info_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/transform_header.rb +84 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +93 -10
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +10 -22
- data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +2 -1
- data/lib/ruby_smb/smb2/packet/write_request.rb +2 -4
- data/lib/ruby_smb/smb2/packet/write_response.rb +2 -1
- data/lib/ruby_smb/smb2/pipe.rb +86 -12
- data/lib/ruby_smb/smb2/smb2_header.rb +1 -1
- data/lib/ruby_smb/smb2/tree.rb +65 -21
- data/lib/ruby_smb/version.rb +1 -1
- data/ruby_smb.gemspec +5 -3
- data/spec/lib/ruby_smb/client_spec.rb +1612 -108
- data/spec/lib/ruby_smb/crypto_spec.rb +25 -0
- data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +410 -0
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +98 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb +28 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +108 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +90 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +39 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +150 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +710 -0
- data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +2 -2
- data/spec/lib/ruby_smb/error_spec.rb +59 -0
- data/spec/lib/ruby_smb/generic_packet_spec.rb +52 -4
- data/spec/lib/ruby_smb/smb1/file_spec.rb +191 -2
- data/spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb +68 -0
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +11 -2
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +11 -2
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +272 -149
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +44 -7
- data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +9 -0
- data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +27 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +323 -6
- data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +332 -0
- data/spec/lib/ruby_smb/smb2/packet/compression_transform_header_spec.rb +108 -0
- data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +78 -0
- data/spec/lib/ruby_smb/smb2/packet/negotiate_request_spec.rb +138 -3
- data/spec/lib/ruby_smb/smb2/packet/negotiate_response_spec.rb +120 -2
- data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +8 -0
- data/spec/lib/ruby_smb/smb2/packet/transform_header_spec.rb +220 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +339 -9
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +3 -22
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +286 -149
- data/spec/lib/ruby_smb/smb2/smb2_header_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +261 -2
- metadata +191 -83
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/smb1/dcerpc.rb +0 -67
- data/lib/ruby_smb/smb2/dcerpc.rb +0 -70
- data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +0 -37
@@ -40,27 +40,28 @@ module RubySMB
|
|
40
40
|
end
|
41
41
|
|
42
42
|
#Writes data to an open file handle
|
43
|
-
def write(file_id, offset = 0, data = '', do_recv = true)
|
43
|
+
def write(file_id = last_file_id, offset = 0, data = '', do_recv = true)
|
44
44
|
@open_files[file_id].send_recv_write(data: data, offset: offset)
|
45
45
|
end
|
46
46
|
|
47
|
-
def read(file_id, offset = 0, length = last_file.size)
|
47
|
+
def read(file_id = last_file_id, offset = 0, length = last_file.size, do_recv = true)
|
48
48
|
data = @open_files[file_id].send_recv_read(read_length: length, offset: offset)
|
49
49
|
data.bytes
|
50
50
|
end
|
51
51
|
|
52
|
-
def delete(path)
|
53
|
-
|
52
|
+
def delete(path, tree_id = last_tree_id, do_recv = true)
|
53
|
+
tree = @tree_connects.detect{ |tree| tree.id == tree_id }
|
54
|
+
file = tree.open_file(filename: path.sub(/^\\/, ''), delete: true)
|
54
55
|
file.delete
|
55
56
|
file.close
|
56
57
|
end
|
57
58
|
|
58
|
-
def close(file_id, tree_id)
|
59
|
+
def close(file_id = last_file_id, tree_id = last_tree_id, do_recv = true)
|
59
60
|
@open_files[file_id].close
|
60
61
|
end
|
61
62
|
|
62
|
-
def tree_disconnect(
|
63
|
-
@tree_connects.detect{|tree| tree.id ==
|
63
|
+
def tree_disconnect(tree_id = last_tree_id, do_recv = true)
|
64
|
+
@tree_connects.detect{|tree| tree.id == tree_id }.disconnect!
|
64
65
|
end
|
65
66
|
|
66
67
|
def native_os
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module RubySMB
|
2
|
+
class Client
|
3
|
+
module Winreg
|
4
|
+
|
5
|
+
def connect_to_winreg(host)
|
6
|
+
share = "\\\\#{host}\\IPC$"
|
7
|
+
tree = @tree_connects.find {|tree| tree.share == share}
|
8
|
+
tree = tree_connect(share) unless tree
|
9
|
+
named_pipe = tree.open_file(filename: "winreg", write: true, read: true)
|
10
|
+
if block_given?
|
11
|
+
res = yield named_pipe
|
12
|
+
named_pipe.close
|
13
|
+
res
|
14
|
+
else
|
15
|
+
named_pipe
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def has_registry_key?(host, key)
|
20
|
+
connect_to_winreg(host) do |named_pipe|
|
21
|
+
named_pipe.has_registry_key?(key)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def read_registry_key_value(host, key, value_name)
|
26
|
+
connect_to_winreg(host) do |named_pipe|
|
27
|
+
named_pipe.read_registry_key_value(key, value_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def enum_registry_key(host, key)
|
32
|
+
connect_to_winreg(host) do |named_pipe|
|
33
|
+
named_pipe.enum_registry_key(key)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def enum_registry_values(host, key)
|
38
|
+
connect_to_winreg(host) do |named_pipe|
|
39
|
+
named_pipe.enum_registry_values(key)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Crypto
|
3
|
+
module KDF
|
4
|
+
def self.counter_mode(ki, label, context, length: 128)
|
5
|
+
digest = OpenSSL::Digest.new('SHA256')
|
6
|
+
r = 32
|
7
|
+
|
8
|
+
n = length / 256
|
9
|
+
n = 1 if n == 0
|
10
|
+
|
11
|
+
raise ArgumentError if n > 2**r - 1
|
12
|
+
result = ""
|
13
|
+
|
14
|
+
n.times do |i|
|
15
|
+
input = [i + 1].pack('L>')
|
16
|
+
input << label
|
17
|
+
input << "\x00"
|
18
|
+
input << context
|
19
|
+
input << [length].pack('L>')
|
20
|
+
k = OpenSSL::HMAC.digest(digest, ki, input)
|
21
|
+
result << k
|
22
|
+
end
|
23
|
+
|
24
|
+
return result[0...(length / 8)]
|
25
|
+
rescue OpenSSL::OpenSSLError => e
|
26
|
+
raise RubySMB::Error::EncryptionError, "Crypto::KDF.counter_mode OpenSSL error: #{e.message}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/ruby_smb/dcerpc.rb
CHANGED
@@ -1,15 +1,53 @@
|
|
1
1
|
module RubySMB
|
2
2
|
module Dcerpc
|
3
|
+
MAX_XMIT_FRAG = 4280
|
4
|
+
MAX_RECV_FRAG = 4280
|
5
|
+
|
6
|
+
require 'windows_error/win32'
|
3
7
|
require 'ruby_smb/dcerpc/error'
|
4
8
|
require 'ruby_smb/dcerpc/uuid'
|
5
9
|
require 'ruby_smb/dcerpc/ndr'
|
6
10
|
require 'ruby_smb/dcerpc/ptypes'
|
7
11
|
require 'ruby_smb/dcerpc/p_syntax_id_t'
|
12
|
+
require 'ruby_smb/dcerpc/rrp_unicode_string'
|
8
13
|
require 'ruby_smb/dcerpc/pdu_header'
|
9
14
|
require 'ruby_smb/dcerpc/srvsvc'
|
15
|
+
require 'ruby_smb/dcerpc/winreg'
|
10
16
|
require 'ruby_smb/dcerpc/request'
|
11
17
|
require 'ruby_smb/dcerpc/response'
|
12
18
|
require 'ruby_smb/dcerpc/bind'
|
13
19
|
require 'ruby_smb/dcerpc/bind_ack'
|
20
|
+
|
21
|
+
|
22
|
+
# Bind to the remote server interface endpoint.
|
23
|
+
#
|
24
|
+
# @param options [Hash] the options to pass to the Bind request packet. At least, :endpoint must but provided with an existing Dcerpc class
|
25
|
+
# @return [RubySMB::Dcerpc::BindAck] the BindAck response packet
|
26
|
+
# @raise [RubySMB::Dcerpc::Error::InvalidPacket] if an invalid packet is received
|
27
|
+
# @raise [RubySMB::Dcerpc::Error::BindError] if the response is not a BindAck packet or if the Bind result code is not ACCEPTANCE
|
28
|
+
def bind(options={})
|
29
|
+
bind_req = RubySMB::Dcerpc::Bind.new(options)
|
30
|
+
write(data: bind_req.to_binary_s)
|
31
|
+
@size = 1024
|
32
|
+
dcerpc_raw_response = read()
|
33
|
+
begin
|
34
|
+
dcerpc_response = RubySMB::Dcerpc::BindAck.read(dcerpc_raw_response)
|
35
|
+
rescue IOError
|
36
|
+
raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the DCERPC response"
|
37
|
+
end
|
38
|
+
unless dcerpc_response.pdu_header.ptype == RubySMB::Dcerpc::PTypes::BIND_ACK
|
39
|
+
raise RubySMB::Dcerpc::Error::BindError, "Not a BindAck packet"
|
40
|
+
end
|
41
|
+
|
42
|
+
res_list = dcerpc_response.p_result_list
|
43
|
+
if res_list.n_results == 0 ||
|
44
|
+
res_list.p_results[0].result != RubySMB::Dcerpc::BindAck::ACCEPTANCE
|
45
|
+
raise RubySMB::Dcerpc::Error::BindError,
|
46
|
+
"Bind Failed (Result: #{res_list.p_results[0].result}, Reason: #{res_list.p_results[0].reason})"
|
47
|
+
end
|
48
|
+
@tree.client.max_buffer_size = dcerpc_response.max_xmit_frag
|
49
|
+
dcerpc_response
|
50
|
+
end
|
51
|
+
|
14
52
|
end
|
15
53
|
end
|
data/lib/ruby_smb/dcerpc/bind.rb
CHANGED
@@ -35,8 +35,8 @@ module RubySMB
|
|
35
35
|
|
36
36
|
pdu_header :pdu_header, label: 'PDU header'
|
37
37
|
|
38
|
-
uint16 :max_xmit_frag, label: 'max transmit frag size', initial_value:
|
39
|
-
uint16 :max_recv_frag, label: 'max receive frag size', initial_value:
|
38
|
+
uint16 :max_xmit_frag, label: 'max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
|
39
|
+
uint16 :max_recv_frag, label: 'max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
|
40
40
|
uint32 :assoc_group_id, label: 'ncarnation of client-server assoc group'
|
41
41
|
|
42
42
|
p_cont_list_t :p_context_list, label: 'Presentation context list', endpoint: -> { endpoint }
|
@@ -46,8 +46,8 @@ module RubySMB
|
|
46
46
|
|
47
47
|
pdu_header :pdu_header, label: 'PDU header'
|
48
48
|
|
49
|
-
uint16 :max_xmit_frag, label: 'Max transmit frag size', initial_value:
|
50
|
-
uint16 :max_recv_frag, label: 'Max receive frag size', initial_value:
|
49
|
+
uint16 :max_xmit_frag, label: 'Max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
|
50
|
+
uint16 :max_recv_frag, label: 'Max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
|
51
51
|
uint32 :assoc_group_id, label: 'Association group ID'
|
52
52
|
port_any_t :sec_addr, label: 'Secondary address'
|
53
53
|
string :pad, length: -> { pad_length }
|
data/lib/ruby_smb/dcerpc/ndr.rb
CHANGED
@@ -7,36 +7,115 @@ module RubySMB
|
|
7
7
|
VER_MAJOR = 2
|
8
8
|
VER_MINOR = 0
|
9
9
|
|
10
|
-
|
10
|
+
# An NDR Top-level Full Pointers representation as defined in
|
11
|
+
# [Transfer Syntax NDR - Top-level Full Pointers](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_11_01)
|
12
|
+
# This class must be inherited and the subclass must have a #referent protperty
|
13
|
+
class NdrTopLevelFullPointer < BinData::Primitive
|
11
14
|
endian :little
|
12
15
|
|
13
|
-
uint32
|
14
|
-
uint32 :offset, initial_value: 0
|
15
|
-
uint32 :actual_count, initial_value: -> { str.length }
|
16
|
-
stringz16 :str, read_length: -> { actual_count }
|
16
|
+
uint32 :referent_identifier, initial_value: 0x00020000
|
17
17
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
def get
|
19
|
+
is_a_null_pointer? ? 0 : self.referent
|
20
|
+
end
|
21
|
+
|
22
|
+
def set(v)
|
23
|
+
if v.is_a?(Integer) && v == 0
|
24
|
+
self.referent_identifier = 0
|
25
|
+
else
|
26
|
+
self.referent = v
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def is_a_null_pointer?
|
31
|
+
self.referent_identifier == 0
|
22
32
|
end
|
23
33
|
end
|
24
34
|
|
25
|
-
|
35
|
+
# An NDR Conformant and Varying String representation as defined in
|
36
|
+
# [Transfer Syntax NDR - Conformant and Varying Strings](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_04_02)
|
37
|
+
# The string elements are Stringz16 (unicode)
|
38
|
+
class NdrString < BinData::Primitive
|
26
39
|
endian :little
|
27
40
|
|
28
|
-
uint32
|
29
|
-
|
41
|
+
uint32 :max_count
|
42
|
+
uint32 :offset, initial_value: 0
|
43
|
+
uint32 :actual_count
|
44
|
+
stringz16 :str, read_length: -> { actual_count }, onlyif: -> { actual_count > 0 }
|
30
45
|
|
31
|
-
def
|
32
|
-
self.
|
46
|
+
def get
|
47
|
+
self.actual_count == 0 ? 0 : self.str
|
33
48
|
end
|
34
49
|
|
50
|
+
def set(v)
|
51
|
+
if v.is_a?(Integer) && v == 0
|
52
|
+
self.actual_count = 0
|
53
|
+
else
|
54
|
+
self.str = v
|
55
|
+
self.max_count = self.actual_count = str.to_binary_s.size / 2
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# A pointer to a NdrString structure
|
61
|
+
class NdrLpStr < NdrTopLevelFullPointer
|
62
|
+
endian :little
|
63
|
+
|
64
|
+
ndr_string :referent, onlyif: -> { !is_a_null_pointer? }
|
65
|
+
|
35
66
|
def to_s
|
36
|
-
self.
|
67
|
+
is_a_null_pointer? ? "\0" : self.referent
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# An NDR Context Handle representation as defined in
|
72
|
+
# [IDL Data Type Declarations - Basic Type Declarations](http://pubs.opengroup.org/onlinepubs/9629399/apdxn.htm#tagcjh_34_01)
|
73
|
+
class NdrContextHandle < BinData::Primitive
|
74
|
+
endian :little
|
75
|
+
uint32 :context_handle_attributes
|
76
|
+
uuid :context_handle_uuid
|
77
|
+
|
78
|
+
def get
|
79
|
+
{:context_handle_attributes => context_handle_attributes, :context_handle_uuid => context_handle_uuid}
|
37
80
|
end
|
81
|
+
|
82
|
+
def set(handle)
|
83
|
+
if handle.is_a?(Hash)
|
84
|
+
self.context_handle_attributes = handle[:context_handle_attributes]
|
85
|
+
self.context_handle_uuid = handle[:context_handle_uuid]
|
86
|
+
elsif handle.is_a?(NdrContextHandle)
|
87
|
+
read(handle.to_binary_s)
|
88
|
+
else
|
89
|
+
read(handle.to_s)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# A pointer to a DWORD
|
95
|
+
class NdrLpDword < NdrTopLevelFullPointer
|
96
|
+
endian :little
|
97
|
+
|
98
|
+
uint32 :referent, onlyif: -> { !is_a_null_pointer? }
|
99
|
+
end
|
100
|
+
|
101
|
+
# An NDR Uni-dimensional Conformant-varying Arrays representation as defined in:
|
102
|
+
# [Transfer Syntax NDR - NDR Constructed Types](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_03_04)
|
103
|
+
class NdrLpByte < BinData::Record
|
104
|
+
endian :little
|
105
|
+
|
106
|
+
uint32 :referent_identifier, initial_value: 0x00020000
|
107
|
+
uint32 :max_count, initial_value: -> { actual_count }, onlyif: -> { referent_identifier != 0 }
|
108
|
+
uint32 :offset, initial_value: 0, onlyif: -> { referent_identifier != 0 }
|
109
|
+
uint32 :actual_count, initial_value: -> { bytes.size }, onlyif: -> { referent_identifier != 0 }
|
110
|
+
array :bytes, :type => :uint8, initial_length: -> { actual_count }, onlyif: -> { referent_identifier != 0 }
|
111
|
+
end
|
112
|
+
|
113
|
+
# A pointer to a Windows FILETIME structure
|
114
|
+
class NdrLpFileTime < NdrTopLevelFullPointer
|
115
|
+
endian :little
|
116
|
+
|
117
|
+
file_time :referent, onlyif: -> { !is_a_null_pointer? }
|
38
118
|
end
|
39
119
|
end
|
40
120
|
end
|
41
|
-
|
42
121
|
end
|
@@ -21,7 +21,7 @@ module RubySMB
|
|
21
21
|
end
|
22
22
|
|
23
23
|
uint32 :packed_drep, label: 'NDR data representation format label', initial_value: 0x10
|
24
|
-
uint16 :frag_length, label: 'Total length of fragment', initial_value: -> { parent.
|
24
|
+
uint16 :frag_length, label: 'Total length of fragment', initial_value: -> { parent.num_bytes }
|
25
25
|
uint16 :auth_length, label: 'Length of auth_value'
|
26
26
|
uint32 :call_id, label: 'Call identifier', initial_value: 1
|
27
27
|
end
|
@@ -6,19 +6,38 @@ module RubySMB
|
|
6
6
|
endian :little
|
7
7
|
|
8
8
|
pdu_header :pdu_header, label: 'PDU header'
|
9
|
+
uint32 :alloc_hint, label: 'Allocation hint', initial_value: -> { stub.num_bytes }
|
10
|
+
uint16 :p_cont_id, label: 'Presentation context identification'
|
11
|
+
uint16 :opnum, label: 'Operation Number'
|
12
|
+
uuid :object, label: 'Object UID', onlyif: -> { pdu_header.pfc_flags.object_uuid == 1 }
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
choice :stub, label: 'Stub', selection: -> { @obj.parent.get_parameter(:endpoint) || '' } do
|
15
|
+
choice 'Winreg', selection: -> { opnum } do
|
16
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKCR, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKCR
|
17
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKCU, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKCU
|
18
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKLM, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKLM
|
19
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKPD, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKPD
|
20
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKU, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKU
|
21
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKCC, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKCC
|
22
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKPT, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKPT
|
23
|
+
open_root_key_request RubySMB::Dcerpc::Winreg::OPEN_HKPN, opnum: RubySMB::Dcerpc::Winreg::OPEN_HKPN
|
24
|
+
close_key_request RubySMB::Dcerpc::Winreg::REG_CLOSE_KEY
|
25
|
+
enum_key_request RubySMB::Dcerpc::Winreg::REG_ENUM_KEY
|
26
|
+
enum_value_request RubySMB::Dcerpc::Winreg::REG_ENUM_VALUE
|
27
|
+
open_key_request RubySMB::Dcerpc::Winreg::REG_OPEN_KEY
|
28
|
+
query_info_key_request RubySMB::Dcerpc::Winreg::REG_QUERY_INFO_KEY
|
29
|
+
query_value_request RubySMB::Dcerpc::Winreg::REG_QUERY_VALUE
|
30
|
+
string :default
|
31
|
+
end
|
32
|
+
choice 'Srvsvc', selection: -> { opnum } do
|
33
|
+
net_share_enum_all RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL, host: -> { host rescue '' }
|
34
|
+
string :default
|
35
|
+
end
|
36
|
+
string :default
|
18
37
|
end
|
19
38
|
|
20
39
|
string :auth_verifier, label: 'Authentication verifier',
|
21
|
-
onlyif:
|
40
|
+
onlyif: -> { pdu_header.auth_length > 0 },
|
22
41
|
read_length: -> { pdu_header.auth_length }
|
23
42
|
|
24
43
|
def initialize_instance
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'ruby_smb/dcerpc/ndr'
|
2
|
+
|
3
|
+
module RubySMB
|
4
|
+
module Dcerpc
|
5
|
+
|
6
|
+
# A RRP_UNICODE_STRING structure as defined in
|
7
|
+
# [2.2.4 RRP_UNICODE_STRING](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/c0c90f11-a4c4-496a-ac09-8a8a3697ceef)
|
8
|
+
class RrpUnicodeString < BinData::Primitive
|
9
|
+
endian :little
|
10
|
+
|
11
|
+
uint16 :buffer_length, initial_value: -> { buffer.to_s == "\0" ? 0 : buffer.actual_count * 2 }
|
12
|
+
uint16 :maximum_length, initial_value: -> { buffer.to_s == "\0" ? 0 : buffer.max_count * 2 }
|
13
|
+
ndr_lp_str :buffer
|
14
|
+
|
15
|
+
def get
|
16
|
+
self.buffer
|
17
|
+
end
|
18
|
+
|
19
|
+
def set(buf)
|
20
|
+
self.buffer = buf
|
21
|
+
self.buffer_length = self.buffer.to_s == "\0" ? 0 : self.buffer.actual_count * 2
|
22
|
+
self.maximum_length = self.buffer.to_s == "\0" ? 0 : self.buffer.max_count * 2
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# A pointer to a RRP_UNICODE_STRING structure
|
27
|
+
class PrrpUnicodeString < Ndr::NdrTopLevelFullPointer
|
28
|
+
endian :little
|
29
|
+
|
30
|
+
rrp_unicode_string :referent, onlyif: -> { !is_a_null_pointer? }
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -10,6 +10,16 @@ module RubySMB
|
|
10
10
|
NET_SHARE_ENUM_ALL = 0xF
|
11
11
|
|
12
12
|
require 'ruby_smb/dcerpc/srvsvc/net_share_enum_all'
|
13
|
+
|
14
|
+
def net_share_enum_all(host)
|
15
|
+
bind(endpoint: RubySMB::Dcerpc::Srvsvc)
|
16
|
+
|
17
|
+
net_share_enum_all_request_packet = RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.new(host: host)
|
18
|
+
response = dcerpc_request(net_share_enum_all_request_packet)
|
19
|
+
|
20
|
+
shares = RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.parse_response(response)
|
21
|
+
shares.map{|s|{name: s[0], type: s[1], comment: s[2]}}
|
22
|
+
end
|
13
23
|
end
|
14
24
|
end
|
15
25
|
end
|