ruby_smb 2.0.11 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/workflows/verify.yml +5 -16
- data/examples/auth_capture.rb +28 -0
- data/examples/dump_secrets_from_sid.rb +207 -0
- data/examples/enum_domain_users.rb +75 -0
- data/examples/file_server.rb +76 -0
- data/examples/get_computer_info.rb +42 -0
- data/examples/query_service_status.rb +42 -4
- data/lib/ruby_smb/client.rb +3 -14
- data/lib/ruby_smb/create_actions.rb +21 -0
- data/lib/ruby_smb/dcerpc/bind.rb +28 -20
- data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
- data/lib/ruby_smb/dcerpc/client.rb +542 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
- data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
- data/lib/ruby_smb/dcerpc/epm.rb +75 -0
- data/lib/ruby_smb/dcerpc/error.rb +17 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
- data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
- data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
- data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
- data/lib/ruby_smb/dcerpc/request.rb +79 -32
- data/lib/ruby_smb/dcerpc/response.rb +45 -10
- data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
- data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +11 -11
- data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
- data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
- data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
- data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
- data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr.rb +613 -0
- data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
- data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
- data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +13 -25
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
- data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +2 -13
- data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
- data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
- data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
- data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
- data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
- data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +5 -6
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
- data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
- data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +0 -9
- data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
- data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
- data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
- data/lib/ruby_smb/dcerpc.rb +41 -11
- data/lib/ruby_smb/field/file_time.rb +1 -1
- data/lib/ruby_smb/field/nt_status.rb +20 -1
- data/lib/ruby_smb/field/string16.rb +5 -1
- data/lib/ruby_smb/fscc/file_information/file_ea_information.rb +14 -0
- data/lib/ruby_smb/fscc/file_information/file_network_open_information.rb +22 -0
- data/lib/ruby_smb/fscc/file_information/file_stream_information.rb +16 -0
- data/lib/ruby_smb/fscc/file_information.rb +29 -0
- data/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information.rb +46 -0
- data/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information.rb +19 -0
- data/lib/ruby_smb/fscc/file_system_information.rb +22 -0
- data/lib/ruby_smb/fscc.rb +1 -0
- data/lib/ruby_smb/generic_packet.rb +6 -0
- data/lib/ruby_smb/gss/provider/authenticator.rb +4 -0
- data/lib/ruby_smb/gss/provider/ntlm.rb +13 -3
- data/lib/ruby_smb/ntlm.rb +18 -2
- data/lib/ruby_smb/server/server_client/negotiation.rb +1 -2
- data/lib/ruby_smb/server/server_client/session_setup.rb +44 -33
- data/lib/ruby_smb/server/server_client/share_io.rb +28 -0
- data/lib/ruby_smb/server/server_client/tree_connect.rb +60 -0
- data/lib/ruby_smb/server/server_client.rb +214 -25
- data/lib/ruby_smb/server/session.rb +71 -0
- data/lib/ruby_smb/server/share/provider/disk.rb +437 -0
- data/lib/ruby_smb/server/share/provider/pipe.rb +27 -0
- data/lib/ruby_smb/server/share/provider/processor.rb +76 -0
- data/lib/ruby_smb/server/share/provider.rb +38 -0
- data/lib/ruby_smb/server/share.rb +11 -0
- data/lib/ruby_smb/server.rb +35 -3
- data/lib/ruby_smb/signing.rb +37 -11
- data/lib/ruby_smb/smb1/commands.rb +4 -0
- data/lib/ruby_smb/smb1/pipe.rb +4 -0
- data/lib/ruby_smb/smb1.rb +0 -1
- data/lib/ruby_smb/smb2/bit_field/smb2_header_flags.rb +2 -1
- data/lib/ruby_smb/smb2/commands.rb +4 -0
- data/lib/ruby_smb/smb2/create_context/request.rb +64 -0
- data/lib/ruby_smb/smb2/create_context/response.rb +62 -0
- data/lib/ruby_smb/smb2/create_context.rb +74 -22
- data/lib/ruby_smb/smb2/packet/create_request.rb +44 -11
- data/lib/ruby_smb/smb2/packet/create_response.rb +17 -3
- data/lib/ruby_smb/smb2/packet/query_directory_request.rb +1 -1
- data/lib/ruby_smb/smb2/packet/query_directory_response.rb +2 -2
- data/lib/ruby_smb/smb2/packet/query_info_request.rb +43 -0
- data/lib/ruby_smb/smb2/packet/query_info_response.rb +23 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +1 -1
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -0
- data/lib/ruby_smb/smb2/packet.rb +2 -0
- data/lib/ruby_smb/smb2/pipe.rb +4 -0
- data/lib/ruby_smb/smb2.rb +11 -0
- data/lib/ruby_smb/smb_error.rb +110 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/lib/ruby_smb.rb +2 -0
- data/ruby_smb.gemspec +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +1 -2
- data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
- data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
- data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
- data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3792 -1373
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
- data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
- data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
- data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
- data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +29 -28
- data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
- data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
- data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
- data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
- data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +56 -79
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
- data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +4 -41
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -25
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +10 -22
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
- data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
- data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
- data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
- data/spec/lib/ruby_smb/field/nt_status_spec.rb +6 -2
- data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +4 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +1 -1
- data/spec/lib/ruby_smb/server/server_client_spec.rb +36 -53
- data/spec/lib/ruby_smb/server/session_spec.rb +38 -0
- data/spec/lib/ruby_smb/server/share/provider/disk_spec.rb +61 -0
- data/spec/lib/ruby_smb/server/share/provider/pipe_spec.rb +31 -0
- data/spec/lib/ruby_smb/server/share/provider_spec.rb +13 -0
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
- data/spec/lib/ruby_smb/smb2/bit_field/header_flags_spec.rb +8 -2
- data/spec/lib/ruby_smb/smb2/{create_context_spec.rb → create_context/create_context_request_spec.rb} +1 -1
- data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +5 -5
- data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +9 -5
- data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +3 -2
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
- data/spec/support/bin_helper.rb +9 -0
- data.tar.gz.sig +2 -3
- metadata +129 -10
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
- data/lib/ruby_smb/smb1/create_actions.rb +0 -20
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 720a034c2e6c19fbb116a1d7b44e024a54d4f3006c393c1b1ad2b131f6d515b4
|
|
4
|
+
data.tar.gz: 4b36bff99e47dd2449d593a03f173f8d0f2da8bf5bab57c6d8f7a1d808cfaf07
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: be75feaa8b061d5d1c49dedf68ef6e4c5476ecd85bdb2d5a10a277027d00acd0e3358e1ee60dfdf376d32d5cb1af8ea4c48fde9a8ce4b7f60f9230cd2bf55409
|
|
7
|
+
data.tar.gz: 64df4daad099138c0e6f57abcb7b1c7894c15df4c17c22dbcf90babf99455edb5a4c99d88526d1e507acf92cd12847b7a9a1ae000ac13aea90140c44c288ff46
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -10,7 +10,7 @@ on:
|
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
12
|
test:
|
|
13
|
-
runs-on: ubuntu-
|
|
13
|
+
runs-on: ubuntu-18.04
|
|
14
14
|
timeout-minutes: 40
|
|
15
15
|
|
|
16
16
|
strategy:
|
|
@@ -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
|
|
|
@@ -32,23 +32,12 @@ jobs:
|
|
|
32
32
|
- name: Checkout code
|
|
33
33
|
uses: actions/checkout@v2
|
|
34
34
|
|
|
35
|
-
-
|
|
35
|
+
- name: Setup Ruby
|
|
36
|
+
uses: ruby/setup-ruby@v1
|
|
36
37
|
with:
|
|
37
38
|
ruby-version: ${{ matrix.ruby }}
|
|
39
|
+
bundler-cache: true
|
|
38
40
|
|
|
39
|
-
- name: Setup bundler
|
|
40
|
-
run: |
|
|
41
|
-
gem install bundler
|
|
42
|
-
- uses: actions/cache@v2
|
|
43
|
-
with:
|
|
44
|
-
path: vendor/bundle
|
|
45
|
-
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
|
46
|
-
restore-keys: |
|
|
47
|
-
${{ runner.os }}-gems-
|
|
48
|
-
- name: Bundle install
|
|
49
|
-
run: |
|
|
50
|
-
bundle config path vendor/bundle
|
|
51
|
-
bundle install --jobs 4 --retry 3
|
|
52
41
|
- name: ${{ matrix.test_cmd }}
|
|
53
42
|
run: |
|
|
54
43
|
echo "${CMD}"
|
data/examples/auth_capture.rb
CHANGED
|
@@ -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
|
-
|
|
65
|
+
start_type << 'Service is disabled'
|
|
50
66
|
when RubySMB::Dcerpc::Svcctl::SERVICE_BOOT_START, RubySMB::Dcerpc::Svcctl::SERVICE_SYSTEM_START
|
|
51
|
-
|
|
67
|
+
start_type << 'Service starts when the system boots up (driver)'
|
|
52
68
|
when RubySMB::Dcerpc::Svcctl::SERVICE_AUTO_START
|
|
53
|
-
|
|
69
|
+
start_type << 'Service starts automatically during system startup'
|
|
54
70
|
when RubySMB::Dcerpc::Svcctl::SERVICE_DEMAND_START
|
|
55
|
-
|
|
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
|
data/lib/ruby_smb/client.rb
CHANGED
|
@@ -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:
|
|
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:
|
|
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:
|
|
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
|