ruby_smb 2.0.2 → 3.0.0
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 +46 -0
- data/README.md +0 -1
- data/examples/anonymous_auth.rb +3 -3
- data/examples/append_file.rb +10 -8
- data/examples/auth_capture.rb +71 -0
- data/examples/authenticate.rb +9 -5
- data/examples/delete_file.rb +8 -6
- data/examples/dump_secrets_from_sid.rb +207 -0
- data/examples/enum_domain_users.rb +75 -0
- data/examples/enum_registry_key.rb +5 -4
- data/examples/enum_registry_values.rb +5 -4
- data/examples/get_computer_info.rb +42 -0
- data/examples/list_directory.rb +8 -6
- data/examples/negotiate_with_netbios_service.rb +9 -5
- data/examples/net_share_enum_all.rb +6 -4
- data/examples/pipes.rb +11 -12
- data/examples/query_service_status.rb +102 -0
- data/examples/read_file.rb +8 -6
- data/examples/read_registry_key_value.rb +6 -5
- data/examples/rename_file.rb +9 -7
- data/examples/tree_connect.rb +7 -5
- data/examples/write_file.rb +9 -7
- data/lib/ruby_smb/client/authentication.rb +5 -10
- data/lib/ruby_smb/client/echo.rb +2 -4
- data/lib/ruby_smb/client/negotiation.rb +13 -16
- data/lib/ruby_smb/client/tree_connect.rb +2 -4
- data/lib/ruby_smb/client/utils.rb +16 -10
- data/lib/ruby_smb/client/winreg.rb +1 -1
- data/lib/ruby_smb/client.rb +102 -75
- data/lib/ruby_smb/compression/lznt1.rb +164 -0
- data/lib/ruby_smb/compression.rb +7 -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 +20 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +1204 -80
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/netlogon.rb +102 -0
- 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 +85 -19
- 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 +34 -0
- 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 +36 -0
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +45 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl.rb +477 -0
- 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 +62 -0
- data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +2 -19
- 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 +6 -7
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -13
- 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 +28 -0
- data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/winreg.rb +99 -22
- 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 +45 -11
- data/lib/ruby_smb/dialect.rb +45 -0
- data/lib/ruby_smb/dispatcher/base.rb +1 -1
- data/lib/ruby_smb/dispatcher/socket.rb +2 -2
- data/lib/ruby_smb/error.rb +21 -5
- data/lib/ruby_smb/field/file_time.rb +1 -1
- data/lib/ruby_smb/field/string16.rb +5 -1
- data/lib/ruby_smb/field/stringz16.rb +17 -1
- data/lib/ruby_smb/generic_packet.rb +11 -1
- data/lib/ruby_smb/gss/provider/authenticator.rb +42 -0
- data/lib/ruby_smb/gss/provider/ntlm.rb +303 -0
- data/lib/ruby_smb/gss/provider.rb +35 -0
- data/lib/ruby_smb/gss.rb +56 -63
- data/lib/ruby_smb/nbss/session_header.rb +4 -4
- data/lib/ruby_smb/ntlm.rb +61 -0
- data/lib/ruby_smb/server/server_client/negotiation.rb +156 -0
- data/lib/ruby_smb/server/server_client/session_setup.rb +82 -0
- data/lib/ruby_smb/server/server_client.rb +162 -0
- data/lib/ruby_smb/server.rb +54 -0
- data/lib/ruby_smb/signing.rb +59 -0
- data/lib/ruby_smb/smb1/file.rb +10 -25
- data/lib/ruby_smb/smb1/packet/negotiate_response.rb +11 -11
- data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +1 -1
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +1 -2
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +1 -13
- data/lib/ruby_smb/smb1/pipe.rb +12 -6
- data/lib/ruby_smb/smb1/tree.rb +13 -9
- data/lib/ruby_smb/smb2/file.rb +33 -33
- data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
- data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +4 -0
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +9 -0
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +0 -1
- data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -2
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +1 -1
- data/lib/ruby_smb/smb2/pipe.rb +13 -6
- data/lib/ruby_smb/smb2/tree.rb +21 -11
- data/lib/ruby_smb/smb2.rb +3 -1
- data/lib/ruby_smb/version.rb +1 -1
- data/lib/ruby_smb.rb +5 -3
- data/spec/lib/ruby_smb/client_spec.rb +199 -86
- data/spec/lib/ruby_smb/compression/lznt1_spec.rb +32 -0
- 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 +3977 -239
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +69 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response_spec.rb +53 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +69 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response_spec.rb +37 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +45 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +37 -0
- 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 +162 -0
- 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 +168 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +68 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +53 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +76 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +47 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +508 -0
- 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 +73 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -56
- 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 -20
- 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_request_spec.rb +0 -4
- 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 +18 -42
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +45 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +219 -62
- 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/dispatcher/socket_spec.rb +10 -10
- data/spec/lib/ruby_smb/error_spec.rb +34 -5
- data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
- data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
- data/spec/lib/ruby_smb/generic_packet_spec.rb +7 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/account_spec.rb +32 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +101 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +32 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm_spec.rb +113 -0
- data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
- data/spec/lib/ruby_smb/server/server_client_spec.rb +156 -0
- data/spec/lib/ruby_smb/server_spec.rb +32 -0
- data/spec/lib/ruby_smb/smb1/file_spec.rb +2 -4
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +0 -5
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +0 -6
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +20 -14
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +22 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +61 -9
- data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +20 -14
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +58 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/bin_helper.rb +9 -0
- data.tar.gz.sig +0 -0
- metadata +229 -23
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -6
- data/lib/ruby_smb/client/signing.rb +0 -64
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -35
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -98
|
@@ -39,7 +39,6 @@ module RubySMB
|
|
|
39
39
|
|
|
40
40
|
# The {RubySMB::SMB1::DataBlock} specific to this packet type.
|
|
41
41
|
class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
|
42
|
-
uint8 :name, label: 'Name', initial_value: 0x00
|
|
43
42
|
string :pad1, length: -> { pad1_length }
|
|
44
43
|
trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
|
45
44
|
string :pad2, length: -> { pad2_length }
|
|
@@ -44,8 +44,7 @@ module RubySMB
|
|
|
44
44
|
class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
|
45
45
|
string :pad1, length: -> { pad1_length }
|
|
46
46
|
trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
|
47
|
-
|
|
48
|
-
string :trans2_data, label: 'Trans2 Data', length: 0
|
|
47
|
+
# trans2_data: No data is sent by this message.
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
smb_header :smb_header
|
|
@@ -23,23 +23,11 @@ module RubySMB
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# The Trans2 Data Block for this particular Subcommand
|
|
27
|
-
class Trans2Data < BinData::Record
|
|
28
|
-
|
|
29
|
-
# Returns the length of the Trans2Data struct
|
|
30
|
-
# in number of bytes
|
|
31
|
-
def length
|
|
32
|
-
do_num_bytes
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
26
|
# The {RubySMB::SMB1::DataBlock} specific to this packet type.
|
|
37
27
|
class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
|
38
|
-
uint8 :name, label: 'Name', initial_value: 0x00
|
|
39
28
|
string :pad1, length: -> { pad1_length }
|
|
40
29
|
trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
|
41
|
-
|
|
42
|
-
trans2_data :trans2_data, label: 'Trans2 Data'
|
|
30
|
+
# trans2_data: No data is sent by this message.
|
|
43
31
|
end
|
|
44
32
|
|
|
45
33
|
smb_header :smb_header
|
data/lib/ruby_smb/smb1/pipe.rb
CHANGED
|
@@ -16,10 +16,18 @@ module RubySMB
|
|
|
16
16
|
def initialize(tree:, response:, name:)
|
|
17
17
|
raise ArgumentError, 'No Name Provided' if name.nil?
|
|
18
18
|
case name
|
|
19
|
-
when '
|
|
19
|
+
when 'netlogon', '\\netlogon'
|
|
20
|
+
extend RubySMB::Dcerpc::Netlogon
|
|
21
|
+
when 'srvsvc', '\\srvsvc'
|
|
20
22
|
extend RubySMB::Dcerpc::Srvsvc
|
|
21
|
-
when '
|
|
23
|
+
when 'svcctl', '\\svcctl'
|
|
24
|
+
extend RubySMB::Dcerpc::Svcctl
|
|
25
|
+
when 'winreg', '\\winreg'
|
|
22
26
|
extend RubySMB::Dcerpc::Winreg
|
|
27
|
+
when 'samr', '\\samr'
|
|
28
|
+
extend RubySMB::Dcerpc::Samr
|
|
29
|
+
when 'wkssvc', '\\wkssvc'
|
|
30
|
+
extend RubySMB::Dcerpc::Wkssvc
|
|
23
31
|
end
|
|
24
32
|
super(tree: tree, response: response, name: name)
|
|
25
33
|
end
|
|
@@ -41,8 +49,7 @@ module RubySMB
|
|
|
41
49
|
raise RubySMB::Error::InvalidPacket.new(
|
|
42
50
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
|
43
51
|
expected_cmd: RubySMB::SMB1::Packet::Trans::PeekNmpipeRequest::COMMAND,
|
|
44
|
-
|
|
45
|
-
received_cmd: response.smb_header.command
|
|
52
|
+
packet: response
|
|
46
53
|
)
|
|
47
54
|
end
|
|
48
55
|
|
|
@@ -100,8 +107,7 @@ module RubySMB
|
|
|
100
107
|
raise RubySMB::Error::InvalidPacket.new(
|
|
101
108
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
|
102
109
|
expected_cmd: RubySMB::SMB1::Packet::Trans::TransactNmpipeResponse::COMMAND,
|
|
103
|
-
|
|
104
|
-
received_cmd: trans_nmpipe_response.smb_header.command
|
|
110
|
+
packet: trans_nmpipe_response
|
|
105
111
|
)
|
|
106
112
|
end
|
|
107
113
|
unless [WindowsError::NTStatus::STATUS_SUCCESS,
|
data/lib/ruby_smb/smb1/tree.rb
CHANGED
|
@@ -49,13 +49,20 @@ module RubySMB
|
|
|
49
49
|
raise RubySMB::Error::InvalidPacket.new(
|
|
50
50
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
|
51
51
|
expected_cmd: RubySMB::SMB1::Packet::TreeDisconnectResponse::COMMAND,
|
|
52
|
-
|
|
53
|
-
received_cmd: response.smb_header.command
|
|
52
|
+
packet: response
|
|
54
53
|
)
|
|
55
54
|
end
|
|
56
55
|
response.status_code
|
|
57
56
|
end
|
|
58
57
|
|
|
58
|
+
def open_pipe(opts)
|
|
59
|
+
# Make sure we don't modify the caller's hash options
|
|
60
|
+
opts = opts.dup
|
|
61
|
+
opts[:filename] = opts[:filename].dup
|
|
62
|
+
opts[:filename].prepend('\\') unless opts[:filename].start_with?('\\')
|
|
63
|
+
open_file(**opts)
|
|
64
|
+
end
|
|
65
|
+
|
|
59
66
|
# Open a file on the remote share.
|
|
60
67
|
#
|
|
61
68
|
# @example
|
|
@@ -135,15 +142,14 @@ module RubySMB
|
|
|
135
142
|
raise RubySMB::Error::InvalidPacket.new(
|
|
136
143
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
|
137
144
|
expected_cmd: RubySMB::SMB1::Packet::NtCreateAndxResponse::COMMAND,
|
|
138
|
-
|
|
139
|
-
received_cmd: response.smb_header.command
|
|
145
|
+
packet: response
|
|
140
146
|
)
|
|
141
147
|
end
|
|
142
148
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
143
149
|
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
|
144
150
|
end
|
|
145
151
|
|
|
146
|
-
case response.parameter_block.resource_type
|
|
152
|
+
case response.parameter_block.resource_type
|
|
147
153
|
when RubySMB::SMB1::ResourceType::BYTE_MODE_PIPE, RubySMB::SMB1::ResourceType::MESSAGE_MODE_PIPE
|
|
148
154
|
RubySMB::SMB1::Pipe.new(name: filename, tree: self, response: response)
|
|
149
155
|
when RubySMB::SMB1::ResourceType::DISK
|
|
@@ -195,8 +201,7 @@ module RubySMB
|
|
|
195
201
|
raise RubySMB::Error::InvalidPacket.new(
|
|
196
202
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
|
197
203
|
expected_cmd: RubySMB::SMB1::Packet::Trans2::FindFirst2Response::COMMAND,
|
|
198
|
-
|
|
199
|
-
received_cmd: response.smb_header.command
|
|
204
|
+
packet: response
|
|
200
205
|
)
|
|
201
206
|
end
|
|
202
207
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
@@ -230,8 +235,7 @@ module RubySMB
|
|
|
230
235
|
raise RubySMB::Error::InvalidPacket.new(
|
|
231
236
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
|
232
237
|
expected_cmd: RubySMB::SMB1::Packet::Trans2::FindNext2Response::COMMAND,
|
|
233
|
-
|
|
234
|
-
received_cmd: response.smb_header.command
|
|
238
|
+
packet: response
|
|
235
239
|
)
|
|
236
240
|
end
|
|
237
241
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
data/lib/ruby_smb/smb2/file.rb
CHANGED
|
@@ -95,8 +95,7 @@ module RubySMB
|
|
|
95
95
|
raise RubySMB::Error::InvalidPacket.new(
|
|
96
96
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
97
97
|
expected_cmd: RubySMB::SMB2::Packet::CloseResponse::COMMAND,
|
|
98
|
-
|
|
99
|
-
received_cmd: response.smb2_header.command
|
|
98
|
+
packet: response
|
|
100
99
|
)
|
|
101
100
|
end
|
|
102
101
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
@@ -115,21 +114,22 @@ module RubySMB
|
|
|
115
114
|
# @raise [RubySMB::Error::InvalidPacket] if the response is not a ReadResponse packet
|
|
116
115
|
# @raise [RubySMB::Error::UnexpectedStatusCode] if the response NTStatus is not STATUS_SUCCESS
|
|
117
116
|
def read(bytes: size, offset: 0)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
max_read = tree.client.server_max_read_size
|
|
118
|
+
max_read = 65536 unless tree.client.server_supports_multi_credit
|
|
119
|
+
atomic_read_size = [bytes, max_read].min
|
|
120
|
+
credit_charge = 0
|
|
121
|
+
if tree.client.server_supports_multi_credit
|
|
122
|
+
credit_charge = (atomic_read_size - 1) / 65536 + 1
|
|
123
|
+
end
|
|
123
124
|
|
|
124
|
-
read_request = read_packet(read_length: atomic_read_size, offset: offset)
|
|
125
|
+
read_request = read_packet(read_length: atomic_read_size, offset: offset, credit_charge: credit_charge)
|
|
125
126
|
raw_response = tree.client.send_recv(read_request, encrypt: @tree_connect_encrypt_data)
|
|
126
127
|
response = RubySMB::SMB2::Packet::ReadResponse.read(raw_response)
|
|
127
128
|
unless response.valid?
|
|
128
129
|
raise RubySMB::Error::InvalidPacket.new(
|
|
129
130
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
130
131
|
expected_cmd: RubySMB::SMB2::Packet::ReadResponse::COMMAND,
|
|
131
|
-
|
|
132
|
-
received_cmd: response.smb2_header.command
|
|
132
|
+
packet: response
|
|
133
133
|
)
|
|
134
134
|
end
|
|
135
135
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
@@ -142,17 +142,16 @@ module RubySMB
|
|
|
142
142
|
|
|
143
143
|
while remaining_bytes > 0
|
|
144
144
|
offset += atomic_read_size
|
|
145
|
-
atomic_read_size = remaining_bytes if remaining_bytes <
|
|
145
|
+
atomic_read_size = remaining_bytes if remaining_bytes < max_read
|
|
146
146
|
|
|
147
|
-
read_request = read_packet(read_length: atomic_read_size, offset: offset)
|
|
147
|
+
read_request = read_packet(read_length: atomic_read_size, offset: offset, credit_charge: credit_charge)
|
|
148
148
|
raw_response = tree.client.send_recv(read_request, encrypt: @tree_connect_encrypt_data)
|
|
149
149
|
response = RubySMB::SMB2::Packet::ReadResponse.read(raw_response)
|
|
150
150
|
unless response.valid?
|
|
151
151
|
raise RubySMB::Error::InvalidPacket.new(
|
|
152
152
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
153
153
|
expected_cmd: RubySMB::SMB2::Packet::ReadResponse::COMMAND,
|
|
154
|
-
|
|
155
|
-
received_cmd: response.smb2_header.command
|
|
154
|
+
packet: response
|
|
156
155
|
)
|
|
157
156
|
end
|
|
158
157
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
@@ -169,11 +168,13 @@ module RubySMB
|
|
|
169
168
|
#
|
|
170
169
|
# @param bytes [Integer] the number of bytes to read
|
|
171
170
|
# @param offset [Integer] the byte offset in the file to start reading from
|
|
171
|
+
# @param credit_charge [Integer] the number of credits that this request consumes
|
|
172
172
|
# @return [RubySMB::SMB2::Packet::ReadRequest] the data read from the file
|
|
173
|
-
def read_packet(read_length: 0, offset: 0)
|
|
173
|
+
def read_packet(read_length: 0, offset: 0, credit_charge: 1)
|
|
174
174
|
read_request = set_header_fields(RubySMB::SMB2::Packet::ReadRequest.new)
|
|
175
175
|
read_request.read_length = read_length
|
|
176
176
|
read_request.offset = offset
|
|
177
|
+
read_request.smb2_header.credit_charge = credit_charge
|
|
177
178
|
read_request
|
|
178
179
|
end
|
|
179
180
|
|
|
@@ -185,8 +186,7 @@ module RubySMB
|
|
|
185
186
|
raise RubySMB::Error::InvalidPacket.new(
|
|
186
187
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
187
188
|
expected_cmd: RubySMB::SMB2::Packet::ReadResponse::COMMAND,
|
|
188
|
-
|
|
189
|
-
received_cmd: response.smb2_header.command
|
|
189
|
+
packet: response
|
|
190
190
|
)
|
|
191
191
|
end
|
|
192
192
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
@@ -206,8 +206,7 @@ module RubySMB
|
|
|
206
206
|
raise RubySMB::Error::InvalidPacket.new(
|
|
207
207
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
208
208
|
expected_cmd: RubySMB::SMB2::Packet::SetInfoResponse::COMMAND,
|
|
209
|
-
|
|
210
|
-
received_cmd: response.smb2_header.command
|
|
209
|
+
packet: response
|
|
211
210
|
)
|
|
212
211
|
end
|
|
213
212
|
response.smb2_header.nt_status.to_nt_status
|
|
@@ -240,29 +239,30 @@ module RubySMB
|
|
|
240
239
|
# @return [WindowsError::ErrorCode] the NTStatus code returned from the operation
|
|
241
240
|
# @raise [RubySMB::Error::InvalidPacket] if the response is not a WriteResponse packet
|
|
242
241
|
def write(data:'', offset: 0)
|
|
242
|
+
max_write = tree.client.server_max_write_size
|
|
243
|
+
max_write = 65536 unless tree.client.server_supports_multi_credit
|
|
243
244
|
buffer = data.dup
|
|
244
245
|
bytes = data.length
|
|
245
|
-
atomic_write_size =
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
246
|
+
atomic_write_size = [bytes, max_write].min
|
|
247
|
+
credit_charge = 0
|
|
248
|
+
if tree.client.server_supports_multi_credit
|
|
249
|
+
credit_charge = (atomic_write_size - 1) / 65536 + 1
|
|
250
|
+
end
|
|
250
251
|
|
|
251
252
|
while buffer.length > 0 do
|
|
252
|
-
write_request = write_packet(data: buffer.slice!(0,atomic_write_size), offset: offset)
|
|
253
|
+
write_request = write_packet(data: buffer.slice!(0, atomic_write_size), offset: offset, credit_charge: credit_charge)
|
|
253
254
|
raw_response = tree.client.send_recv(write_request, encrypt: @tree_connect_encrypt_data)
|
|
254
255
|
response = RubySMB::SMB2::Packet::WriteResponse.read(raw_response)
|
|
255
256
|
unless response.valid?
|
|
256
257
|
raise RubySMB::Error::InvalidPacket.new(
|
|
257
258
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
258
259
|
expected_cmd: RubySMB::SMB2::Packet::WriteResponse::COMMAND,
|
|
259
|
-
|
|
260
|
-
received_cmd: response.smb2_header.command
|
|
260
|
+
packet: response
|
|
261
261
|
)
|
|
262
262
|
end
|
|
263
263
|
status = response.smb2_header.nt_status.to_nt_status
|
|
264
264
|
|
|
265
|
-
offset+= atomic_write_size
|
|
265
|
+
offset += atomic_write_size
|
|
266
266
|
return status unless status == WindowsError::NTStatus::STATUS_SUCCESS
|
|
267
267
|
end
|
|
268
268
|
|
|
@@ -273,11 +273,13 @@ module RubySMB
|
|
|
273
273
|
#
|
|
274
274
|
# @param data [String] the data to write to the file
|
|
275
275
|
# @param offset [Integer] the offset in the file to start writing from
|
|
276
|
+
# @param credit_charge [Integer] the number of credits that this request consumes
|
|
276
277
|
# @return []RubySMB::SMB2::Packet::WriteRequest] the request packet
|
|
277
|
-
def write_packet(data:'', offset: 0)
|
|
278
|
+
def write_packet(data:'', offset: 0, credit_charge: 1)
|
|
278
279
|
write_request = set_header_fields(RubySMB::SMB2::Packet::WriteRequest.new)
|
|
279
280
|
write_request.write_offset = offset
|
|
280
281
|
write_request.buffer = data
|
|
282
|
+
write_request.smb2_header.credit_charge = credit_charge
|
|
281
283
|
write_request
|
|
282
284
|
end
|
|
283
285
|
|
|
@@ -289,8 +291,7 @@ module RubySMB
|
|
|
289
291
|
raise RubySMB::Error::InvalidPacket.new(
|
|
290
292
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
291
293
|
expected_cmd: RubySMB::SMB2::Packet::WriteResponse::COMMAND,
|
|
292
|
-
|
|
293
|
-
received_cmd: response.smb2_header.command
|
|
294
|
+
packet: response
|
|
294
295
|
)
|
|
295
296
|
end
|
|
296
297
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
@@ -311,8 +312,7 @@ module RubySMB
|
|
|
311
312
|
raise RubySMB::Error::InvalidPacket.new(
|
|
312
313
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
313
314
|
expected_cmd: RubySMB::SMB2::Packet::SetInfoResponse::COMMAND,
|
|
314
|
-
|
|
315
|
-
received_cmd: response.smb2_header.command
|
|
315
|
+
packet: response
|
|
316
316
|
)
|
|
317
317
|
end
|
|
318
318
|
response.smb2_header.nt_status.to_nt_status
|
|
@@ -69,9 +69,22 @@ module RubySMB
|
|
|
69
69
|
class NetnameNegotiateContextId < BinData::Record
|
|
70
70
|
endian :little
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
count_bytes_remaining :bytes_remaining
|
|
73
|
+
default_parameter data_length: nil
|
|
74
|
+
hide :bytes_remaining
|
|
75
|
+
|
|
76
|
+
string16 :net_name, label: 'Net Name', read_length: -> { data_length.nil? ? bytes_remaining : data_length }
|
|
73
77
|
end
|
|
74
78
|
|
|
79
|
+
# An SMB2 TRANSPORT_CAPABILITIES context struct as defined in
|
|
80
|
+
# [2.2.3.1.5 SMB2_TRANSPORT_CAPABILITIES](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/450a1888-a645-4988-8638-5a11f4617545)
|
|
81
|
+
class TransportCapabilities < BinData::Record
|
|
82
|
+
SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY = 1 # Transport security is offered to skip SMB2 encryption on this connection.
|
|
83
|
+
|
|
84
|
+
endian :little
|
|
85
|
+
|
|
86
|
+
uint32 :flags, label: 'Flags'
|
|
87
|
+
end
|
|
75
88
|
|
|
76
89
|
# An SMB2 NEGOTIATE_CONTEXT struct as defined in
|
|
77
90
|
# [2.2.3.1 SMB2 NEGOTIATE_CONTEXT Request Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/15332256-522e-4a53-8cd7-0bd17678a2f7)
|
|
@@ -84,6 +97,8 @@ module RubySMB
|
|
|
84
97
|
SMB2_COMPRESSION_CAPABILITIES = 0x0003
|
|
85
98
|
# The NegotiateContext Data field contains the server name to which the client connects.
|
|
86
99
|
SMB2_NETNAME_NEGOTIATE_CONTEXT_ID = 0x0005
|
|
100
|
+
# The NegotiateContext Data field contains the transport capabilities, as specified in section 2.2.3.1.5.
|
|
101
|
+
SMB2_TRANSPORT_CAPABILITIES = 0x0006
|
|
87
102
|
|
|
88
103
|
endian :little
|
|
89
104
|
|
|
@@ -95,7 +110,8 @@ module RubySMB
|
|
|
95
110
|
preauth_integrity_capabilities SMB2_PREAUTH_INTEGRITY_CAPABILITIES, label: 'Preauthentication Integrity Capabilities'
|
|
96
111
|
encryption_capabilities SMB2_ENCRYPTION_CAPABILITIES, label: 'Encryption Capabilities'
|
|
97
112
|
compression_capabilities SMB2_COMPRESSION_CAPABILITIES, label: 'Compression Capabilities'
|
|
98
|
-
netname_negotiate_context_id SMB2_NETNAME_NEGOTIATE_CONTEXT_ID, label: 'Netname Negotiate Context ID'
|
|
113
|
+
netname_negotiate_context_id SMB2_NETNAME_NEGOTIATE_CONTEXT_ID, label: 'Netname Negotiate Context ID', data_length: :data_length
|
|
114
|
+
transport_capabilities SMB2_TRANSPORT_CAPABILITIES, label: 'Transport Capabilities'
|
|
99
115
|
end
|
|
100
116
|
|
|
101
117
|
def pad_length
|
|
@@ -3,6 +3,9 @@ module RubySMB
|
|
|
3
3
|
module Packet
|
|
4
4
|
# An SMB2 COMPRESSION_TRANSFORM_HEADER Packet as defined in
|
|
5
5
|
# [2.2.42 SMB2 COMPRESSION_TRANSFORM_HEADER](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/1d435f21-9a21-4f4c-828e-624a176cf2a0)
|
|
6
|
+
# NOTE: On 2021-04-06 the official documentation split the definition of COMPRESSION_TRANSFORM_HEADER into the following two variants:
|
|
7
|
+
# * SMB2_COMPRESSION_TRANSFORM_HEADER_CHAINED
|
|
8
|
+
# * SMB2_COMPRESSION_TRANSFORM_HEADER_UNCHAINED
|
|
6
9
|
class CompressionTransformHeader < BinData::Record
|
|
7
10
|
endian :little
|
|
8
11
|
|
|
@@ -11,6 +14,7 @@ module RubySMB
|
|
|
11
14
|
uint16 :compression_algorithm, label: 'Compression Algorithm'
|
|
12
15
|
uint16 :flags, label: 'Flags'
|
|
13
16
|
uint32 :offset, label: 'Offset / Length'
|
|
17
|
+
array :compressed_data, label: 'Compressed Data', type: :uint8, read_until: :eof
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
# An SMB2 SMB2_COMPRESSION_TRANSFORM_HEADER_PAYLOAD Packet as defined in
|
|
@@ -64,6 +64,15 @@ module RubySMB
|
|
|
64
64
|
self.negotiate_context_list
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
# Find the first Negotiate Context structure that matches the given
|
|
68
|
+
# context type
|
|
69
|
+
#
|
|
70
|
+
# @param [Integer] the Negotiate Context structure you wish to add
|
|
71
|
+
# @return [NegotiateContext] the Negotiate Context structure or nil if
|
|
72
|
+
# not found
|
|
73
|
+
def find_negotiate_context(type)
|
|
74
|
+
negotiate_context_list.find { |nc| nc.context_type == type }
|
|
75
|
+
end
|
|
67
76
|
|
|
68
77
|
private
|
|
69
78
|
|
|
@@ -11,8 +11,8 @@ module RubySMB
|
|
|
11
11
|
uint16 :structure_size, label: 'Structure Size', initial_value: 9
|
|
12
12
|
session_flags :session_flags
|
|
13
13
|
uint16 :security_buffer_offset, label: 'Security Buffer Offset', initial_value: 0x48
|
|
14
|
-
uint16 :security_buffer_length, label: 'Security Buffer Length'
|
|
15
|
-
string :buffer, label: 'Security Buffer',
|
|
14
|
+
uint16 :security_buffer_length, label: 'Security Buffer Length', initial_value: -> { buffer.length }
|
|
15
|
+
string :buffer, label: 'Security Buffer', read_length: -> { security_buffer_length }
|
|
16
16
|
|
|
17
17
|
def initialize_instance
|
|
18
18
|
super
|
|
@@ -101,7 +101,7 @@ module RubySMB
|
|
|
101
101
|
path.to_binary_s.length
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
|
-
string16 :path, label: 'Path Buffer', onlyif: -> { flags != SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT }
|
|
104
|
+
string16 :path, label: 'Path Buffer', onlyif: -> { flags != SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT }, read_length: -> { path_length }
|
|
105
105
|
tree_connect_request_extension :tree_connect_request_extension, label: 'Tree Connect Request Extension', onlyif: -> { flags == SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT }
|
|
106
106
|
end
|
|
107
107
|
end
|
data/lib/ruby_smb/smb2/pipe.rb
CHANGED
|
@@ -13,10 +13,18 @@ module RubySMB
|
|
|
13
13
|
def initialize(tree:, response:, name:)
|
|
14
14
|
raise ArgumentError, 'No Name Provided' if name.nil?
|
|
15
15
|
case name
|
|
16
|
-
when '
|
|
16
|
+
when 'netlogon', '\\netlogon'
|
|
17
|
+
extend RubySMB::Dcerpc::Netlogon
|
|
18
|
+
when 'srvsvc', '\\srvsvc'
|
|
17
19
|
extend RubySMB::Dcerpc::Srvsvc
|
|
18
|
-
when '
|
|
20
|
+
when 'svcctl', '\\svcctl'
|
|
21
|
+
extend RubySMB::Dcerpc::Svcctl
|
|
22
|
+
when 'winreg', '\\winreg'
|
|
19
23
|
extend RubySMB::Dcerpc::Winreg
|
|
24
|
+
when 'samr', '\\samr'
|
|
25
|
+
extend RubySMB::Dcerpc::Samr
|
|
26
|
+
when 'wkssvc', '\\wkssvc'
|
|
27
|
+
extend RubySMB::Dcerpc::Wkssvc
|
|
20
28
|
end
|
|
21
29
|
super(tree: tree, response: response, name: name)
|
|
22
30
|
end
|
|
@@ -40,8 +48,7 @@ module RubySMB
|
|
|
40
48
|
raise RubySMB::Error::InvalidPacket.new(
|
|
41
49
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
42
50
|
expected_cmd: RubySMB::SMB2::Packet::IoctlResponse::COMMAND,
|
|
43
|
-
|
|
44
|
-
received_cmd: response.smb2_header.command
|
|
51
|
+
packet: response
|
|
45
52
|
)
|
|
46
53
|
end
|
|
47
54
|
|
|
@@ -89,6 +96,7 @@ module RubySMB
|
|
|
89
96
|
request = set_header_fields(RubySMB::SMB2::Packet::IoctlRequest.new(options))
|
|
90
97
|
request.ctl_code = 0x0011C017
|
|
91
98
|
request.flags.is_fsctl = 0x00000001
|
|
99
|
+
# TODO: handle fragmentation when the request size > MAX_XMIT_FRAG
|
|
92
100
|
request.buffer = action.to_binary_s
|
|
93
101
|
|
|
94
102
|
ioctl_raw_response = @tree.client.send_recv(request)
|
|
@@ -97,8 +105,7 @@ module RubySMB
|
|
|
97
105
|
raise RubySMB::Error::InvalidPacket.new(
|
|
98
106
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
99
107
|
expected_cmd: RubySMB::SMB2::Packet::IoctlRequest::COMMAND,
|
|
100
|
-
|
|
101
|
-
received_cmd: ioctl_response.smb2_header.command
|
|
108
|
+
packet: ioctl_response
|
|
102
109
|
)
|
|
103
110
|
end
|
|
104
111
|
unless [WindowsError::NTStatus::STATUS_SUCCESS,
|
data/lib/ruby_smb/smb2/tree.rb
CHANGED
|
@@ -50,13 +50,20 @@ module RubySMB
|
|
|
50
50
|
raise RubySMB::Error::InvalidPacket.new(
|
|
51
51
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
52
52
|
expected_cmd: RubySMB::SMB2::Packet::TreeDisconnectResponse::COMMAND,
|
|
53
|
-
|
|
54
|
-
received_cmd: response.smb2_header.command
|
|
53
|
+
packet: response
|
|
55
54
|
)
|
|
56
55
|
end
|
|
57
56
|
response.status_code
|
|
58
57
|
end
|
|
59
58
|
|
|
59
|
+
def open_pipe(opts)
|
|
60
|
+
# Make sure we don't modify the caller's hash options
|
|
61
|
+
opts = opts.dup
|
|
62
|
+
opts[:filename] = opts[:filename].dup
|
|
63
|
+
opts[:filename] = opts[:filename][1..-1] if opts[:filename].start_with? '\\'
|
|
64
|
+
open_file(**opts)
|
|
65
|
+
end
|
|
66
|
+
|
|
60
67
|
def open_file(filename:, attributes: nil, options: nil, disposition: RubySMB::Dispositions::FILE_OPEN,
|
|
61
68
|
impersonation: RubySMB::ImpersonationLevels::SEC_IMPERSONATE, read: true, write: false, delete: false)
|
|
62
69
|
|
|
@@ -108,8 +115,7 @@ module RubySMB
|
|
|
108
115
|
raise RubySMB::Error::InvalidPacket.new(
|
|
109
116
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
110
117
|
expected_cmd: RubySMB::SMB2::Packet::CreateResponse::COMMAND,
|
|
111
|
-
|
|
112
|
-
received_cmd: response.smb2_header.command
|
|
118
|
+
packet: response
|
|
113
119
|
)
|
|
114
120
|
end
|
|
115
121
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
@@ -147,12 +153,19 @@ module RubySMB
|
|
|
147
153
|
directory_request.file_information_class = type::CLASS_LEVEL
|
|
148
154
|
directory_request.file_id = file_id
|
|
149
155
|
directory_request.name = pattern
|
|
150
|
-
|
|
156
|
+
|
|
157
|
+
max_read = client.server_max_read_size
|
|
158
|
+
max_read = 65536 unless client.server_supports_multi_credit
|
|
159
|
+
credit_charge = 0
|
|
160
|
+
if client.server_supports_multi_credit
|
|
161
|
+
credit_charge = (max_read - 1) / 65536 + 1
|
|
162
|
+
end
|
|
163
|
+
directory_request.output_length = max_read
|
|
164
|
+
directory_request.smb2_header.credit_charge = credit_charge
|
|
151
165
|
|
|
152
166
|
directory_request = set_header_fields(directory_request)
|
|
153
167
|
|
|
154
168
|
files = []
|
|
155
|
-
|
|
156
169
|
loop do
|
|
157
170
|
response = client.send_recv(directory_request, encrypt: @tree_connect_encrypt_data)
|
|
158
171
|
directory_response = RubySMB::SMB2::Packet::QueryDirectoryResponse.read(response)
|
|
@@ -160,8 +173,7 @@ module RubySMB
|
|
|
160
173
|
raise RubySMB::Error::InvalidPacket.new(
|
|
161
174
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
162
175
|
expected_cmd: RubySMB::SMB2::Packet::QueryDirectoryResponse::COMMAND,
|
|
163
|
-
|
|
164
|
-
received_cmd: directory_response.smb2_header.command
|
|
176
|
+
packet: directory_response
|
|
165
177
|
)
|
|
166
178
|
end
|
|
167
179
|
|
|
@@ -205,8 +217,7 @@ module RubySMB
|
|
|
205
217
|
raise RubySMB::Error::InvalidPacket.new(
|
|
206
218
|
expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
|
|
207
219
|
expected_cmd: RubySMB::SMB2::Packet::CreateResponse::COMMAND,
|
|
208
|
-
|
|
209
|
-
received_cmd: response.smb2_header.command
|
|
220
|
+
packet: response
|
|
210
221
|
)
|
|
211
222
|
end
|
|
212
223
|
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
@@ -256,7 +267,6 @@ module RubySMB
|
|
|
256
267
|
# @return [RubySMB::SMB2::Packet] the modified packet.
|
|
257
268
|
def set_header_fields(request)
|
|
258
269
|
request.smb2_header.tree_id = id
|
|
259
|
-
request.smb2_header.credit_charge = 1
|
|
260
270
|
request.smb2_header.credits = 256
|
|
261
271
|
request
|
|
262
272
|
end
|
data/lib/ruby_smb/smb2.rb
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
module RubySMB
|
|
2
2
|
# A packet parsing and manipulation library for the SMB2 protocol
|
|
3
3
|
#
|
|
4
|
-
# [[MS-SMB2] Server
|
|
4
|
+
# [[MS-SMB2] Server Message Block (SMB) Protocol Versions 2 and 3](https://msdn.microsoft.com/en-us/library/cc246482.aspx)
|
|
5
5
|
module SMB2
|
|
6
6
|
# Protocol ID value. Translates to \xFESMB
|
|
7
7
|
SMB2_PROTOCOL_ID = 0xFE534D42
|
|
8
|
+
# Wildcard revision, see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/63abf97c-0d09-47e2-88d6-6bfa552949a5
|
|
9
|
+
SMB2_WILDCARD_REVISION = 0x02ff
|
|
8
10
|
|
|
9
11
|
require 'ruby_smb/smb2/info_type'
|
|
10
12
|
require 'ruby_smb/smb2/commands'
|
data/lib/ruby_smb/version.rb
CHANGED
data/lib/ruby_smb.rb
CHANGED
|
@@ -8,8 +8,8 @@ require 'windows_error'
|
|
|
8
8
|
require 'windows_error/nt_status'
|
|
9
9
|
# A packet parsing and manipulation library for the SMB1 and SMB2 protocols
|
|
10
10
|
#
|
|
11
|
-
# [[MS-SMB] Server
|
|
12
|
-
# [[MS-SMB2] Server
|
|
11
|
+
# [[MS-SMB] Server Message Block (SMB) Protocol Version 1](https://msdn.microsoft.com/en-us/library/cc246482.aspx)
|
|
12
|
+
# [[MS-SMB2] Server Message Block (SMB) Protocol Versions 2 and 3](https://msdn.microsoft.com/en-us/library/cc246482.aspx)
|
|
13
13
|
module RubySMB
|
|
14
14
|
require 'ruby_smb/error'
|
|
15
15
|
require 'ruby_smb/dispositions'
|
|
@@ -21,9 +21,11 @@ module RubySMB
|
|
|
21
21
|
require 'ruby_smb/generic_packet'
|
|
22
22
|
require 'ruby_smb/dispatcher'
|
|
23
23
|
require 'ruby_smb/version'
|
|
24
|
-
require 'ruby_smb/version'
|
|
25
24
|
require 'ruby_smb/smb2'
|
|
26
25
|
require 'ruby_smb/smb1'
|
|
27
26
|
require 'ruby_smb/client'
|
|
28
27
|
require 'ruby_smb/crypto'
|
|
28
|
+
require 'ruby_smb/compression'
|
|
29
|
+
require 'ruby_smb/server'
|
|
30
|
+
require 'ruby_smb/dialect'
|
|
29
31
|
end
|