ruby_smb 3.2.4 → 3.2.6

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.
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