ruby_smb 2.0.12 → 3.0.2

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 (279) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +1 -1
  4. data/examples/auth_capture.rb +28 -0
  5. data/examples/dump_secrets_from_sid.rb +207 -0
  6. data/examples/enum_domain_users.rb +75 -0
  7. data/examples/file_server.rb +76 -0
  8. data/examples/get_computer_info.rb +42 -0
  9. data/examples/query_service_status.rb +42 -4
  10. data/lib/ruby_smb/client.rb +3 -14
  11. data/lib/ruby_smb/create_actions.rb +21 -0
  12. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  13. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  14. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  15. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  16. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  17. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  18. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  19. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  20. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  21. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  22. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  23. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  24. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  25. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  26. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  27. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_request.rb +20 -0
  28. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_response.rb +20 -0
  29. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_request.rb +21 -0
  30. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_response.rb +21 -0
  31. data/lib/ruby_smb/dcerpc/encrypting_file_system.rb +44 -0
  32. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  33. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  34. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  35. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  36. data/lib/ruby_smb/dcerpc/error.rb +17 -0
  37. data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
  38. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
  39. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
  40. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
  41. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
  42. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
  43. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
  44. data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
  45. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  46. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  47. data/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_request.rb +22 -0
  48. data/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_response.rb +20 -0
  49. data/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_request.rb +24 -0
  50. data/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_response.rb +23 -0
  51. data/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_request.rb +24 -0
  52. data/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_response.rb +22 -0
  53. data/lib/ruby_smb/dcerpc/print_system.rb +69 -0
  54. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  55. data/lib/ruby_smb/dcerpc/request.rb +79 -32
  56. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  57. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  58. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +11 -11
  59. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  60. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  61. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  62. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  63. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  64. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  65. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  66. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  67. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  68. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  69. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  70. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  71. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  72. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  73. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  74. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  75. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  76. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  77. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  78. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  79. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  80. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  81. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  82. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  83. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +13 -25
  84. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
  85. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
  86. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
  87. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
  88. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
  89. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
  90. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
  91. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
  92. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
  93. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
  94. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
  95. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
  96. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
  97. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
  98. data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
  99. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  100. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  101. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +2 -13
  102. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
  103. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
  104. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  105. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  106. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  107. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  108. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  109. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +5 -6
  110. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  111. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  112. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
  113. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  114. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  115. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +0 -9
  116. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
  117. data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
  118. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  119. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  120. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  121. data/lib/ruby_smb/dcerpc.rb +43 -13
  122. data/lib/ruby_smb/field/file_time.rb +1 -1
  123. data/lib/ruby_smb/field/nt_status.rb +20 -1
  124. data/lib/ruby_smb/field/string16.rb +5 -1
  125. data/lib/ruby_smb/fscc/file_information/file_ea_information.rb +14 -0
  126. data/lib/ruby_smb/fscc/file_information/file_network_open_information.rb +22 -0
  127. data/lib/ruby_smb/fscc/file_information/file_stream_information.rb +16 -0
  128. data/lib/ruby_smb/fscc/file_information.rb +29 -0
  129. data/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information.rb +46 -0
  130. data/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information.rb +19 -0
  131. data/lib/ruby_smb/fscc/file_system_information.rb +22 -0
  132. data/lib/ruby_smb/fscc.rb +1 -0
  133. data/lib/ruby_smb/generic_packet.rb +6 -0
  134. data/lib/ruby_smb/gss/provider/authenticator.rb +4 -0
  135. data/lib/ruby_smb/gss/provider/ntlm.rb +13 -3
  136. data/lib/ruby_smb/ntlm.rb +18 -2
  137. data/lib/ruby_smb/server/server_client/negotiation.rb +0 -2
  138. data/lib/ruby_smb/server/server_client/session_setup.rb +43 -32
  139. data/lib/ruby_smb/server/server_client/share_io.rb +28 -0
  140. data/lib/ruby_smb/server/server_client/tree_connect.rb +60 -0
  141. data/lib/ruby_smb/server/server_client.rb +214 -24
  142. data/lib/ruby_smb/server/session.rb +71 -0
  143. data/lib/ruby_smb/server/share/provider/disk.rb +437 -0
  144. data/lib/ruby_smb/server/share/provider/pipe.rb +27 -0
  145. data/lib/ruby_smb/server/share/provider/processor.rb +76 -0
  146. data/lib/ruby_smb/server/share/provider.rb +38 -0
  147. data/lib/ruby_smb/server/share.rb +11 -0
  148. data/lib/ruby_smb/server.rb +35 -3
  149. data/lib/ruby_smb/signing.rb +37 -11
  150. data/lib/ruby_smb/smb1/commands.rb +4 -0
  151. data/lib/ruby_smb/smb1/pipe.rb +4 -0
  152. data/lib/ruby_smb/smb1.rb +0 -1
  153. data/lib/ruby_smb/smb2/bit_field/smb2_header_flags.rb +2 -1
  154. data/lib/ruby_smb/smb2/commands.rb +4 -0
  155. data/lib/ruby_smb/smb2/create_context/request.rb +64 -0
  156. data/lib/ruby_smb/smb2/create_context/response.rb +62 -0
  157. data/lib/ruby_smb/smb2/create_context.rb +74 -22
  158. data/lib/ruby_smb/smb2/packet/create_request.rb +44 -11
  159. data/lib/ruby_smb/smb2/packet/create_response.rb +17 -3
  160. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +1 -1
  161. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +2 -2
  162. data/lib/ruby_smb/smb2/packet/query_info_request.rb +43 -0
  163. data/lib/ruby_smb/smb2/packet/query_info_response.rb +23 -0
  164. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +1 -1
  165. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -0
  166. data/lib/ruby_smb/smb2/packet.rb +2 -0
  167. data/lib/ruby_smb/smb2/pipe.rb +4 -0
  168. data/lib/ruby_smb/smb2.rb +11 -0
  169. data/lib/ruby_smb/smb_error.rb +110 -0
  170. data/lib/ruby_smb/version.rb +1 -1
  171. data/lib/ruby_smb.rb +2 -0
  172. data/ruby_smb.gemspec +1 -1
  173. data/spec/lib/ruby_smb/client_spec.rb +1 -2
  174. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  175. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  176. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  177. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  178. data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_request_spec.rb +30 -0
  179. data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_response_spec.rb +30 -0
  180. data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_request_spec.rb +38 -0
  181. data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_response_spec.rb +38 -0
  182. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3792 -1373
  183. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
  184. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
  185. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
  186. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
  187. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  188. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  189. data/spec/lib/ruby_smb/dcerpc/print_system/driver_container_spec.rb +41 -0
  190. data/spec/lib/ruby_smb/dcerpc/print_system/driver_info2_spec.rb +64 -0
  191. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_request_spec.rb +59 -0
  192. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_response_spec.rb +30 -0
  193. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_request_spec.rb +62 -0
  194. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_response_spec.rb +54 -0
  195. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_request_spec.rb +62 -0
  196. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_response_spec.rb +46 -0
  197. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  198. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  199. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  200. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +29 -28
  201. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  202. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  203. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  204. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  205. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  206. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  207. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  208. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  209. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  210. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  211. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  212. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  213. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  214. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  215. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  216. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  217. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  218. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  219. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +56 -79
  220. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
  221. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
  222. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
  223. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
  224. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
  225. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
  226. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
  227. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
  228. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
  229. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
  230. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
  231. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
  232. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
  233. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
  234. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
  235. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  236. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  237. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +4 -41
  238. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
  239. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
  240. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  241. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  242. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  243. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  244. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  245. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -25
  246. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  247. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  248. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  249. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +10 -22
  250. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  251. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
  252. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
  253. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
  254. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  255. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  256. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  257. data/spec/lib/ruby_smb/field/nt_status_spec.rb +6 -2
  258. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  259. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +4 -0
  260. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +1 -1
  261. data/spec/lib/ruby_smb/server/server_client_spec.rb +36 -53
  262. data/spec/lib/ruby_smb/server/session_spec.rb +38 -0
  263. data/spec/lib/ruby_smb/server/share/provider/disk_spec.rb +61 -0
  264. data/spec/lib/ruby_smb/server/share/provider/pipe_spec.rb +31 -0
  265. data/spec/lib/ruby_smb/server/share/provider_spec.rb +13 -0
  266. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
  267. data/spec/lib/ruby_smb/smb2/bit_field/header_flags_spec.rb +8 -2
  268. data/spec/lib/ruby_smb/smb2/{create_context_spec.rb → create_context/create_context_request_spec.rb} +1 -1
  269. data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +5 -5
  270. data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +9 -5
  271. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +3 -2
  272. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
  273. data/spec/support/bin_helper.rb +9 -0
  274. data.tar.gz.sig +0 -0
  275. metadata +165 -10
  276. metadata.gz.sig +0 -0
  277. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
  278. data/lib/ruby_smb/smb1/create_actions.rb +0 -20
  279. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -135
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e390e96aa471e87e6406cf5b7eae77a4c45f882201f4132d3243eb25506554dc
4
- data.tar.gz: 65620d67c3dbfbf2d3f795856c8da03207a8df32aa439a6f6a0b5d46b385dd31
3
+ metadata.gz: 9a0b34939805bf96ca0b83284b946fc2d96c1e5d7b6e63c67c4d0c40b73d257d
4
+ data.tar.gz: f8c1e25526de8821ec484c820b32734e0cfcefce6e34de2a90b25ce876225e61
5
5
  SHA512:
6
- metadata.gz: 0c252450305e217779de4c1bf6850fa55f12c95d6380795f6940c0451d33c64f1287ab13f6a373d1dcaa1752d399dac04fd0e358a49000335deba27d46ab8fc7
7
- data.tar.gz: 2734dd65b1a84a03fdd914a6877640107caf6bcf561f3a41b769ef947e21276bc8759859ac4a36ba0b2ccfe15778ff06c234ff41dabf9ea4563a74a95ea1b891
6
+ metadata.gz: b669ae3cdc6e7c875c92890ac15608ab45b8d223eb064756d340e046a5dd3b4273971ebdf8419a033ae87fc75af8f08d7e7ce5466186e2e531adada3efaedab4
7
+ data.tar.gz: 052ad0693a7f9ea8b3b767a58ecc710e37f2c9c0ef7c910b8c385b22b9a6eee678596a49de385cb0d0200964e620b171bd667a76b7b393f96a1ebded64e6f5b7
checksums.yaml.gz.sig CHANGED
Binary file
@@ -20,7 +20,7 @@ jobs:
20
20
  - 2.5
21
21
  - 2.6
22
22
  - 2.7
23
- - 3.0
23
+ - 3.0.3
24
24
  test_cmd:
25
25
  - bundle exec rspec
26
26
 
@@ -1,12 +1,31 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  require 'bundler/setup'
4
+ require 'optparse'
4
5
  require 'ruby_smb'
5
6
  require 'ruby_smb/gss/provider/ntlm'
6
7
 
7
8
  # we just need *a* default encoding to handle the strings from the NTLM messages
8
9
  Encoding.default_internal = 'UTF-8' if Encoding.default_internal.nil?
9
10
 
11
+ options = {
12
+ smbv1: true,
13
+ smbv2: true,
14
+ smbv3: true
15
+ }
16
+ OptionParser.new do |opts|
17
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options]"
18
+ opts.on("--[no-]smbv1", "Enabled or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
19
+ options[:smbv1] = smbv1
20
+ end
21
+ opts.on("--[no-]smbv2", "Enabled or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
22
+ options[:smbv2] = smbv2
23
+ end
24
+ opts.on("--[no-]smbv3", "Enabled or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
25
+ options[:smbv3] = smbv3
26
+ end
27
+ end.parse!
28
+
10
29
  def bin_to_hex(s)
11
30
  s.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
12
31
  end
@@ -63,6 +82,15 @@ end
63
82
  server = RubySMB::Server.new(
64
83
  gss_provider: HaxorNTLMProvider.new
65
84
  )
85
+ server.dialects.select! { |dialect| RubySMB::Dialect[dialect].family != RubySMB::Dialect::FAMILY_SMB1 } unless options[:smbv1]
86
+ server.dialects.select! { |dialect| RubySMB::Dialect[dialect].family != RubySMB::Dialect::FAMILY_SMB2 } unless options[:smbv2]
87
+ server.dialects.select! { |dialect| RubySMB::Dialect[dialect].family != RubySMB::Dialect::FAMILY_SMB3 } unless options[:smbv3]
88
+
89
+ if server.dialects.empty?
90
+ puts "at least one version must be enabled"
91
+ exit false
92
+ end
93
+
66
94
  puts "server is running"
67
95
  server.run do
68
96
  puts "received connection"
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # This example script is used for testing DCERPC client and DRSR structures.
4
+ # It will attempt to connect to a host and enumerate user secrets.
5
+ # Example usage: ruby dump_secrets_from_sid.rb 192.168.172.138 msfadmin msfadmin MYDOMAIN S-1-5-21-419547006-9448028-4223375872-500
6
+ # This will try to connect to \\192.168.172.138 with the msfadmin:msfadmin
7
+ # credentials and enumerate secrets of domain user with SID
8
+ # S-1-5-21-419547006-9448028-4223375872-500
9
+
10
+ require 'bundler/setup'
11
+ require 'ruby_smb/dcerpc/client'
12
+
13
+
14
+ address = ARGV[0]
15
+ username = ARGV[1]
16
+ password = ARGV[2]
17
+ domain = ARGV[3]
18
+ sid = ARGV[4]
19
+
20
+ client = RubySMB::Dcerpc::Client.new(
21
+ address,
22
+ RubySMB::Dcerpc::Drsr,
23
+ username: username,
24
+ password: password,
25
+ )
26
+ client.connect
27
+ puts('Binding to DRSR...')
28
+ client.bind(
29
+ auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
30
+ auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
31
+ )
32
+ puts('Bound to DRSR')
33
+ ph_drs = client.drs_bind
34
+ puts "ph_drs: #{ph_drs}"
35
+ puts
36
+
37
+ dc_infos = client.drs_domain_controller_info(ph_drs, domain)
38
+ dc_infos.each do |dc_info|
39
+ dc_info.field_names.each do |field|
40
+ puts "#{field}: #{dc_info.send(field).to_s.encode('utf-8')}"
41
+ end
42
+ puts
43
+ puts
44
+
45
+ crack_names = client.drs_crack_names(ph_drs, rp_names: [sid])
46
+ puts "SID: #{sid}"
47
+ crack_names.each do |crack_name|
48
+ puts "Domain: #{crack_name.p_domain.to_s.encode('utf-8')}"
49
+ puts "Name: #{crack_name.p_name.to_s.encode('utf-8')}"
50
+
51
+ user_record = client.drs_get_nc_changes(
52
+ ph_drs,
53
+ nc_guid: crack_name.p_name.to_s.encode('utf-8'),
54
+ dsa_object_guid: dc_info.ntds_dsa_object_guid,
55
+ )
56
+
57
+ # self.__decryptHash
58
+ dn = user_record.pmsg_out.msg_getchg.p_nc.string_name.to_ary[0..-1].join.encode('utf-8')
59
+ puts "Decrypting hash for user: #{dn}"
60
+
61
+ entinf_struct = user_record.pmsg_out.msg_getchg.p_objects.entinf
62
+ object_sid = rid = entinf_struct.p_name.sid[-4..-1].unpack('<L').first
63
+ lm_hash = Net::NTLM.lm_hash('')
64
+ nt_hash = Net::NTLM.ntlm_hash('')
65
+ disabled = nil
66
+ computer_account = nil
67
+ password_never_expires = nil
68
+ password_not_required = nil
69
+ pwd_last_set = nil
70
+ last_logon = nil
71
+ expires = nil
72
+ lm_history = []
73
+ nt_history = []
74
+ domain_name = ''
75
+ user = 'unknown'
76
+ kerberos_keys = {}
77
+ clear_text_passwords = []
78
+
79
+ entinf_struct.attr_block.p_attr.each do |attr|
80
+ next unless attr.attr_val.val_count > 0
81
+ # begin
82
+ att_id = user_record.pmsg_out.msg_getchg.oid_from_attid(attr.attr_typ)
83
+ lookup_table = RubySMB::Dcerpc::Drsr::ATTRTYP_TO_ATTID
84
+ # rescue XXXX
85
+ # att_id = attr.attr_typ
86
+ # lookup_table = NAME_TO_ATTRTYP
87
+ # end
88
+
89
+ #puts "#{lookup_table.key(att_id) || 'Unknown'}: #{attr.attr_val.p_aval[0].p_val}"
90
+
91
+ attribute_value = attr.attr_val.p_aval[0].p_val.to_ary.map(&:chr).join
92
+ case att_id
93
+ when lookup_table['dBCSPwd']
94
+ encrypted_lm_hash = client.decrypt_attribute_value(attribute_value)
95
+ lm_hash = client.remove_des_layer(encrypted_lm_hash, rid)
96
+ when lookup_table['unicodePwd']
97
+ encrypted_nt_hash = client.decrypt_attribute_value(attribute_value)
98
+ nt_hash = client.remove_des_layer(encrypted_nt_hash, rid)
99
+ when lookup_table['userPrincipalName']
100
+ domain_name = attribute_value.force_encoding('utf-16le').encode('utf-8').split('@').last
101
+ when lookup_table['sAMAccountName']
102
+ user = attribute_value.force_encoding('utf-16le').encode('utf-8')
103
+ when lookup_table['objectSid']
104
+ object_sid = attribute_value
105
+ when lookup_table['userAccountControl']
106
+ user_account_control = attribute_value.unpack('L<')[0]
107
+ disabled = user_account_control & RubySMB::Dcerpc::Samr::UF_ACCOUNTDISABLE != 0
108
+ computer_account = user_account_control & RubySMB::Dcerpc::Samr::UF_NORMAL_ACCOUNT == 0
109
+ password_never_expires = user_account_control & RubySMB::Dcerpc::Samr::UF_DONT_EXPIRE_PASSWD != 0
110
+ password_not_required = user_account_control & RubySMB::Dcerpc::Samr::UF_PASSWD_NOTREQD != 0
111
+ when lookup_table['pwdLastSet']
112
+ pwd_last_set = Time.at(0)
113
+ time_value = attribute_value.unpack('Q<')[0]
114
+ if time_value > 0
115
+ pwd_last_set = RubySMB::Field::FileTime.new(time_value).to_time.utc
116
+ end
117
+ when lookup_table['accountExpires']
118
+ expires = Time.at(0)
119
+ time_value = attribute_value.unpack('Q<')[0]
120
+ if time_value > 0 && time_value != 0x7FFFFFFFFFFFFFFF
121
+ expires = RubySMB::Field::FileTime.new(time_value).to_time.utc
122
+ end
123
+ when lookup_table['lastLogonTimestamp']
124
+ last_logon = Time.at(0)
125
+ time_value = attribute_value.unpack('Q<')[0]
126
+ if time_value > 0
127
+ last_logon = RubySMB::Field::FileTime.new(time_value).to_time.utc
128
+ end
129
+ when lookup_table['lmPwdHistory']
130
+ tmp_lm_history = client.decrypt_attribute_value(attribute_value)
131
+ tmp_lm_history.bytes.each_slice(16) do |block|
132
+ lm_history << client.remove_des_layer(block.map(&:chr).join, rid)
133
+ end
134
+ when lookup_table['ntPwdHistory']
135
+ tmp_nt_history = client.decrypt_attribute_value(attribute_value)
136
+ tmp_nt_history.bytes.each_slice(16) do |block|
137
+ nt_history << client.remove_des_layer(block.map(&:chr).join, rid)
138
+ end
139
+ when lookup_table['supplementalCredentials']
140
+ # self.__decryptSupplementalInfo
141
+ plain_text = client.decrypt_attribute_value(attribute_value)
142
+ user_properties = RubySMB::Dcerpc::Samr::UserProperties.read(plain_text)
143
+ user_properties.user_properties.each do |user_property|
144
+ case user_property.property_name.encode('utf-8')
145
+ when 'Primary:Kerberos-Newer-Keys'
146
+ value = user_property.property_value
147
+ binary_value = value.chars.each_slice(2).map {|a,b| (a+b).hex.chr}.join
148
+ kerb_stored_credential_new = RubySMB::Dcerpc::Samr::KerbStoredCredentialNew.read(binary_value)
149
+ key_values = kerb_stored_credential_new.get_key_values
150
+ kerb_stored_credential_new.credentials.each_with_index do |credential, i|
151
+ kerberos_type = RubySMB::Dcerpc::Samr::KERBEROS_TYPE[credential.key_type]
152
+ if kerberos_type
153
+ kerberos_keys[kerberos_type] = key_values[i].unpack('H*')[0]
154
+ else
155
+ kerberos_keys["0x#{credential.key_type.to_i.to_s(16)}"] = key_values[i].unpack('H*')[0]
156
+ end
157
+ end
158
+ when 'Primary:CLEARTEXT'
159
+ # [MS-SAMR] 3.1.1.8.11.5 Primary:CLEARTEXT Property
160
+ # This credential type is the cleartext password. The value format is the UTF-16 encoded cleartext password.
161
+ begin
162
+ clear_text_passwords << user_property.property_value.to_s.force_encoding('utf-16le').encode('utf-8')
163
+ rescue EncodingError
164
+ # This could be because we're decoding a machine password. Printing it hex
165
+ # Keep clear_text_passwords with a ASCII-8BIT encoding
166
+ clear_text_passwords << user_property.property_value.to_s
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+
173
+ user = "#{domain_name}\\#{user}" unless domain_name.empty?
174
+
175
+ puts "#{user}:#{rid}:#{lm_hash.unpack('H*')[0]}:#{nt_hash.unpack('H*')[0]}:::"
176
+ puts "Object SID: 0x#{object_sid.unpack('H*')[0]}"
177
+ puts "Password last set: #{pwd_last_set && pwd_last_set > Time.at(0) ? pwd_last_set : 'never'}"
178
+ puts "Last logon: #{last_logon && last_logon > Time.at(0) ? last_logon : 'never'}"
179
+ puts "Account disabled: #{disabled.nil? ? 'N/A' : disabled}"
180
+ puts "Computer account: #{computer_account.nil? ? 'N/A' : computer_account}"
181
+ puts "Password never expires: #{password_never_expires.nil? ? 'N/A' : password_never_expires}"
182
+ puts "Password not required: #{password_not_required.nil? ? 'N/A' : password_not_required}"
183
+ puts "Expired: #{!disabled && expires && expires > Time.at(0) && expires < Time.now}"
184
+ if nt_history.size > 1 and lm_history.size > 1
185
+ puts "Password history:"
186
+ nt_history[1..-1].zip(lm_history[1..-1]).each_with_index do |history, i|
187
+ nt_h, lm_h = history
188
+ empty_lm_h = Net::NTLM.lm_hash('')
189
+ puts " #{user}_history#{i}:#{rid}:#{empty_lm_h.unpack('H*')[0]}:#{nt_h.to_s.unpack('H*')[0]}::: (if LMHashes are not stored)"
190
+ puts " #{user}_history#{i}:#{rid}:#{lm_h.to_s.unpack('H*')[0]}:#{nt_h.to_s.unpack('H*')[0]}::: (if LMHashes are stored)"
191
+ end
192
+ end
193
+ puts "Kerberos keys:"
194
+ kerberos_keys.each do |key_type, key_value|
195
+ puts " #{user}:#{key_type}:#{key_value}"
196
+ end
197
+ puts "Clear passwords:"
198
+ clear_text_passwords.each do |passwd|
199
+ puts " #{user}:CLEARTEXT:#{passwd}"
200
+ end
201
+ end
202
+ end
203
+
204
+ client.drs_unbind(ph_drs)
205
+ client.close
206
+
207
+ puts 'Done'
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # This example script is used for testing DCERPC SAMR requests.
4
+ # It will attempt to connect to a server object and enumerate domain users.
5
+ # Example usage: ruby enum_domain_users.rb 192.168.172.138 msfadmin msfadmin MyDomain
6
+
7
+ require 'bundler/setup'
8
+ require 'ruby_smb'
9
+
10
+ address = ARGV[0]
11
+ username = ARGV[1]
12
+ password = ARGV[2]
13
+ domain = ARGV[3]
14
+ smb_versions = ARGV[4]&.split(',') || ['1','2','3']
15
+
16
+ sock = TCPSocket.new address, 445
17
+ dispatcher = RubySMB::Dispatcher::Socket.new(sock, read_timeout: 60)
18
+
19
+ client = RubySMB::Client.new(dispatcher, smb1: smb_versions.include?('1'), smb2: smb_versions.include?('2'), smb3: smb_versions.include?('3'), username: username, password: password)
20
+ protocol = client.negotiate
21
+ status = client.authenticate
22
+
23
+ puts "#{protocol} : #{status}"
24
+
25
+ tree = client.tree_connect("\\\\#{address}\\IPC$")
26
+ samr = tree.open_file(filename: 'samr', write: true, read: true)
27
+
28
+ puts('Binding to \\samr...')
29
+ samr.bind(endpoint: RubySMB::Dcerpc::Samr)
30
+ puts('Bound to \\samr')
31
+
32
+ puts('[+] SAMR Connect')
33
+ server_handle = samr.samr_connect
34
+
35
+ domain_sid = samr.samr_lookup_domain(server_handle: server_handle, name: domain)
36
+ domain_handle = samr.samr_open_domain(server_handle: server_handle, domain_id: domain_sid)
37
+
38
+ builtin_domain_sid = samr.samr_lookup_domain(server_handle: server_handle, name: 'Builtin')
39
+ builtin_domain_handle = samr.samr_open_domain(server_handle: server_handle, domain_id: builtin_domain_sid)
40
+
41
+ users = samr.samr_enumerate_users_in_domain(domain_handle: domain_handle)
42
+
43
+ puts 'RID | SID | Name | Domain Groups | Domain Alias Groups | Builtin Alias Groups'
44
+ puts '--------------------------------------------------------------------------------------------------------------------------------'
45
+ users.each do |rid, name|
46
+ sid = samr.samr_rid_to_sid(object_handle: domain_handle, rid: rid)
47
+ domain_sid = sid.to_s.split('-')[0..-2].join('-')
48
+
49
+ user_handle = samr.samr_open_user(domain_handle: domain_handle, user_id: rid)
50
+ groups = samr.samr_get_group_for_user(user_handle: user_handle)
51
+ groups = groups.map { |group| RubySMB::Dcerpc::Samr::RpcSid.new("#{domain_sid}-#{group.relative_id.to_i}") }
52
+
53
+ alias_groups = samr.samr_get_alias_membership(domain_handle: domain_handle, sids: groups + [sid])
54
+ alias_groups = alias_groups.map { |group| RubySMB::Dcerpc::Samr::RpcSid.new("#{domain_sid}-#{group}") }
55
+
56
+ builtin_alias_groups = samr.samr_get_alias_membership(domain_handle: builtin_domain_handle, sids: groups + [sid])
57
+ builtin_alias_groups = builtin_alias_groups.map { |group| RubySMB::Dcerpc::Samr::RpcSid.new("#{domain_sid}-#{group}") }
58
+
59
+ #TODO: implement [LSAT] LsarLookupSids2 call to get the name of the "Unknown SID"'s
60
+
61
+ output = "#{"%-5s" % rid} | #{"%-43s" % sid} | #{name.encode('UTF-8')}"
62
+ output << " | #{groups.empty? ? 'N/A' : groups.map(&:name).join(', ')}"
63
+ output << " | #{alias_groups.empty? ? 'N/A' : alias_groups.map(&:name).join(', ')}"
64
+ output << " | #{builtin_alias_groups.empty? ? 'N/A' : builtin_alias_groups.map(&:name).join(', ')}"
65
+ puts output
66
+
67
+ samr.close_handle(user_handle)
68
+ end
69
+
70
+ samr.close_handle(domain_handle)
71
+ samr.close_handle(builtin_domain_handle)
72
+ samr.close_handle(server_handle)
73
+
74
+ client.disconnect!
75
+
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'optparse'
5
+ require 'ruby_smb'
6
+ require 'ruby_smb/gss/provider/ntlm'
7
+
8
+ # we just need *a* default encoding to handle the strings from the NTLM messages
9
+ Encoding.default_internal = 'UTF-8' if Encoding.default_internal.nil?
10
+
11
+ options = {
12
+ allow_anonymous: true,
13
+ domain: nil,
14
+ username: 'RubySMB',
15
+ password: 'password',
16
+ share_name: 'home',
17
+ share_path: '.',
18
+ smbv1: true,
19
+ smbv2: true,
20
+ smbv3: true
21
+ }
22
+ OptionParser.new do |opts|
23
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options]"
24
+ opts.on("--path PATH", "The path to share (default: #{options[:share_path]})") do |path|
25
+ options[:share_path] = path
26
+ end
27
+ opts.on("--share SHARE", "The share name (default: #{options[:share_name]})") do |share|
28
+ options[:share_name] = share
29
+ end
30
+ opts.on("--[no-]anonymous", "Allow anonymous access (default: #{options[:allow_anonymous]})") do |allow_anonymous|
31
+ options[:allow_anonymous] = allow_anonymous
32
+ end
33
+ opts.on("--[no-]smbv1", "Enabled or disable SMBv1 (default: #{options[:smbv1] ? 'Enabled' : 'Disabled'})") do |smbv1|
34
+ options[:smbv1] = smbv1
35
+ end
36
+ opts.on("--[no-]smbv2", "Enabled or disable SMBv2 (default: #{options[:smbv2] ? 'Enabled' : 'Disabled'})") do |smbv2|
37
+ options[:smbv2] = smbv2
38
+ end
39
+ opts.on("--[no-]smbv3", "Enabled or disable SMBv3 (default: #{options[:smbv3] ? 'Enabled' : 'Disabled'})") do |smbv3|
40
+ options[:smbv3] = smbv3
41
+ end
42
+ opts.on("--username USERNAME", "The account's username (default: #{options[:username]})") do |username|
43
+ if username.include?('\\')
44
+ options[:domain], options[:username] = username.split('\\', 2)
45
+ else
46
+ options[:username] = username
47
+ end
48
+ end
49
+ opts.on("--password PASSWORD", "The account's password (default: #{options[:password]})") do |password|
50
+ options[:password] = password
51
+ end
52
+ end.parse!
53
+
54
+ ntlm_provider = RubySMB::Gss::Provider::NTLM.new(allow_anonymous: options[:allow_anonymous])
55
+ ntlm_provider.put_account(options[:username], options[:password], domain: options[:domain]) # password can also be an NTLM hash
56
+
57
+ server = RubySMB::Server.new(
58
+ gss_provider: ntlm_provider,
59
+ logger: :stdout
60
+ )
61
+ server.dialects.select! { |dialect| RubySMB::Dialect[dialect].family != RubySMB::Dialect::FAMILY_SMB1 } unless options[:smbv1]
62
+ server.dialects.select! { |dialect| RubySMB::Dialect[dialect].family != RubySMB::Dialect::FAMILY_SMB2 } unless options[:smbv2]
63
+ server.dialects.select! { |dialect| RubySMB::Dialect[dialect].family != RubySMB::Dialect::FAMILY_SMB3 } unless options[:smbv3]
64
+
65
+ if server.dialects.empty?
66
+ puts "at least one version must be enabled"
67
+ exit false
68
+ end
69
+
70
+ server.add_share(RubySMB::Server::Share::Provider::Disk.new(options[:share_name], options[:share_path]))
71
+ puts "server is running"
72
+ server.run do
73
+ puts "received connection"
74
+ true
75
+ end
76
+
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # This example script is used for testing DCERPC WKST requests.
4
+ # It will attempt to retrieve configuration information of a remote computer/server.
5
+ # Example usage: ruby enum_domain_users.rb 192.168.172.138 msfadmin msfadmin MyDomain
6
+
7
+ require 'bundler/setup'
8
+ require 'ruby_smb'
9
+
10
+ address = ARGV[0]
11
+ username = ARGV[1]
12
+ password = ARGV[2]
13
+ smb_versions = ARGV[3]&.split(',') || ['1','2','3']
14
+
15
+ sock = TCPSocket.new address, 445
16
+ dispatcher = RubySMB::Dispatcher::Socket.new(sock, read_timeout: 60)
17
+
18
+ client = RubySMB::Client.new(dispatcher, smb1: smb_versions.include?('1'), smb2: smb_versions.include?('2'), smb3: smb_versions.include?('3'), username: username, password: password)
19
+ protocol = client.negotiate
20
+ status = client.authenticate
21
+
22
+ puts "#{protocol} : #{status}"
23
+
24
+ tree = client.tree_connect("\\\\#{address}\\IPC$")
25
+ wkssvc = tree.open_file(filename: 'wkssvc', write: true, read: true)
26
+
27
+ puts('Binding to \\wkssvc...')
28
+ wkssvc.bind(endpoint: RubySMB::Dcerpc::Wkssvc)
29
+ puts('Bound to \\wkssvc')
30
+
31
+ puts('[+] WKSSVC Connect')
32
+
33
+ info = wkssvc.netr_wksta_get_info
34
+ platform = RubySMB::Dcerpc::Wkssvc::PLATFORM_ID[info.wki100_platform_id]
35
+ puts "Platform: #{platform || 'Unknown'}"
36
+ puts "Computer Name: #{info.wki100_computername.encode('utf-8')}"
37
+ puts "LAN Group: #{info.wki100_langroup.encode('utf-8')}"
38
+ puts "OS Version: #{info.wki100_ver_major}.#{info.wki100_ver_minor}"
39
+
40
+ client.disconnect!
41
+
42
+
@@ -36,25 +36,63 @@ scm_handle = svcctl.open_sc_manager_w(address)
36
36
  svc_handle = svcctl.open_service_w(scm_handle, service)
37
37
  svc_status = svcctl.query_service_status(svc_handle)
38
38
 
39
+ puts
39
40
  case svc_status.dw_current_state
40
41
  when RubySMB::Dcerpc::Svcctl::SERVICE_RUNNING
41
42
  puts("Service #{service} is running")
42
43
  when RubySMB::Dcerpc::Svcctl::SERVICE_STOPPED
43
44
  puts("Service #{service} is in stopped state")
44
45
  end
46
+ puts
45
47
 
46
48
  svc_config = svcctl.query_service_config(svc_handle)
49
+
50
+ service_type = 'Service type: '
51
+ case svc_config.dw_service_type
52
+ when RubySMB::Dcerpc::Svcctl::SERVICE_KERNEL_DRIVER
53
+ service_type << 'Driver service'
54
+ when RubySMB::Dcerpc::Svcctl::SERVICE_FILE_SYSTEM_DRIVER
55
+ service_type << 'File system driver service'
56
+ when RubySMB::Dcerpc::Svcctl::SERVICE_WIN32_OWN_PROCESS
57
+ service_type << 'Service that runs in its own process'
58
+ when RubySMB::Dcerpc::Svcctl::SERVICE_WIN32_SHARE_PROCESS
59
+ service_type << 'Service that shares a process with other services'
60
+ end
61
+
62
+ start_type = 'Service start type: '
47
63
  case svc_config.dw_start_type
48
64
  when RubySMB::Dcerpc::Svcctl::SERVICE_DISABLED
49
- puts("Service #{service} is disabled")
65
+ start_type << 'Service is disabled'
50
66
  when RubySMB::Dcerpc::Svcctl::SERVICE_BOOT_START, RubySMB::Dcerpc::Svcctl::SERVICE_SYSTEM_START
51
- puts("Service #{service} starts when the system boots up (driver)")
67
+ start_type << 'Service starts when the system boots up (driver)'
52
68
  when RubySMB::Dcerpc::Svcctl::SERVICE_AUTO_START
53
- puts("Service #{service} starts automatically during system startup")
69
+ start_type << 'Service starts automatically during system startup'
54
70
  when RubySMB::Dcerpc::Svcctl::SERVICE_DEMAND_START
55
- puts("Service #{service} starts manually")
71
+ start_type << 'Service starts manually'
56
72
  end
57
73
 
74
+ error_control = 'Error control: '
75
+ case svc_config.dw_error_control
76
+ when RubySMB::Dcerpc::Svcctl::SERVICE_ERROR_IGNORE
77
+ error_control << 'SERVICE_ERROR_IGNORE'
78
+ when RubySMB::Dcerpc::Svcctl::SERVICE_ERROR_NORMAL
79
+ error_control << 'SERVICE_ERROR_NORMAL'
80
+ when RubySMB::Dcerpc::Svcctl::SERVICE_ERROR_SEVERE
81
+ error_control << 'SERVICE_ERROR_SEVERE'
82
+ when RubySMB::Dcerpc::Svcctl::SERVICE_ERROR_CRITICAL
83
+ error_control << 'SERVICE_ERROR_CRITICAL'
84
+ end
85
+
86
+ puts service_type
87
+ puts start_type
88
+ puts error_control
89
+ puts "Binary path: #{svc_config.lp_binary_path_name.to_s.encode('utf-8')}"
90
+ puts "Load ordering service group: #{svc_config.lp_load_order_group.to_s.encode('utf-8')}"
91
+ puts "Service group tag ID: #{svc_config.dw_tag_id.to_s.encode('utf-8')}"
92
+ puts "Dependencies: #{svc_config.lp_dependencies.to_s.encode('utf-8')}"
93
+ puts "Service start name: #{svc_config.lp_service_start_name.to_s.encode('utf-8')}"
94
+
95
+
58
96
  if svcctl
59
97
  svcctl.close_service_handle(svc_handle) if svc_handle
60
98
  svcctl.close_service_handle(scm_handle) if scm_handle
@@ -279,7 +279,7 @@ module RubySMB
279
279
  # @param smb2 [Boolean] whether or not to enable SMB2 support
280
280
  # @param smb3 [Boolean] whether or not to enable SMB3 support
281
281
  def initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.',
282
- local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags: default_flags)
282
+ local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
283
283
  raise ArgumentError, 'No Dispatcher provided' unless dispatcher.is_a? RubySMB::Dispatcher::Base
284
284
  if smb1 == false && smb2 == false && smb3 == false
285
285
  raise ArgumentError, 'You must enable at least one Protocol'
@@ -366,7 +366,7 @@ module RubySMB
366
366
  # the credentials supplied during initialization, but can take a new set of credentials if needed.
367
367
  def login(username: self.username, password: self.password,
368
368
  domain: self.domain, local_workstation: self.local_workstation,
369
- ntlm_flags: default_flags)
369
+ ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
370
370
  negotiate
371
371
  session_setup(username, password, domain,
372
372
  local_workstation: local_workstation,
@@ -374,7 +374,7 @@ module RubySMB
374
374
  end
375
375
 
376
376
  def session_setup(user, pass, domain, do_recv=true,
377
- local_workstation: self.local_workstation, ntlm_flags: default_flags)
377
+ local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
378
378
  @domain = domain
379
379
  @local_workstation = local_workstation
380
380
  @password = pass.encode('utf-8') || ''.encode('utf-8')
@@ -648,16 +648,5 @@ module RubySMB
648
648
  )
649
649
  end
650
650
 
651
- private
652
-
653
- def default_flags
654
- negotiate_version_flag = 0x02000000
655
- flags = Net::NTLM::Client::DEFAULT_FLAGS |
656
- RubySMB::NTLM::NEGOTIATE_FLAGS[:TARGET_INFO] |
657
- negotiate_version_flag ^
658
- RubySMB::NTLM::NEGOTIATE_FLAGS[:OEM]
659
-
660
- flags
661
- end
662
651
  end
663
652
  end
@@ -0,0 +1,21 @@
1
+ module RubySMB
2
+ # This module holds the Create Actions used in NT_TRANSACT_CREATE,
3
+ # SMB_COM_NT_CREATE_ANDX, and SMB2_CREATE responses. The definitions for these
4
+ # values can be found at
5
+ # [2.2.7.1.2 Response](https://msdn.microsoft.com/en-us/library/ee441961.aspx)
6
+ # and
7
+ # [2.2.14 SMB2 CREATE Response](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/d166aa9e-0b53-410e-b35e-3933d8131927)
8
+ module CreateActions
9
+ # An existing file was deleted and a new file was created in its place.
10
+ FILE_SUPERSEDED = 0x00000000
11
+
12
+ # An existing file was opened.
13
+ FILE_OPENED = 0x00000001
14
+
15
+ # A new file was created.
16
+ FILE_CREATED = 0x00000002
17
+
18
+ # An existing file was overwritten.
19
+ FILE_OVERWRITTEN = 0x00000003
20
+ end
21
+ end