ruby_smb 1.0.5 → 2.0.3
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/anonymous_auth.rb +3 -3
- data/examples/append_file.rb +10 -8
- data/examples/authenticate.rb +9 -5
- data/examples/delete_file.rb +8 -6
- data/examples/enum_registry_key.rb +29 -0
- data/examples/enum_registry_values.rb +31 -0
- data/examples/list_directory.rb +8 -6
- data/examples/negotiate.rb +51 -8
- data/examples/negotiate_with_netbios_service.rb +9 -5
- data/examples/net_share_enum_all.rb +6 -4
- data/examples/pipes.rb +13 -13
- data/examples/query_service_status.rb +64 -0
- data/examples/read_file.rb +8 -6
- data/examples/read_file_encryption.rb +56 -0
- data/examples/read_registry_key_value.rb +33 -0
- data/examples/rename_file.rb +9 -7
- data/examples/tree_connect.rb +7 -5
- data/examples/write_file.rb +9 -7
- data/lib/ruby_smb.rb +4 -1
- data/lib/ruby_smb/client.rb +239 -21
- data/lib/ruby_smb/client/authentication.rb +27 -8
- data/lib/ruby_smb/client/encryption.rb +62 -0
- data/lib/ruby_smb/client/negotiation.rb +154 -12
- data/lib/ruby_smb/client/signing.rb +19 -0
- data/lib/ruby_smb/client/tree_connect.rb +4 -4
- 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 +40 -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 +6 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +260 -16
- data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
- data/lib/ruby_smb/dcerpc/request.rb +41 -9
- data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +38 -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/svcctl.rb +479 -0
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +48 -0
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +35 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +31 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +44 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/winreg.rb +421 -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/create_key_request.rb +73 -0
- data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -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 +40 -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/dcerpc/winreg/save_key_request.rb +37 -0
- data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
- data/lib/ruby_smb/dispatcher/base.rb +1 -1
- data/lib/ruby_smb/dispatcher/socket.rb +5 -4
- data/lib/ruby_smb/error.rb +28 -1
- data/lib/ruby_smb/field/stringz16.rb +17 -1
- data/lib/ruby_smb/nbss/session_header.rb +4 -4
- data/lib/ruby_smb/smb1/commands.rb +1 -1
- data/lib/ruby_smb/smb1/file.rb +8 -14
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +2 -2
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -2
- data/lib/ruby_smb/smb1/packet/write_andx_request.rb +1 -1
- data/lib/ruby_smb/smb1/pipe.rb +81 -3
- data/lib/ruby_smb/smb1/tree.rb +12 -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 +51 -61
- 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/compression_transform_header.rb +41 -0
- data/lib/ruby_smb/smb2/packet/error_packet.rb +2 -4
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +51 -14
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +50 -4
- data/lib/ruby_smb/smb2/packet/transform_header.rb +84 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +92 -6
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +8 -26
- data/lib/ruby_smb/smb2/pipe.rb +80 -3
- data/lib/ruby_smb/smb2/smb2_header.rb +1 -1
- data/lib/ruby_smb/smb2/tree.rb +32 -20
- data/lib/ruby_smb/version.rb +1 -1
- data/ruby_smb.gemspec +5 -3
- data/spec/lib/ruby_smb/client_spec.rb +1583 -102
- 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 +1729 -0
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
- data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +161 -0
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +135 -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/svcctl/change_service_config_w_request_spec.rb +191 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +78 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +59 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +72 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +46 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +512 -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/create_key_request_spec.rb +110 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +104 -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 +95 -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 +35 -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 +138 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +57 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +884 -0
- data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +12 -12
- data/spec/lib/ruby_smb/error_spec.rb +59 -0
- data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
- data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
- data/spec/lib/ruby_smb/smb1/file_spec.rb +9 -1
- 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/pipe_spec.rb +216 -147
- 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 +146 -68
- 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 +3 -24
- 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/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 -30
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +226 -148
- data/spec/lib/ruby_smb/smb2/smb2_header_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +88 -9
- metadata +257 -81
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/smb1/dcerpc.rb +0 -72
- data/lib/ruby_smb/smb2/dcerpc.rb +0 -75
data/lib/ruby_smb/dcerpc.rb
CHANGED
@@ -1,15 +1,55 @@
|
|
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'
|
13
|
+
require 'ruby_smb/dcerpc/rpc_security_attributes'
|
8
14
|
require 'ruby_smb/dcerpc/pdu_header'
|
9
15
|
require 'ruby_smb/dcerpc/srvsvc'
|
16
|
+
require 'ruby_smb/dcerpc/winreg'
|
17
|
+
require 'ruby_smb/dcerpc/svcctl'
|
10
18
|
require 'ruby_smb/dcerpc/request'
|
11
19
|
require 'ruby_smb/dcerpc/response'
|
12
20
|
require 'ruby_smb/dcerpc/bind'
|
13
21
|
require 'ruby_smb/dcerpc/bind_ack'
|
22
|
+
|
23
|
+
|
24
|
+
# Bind to the remote server interface endpoint.
|
25
|
+
#
|
26
|
+
# @param options [Hash] the options to pass to the Bind request packet. At least, :endpoint must but provided with an existing Dcerpc class
|
27
|
+
# @return [RubySMB::Dcerpc::BindAck] the BindAck response packet
|
28
|
+
# @raise [RubySMB::Dcerpc::Error::InvalidPacket] if an invalid packet is received
|
29
|
+
# @raise [RubySMB::Dcerpc::Error::BindError] if the response is not a BindAck packet or if the Bind result code is not ACCEPTANCE
|
30
|
+
def bind(options={})
|
31
|
+
bind_req = RubySMB::Dcerpc::Bind.new(options)
|
32
|
+
write(data: bind_req.to_binary_s)
|
33
|
+
@size = 1024
|
34
|
+
dcerpc_raw_response = read()
|
35
|
+
begin
|
36
|
+
dcerpc_response = RubySMB::Dcerpc::BindAck.read(dcerpc_raw_response)
|
37
|
+
rescue IOError
|
38
|
+
raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the DCERPC response"
|
39
|
+
end
|
40
|
+
unless dcerpc_response.pdu_header.ptype == RubySMB::Dcerpc::PTypes::BIND_ACK
|
41
|
+
raise RubySMB::Dcerpc::Error::BindError, "Not a BindAck packet"
|
42
|
+
end
|
43
|
+
|
44
|
+
res_list = dcerpc_response.p_result_list
|
45
|
+
if res_list.n_results == 0 ||
|
46
|
+
res_list.p_results[0].result != RubySMB::Dcerpc::BindAck::ACCEPTANCE
|
47
|
+
raise RubySMB::Dcerpc::Error::BindError,
|
48
|
+
"Bind Failed (Result: #{res_list.p_results[0].result}, Reason: #{res_list.p_results[0].reason})"
|
49
|
+
end
|
50
|
+
@tree.client.max_buffer_size = dcerpc_response.max_xmit_frag
|
51
|
+
dcerpc_response
|
52
|
+
end
|
53
|
+
|
14
54
|
end
|
15
55
|
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 }
|
@@ -10,6 +10,12 @@ module RubySMB
|
|
10
10
|
|
11
11
|
# Raised when an invalid packet is received
|
12
12
|
class InvalidPacket < DcerpcError; end
|
13
|
+
|
14
|
+
# Raised when an error is returned during a Winreg operation
|
15
|
+
class WinregError < DcerpcError; end
|
16
|
+
|
17
|
+
# Raised when an error is returned during a Svcctl operation
|
18
|
+
class SvcctlError < DcerpcError; end
|
13
19
|
end
|
14
20
|
end
|
15
21
|
end
|
data/lib/ruby_smb/dcerpc/ndr.rb
CHANGED
@@ -7,36 +7,280 @@ module RubySMB
|
|
7
7
|
VER_MAJOR = 2
|
8
8
|
VER_MINOR = 0
|
9
9
|
|
10
|
-
|
10
|
+
|
11
|
+
# An NDR Conformant and Varying String representation as defined in
|
12
|
+
# [Transfer Syntax NDR - Conformant and Varying Strings](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_04_02)
|
13
|
+
# The string elements are Stringz16 (unicode)
|
14
|
+
class NdrString < BinData::Primitive
|
11
15
|
endian :little
|
12
16
|
|
13
|
-
uint32 :max_count
|
17
|
+
uint32 :max_count
|
14
18
|
uint32 :offset, initial_value: 0
|
15
|
-
uint32 :actual_count
|
16
|
-
stringz16 :str,
|
19
|
+
uint32 :actual_count
|
20
|
+
stringz16 :str, max_length: -> { actual_count * 2 }, onlyif: -> { actual_count > 0 }
|
21
|
+
|
22
|
+
def get
|
23
|
+
self.actual_count == 0 ? 0 : self.str
|
24
|
+
end
|
25
|
+
|
26
|
+
def set(v)
|
27
|
+
if v == 0
|
28
|
+
self.str.clear
|
29
|
+
self.actual_count = 0
|
30
|
+
else
|
31
|
+
v = v.str if v.is_a?(self.class)
|
32
|
+
unless self.str.equal?(v)
|
33
|
+
if v.empty?
|
34
|
+
self.actual_count = 0
|
35
|
+
else
|
36
|
+
self.actual_count = v.to_s.size + 1
|
37
|
+
self.max_count = self.actual_count
|
38
|
+
end
|
39
|
+
end
|
40
|
+
self.str = v.to_s
|
41
|
+
end
|
42
|
+
end
|
17
43
|
|
18
|
-
def
|
19
|
-
|
20
|
-
self.
|
21
|
-
self.
|
44
|
+
def clear
|
45
|
+
# Make sure #max_count and #offset are not cleared out
|
46
|
+
self.str.clear
|
47
|
+
self.actual_count.clear
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
self.str.to_s
|
22
52
|
end
|
23
53
|
end
|
24
54
|
|
25
|
-
|
55
|
+
# An NDR Uni-dimensional Conformant Array of Bytes representation as defined in
|
56
|
+
# [Transfer Syntax NDR - Uni-dimensional Conformant Arrays](https://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_03_02)
|
57
|
+
class NdrLpByte < BinData::Primitive
|
26
58
|
endian :little
|
27
59
|
|
28
|
-
uint32
|
29
|
-
|
60
|
+
uint32 :max_count, initial_value: -> { self.elements.size }
|
61
|
+
array :elements, type: :uint8, read_until: -> { index == self.max_count - 1 }, onlyif: -> { self.max_count > 0 }
|
30
62
|
|
31
|
-
def
|
32
|
-
self.
|
63
|
+
def get
|
64
|
+
self.elements
|
33
65
|
end
|
34
66
|
|
35
|
-
def
|
36
|
-
self.
|
67
|
+
def set(v)
|
68
|
+
v = v.elements if v.is_a?(self.class)
|
69
|
+
self.elements = v.to_ary
|
70
|
+
self.max_count = self.elements.size unless self.elements.equal?(v)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# An NDR Uni-dimensional Conformant-varying Arrays of bytes representation as defined in:
|
75
|
+
# [Transfer Syntax NDR - NDR Constructed Types](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_03_04)
|
76
|
+
class NdrByteArray < BinData::Primitive
|
77
|
+
endian :little
|
78
|
+
|
79
|
+
uint32 :max_count, initial_value: -> { self.actual_count }
|
80
|
+
uint32 :offset, initial_value: 0
|
81
|
+
uint32 :actual_count, initial_value: -> { self.bytes.size }
|
82
|
+
array :bytes, :type => :uint8, initial_length: -> { self.actual_count }
|
83
|
+
|
84
|
+
def get
|
85
|
+
self.bytes
|
86
|
+
end
|
87
|
+
|
88
|
+
def set(v)
|
89
|
+
v = v.bytes if v.is_a?(self.class)
|
90
|
+
self.bytes = v.to_ary
|
91
|
+
self.max_count = self.bytes.size unless self.bytes.equal?(v)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# An NDR Context Handle representation as defined in
|
96
|
+
# [IDL Data Type Declarations - Basic Type Declarations](http://pubs.opengroup.org/onlinepubs/9629399/apdxn.htm#tagcjh_34_01)
|
97
|
+
class NdrContextHandle < BinData::Primitive
|
98
|
+
endian :little
|
99
|
+
|
100
|
+
uint32 :context_handle_attributes
|
101
|
+
uuid :context_handle_uuid
|
102
|
+
|
103
|
+
def get
|
104
|
+
{:context_handle_attributes => context_handle_attributes, :context_handle_uuid => context_handle_uuid}
|
105
|
+
end
|
106
|
+
|
107
|
+
def set(handle)
|
108
|
+
if handle.is_a?(Hash)
|
109
|
+
self.context_handle_attributes = handle[:context_handle_attributes]
|
110
|
+
self.context_handle_uuid = handle[:context_handle_uuid]
|
111
|
+
elsif handle.is_a?(NdrContextHandle)
|
112
|
+
read(handle.to_binary_s)
|
113
|
+
else
|
114
|
+
read(handle.to_s)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# An NDR Top-level Full Pointers representation as defined in
|
120
|
+
# [Transfer Syntax NDR - Top-level Full Pointers](http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagcjh_19_03_11_01)
|
121
|
+
# This class must be inherited and the subclass must have a #referent property
|
122
|
+
class NdrPointer < BinData::Primitive
|
123
|
+
endian :little
|
124
|
+
|
125
|
+
uint32 :referent_id, initial_value: 0
|
126
|
+
|
127
|
+
def do_read(io)
|
128
|
+
self.referent_id.do_read(io)
|
129
|
+
if process_referent?
|
130
|
+
self.referent.do_read(io) unless self.referent_id == 0
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def do_write(io)
|
135
|
+
self.referent_id.do_write(io)
|
136
|
+
if process_referent?
|
137
|
+
self.referent.do_write(io) unless self.referent_id == 0
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def set(v)
|
142
|
+
if v == :null
|
143
|
+
self.referent.clear
|
144
|
+
self.referent_id = 0
|
145
|
+
else
|
146
|
+
if self.referent.respond_to?(:set)
|
147
|
+
self.referent.set(v)
|
148
|
+
else
|
149
|
+
self.referent = v
|
150
|
+
end
|
151
|
+
self.referent_id = rand(0xFFFFFFFF) if self.referent_id == 0
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def get
|
156
|
+
if self.referent_id == 0
|
157
|
+
:null
|
158
|
+
else
|
159
|
+
self.referent
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def process_referent?
|
164
|
+
current_parent = parent
|
165
|
+
loop do
|
166
|
+
return true unless current_parent
|
167
|
+
return false if current_parent.is_a?(NdrStruct)
|
168
|
+
current_parent = current_parent.parent
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# A pointer to a NdrString structure
|
174
|
+
class NdrLpStr < NdrPointer
|
175
|
+
endian :little
|
176
|
+
|
177
|
+
ndr_string :referent, onlyif: -> { self.referent_id != 0 }
|
178
|
+
end
|
179
|
+
|
180
|
+
class NdrLpDword < NdrPointer
|
181
|
+
endian :little
|
182
|
+
|
183
|
+
uint32 :referent, onlyif: -> { self.referent_id != 0 }
|
184
|
+
end
|
185
|
+
|
186
|
+
# A pointer to an NDR Uni-dimensional Conformant-varying Arrays of bytes
|
187
|
+
class NdrLpByteArray < NdrPointer
|
188
|
+
endian :little
|
189
|
+
|
190
|
+
ndr_byte_array :referent, onlyif: -> { self.referent_id != 0 }
|
191
|
+
|
192
|
+
def set(v)
|
193
|
+
if v != :null && v.is_a?(NdrLpByteArray)
|
194
|
+
super(v.referent)
|
195
|
+
else
|
196
|
+
super(v)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# A pointer to a Windows FILETIME structure
|
202
|
+
class NdrLpFileTime < NdrPointer
|
203
|
+
endian :little
|
204
|
+
|
205
|
+
file_time :referent, onlyif: -> { self.referent_id != 0 }
|
206
|
+
end
|
207
|
+
|
208
|
+
# A generic NDR structure that implements logic to #read and #write
|
209
|
+
# (#to_binary_s) in case the structure contains BinData::Array or
|
210
|
+
# NdrPointer fields. This class must be inherited.
|
211
|
+
class NdrStruct < BinData::Record
|
212
|
+
|
213
|
+
def do_read(io)
|
214
|
+
super(io)
|
215
|
+
each_pair do |_name, field|
|
216
|
+
case field
|
217
|
+
when BinData::Array
|
218
|
+
field.each do |element|
|
219
|
+
next unless element.is_a?(NdrPointer)
|
220
|
+
next if element.referent_id == 0
|
221
|
+
pad = (4 - io.offset % 4) % 4
|
222
|
+
io.seekbytes(pad) if pad > 0
|
223
|
+
element.referent.do_read(io)
|
224
|
+
end
|
225
|
+
when NdrPointer
|
226
|
+
next if field.referent_id == 0
|
227
|
+
pad = (4 - io.offset % 4) % 4
|
228
|
+
io.seekbytes(pad) if pad > 0
|
229
|
+
field.referent.do_read(io)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def do_write(io)
|
235
|
+
super(io)
|
236
|
+
each_pair do |_name, field|
|
237
|
+
case field
|
238
|
+
when BinData::Array
|
239
|
+
field.each do |element|
|
240
|
+
next unless element.is_a?(NdrPointer)
|
241
|
+
next if element.referent_id == 0
|
242
|
+
pad = (4 - io.offset % 4) % 4
|
243
|
+
io.writebytes("\x00" * pad + element.referent.to_binary_s)
|
244
|
+
end
|
245
|
+
when NdrPointer
|
246
|
+
next if field.referent_id == 0
|
247
|
+
pad = (4 - io.offset % 4) % 4
|
248
|
+
io.writebytes("\x00" * pad + field.referent.to_binary_s)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
class NdrStringPtrsw < NdrStruct
|
255
|
+
endian :little
|
256
|
+
|
257
|
+
uint32 :max_count, initial_value: -> { self.elements.size }
|
258
|
+
array :elements, type: :ndr_lp_str, read_until: -> { index == self.max_count - 1 }, onlyif: -> { self.max_count > 0 }
|
259
|
+
|
260
|
+
def get
|
261
|
+
self.elements
|
262
|
+
end
|
263
|
+
|
264
|
+
def set(v)
|
265
|
+
v = v.elements if v.is_a?(self.class)
|
266
|
+
self.elements = v.to_ary
|
267
|
+
self.max_count = self.elements.size unless self.elements.equal?(v)
|
268
|
+
end
|
269
|
+
|
270
|
+
def do_num_bytes
|
271
|
+
to_binary_s.size
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
class NdrLpStringPtrsw < NdrPointer
|
276
|
+
endian :little
|
277
|
+
|
278
|
+
ndr_string_ptrsw :referent, onlyif: -> { self.referent_id != 0 }
|
279
|
+
|
280
|
+
def set(v)
|
281
|
+
super(v.respond_to?(:to_ary) ? v.to_ary : v)
|
37
282
|
end
|
38
283
|
end
|
39
284
|
end
|
40
285
|
end
|
41
|
-
|
42
286
|
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,51 @@ 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
|
+
create_key_request RubySMB::Dcerpc::Winreg::REG_CREATE_KEY
|
31
|
+
save_key_request RubySMB::Dcerpc::Winreg::REG_SAVE_KEY
|
32
|
+
string :default
|
33
|
+
end
|
34
|
+
choice 'Srvsvc', selection: -> { opnum } do
|
35
|
+
net_share_enum_all RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL, host: -> { host rescue '' }
|
36
|
+
string :default
|
37
|
+
end
|
38
|
+
choice 'Svcctl', selection: -> { opnum } do
|
39
|
+
open_sc_manager_w_request RubySMB::Dcerpc::Svcctl::OPEN_SC_MANAGER_W
|
40
|
+
open_service_w_request RubySMB::Dcerpc::Svcctl::OPEN_SERVICE_W
|
41
|
+
query_service_status_request RubySMB::Dcerpc::Svcctl::QUERY_SERVICE_STATUS
|
42
|
+
query_service_config_w_request RubySMB::Dcerpc::Svcctl::QUERY_SERVICE_CONFIG_W
|
43
|
+
change_service_config_w_request RubySMB::Dcerpc::Svcctl::CHANGE_SERVICE_CONFIG_W
|
44
|
+
start_service_w_request RubySMB::Dcerpc::Svcctl::START_SERVICE_W
|
45
|
+
control_service_request RubySMB::Dcerpc::Svcctl::CONTROL_SERVICE
|
46
|
+
close_service_handle_request RubySMB::Dcerpc::Svcctl::CLOSE_SERVICE_HANDLE
|
47
|
+
string :default
|
48
|
+
end
|
49
|
+
string :default
|
18
50
|
end
|
19
51
|
|
20
52
|
string :auth_verifier, label: 'Authentication verifier',
|
21
|
-
onlyif:
|
53
|
+
onlyif: -> { pdu_header.auth_length > 0 },
|
22
54
|
read_length: -> { pdu_header.auth_length }
|
23
55
|
|
24
56
|
def initialize_instance
|