ruby_smb 3.2.4 → 3.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/cortex.yaml +15 -0
  4. data/examples/dump_secrets_from_sid.rb +1 -1
  5. data/lib/ruby_smb/dcerpc/alter_context.rb +30 -0
  6. data/lib/ruby_smb/dcerpc/alter_context_resp.rb +42 -0
  7. data/lib/ruby_smb/dcerpc/bind.rb +3 -35
  8. data/lib/ruby_smb/dcerpc/bind_ack.rb +0 -31
  9. data/lib/ruby_smb/dcerpc/client.rb +4 -0
  10. data/lib/ruby_smb/dcerpc/drsr.rb +13 -13
  11. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_decrypt_file_srv_request.rb +22 -0
  12. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_decrypt_file_srv_response.rb +21 -0
  13. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_query_recover_agents_request.rb +20 -0
  14. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_query_recover_agents_response.rb +21 -0
  15. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_query_users_on_file_request.rb +20 -0
  16. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_query_users_on_file_response.rb +21 -0
  17. data/lib/ruby_smb/dcerpc/encrypting_file_system.rb +52 -0
  18. data/lib/ruby_smb/dcerpc/p_cont_list_t.rb +37 -0
  19. data/lib/ruby_smb/dcerpc/p_result_list_t.rb +13 -0
  20. data/lib/ruby_smb/dcerpc/p_result_t.rb +15 -0
  21. data/lib/ruby_smb/dcerpc/port_any_t.rb +11 -0
  22. data/lib/ruby_smb/dcerpc/request.rb +8 -3
  23. data/lib/ruby_smb/dcerpc/response.rb +6 -1
  24. data/lib/ruby_smb/dcerpc.rb +165 -122
  25. data/lib/ruby_smb/ntlm/custom/string_encoder.rb +22 -0
  26. data/lib/ruby_smb/ntlm.rb +1 -1
  27. data/lib/ruby_smb/version.rb +1 -1
  28. data/lib/ruby_smb.rb +1 -1
  29. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +31 -16
  30. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +4 -1
  31. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +0 -6
  32. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +0 -6
  33. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +0 -14
  34. data.tar.gz.sig +0 -0
  35. metadata +16 -3
  36. metadata.gz.sig +0 -0
  37. data/lib/ruby_smb/ntlm/custom/ntlm.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f850321711ac70e25f6b483f82454520f2b567cc349ee02eb99bba5c48dfeb4
4
- data.tar.gz: 22ee0ab297710e76071fa8302165b903b39d211205ca1d6b95d697bf3eecae67
3
+ metadata.gz: 6220ba1edc47882a9d30dd1937d877c22094ebaf9c2a72cb806489a65598e1ce
4
+ data.tar.gz: 1b650bfdd2b6ba8323e9d3e7f4e161c7a659dddbffc7fa21a03d4a2e538f7297
5
5
  SHA512:
6
- metadata.gz: 8708897bda47dd2c07b064eaafbbfe8641af469a1b5688a98bbef9e38119675de9ce52287fdb00c75f908e29e70499d14203fc53a11c6824691c315a5ebeb746
7
- data.tar.gz: aad169c776223bb67198ba223f0b53d640706540f67ec125d4527a05fa4ac8c42676588b84f5e0385c4db846631783159c2a44801964284b6ae0b78b83c0a031
6
+ metadata.gz: 9e49bc0af1cd4ad61cba01ec70aecead1adbe3b4d58d6127593878596bdbc7f64c8d50b9aaa396004ffc3a3b5e8cf1806053d0825d44322aa4d4584bdddeced7
7
+ data.tar.gz: 36ca2d7c9e6256a0faabac441e89ea86d43ccd8d2de342dba4965679d2e2c4fafa541fbc09c4457d656a2cccef1af53fe5ab487245800914ad8b9a6431679088
checksums.yaml.gz.sig CHANGED
Binary file
data/cortex.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ info:
3
+ title: Ruby Smb
4
+ description: A native Ruby implementation of the SMB Protocol Family
5
+ x-cortex-git:
6
+ github:
7
+ alias: r7org
8
+ repository: rapid7/ruby_smb
9
+ x-cortex-tag: ruby-smb
10
+ x-cortex-type: service
11
+ x-cortex-domain-parents:
12
+ - tag: metasploit
13
+ openapi: 3.0.1
14
+ servers:
15
+ - url: "/"
@@ -60,7 +60,7 @@ dc_infos.each do |dc_info|
60
60
  puts "Decrypting hash for user: #{dn}"
61
61
 
62
62
  entinf_struct = user_record.pmsg_out.msg_getchg.p_objects.entinf
63
- object_sid = rid = entinf_struct.p_name.sid[-4..-1].unpack('<L').first
63
+ object_sid = rid = entinf_struct.p_name.sid[-4..-1].unpack('L<').first
64
64
  lm_hash = Net::NTLM.lm_hash('')
65
65
  nt_hash = Net::NTLM.ntlm_hash('')
66
66
  disabled = nil
@@ -0,0 +1,30 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ # The Alter context PDU as defined in
4
+ # [The alter_context PDU](https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_04_01)
5
+ class AlterContext < BinData::Record
6
+ PTYPE = PTypes::ALTER_CONTEXT
7
+
8
+ endian :little
9
+
10
+ # PDU Header
11
+ pdu_header :pdu_header, label: 'PDU header'
12
+ ndr_uint16 :max_xmit_frag, label: 'Max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
13
+ ndr_uint16 :max_recv_frag, label: 'Max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
14
+ ndr_uint32 :assoc_group_id, label: 'Incarnation of client-server assoc group'
15
+ p_cont_list_t :p_context_list, label: 'Presentation context list', endpoint: -> { endpoint }
16
+
17
+ # Auth Verifier
18
+ sec_trailer :sec_trailer, onlyif: -> { pdu_header.auth_length > 0 }
19
+ string :auth_value,
20
+ onlyif: -> { pdu_header.auth_length > 0 },
21
+ read_length: -> { pdu_header.auth_length }
22
+
23
+ def initialize_instance
24
+ super
25
+ pdu_header.ptype = PTYPE
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,42 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ # The Alter context resp PDU as defined in
4
+ # [The alter_context_resp PDU](https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_04_02)
5
+
6
+ class AlterContextResp < BinData::Record
7
+ PTYPE = PTypes::ALTER_CONTEXT_RESP
8
+
9
+ # Presentation context negotiation results
10
+ ACCEPTANCE = 0
11
+ USER_REJECTION = 1
12
+ PROVIDER_REJECTION = 2
13
+
14
+ # Reasons for rejection of a context element
15
+ REASON_NOT_SPECIFIED = 0
16
+ ABSTRACT_SYNTAX_NOT_SUPPORTED = 1
17
+ PROPOSED_TRANSFER_SYNTAXES_NOT_SUPPORTED = 2
18
+ LOCAL_LIMIT_EXCEEDED = 3
19
+
20
+ endian :little
21
+
22
+ # PDU Header
23
+ pdu_header :pdu_header, label: 'PDU header'
24
+ ndr_uint16 :max_xmit_frag, label: 'Max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
25
+ ndr_uint16 :max_recv_frag, label: 'Max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
26
+ ndr_uint32 :assoc_group_id, label: 'Association group ID'
27
+ port_any_t :sec_addr, label: 'Secondary address'
28
+ p_result_list_t :p_result_list, label: 'Presentation context result list'
29
+
30
+ # Auth Verifier
31
+ sec_trailer :sec_trailer, onlyif: -> { pdu_header.auth_length > 0 }
32
+ string :auth_value,
33
+ onlyif: -> { pdu_header.auth_length > 0 },
34
+ read_length: -> { pdu_header.auth_length }
35
+
36
+ def initialize_instance
37
+ super
38
+ pdu_header.ptype = PTYPE
39
+ end
40
+ end
41
+ end
42
+ end
@@ -2,38 +2,6 @@ module RubySMB
2
2
  module Dcerpc
3
3
  # The Bind PDU as defined in
4
4
  # [The bind PDU](http://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_04_03)
5
- class PContElemT < Ndr::NdrStruct
6
- default_parameter byte_align: 4
7
- endian :little
8
-
9
- ndr_uint16 :p_cont_id, label: 'Context ID'
10
- ndr_uint8 :n_transfer_syn, label: 'Number of transfer syntaxes', initial_value: 1
11
- ndr_uint8 :reserved
12
- p_syntax_id_t :abstract_syntax, label: 'Abstract syntax',
13
- uuid: -> { endpoint::UUID },
14
- ver_major: -> { endpoint::VER_MAJOR },
15
- ver_minor: -> { endpoint::VER_MINOR }
16
- array :transfer_syntaxes, label: 'Transfer syntax', type: :p_syntax_id_t,
17
- initial_length: -> { n_transfer_syn },
18
- uuid: -> { Ndr::UUID },
19
- ver_major: -> { Ndr::VER_MAJOR },
20
- ver_minor: -> { Ndr::VER_MINOR },
21
- byte_align: 4
22
- end
23
-
24
- class PContListT < Ndr::NdrStruct
25
- default_parameter byte_align: 4
26
- endian :little
27
-
28
- ndr_uint8 :n_context_elem, label: 'Number of context elements', initial_value: -> { 1 }
29
- ndr_uint8 :reserved
30
- ndr_uint16 :reserved2
31
- array :p_cont_elem, label: 'Presentation context elements', type: :p_cont_elem_t,
32
- initial_length: -> {n_context_elem},
33
- endpoint: -> {endpoint},
34
- byte_align: 4
35
- end
36
-
37
5
  class Bind < BinData::Record
38
6
  PTYPE = PTypes::BIND
39
7
 
@@ -41,9 +9,9 @@ module RubySMB
41
9
 
42
10
  # PDU Header
43
11
  pdu_header :pdu_header, label: 'PDU header'
44
- ndr_uint16 :max_xmit_frag, label: 'max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
45
- ndr_uint16 :max_recv_frag, label: 'max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
46
- ndr_uint32 :assoc_group_id, label: 'incarnation of client-server assoc group'
12
+ ndr_uint16 :max_xmit_frag, label: 'Max transmit frag size', initial_value: RubySMB::Dcerpc::MAX_XMIT_FRAG
13
+ ndr_uint16 :max_recv_frag, label: 'Max receive frag size', initial_value: RubySMB::Dcerpc::MAX_RECV_FRAG
14
+ ndr_uint32 :assoc_group_id, label: 'Incarnation of client-server assoc group'
47
15
  p_cont_list_t :p_context_list, label: 'Presentation context list', endpoint: -> { endpoint }
48
16
 
49
17
  # Auth Verifier
@@ -2,37 +2,6 @@ module RubySMB
2
2
  module Dcerpc
3
3
  # The Bind ACK PDU as defined in
4
4
  # [The bind_ack PDU](http://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_04_04)
5
-
6
- class PResultT < Ndr::NdrStruct
7
- default_parameter byte_align: 4
8
- endian :little
9
-
10
- ndr_uint16 :result, label: 'Presentation context negotiation results'
11
- ndr_uint16 :reason, label: 'Rejection reason'
12
- p_syntax_id_t :transfer_syntax, label: 'Presentation syntax ID',
13
- uuid: -> { Ndr::UUID },
14
- ver_major: -> { Ndr::VER_MAJOR },
15
- ver_minor: -> { Ndr::VER_MINOR }
16
- end
17
-
18
- class PResultListT < Ndr::NdrStruct
19
- default_parameter byte_align: 4
20
- endian :little
21
-
22
- ndr_uint8 :n_results, label: 'Number of results', initial_value: -> { p_results.size }
23
- ndr_uint8 :reserved
24
- ndr_uint16 :reserved2
25
- array :p_results, label: 'Results', type: :p_result_t, initial_length: -> { n_results }, byte_align: 4
26
- end
27
-
28
- class PortAnyT < Ndr::NdrStruct
29
- default_parameter byte_align: 2
30
- endian :little
31
-
32
- ndr_uint16 :str_length, label: 'Length', initial_value: -> { port_spec.to_binary_s.size }
33
- stringz :port_spec, label: 'Port string spec', byte_align: 2
34
- end
35
-
36
5
  class BindAck < BinData::Record
37
6
  PTYPE = PTypes::BIND_ACK
38
7
 
@@ -209,6 +209,10 @@ module RubySMB
209
209
  if auth_level &&
210
210
  [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY].include?(auth_level)
211
211
  set_integrity_privacy(dcerpc_req, auth_level: auth_level, auth_type: auth_type)
212
+ # Per the spec (MS_RPCE 2.2.2.11): start of the trailer should be a multiple of 16 bytes offset from the start of the stub
213
+ valid_offset = (((dcerpc_req.sec_trailer.abs_offset - dcerpc_req.stub.abs_offset) % 16))
214
+ valid_auth_pad = (dcerpc_req.sec_trailer.auth_pad_length == dcerpc_req.auth_pad.length)
215
+ raise Error::InvalidPacket unless valid_offset == 0 && valid_auth_pad
212
216
  end
213
217
 
214
218
  send_packet(dcerpc_req)
@@ -613,8 +613,8 @@ module RubySMB
613
613
  drs_bind_request = DrsBindRequest.new(pext_client: drs_extensions_int)
614
614
  response = dcerpc_request(
615
615
  drs_bind_request,
616
- auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
617
- auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
616
+ auth_level: @auth_level,
617
+ auth_type: @auth_type
618
618
  )
619
619
  begin
620
620
  drs_bind_response = DrsBindResponse.read(response)
@@ -640,8 +640,8 @@ module RubySMB
640
640
  drs_bind_request.pext_client.assign(drs_extensions_int)
641
641
  response = dcerpc_request(
642
642
  drs_bind_request,
643
- auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
644
- auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
643
+ auth_level: @auth_level,
644
+ auth_type: @auth_type
645
645
  )
646
646
  begin
647
647
  drs_bind_response = DrsBindResponse.read(response)
@@ -668,8 +668,8 @@ module RubySMB
668
668
  drs_unbind_request = DrsUnbindRequest.new(ph_drs: ph_drs)
669
669
  response = dcerpc_request(
670
670
  drs_unbind_request,
671
- auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
672
- auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
671
+ auth_level: @auth_level,
672
+ auth_type: @auth_type
673
673
  )
674
674
  begin
675
675
  drs_unbind_response = DrsUnbindResponse.read(response)
@@ -709,8 +709,8 @@ module RubySMB
709
709
  )
710
710
  response = dcerpc_request(
711
711
  drs_domain_controller_info_request,
712
- auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
713
- auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
712
+ auth_level: @auth_level,
713
+ auth_type: @auth_type
714
714
  )
715
715
  begin
716
716
  drs_domain_controller_info_response = DrsDomainControllerInfoResponse.read(response)
@@ -759,8 +759,8 @@ module RubySMB
759
759
  )
760
760
  response = dcerpc_request(
761
761
  drs_crack_names_request,
762
- auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
763
- auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
762
+ auth_level: @auth_level,
763
+ auth_type: @auth_type
764
764
  )
765
765
  begin
766
766
  drs_crack_names_response = DrsCrackNamesResponse.read(response)
@@ -790,8 +790,8 @@ module RubySMB
790
790
  unless @session_key
791
791
  raise RubySMB::Error::EncryptionError, 'Unable to decrypt attribute value: session key is empty'
792
792
  end
793
- encrypted_payload = EncryptedPayload.read(attribute)
794
793
 
794
+ encrypted_payload = EncryptedPayload.read(attribute)
795
795
  signature = OpenSSL::Digest::MD5.digest(@session_key + encrypted_payload.salt.to_binary_s)
796
796
  rc4 = OpenSSL::Cipher.new('rc4')
797
797
  rc4.decrypt
@@ -886,8 +886,8 @@ module RubySMB
886
886
 
887
887
  response = dcerpc_request(
888
888
  drs_get_nc_changes_request,
889
- auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
890
- auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
889
+ auth_level: @auth_level,
890
+ auth_type: @auth_type
891
891
  )
892
892
  begin
893
893
  drs_get_nc_changes_response = DrsGetNcChangesResponse.read(response)
@@ -0,0 +1,22 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module EncryptingFileSystem
4
+
5
+ # [3.1.4.2.6 Receiving an EfsRpcDecryptFileSrv Message (Opnum 5)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/043715de-caee-402a-a61b-921743337e78)
6
+ class EfsRpcDecryptFileSrvRequest < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ ndr_conf_var_wide_stringz :file_name
12
+ ndr_uint32 :open_flag
13
+
14
+ def initialize_instance
15
+ super
16
+ @opnum = EFS_RPC_DECRYPT_FILE_SRV
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module EncryptingFileSystem
4
+
5
+ # [3.1.4.2.6 Receiving an EfsRpcDecryptFileSrv Message (Opnum 5)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/043715de-caee-402a-a61b-921743337e78)
6
+ class EfsRpcDecryptFileSrvResponse < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ ndr_uint32 :error_status
12
+
13
+ def initialize_instance
14
+ super
15
+ @opnum = EFS_RPC_DECRYPT_FILE_SRV
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module EncryptingFileSystem
4
+
5
+ # [3.1.4.2.8 Receiving an EfsRpcQueryRecoveryAgents Message (Opnum 7)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/cf759c00-1b90-4c33-9ace-f51c20149cea)
6
+ class EfsRpcQueryRecoveryAgentsRequest < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ ndr_conf_var_wide_stringz :file_name
12
+
13
+ def initialize_instance
14
+ super
15
+ @opnum = EFS_RPC_QUERY_RECOVERY_AGENTS
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module EncryptingFileSystem
4
+
5
+ # [3.1.4.2.8 Receiving an EfsRpcQueryRecoveryAgents Message (Opnum 7)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/cf759c00-1b90-4c33-9ace-f51c20149cea)
6
+ class EfsRpcQueryRecoveryAgentsResponse < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ encryption_certificate_hash_list_ptr :recover_agents
12
+ ndr_uint32 :error_status
13
+
14
+ def initialize_instance
15
+ super
16
+ @opnum = EFS_RPC_QUERY_RECOVERY_AGENTS
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module EncryptingFileSystem
4
+
5
+ # [3.1.4.2.7 Receiving an EfsRpcQueryUsersOnFile Message (Opnum 6)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/a058dc6c-bb7e-491c-9143-a5cb1f7e7cea)
6
+ class EfsRpcQueryUsersOnFileRequest < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ ndr_conf_var_wide_stringz :file_name
12
+
13
+ def initialize_instance
14
+ super
15
+ @opnum = EFS_RPC_QUERY_USERS_ON_FILE
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module EncryptingFileSystem
4
+
5
+ # [3.1.4.2.7 Receiving an EfsRpcQueryUsersOnFile Message (Opnum 6)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/a058dc6c-bb7e-491c-9143-a5cb1f7e7cea)
6
+ class EfsRpcQueryUsersOnFileResponse < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ encryption_certificate_hash_list_ptr :users
12
+ ndr_uint32 :error_status
13
+
14
+ def initialize_instance
15
+ super
16
+ @opnum = EFS_RPC_QUERY_USERS_ON_FILE
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -35,10 +35,62 @@ module RubySMB
35
35
  OVERWRITE_HIDDEN = 0x00000004
36
36
  EFS_DROP_ALTERNATE_STREAMS = 0x00000010
37
37
 
38
+ # [2.2.7 EFS_HASH_BLOB](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/242d857f-ac8e-4cc8-b5e4-9314a942f45e)
39
+ class EfsHashBlob < Ndr::NdrStruct
40
+ endian :little
41
+ default_parameter byte_align: 4
42
+
43
+ ndr_uint32 :cb_data
44
+ ndr_byte_conf_array_ptr :b_data
45
+ end
46
+
47
+ class EfsHashBlobPtr < EfsHashBlob
48
+ extend Ndr::PointerClassPlugin
49
+ end
50
+
51
+ # [2.2.10 ENCRYPTION_CERTIFICATE_HASH](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/3a7e7151-edcb-4b32-a119-35cdce1584c0)
52
+ class EncryptionCertificateHash < Ndr::NdrStruct
53
+ endian :little
54
+ default_parameter byte_align: 4
55
+
56
+ ndr_uint32 :cb_total_length
57
+ prpc_sid :user_sid
58
+ efs_hash_blob_ptr :certificate_hash
59
+ ndr_wide_stringz_ptr :lp_display_information
60
+ end
61
+
62
+ class EncryptionCertificateHashPtr < EncryptionCertificateHash
63
+ extend Ndr::PointerClassPlugin
64
+ end
65
+
66
+ class EncryptionCertificateHashPtrArrayPtr < Ndr::NdrConfArray
67
+ default_parameter type: :encryption_certificate_hash_ptr
68
+ extend Ndr::PointerClassPlugin
69
+ end
70
+
71
+ # [2.2.11 ENCRYPTION_CERTIFICATE_HASH_LIST](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/2718804c-6ab9-45fd-98cf-541bc3b6bc75)
72
+ class EncryptionCertificateHashList < BinData::Record
73
+ endian :little
74
+ default_parameter byte_align: 4
75
+
76
+ uint32 :ncert_hash
77
+ encryption_certificate_hash_ptr_array_ptr :users
78
+ end
79
+
80
+ class EncryptionCertificateHashListPtr < EncryptionCertificateHashList
81
+ extend Ndr::PointerClassPlugin
82
+ end
83
+
84
+ require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_decrypt_file_srv_request'
85
+ require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_decrypt_file_srv_response'
38
86
  require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_request'
39
87
  require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_response'
40
88
  require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_request'
41
89
  require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_response'
90
+ require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_query_recover_agents_request'
91
+ require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_query_recover_agents_response'
92
+ require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_query_users_on_file_request'
93
+ require 'ruby_smb/dcerpc/encrypting_file_system/efs_rpc_query_users_on_file_response'
42
94
  end
43
95
  end
44
96
  end
@@ -0,0 +1,37 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ # The presentation context list and its element as defined in
4
+ # [Connection-oriented PDU Data Types - Declarations](https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06_03_01)
5
+ class PContElemT < Ndr::NdrStruct
6
+ default_parameter byte_align: 4
7
+ endian :little
8
+
9
+ ndr_uint16 :p_cont_id, label: 'Context ID'
10
+ ndr_uint8 :n_transfer_syn, label: 'Number of transfer syntaxes', initial_value: 1
11
+ ndr_uint8 :reserved
12
+ p_syntax_id_t :abstract_syntax, label: 'Abstract syntax',
13
+ uuid: -> { endpoint::UUID },
14
+ ver_major: -> { endpoint::VER_MAJOR },
15
+ ver_minor: -> { endpoint::VER_MINOR }
16
+ array :transfer_syntaxes, label: 'Transfer syntax', type: :p_syntax_id_t,
17
+ initial_length: -> { n_transfer_syn },
18
+ uuid: -> { Ndr::UUID },
19
+ ver_major: -> { Ndr::VER_MAJOR },
20
+ ver_minor: -> { Ndr::VER_MINOR },
21
+ byte_align: 4
22
+ end
23
+
24
+ class PContListT < Ndr::NdrStruct
25
+ default_parameter byte_align: 4
26
+ endian :little
27
+
28
+ ndr_uint8 :n_context_elem, label: 'Number of context elements', initial_value: -> { 1 }
29
+ ndr_uint8 :reserved
30
+ ndr_uint16 :reserved2
31
+ array :p_cont_elem, label: 'Presentation context elements', type: :p_cont_elem_t,
32
+ initial_length: -> {n_context_elem},
33
+ endpoint: -> {endpoint},
34
+ byte_align: 4
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ class PResultListT < Ndr::NdrStruct
4
+ default_parameter byte_align: 4
5
+ endian :little
6
+
7
+ ndr_uint8 :n_results, label: 'Number of results', initial_value: -> { p_results.size }
8
+ ndr_uint8 :reserved
9
+ ndr_uint16 :reserved2
10
+ array :p_results, label: 'Results', type: :p_result_t, initial_length: -> { n_results }, byte_align: 4
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ class PResultT < Ndr::NdrStruct
4
+ default_parameter byte_align: 4
5
+ endian :little
6
+
7
+ ndr_uint16 :result, label: 'Presentation context negotiation results'
8
+ ndr_uint16 :reason, label: 'Rejection reason'
9
+ p_syntax_id_t :transfer_syntax, label: 'Presentation syntax ID',
10
+ uuid: -> { Ndr::UUID },
11
+ ver_major: -> { Ndr::VER_MAJOR },
12
+ ver_minor: -> { Ndr::VER_MINOR }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ class PortAnyT < Ndr::NdrStruct
4
+ default_parameter byte_align: 2
5
+ endian :little
6
+
7
+ ndr_uint16 :str_length, label: 'Length', initial_value: -> { port_spec.to_binary_s.size }
8
+ stringz :port_spec, label: 'Port string spec', byte_align: 2, onlyif: -> { str_length > 0 }
9
+ end
10
+ end
11
+ end
@@ -103,9 +103,10 @@ module RubySMB
103
103
  end
104
104
  string :default
105
105
  end
106
- string :auth_pad,
106
+
107
+ string :auth_pad,
107
108
  onlyif: -> { has_auth_verifier? },
108
- length: -> { (16 - (stub.num_bytes % 16)) % 16 }
109
+ length: -> { calculate_padding_size }
109
110
 
110
111
  # Auth Verifier
111
112
  sec_trailer :sec_trailer, onlyif: -> { has_auth_verifier? }
@@ -113,6 +114,11 @@ module RubySMB
113
114
  onlyif: -> { has_auth_verifier? },
114
115
  read_length: -> { pdu_header.auth_length }
115
116
 
117
+ # Per the spec (MS_RPCE 2.2.2.11): start of the trailer should be a multiple of 16 bytes offset from the start of the stub
118
+ def calculate_padding_size
119
+ (16 - (stub.num_bytes % 16)) % 16
120
+ end
121
+
116
122
  def initialize_instance
117
123
  super
118
124
  pdu_header.ptype = PTYPE
@@ -125,7 +131,6 @@ module RubySMB
125
131
  def has_auth_verifier?
126
132
  self.pdu_header.auth_length > 0
127
133
  end
128
-
129
134
  end
130
135
  end
131
136
  end
@@ -18,7 +18,7 @@ module RubySMB
18
18
  string :stub, label: 'Stub', read_length: -> { stub_length }
19
19
  string :auth_pad,
20
20
  onlyif: -> { has_auth_verifier? },
21
- length: -> { (16 - (stub.num_bytes % 16)) % 16 }
21
+ length: -> { calculate_padding_size }
22
22
 
23
23
  # Auth Verifier
24
24
  sec_trailer :sec_trailer, onlyif: -> { has_auth_verifier? }
@@ -26,6 +26,11 @@ module RubySMB
26
26
  onlyif: -> { has_auth_verifier? },
27
27
  read_length: -> { pdu_header.auth_length }
28
28
 
29
+ # Per the spec (MS_RPCE 2.2.2.11): start of the trailer should be a multiple of 16 bytes offset from the start of the stub
30
+ def calculate_padding_size
31
+ (16 - (stub.num_bytes % 16)) % 16
32
+ end
33
+
29
34
  def initialize_instance
30
35
  super
31
36
  pdu_header.ptype = PTYPE