ruby_smb 2.0.10 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (224) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +5 -16
  4. data/examples/auth_capture.rb +71 -0
  5. data/examples/dump_secrets_from_sid.rb +207 -0
  6. data/examples/enum_domain_users.rb +75 -0
  7. data/examples/get_computer_info.rb +42 -0
  8. data/examples/query_service_status.rb +42 -4
  9. data/lib/ruby_smb/client/negotiation.rb +1 -1
  10. data/lib/ruby_smb/client.rb +10 -20
  11. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  12. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  13. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  14. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  15. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  16. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  17. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  18. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  19. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  20. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  21. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  22. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  23. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  24. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  25. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  26. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  27. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  28. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  29. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  30. data/lib/ruby_smb/dcerpc/error.rb +17 -0
  31. data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
  32. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
  33. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
  34. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
  35. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
  36. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
  37. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
  38. data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
  39. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  40. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  41. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  42. data/lib/ruby_smb/dcerpc/request.rb +79 -32
  43. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  44. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  45. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +11 -11
  46. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  47. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  48. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  49. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  50. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  51. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  52. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  53. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  54. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  55. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  56. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  57. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  58. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  59. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  60. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  61. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  62. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  63. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  64. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  65. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  66. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  67. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  68. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  69. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  70. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +13 -25
  71. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
  72. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
  73. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
  74. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
  75. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
  76. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
  77. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
  78. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
  79. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
  80. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
  81. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
  82. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
  83. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
  84. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
  85. data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
  86. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  87. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  88. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +2 -13
  89. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
  90. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
  91. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  92. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  93. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  94. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  95. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  96. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +5 -6
  97. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  98. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  99. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
  100. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  101. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  102. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +0 -9
  103. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
  104. data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
  105. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  106. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  107. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  108. data/lib/ruby_smb/dcerpc.rb +41 -11
  109. data/lib/ruby_smb/dialect.rb +45 -0
  110. data/lib/ruby_smb/dispatcher/base.rb +1 -1
  111. data/lib/ruby_smb/field/file_time.rb +1 -1
  112. data/lib/ruby_smb/field/string16.rb +5 -1
  113. data/lib/ruby_smb/gss/provider/authenticator.rb +42 -0
  114. data/lib/ruby_smb/gss/provider/ntlm.rb +303 -0
  115. data/lib/ruby_smb/gss/provider.rb +35 -0
  116. data/lib/ruby_smb/gss.rb +56 -63
  117. data/lib/ruby_smb/ntlm.rb +61 -0
  118. data/lib/ruby_smb/server/server_client/negotiation.rb +156 -0
  119. data/lib/ruby_smb/server/server_client/session_setup.rb +82 -0
  120. data/lib/ruby_smb/server/server_client.rb +162 -0
  121. data/lib/ruby_smb/server.rb +54 -0
  122. data/lib/ruby_smb/signing.rb +59 -0
  123. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +11 -11
  124. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +1 -1
  125. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
  126. data/lib/ruby_smb/smb1/pipe.rb +4 -0
  127. data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
  128. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +9 -0
  129. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +0 -1
  130. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -2
  131. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +1 -1
  132. data/lib/ruby_smb/smb2/pipe.rb +4 -0
  133. data/lib/ruby_smb/smb2.rb +3 -1
  134. data/lib/ruby_smb/version.rb +1 -1
  135. data/lib/ruby_smb.rb +2 -1
  136. data/spec/lib/ruby_smb/client_spec.rb +8 -11
  137. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  138. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  139. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  140. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  141. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3792 -1373
  142. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
  143. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
  144. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
  145. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
  146. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  147. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  148. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  149. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  150. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  151. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +29 -28
  152. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  153. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  154. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  155. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  156. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  157. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  158. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  159. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  160. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  161. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  162. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  163. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  164. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  165. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  166. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  167. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  168. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  169. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  170. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +56 -79
  171. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
  172. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
  173. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
  174. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
  175. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
  176. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
  177. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
  178. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
  179. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
  180. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
  181. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
  182. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
  183. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
  184. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
  185. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
  186. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  187. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  188. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +4 -41
  189. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
  190. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
  191. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  192. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  193. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  194. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  195. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  196. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -25
  197. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  198. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  199. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  200. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +10 -22
  201. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  202. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
  203. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
  204. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
  205. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  206. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  207. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  208. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  209. data/spec/lib/ruby_smb/gss/provider/ntlm/account_spec.rb +32 -0
  210. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +101 -0
  211. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +32 -0
  212. data/spec/lib/ruby_smb/gss/provider/ntlm_spec.rb +113 -0
  213. data/spec/lib/ruby_smb/server/server_client_spec.rb +156 -0
  214. data/spec/lib/ruby_smb/server_spec.rb +32 -0
  215. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
  216. data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
  217. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
  218. data/spec/support/bin_helper.rb +9 -0
  219. data.tar.gz.sig +0 -0
  220. metadata +119 -6
  221. metadata.gz.sig +0 -0
  222. data/lib/ruby_smb/client/signing.rb +0 -64
  223. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
  224. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -135
@@ -0,0 +1,23 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Samr
4
+
5
+ # [3.1.5.13.5 SamrRidToSid (Opnum 65)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/00ff8192-a4f6-45ba-9f65-917e46b6a693)
6
+ class SamrRidToSidResponse < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ prpc_sid :sid
12
+ ndr_uint32 :error_status
13
+
14
+ def initialize_instance
15
+ super
16
+ @opnum = SAMR_RID_TO_SID
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,613 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Samr
4
+
5
+ UUID = '12345778-1234-abcd-ef00-0123456789ac'
6
+ VER_MAJOR = 1
7
+ VER_MINOR = 0
8
+
9
+ # Operation numbers
10
+ SAMR_CONNECT = 0x0000
11
+ SAMR_CLOSE_HANDLE = 0x0001
12
+ SAMR_LOOKUP_DOMAIN_IN_SAM_SERVER = 0x0005
13
+ SAMR_OPEN_DOMAIN = 0x0007
14
+ SAMR_ENUMERATE_USERS_IN_DOMAIN = 0x000D
15
+ SAMR_GET_ALIAS_MEMBERSHIP = 0x0010
16
+ SAMR_OPEN_USER = 0x0022
17
+ SAMR_GET_GROUPS_FOR_USER = 0x0027
18
+ SAMR_RID_TO_SID = 0x0041
19
+
20
+ class SamprHandle < Ndr::NdrContextHandle; end
21
+
22
+ # [2.2.10.2 USER_PROPERTY](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/7c0f2eca-1783-450b-b5a0-754cf11f22c9)
23
+ class UserProperty < BinData::Record
24
+ endian :little
25
+
26
+ uint16 :name_length, initial_value: -> { property_name.num_bytes }
27
+ uint16 :value_length, initial_value: -> { property_value.num_bytes }
28
+ uint16 :reserved
29
+ string16 :property_name, read_length: :name_length
30
+ string :property_value, read_length: :value_length
31
+ end
32
+
33
+ # [2.2.10.1 USER_PROPERTIES](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/8263e7ab-aba9-43d2-8a36-3a9cb2dd3dad)
34
+ class UserProperties < BinData::Record
35
+ endian :little
36
+
37
+ uint32 :reserved1
38
+ uint32 :struct_length, initial_value: -> { num_bytes - 12 }
39
+ uint16 :reserved2
40
+ uint16 :reserved3
41
+ string :reserved4, length: 96
42
+ uint16 :property_signature, initial_value: 0x50
43
+ uint16 :property_count, initial_value: -> { user_properties.size }
44
+ array :user_properties, type: :user_property, initial_length: :property_count
45
+ uint8 :reserved5
46
+ end
47
+
48
+ class KerbKeyDataNew < BinData::Record
49
+ endian :little
50
+
51
+ uint16 :reserved1
52
+ uint16 :reserved2
53
+ uint32 :reserved3
54
+ uint32 :iteration_count
55
+ uint32 :key_type
56
+ uint32 :key_length
57
+ uint32 :key_offset
58
+ end
59
+
60
+ # [2.2.10.6 Primary:Kerberos-Newer-Keys - KERB_STORED_CREDENTIAL_NEW](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/08cb3ca7-954b-45e3-902e-77512fe3ba8e)
61
+ class KerbStoredCredentialNew < BinData::Record
62
+ endian :little
63
+
64
+ uint16 :revision
65
+ uint16 :flags
66
+ uint16 :credential_count
67
+ uint16 :service_credential_count
68
+ uint16 :old_credential_count
69
+ uint16 :older_credential_count
70
+ uint16 :default_salt_length
71
+ uint16 :default_salt_maximum_length
72
+ uint32 :default_salt_offset
73
+ uint32 :default_iteration_count
74
+ array :credentials, type: :kerb_key_data_new, initial_length: :credential_count
75
+ array :service_credentials, type: :kerb_key_data_new, initial_length: :service_credential_count
76
+ array :old_credentials, type: :kerb_key_data_new, initial_length: :old_credential_count
77
+ array :older_credentials, type: :kerb_key_data_new, initial_length: :older_credential_count
78
+ string :default_salt, read_length: -> { credentials.map { |e| e.key_offset }.min - @obj.abs_offset }
79
+ string :key_values, read_length: -> { credentials.map { |e| e.key_length }.sum }
80
+
81
+ def get_key_values
82
+ credentials.map do |credential|
83
+ offset = credential.key_offset - key_values.abs_offset
84
+ key_values[offset, credential.key_length]
85
+ end
86
+ end
87
+ end
88
+
89
+
90
+ #################################
91
+ # Constants #
92
+ #################################
93
+
94
+
95
+ ################
96
+ # ACCESS_MASK Values
97
+
98
+ # [2.2.1.1 Common ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/15b9ebf7-161d-4c83-a672-dceb2ac8c448)
99
+ DELETE = 0x00010000
100
+ READ_CONTROL = 0x00020000
101
+ WRITE_DAC = 0x00040000
102
+ WRITE_OWNER = 0x00080000
103
+ ACCESS_SYSTEM_SECURITY = 0x01000000
104
+ MAXIMUM_ALLOWED = 0x02000000
105
+
106
+
107
+ # [2.2.1.3 Server ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/e8afb15e-c053-4984-b84b-66877236e141)
108
+ SAM_SERVER_CONNECT = 0x00000001
109
+ SAM_SERVER_SHUTDOWN = 0x00000002
110
+ SAM_SERVER_INITIALIZE = 0x00000004
111
+ SAM_SERVER_CREATE_DOMAIN = 0x00000008
112
+ SAM_SERVER_ENUMERATE_DOMAINS = 0x00000010
113
+ SAM_SERVER_LOOKUP_DOMAIN = 0x00000020
114
+ SAM_SERVER_ALL_ACCESS = 0x000F003F
115
+ SAM_SERVER_READ = 0x00020010
116
+ SAM_SERVER_WRITE = 0x0002000E
117
+ SAM_SERVER_EXECUTE = 0x00020021
118
+
119
+ # [2.2.1.4 Domain ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/aef23495-f6aa-48e9-aebc-22e022a2b4eb)
120
+ DOMAIN_READ_PASSWORD_PARAMETERS = 0x00000001
121
+ DOMAIN_WRITE_PASSWORD_PARAMS = 0x00000002
122
+ DOMAIN_READ_OTHER_PARAMETERS = 0x00000004
123
+ DOMAIN_WRITE_OTHER_PARAMETERS = 0x00000008
124
+ DOMAIN_CREATE_USER = 0x00000010
125
+ DOMAIN_CREATE_GROUP = 0x00000020
126
+ DOMAIN_CREATE_ALIAS = 0x00000040
127
+ DOMAIN_GET_ALIAS_MEMBERSHIP = 0x00000080
128
+ DOMAIN_LIST_ACCOUNTS = 0x00000100
129
+ DOMAIN_LOOKUP = 0x00000200
130
+ DOMAIN_ADMINISTER_SERVER = 0x00000400
131
+ DOMAIN_ALL_ACCESS = 0x000F07FF
132
+ DOMAIN_READ = 0x00020084
133
+ DOMAIN_WRITE = 0x0002047A
134
+ DOMAIN_EXECUTE = 0x00020301
135
+
136
+ # [2.2.1.5 Group ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/f24f9fa8-798d-4e7d-a110-a5eda6900f41)
137
+ GROUP_READ_INFORMATION = 0x00000001
138
+ GROUP_WRITE_ACCOUNT = 0x00000002
139
+ GROUP_ADD_MEMBER = 0x00000004
140
+ GROUP_REMOVE_MEMBER = 0x00000008
141
+ GROUP_LIST_MEMBERS = 0x00000010
142
+ GROUP_ALL_ACCESS = 0x000F001F
143
+ GROUP_READ = 0x00020010
144
+ GROUP_WRITE = 0x0002000E
145
+ GROUP_EXECUTE = 0x00020001
146
+
147
+ # [2.2.1.6 Alias ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/2da21c6c-5b15-46c8-bd4e-6a8443216e1a)
148
+ ALIAS_ADD_MEMBER = 0x00000001
149
+ ALIAS_REMOVE_MEMBER = 0x00000002
150
+ ALIAS_LIST_MEMBERS = 0x00000004
151
+ ALIAS_READ_INFORMATION = 0x00000008
152
+ ALIAS_WRITE_ACCOUNT = 0x00000010
153
+ ALIAS_ALL_ACCESS = 0x000F001F
154
+ ALIAS_READ = 0x00020004
155
+ ALIAS_WRITE = 0x00020013
156
+ ALIAS_EXECUTE = 0x00020008
157
+
158
+ # [2.2.1.7 User ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/c0be3f43-bcf9-43ee-b027-3d02ab372c53)
159
+ USER_READ_GENERAL = 0x00000001
160
+ USER_READ_PREFERENCES = 0x00000002
161
+ USER_WRITE_PREFERENCES = 0x00000004
162
+ USER_READ_LOGON = 0x00000008
163
+ USER_READ_ACCOUNT = 0x00000010
164
+ USER_WRITE_ACCOUNT = 0x00000020
165
+ USER_CHANGE_PASSWORD = 0x00000040
166
+ USER_FORCE_PASSWORD_CHANGE = 0x00000080
167
+ USER_LIST_GROUPS = 0x00000100
168
+ USER_READ_GROUP_INFORMATION = 0x00000200
169
+ USER_WRITE_GROUP_INFORMATION = 0x00000400
170
+ USER_ALL_ACCESS = 0x000F07FF
171
+ USER_READ = 0x0002031A
172
+ USER_WRITE = 0x00020044
173
+ USER_EXECUTE = 0x00020041
174
+
175
+ # [2.2.1.8 USER_ALL Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/2675c176-72e0-4ac9-ae6d-cdd87b8ba520)
176
+ USER_ALL_USERNAME = 0x00000001
177
+ USER_ALL_FULLNAME = 0x00000002
178
+ USER_ALL_USERID = 0x00000004
179
+ USER_ALL_PRIMARYGROUPID = 0x00000008
180
+ USER_ALL_ADMINCOMMENT = 0x00000010
181
+ USER_ALL_USERCOMMENT = 0x00000020
182
+ USER_ALL_HOMEDIRECTORY = 0x00000040
183
+ USER_ALL_HOMEDIRECTORYDRIVE = 0x00000080
184
+ USER_ALL_SCRIPTPATH = 0x00000100
185
+ USER_ALL_PROFILEPATH = 0x00000200
186
+ USER_ALL_WORKSTATIONS = 0x00000400
187
+ USER_ALL_LASTLOGON = 0x00000800
188
+ USER_ALL_LASTLOGOFF = 0x00001000
189
+ USER_ALL_LOGONHOURS = 0x00002000
190
+ USER_ALL_BADPASSWORDCOUNT = 0x00004000
191
+ USER_ALL_LOGONCOUNT = 0x00008000
192
+ USER_ALL_PASSWORDCANCHANGE = 0x00010000
193
+ USER_ALL_PASSWORDMUSTCHANGE = 0x00020000
194
+ USER_ALL_PASSWORDLASTSET = 0x00040000
195
+ USER_ALL_ACCOUNTEXPIRES = 0x00080000
196
+ USER_ALL_USERACCOUNTCONTROL = 0x00100000
197
+ USER_ALL_PARAMETERS = 0x00200000
198
+ USER_ALL_COUNTRYCODE = 0x00400000
199
+ USER_ALL_CODEPAGE = 0x00800000
200
+ USER_ALL_NTPASSWORDPRESENT = 0x01000000
201
+ USER_ALL_LMPASSWORDPRESENT = 0x02000000
202
+ USER_ALL_PRIVATEDATA = 0x04000000
203
+ USER_ALL_PASSWORDEXPIRED = 0x08000000
204
+ USER_ALL_SECURITYDESCRIPTOR = 0x10000000
205
+ USER_ALL_UNDEFINED_MASK = 0xC0000000
206
+
207
+ # [2.2.1.9 ACCOUNT_TYPE Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/e742be45-665d-4576-b872-0bc99d1e1fbe)
208
+ SAM_DOMAIN_OBJECT = 0x00000000
209
+ SAM_GROUP_OBJECT = 0x10000000
210
+ SAM_NON_SECURITY_GROUP_OBJECT = 0x10000001
211
+ SAM_ALIAS_OBJECT = 0x20000000
212
+ SAM_NON_SECURITY_ALIAS_OBJECT = 0x20000001
213
+ SAM_USER_OBJECT = 0x30000000
214
+ SAM_MACHINE_ACCOUNT = 0x30000001
215
+ SAM_TRUST_ACCOUNT = 0x30000002
216
+ SAM_APP_BASIC_GROUP = 0x40000000
217
+ SAM_APP_QUERY_GROUP = 0x40000001
218
+
219
+ # [2.2.1.10 SE_GROUP Attributes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/9e093bd2-e451-4dd5-9700-97b977d7ebb2)
220
+ SE_GROUP_MANDATORY = 0x00000001
221
+ SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002
222
+ SE_GROUP_ENABLED = 0x00000004
223
+
224
+ # [2.2.1.11 GROUP_TYPE Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1f8d7ea1-fcc1-4833-839a-f94d67c08fcd)
225
+ GROUP_TYPE_ACCOUNT_GROUP = 0x00000002
226
+ GROUP_TYPE_RESOURCE_GROUP = 0x00000004
227
+ GROUP_TYPE_UNIVERSAL_GROUP = 0x00000008
228
+ GROUP_TYPE_SECURITY_ENABLED = 0x80000000
229
+ GROUP_TYPE_SECURITY_ACCOUNT = 0x80000002
230
+ GROUP_TYPE_SECURITY_RESOURCE = 0x80000004
231
+ GROUP_TYPE_SECURITY_UNIVERSAL = 0x80000008
232
+
233
+ # [2.2.1.12 USER_ACCOUNT Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/b10cfda1-f24f-441b-8f43-80cb93e786ec)
234
+ USER_ACCOUNT_DISABLED = 0x00000001
235
+ USER_HOME_DIRECTORY_REQUIRED = 0x00000002
236
+ USER_PASSWORD_NOT_REQUIRED = 0x00000004
237
+ USER_TEMP_DUPLICATE_ACCOUNT = 0x00000008
238
+ USER_NORMAL_ACCOUNT = 0x00000010
239
+ USER_MNS_LOGON_ACCOUNT = 0x00000020
240
+ USER_INTERDOMAIN_TRUST_ACCOUNT = 0x00000040
241
+ USER_WORKSTATION_TRUST_ACCOUNT = 0x00000080
242
+ USER_SERVER_TRUST_ACCOUNT = 0x00000100
243
+ USER_DONT_EXPIRE_PASSWORD = 0x00000200
244
+ USER_ACCOUNT_AUTO_LOCKED = 0x00000400
245
+ USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000800
246
+ USER_SMARTCARD_REQUIRED = 0x00001000
247
+ USER_TRUSTED_FOR_DELEGATION = 0x00002000
248
+ USER_NOT_DELEGATED = 0x00004000
249
+ USER_USE_DES_KEY_ONLY = 0x00008000
250
+ USER_DONT_REQUIRE_PREAUTH = 0x00010000
251
+ USER_PASSWORD_EXPIRED = 0x00020000
252
+ USER_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x00040000
253
+ USER_NO_AUTH_DATA_REQUIRED = 0x00080000
254
+ USER_PARTIAL_SECRETS_ACCOUNT = 0x00100000
255
+ USER_USE_AES_KEYS = 0x00200000
256
+
257
+ # [2.2.1.13 UF_FLAG Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/10bf6c8e-34af-4cf9-8dff-6b6330922863)
258
+ UF_SCRIPT = 0x00000001
259
+ UF_ACCOUNTDISABLE = 0x00000002
260
+ UF_HOMEDIR_REQUIRED = 0x00000008
261
+ UF_LOCKOUT = 0x00000010
262
+ UF_PASSWD_NOTREQD = 0x00000020
263
+ UF_PASSWD_CANT_CHANGE = 0x00000040
264
+ UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000080
265
+ UF_TEMP_DUPLICATE_ACCOUNT = 0x00000100
266
+ UF_NORMAL_ACCOUNT = 0x00000200
267
+ UF_INTERDOMAIN_TRUST_ACCOUNT = 0x00000800
268
+ UF_WORKSTATION_TRUST_ACCOUNT = 0x00001000
269
+ UF_SERVER_TRUST_ACCOUNT = 0x00002000
270
+ UF_DONT_EXPIRE_PASSWD = 0x00010000
271
+ UF_MNS_LOGON_ACCOUNT = 0x00020000
272
+ UF_SMARTCARD_REQUIRED = 0x00040000
273
+ UF_TRUSTED_FOR_DELEGATION = 0x00080000
274
+ UF_NOT_DELEGATED = 0x00100000
275
+ UF_USE_DES_KEY_ONLY = 0x00200000
276
+ UF_DONT_REQUIRE_PREAUTH = 0x00400000
277
+ UF_PASSWORD_EXPIRED = 0x00800000
278
+ UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x01000000
279
+ UF_NO_AUTH_DATA_REQUIRED = 0x02000000
280
+ UF_PARTIAL_SECRETS_ACCOUNT = 0x04000000
281
+ UF_USE_AES_KEYS = 0x08000000
282
+
283
+ # [2.2.1.14 Predefined RIDs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/565a6584-3061-4ede-a531-f5c53826504b)
284
+ DOMAIN_USER_RID_ADMIN = 0x000001F4
285
+ DOMAIN_USER_RID_GUEST = 0x000001F5
286
+ DOMAIN_USER_RID_KRBTGT = 0x000001F6
287
+ DOMAIN_GROUP_RID_ADMINS = 0x00000200
288
+ DOMAIN_GROUP_RID_USERS = 0x00000201
289
+ DOMAIN_GROUP_RID_COMPUTERS = 0x00000203
290
+ DOMAIN_GROUP_RID_CONTROLLERS = 0x00000204
291
+ DOMAIN_ALIAS_RID_ADMINS = 0x00000220
292
+ DOMAIN_GROUP_RID_READONLY_CONTROLLERS = 0x00000209
293
+
294
+ # [2.2.10.8 Kerberos Encryption Algorithm Identifiers](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1355fa6b-d097-4ecc-8d5e-75b3a6533e04)
295
+ KERBEROS_TYPE = {
296
+ 1 => 'dec-cbc-crc',
297
+ 3 => 'des-cbc-md5',
298
+ 17 => 'aes128-cts-hmac-sha1-96',
299
+ 18 => 'aes256-cts-hmac-sha1-96',
300
+ 0xffffff74 => 'rc4_hmac'
301
+ }
302
+
303
+ require 'ruby_smb/dcerpc/samr/rpc_sid'
304
+
305
+ require 'ruby_smb/dcerpc/samr/samr_connect_request'
306
+ require 'ruby_smb/dcerpc/samr/samr_connect_response'
307
+ require 'ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request'
308
+ require 'ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response'
309
+ require 'ruby_smb/dcerpc/samr/samr_open_domain_request'
310
+ require 'ruby_smb/dcerpc/samr/samr_open_domain_response'
311
+ require 'ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request'
312
+ require 'ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response'
313
+ require 'ruby_smb/dcerpc/samr/samr_rid_to_sid_request'
314
+ require 'ruby_smb/dcerpc/samr/samr_rid_to_sid_response'
315
+ require 'ruby_smb/dcerpc/samr/samr_close_handle_request'
316
+ require 'ruby_smb/dcerpc/samr/samr_close_handle_response'
317
+ require 'ruby_smb/dcerpc/samr/samr_get_alias_membership_request'
318
+ require 'ruby_smb/dcerpc/samr/samr_get_alias_membership_response'
319
+ require 'ruby_smb/dcerpc/samr/samr_open_user_request'
320
+ require 'ruby_smb/dcerpc/samr/samr_open_user_response'
321
+ require 'ruby_smb/dcerpc/samr/samr_get_groups_for_user_request'
322
+ require 'ruby_smb/dcerpc/samr/samr_get_groups_for_user_response'
323
+
324
+ # Returns a handle to a server object.
325
+ #
326
+ # @param server_name [Char] the first character of the NETBIOS name of
327
+ # the server (optional)
328
+ # @param access [Numeric] access requested for ServerHandle upon output:
329
+ # bitwise OR of common and server ACCESS_MASK values (defined in
330
+ # lib/ruby_smb/dcerpc/samr.rb).
331
+ # @return [RubySMB::Dcerpc::Samr::SamprHandle] handle to the server object.
332
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
333
+ # SamrConnectResponse packet
334
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
335
+ # is not STATUS_SUCCESS
336
+ def samr_connect(server_name: '', access: MAXIMUM_ALLOWED)
337
+ samr_connect_request = SamrConnectRequest.new(
338
+ server_name: server_name,
339
+ desired_access: access
340
+ )
341
+ response = dcerpc_request(samr_connect_request)
342
+ begin
343
+ samr_connect_response = SamrConnectResponse.read(response)
344
+ rescue IOError
345
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrConnectResponse'
346
+ end
347
+ unless samr_connect_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
348
+ raise RubySMB::Dcerpc::Error::SamrError,
349
+ "Error returned with samr_connect: "\
350
+ "#{WindowsError::NTStatus.find_by_retval(samr_connect_response.error_status.value).join(',')}"
351
+ end
352
+ samr_connect_response.server_handle
353
+ end
354
+
355
+ # Obtains the SID of a domain object
356
+ #
357
+ # @param server_handle [RubySMB::Dcerpc::Samr::SamprHandle] RPC context
358
+ # handle representing the server object
359
+ # @param name [String] The domain name
360
+ # @return [RubySMB::Dcerpc::RpcSid] SID value of a domain that
361
+ # corresponds to the Name passed in
362
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
363
+ # SamrLookupDomainInSamServerResponse packet
364
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
365
+ # is not STATUS_SUCCESS
366
+ def samr_lookup_domain(server_handle:, name:)
367
+ samr_lookup_domain_in_sam_server_request = SamrLookupDomainInSamServerRequest.new(
368
+ server_handle: server_handle,
369
+ name: name
370
+ )
371
+ response = dcerpc_request(samr_lookup_domain_in_sam_server_request)
372
+ begin
373
+ samr_lookup_domain_in_sam_server_response = SamrLookupDomainInSamServerResponse.read(response)
374
+ rescue IOError
375
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrLookupDomainInSamServerResponse'
376
+ end
377
+ unless samr_lookup_domain_in_sam_server_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
378
+ raise RubySMB::Dcerpc::Error::SamrError,
379
+ "Error returned during domain lookup in SAM server: "\
380
+ "#{WindowsError::NTStatus.find_by_retval(samr_lookup_domain_in_sam_server_response.error_status.value).join(',')}"
381
+ end
382
+ samr_lookup_domain_in_sam_server_response.domain_id
383
+ end
384
+
385
+ # Returns a handle to a domain object.
386
+ #
387
+ # @param server_handle [RubySMB::Dcerpc::Samr::SamprHandle] RPC context
388
+ # handle representing the server object
389
+ # @param access [Numeric] access requested for ServerHandle upon output:
390
+ # bitwise OR of common and server ACCESS_MASK values (defined in
391
+ # lib/ruby_smb/dcerpc/samr.rb).
392
+ # @param domain_id [RubySMB::Dcerpc::RpcSid] SID value of a domain
393
+ # @return [RubySMB::Dcerpc::Samr::SamprHandle] handle to the domain object.
394
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
395
+ # SamrOpenDomainResponse packet
396
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
397
+ # is not STATUS_SUCCESS
398
+ def samr_open_domain(server_handle:, access: MAXIMUM_ALLOWED, domain_id:)
399
+ samr_open_domain_request = SamrOpenDomainRequest.new(
400
+ server_handle: server_handle,
401
+ desired_access: access,
402
+ domain_id: domain_id
403
+ )
404
+ response = dcerpc_request(samr_open_domain_request)
405
+ begin
406
+ samr_open_domain_response = SamrOpenDomainResponse.read(response)
407
+ rescue IOError
408
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrLookupDomainInSamServerResponse'
409
+ end
410
+ unless samr_open_domain_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
411
+ raise RubySMB::Dcerpc::Error::SamrError,
412
+ "Error returned during domain lookup in SAM server: "\
413
+ "#{WindowsError::NTStatus.find_by_retval(samr_open_domain_response.error_status.value).join(',')}"
414
+ end
415
+ samr_open_domain_response.domain_handle
416
+ end
417
+
418
+ # Enumerates all users in the specified domain.
419
+ #
420
+ # @param domain_handle [RubySMB::Dcerpc::Samr::SamprHandle] RPC context
421
+ # handle representing the domain object
422
+ # @return [Hash] hash mapping RID and username
423
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
424
+ # SamrEnumerateUsersInDomainResponse packet
425
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
426
+ # is not STATUS_SUCCESS
427
+ def samr_enumerate_users_in_domain(domain_handle:,
428
+ enumeration_context: 0,
429
+ user_account_control: USER_NORMAL_ACCOUNT |
430
+ USER_WORKSTATION_TRUST_ACCOUNT |
431
+ USER_SERVER_TRUST_ACCOUNT |
432
+ USER_INTERDOMAIN_TRUST_ACCOUNT)
433
+ samr_enum_users_request = SamrEnumerateUsersInDomainRequest.new(
434
+ domain_handle: domain_handle,
435
+ user_account_control: user_account_control,
436
+ prefered_maximum_length: 0xFFFFFFFF
437
+ )
438
+ res = {}
439
+ loop do
440
+ samr_enum_users_request.enumeration_context = enumeration_context
441
+ response = dcerpc_request(samr_enum_users_request)
442
+ begin
443
+ samr_enum_users_reponse= SamrEnumerateUsersInDomainResponse.read(response)
444
+ rescue IOError
445
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrEnumerateUsersInDomainResponse'
446
+ end
447
+ unless samr_enum_users_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS ||
448
+ samr_enum_users_reponse.error_status == WindowsError::NTStatus::STATUS_MORE_ENTRIES
449
+ raise RubySMB::Dcerpc::Error::SamrError,
450
+ "Error returned during users enumeration in SAM server: "\
451
+ "#{WindowsError::NTStatus.find_by_retval(samr_enum_users_reponse.error_status.value).join(',')}"
452
+ end
453
+ samr_enum_users_reponse.buffer.buffer.each_with_object(res) do |entry, hash|
454
+ hash[entry.relative_id] = entry.name.buffer
455
+ end
456
+ break unless samr_enum_users_reponse.error_status == WindowsError::NTStatus::STATUS_MORE_ENTRIES
457
+ enumeration_context = samr_enum_users_reponse.enumeration_context
458
+ end
459
+ res
460
+ end
461
+
462
+ # Returns the SID of an account, given a RID.
463
+ #
464
+ # @param rid [Numeric] the RID
465
+ # @return [String] The SID of the account referenced by RID
466
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
467
+ # SamrRidToSidResponse packet
468
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
469
+ # is not STATUS_SUCCESS
470
+ def samr_rid_to_sid(object_handle:, rid:)
471
+ samr_rid_to_sid_request = SamrRidToSidRequest.new(
472
+ object_handle: object_handle,
473
+ rid: rid
474
+ )
475
+ response = dcerpc_request(samr_rid_to_sid_request)
476
+ begin
477
+ samr_rid_to_sid_response = SamrRidToSidResponse.read(response)
478
+ rescue IOError
479
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrRidToSidResponse'
480
+ end
481
+ unless samr_rid_to_sid_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
482
+ raise RubySMB::Dcerpc::Error::SamrError,
483
+ "Error returned during SID lookup in SAM server: "\
484
+ "#{WindowsError::NTStatus.find_by_retval(samr_rid_to_sid_response.error_status.value).join(',')}"
485
+ end
486
+ samr_rid_to_sid_response.sid
487
+ end
488
+
489
+ # Closes (that is, releases server-side resources used by) any context
490
+ # handle obtained from this RPC interface
491
+ #
492
+ # @param sam_handle [RubySMB::Dcerpc::Samr::SamprHandle] An RPC context
493
+ # handle to close
494
+ # @return [RubySMB::Dcerpc::Samr::SamprHandle] A zero handle on success
495
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
496
+ # SamrCloseHandle packet
497
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
498
+ # is not STATUS_SUCCESS
499
+ def close_handle(sam_handle)
500
+ samr_close_handle_request = SamrCloseHandleRequest.new(sam_handle: sam_handle)
501
+ response = dcerpc_request(samr_close_handle_request)
502
+ begin
503
+ samr_close_handle_response = SamrCloseHandleResponse.read(response)
504
+ rescue IOError
505
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrCloseHandleResponse'
506
+ end
507
+ unless samr_close_handle_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
508
+ raise RubySMB::Dcerpc::Error::SamrError,
509
+ "Error returned with samr_connect: "\
510
+ "#{WindowsError::NTStatus.find_by_retval(samr_close_handle_response.error_status.value).join(',')}"
511
+ end
512
+ samr_close_handle_response.sam_handle
513
+ end
514
+
515
+ # Returns the union of all aliases that a given set of SIDs is a member of.
516
+ #
517
+ # @param domain_handle [RubySMB::Dcerpc::Samr::SamprHandle] An RPC context
518
+ # representing a domain object.
519
+ # @param sids [Array<RubySMB::Dcerpc::Samr::RpcSid>, RubySMB::Dcerpc::Samr::RpcSid] List of SID's
520
+ # @return [Array<RubySMB::Dcerpc::Ndr::NdrUint32>] The union of all aliases represented by RID's
521
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
522
+ # SamrGetAliasMembership packet
523
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
524
+ # is not STATUS_SUCCESS
525
+ def samr_get_alias_membership(domain_handle:, sids:)
526
+ sids = [sids] unless sids.is_a?(::Array)
527
+ samr_get_alias_membership_request = SamrGetAliasMembershipRequest.new(
528
+ domain_handle: domain_handle
529
+ )
530
+ sids.each do |sid|
531
+ samr_get_alias_membership_request.sid_array.sids << {sid_pointer: sid}
532
+ end
533
+ response = dcerpc_request(samr_get_alias_membership_request)
534
+ begin
535
+ samr_get_alias_membership_reponse= SamrGetAliasMembershipResponse.read(response)
536
+ rescue IOError
537
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrGetAliasMembershipResponse'
538
+ end
539
+ unless samr_get_alias_membership_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS
540
+ raise RubySMB::Dcerpc::Error::SamrError,
541
+ "Error returned while getting alias membership: "\
542
+ "#{WindowsError::NTStatus.find_by_retval(samr_get_alias_membership_reponse.error_status.value).join(',')}"
543
+ end
544
+ return [] if samr_get_alias_membership_reponse.membership.elem_count == 0
545
+ samr_get_alias_membership_reponse.membership.elements.to_ary
546
+ end
547
+
548
+ # Returns a handle to a user, given a RID
549
+ #
550
+ # @param domain_handle [RubySMB::Dcerpc::Samr::SamprHandle] An RPC context
551
+ # representing a domain object
552
+ # @param access [Integer] An access control that indicates the requested
553
+ # access for the returned handle. It is a bitwise OR of common
554
+ # ACCESS_MASK and user ACCESS_MASK values (see
555
+ # lib/ruby_smb/dcerpc/samr.rb)
556
+ # @param user_id [Integer] RID of a user account
557
+ # @return [RubySMB::Dcerpc::Samr::SamprHandle] The user handle
558
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
559
+ # SamrOpenUser packet
560
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
561
+ # is not STATUS_SUCCESS
562
+ def samr_open_user(domain_handle:, access: MAXIMUM_ALLOWED, user_id:)
563
+ samr_open_user_request = SamrOpenUserRequest.new(
564
+ domain_handle: domain_handle,
565
+ desired_access: access,
566
+ user_id: user_id
567
+ )
568
+ response = dcerpc_request(samr_open_user_request)
569
+ begin
570
+ samr_open_user_response = SamrOpenUserResponse.read(response)
571
+ rescue IOError
572
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrOpenUserResponse'
573
+ end
574
+ unless samr_open_user_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
575
+ raise RubySMB::Dcerpc::Error::SamrError,
576
+ "Error returned when getting a handle to user #{user_id}: "\
577
+ "#{WindowsError::NTStatus.find_by_retval(samr_open_user_response.error_status.value).join(',')}"
578
+ end
579
+ samr_open_user_response.user_handle
580
+ end
581
+
582
+ # Returns a listing of groups that a user is a member of
583
+ #
584
+ # @param user_handle [RubySMB::Dcerpc::Samr::SamprHandle] An RPC context
585
+ # representing a user object.
586
+ # @return [Array<RubySMB::Dcerpc::Samr::GroupMembership>] Array of
587
+ # GroupMembership containing RID and Attributes
588
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
589
+ # SamrGetGroupsForUser packet
590
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
591
+ # is not STATUS_SUCCESS
592
+ def samr_get_group_for_user(user_handle:)
593
+ samr_get_groups_for_user_request = SamrGetGroupsForUserRequest.new(
594
+ user_handle: user_handle
595
+ )
596
+ response = dcerpc_request(samr_get_groups_for_user_request)
597
+ begin
598
+ samr_get_groups_for_user_reponse= SamrGetGroupsForUserResponse.read(response)
599
+ rescue IOError
600
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrGetGroupsForUserResponse'
601
+ end
602
+ unless samr_get_groups_for_user_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS
603
+ raise RubySMB::Dcerpc::Error::SamrError,
604
+ "Error returned while getting user groups: "\
605
+ "#{WindowsError::NTStatus.find_by_retval(samr_get_groups_for_user_reponse.error_status.value).join(',')}"
606
+ end
607
+ samr_get_groups_for_user_reponse.groups.groups.to_ary
608
+ end
609
+
610
+ end
611
+ end
612
+ end
613
+
@@ -0,0 +1,26 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+
4
+ # [2.2.2.11 sec_trailer Structure](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/ab45c6a5-951a-4096-b805-7347674dc6ab)
5
+ class SecTrailer < Ndr::NdrStruct
6
+ # Disabling auto alignment since it is handled by the parent structure directly
7
+ default_parameter byte_align: 1
8
+ endian :little
9
+
10
+ ndr_uint8 :auth_type
11
+ ndr_uint8 :auth_level
12
+ ndr_uint8 :auth_pad_length, initial_value: -> { get_auth_pad_length(@obj) }
13
+ ndr_uint8 :auth_reserved
14
+ ndr_uint32 :auth_context_id
15
+
16
+ def get_auth_pad_length(obj)
17
+ parent = obj&.parent&.parent
18
+ if parent&.respond_to?(:auth_pad)
19
+ return parent.auth_pad.length if parent.auth_pad.respond_to?(:length)
20
+ end
21
+ 0
22
+ end
23
+ end
24
+
25
+ end
26
+ end