ruby_smb 0.0.18 → 0.0.19
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.tar.gz.sig +0 -0
- data/README.md +247 -7
- data/examples/anonymous_auth.rb +6 -3
- data/examples/append_file.rb +40 -0
- data/examples/authenticate.rb +12 -7
- data/examples/delete_file.rb +40 -0
- data/examples/list_directory.rb +45 -0
- data/examples/negotiate.rb +0 -1
- data/examples/negotiate_with_netbios_service.rb +36 -0
- data/examples/net_share_enum_all.rb +30 -0
- data/examples/read_file.rb +39 -0
- data/examples/rename_file.rb +41 -0
- data/examples/tree_connect.rb +2 -4
- data/examples/write_file.rb +40 -0
- data/lib/ruby_smb.rb +5 -0
- data/lib/ruby_smb/client.rb +196 -43
- data/lib/ruby_smb/client/authentication.rb +89 -48
- data/lib/ruby_smb/client/echo.rb +1 -4
- data/lib/ruby_smb/client/negotiation.rb +46 -45
- data/lib/ruby_smb/client/signing.rb +9 -16
- data/lib/ruby_smb/client/tree_connect.rb +8 -13
- data/lib/ruby_smb/client/utils.rb +79 -0
- data/lib/ruby_smb/dcerpc.rb +30 -0
- data/lib/ruby_smb/dcerpc/bind.rb +60 -0
- data/lib/ruby_smb/dcerpc/handle.rb +60 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +41 -0
- data/lib/ruby_smb/dcerpc/request.rb +43 -0
- data/lib/ruby_smb/dcerpc/response.rb +46 -0
- data/lib/ruby_smb/dcerpc/srvsvc.rb +17 -0
- data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +93 -0
- data/lib/ruby_smb/dcerpc/uuid.rb +28 -0
- data/lib/ruby_smb/dispatcher.rb +7 -3
- data/lib/ruby_smb/dispatcher/base.rb +23 -14
- data/lib/ruby_smb/dispatcher/socket.rb +71 -51
- data/lib/ruby_smb/dispositions.rb +32 -0
- data/lib/ruby_smb/error.rb +24 -18
- data/lib/ruby_smb/field.rb +5 -2
- data/lib/ruby_smb/field/extended_attribute_flag.rb +1 -1
- data/lib/ruby_smb/field/file_time.rb +3 -1
- data/lib/ruby_smb/field/security_descriptor.rb +6 -6
- data/lib/ruby_smb/field/smb2_fileid.rb +11 -0
- data/lib/ruby_smb/field/smb_fea.rb +3 -3
- data/lib/ruby_smb/field/smb_fea_list.rb +3 -3
- data/lib/ruby_smb/field/smb_gea.rb +12 -0
- data/lib/ruby_smb/field/smb_gea_list.rb +13 -0
- data/lib/ruby_smb/field/string16.rb +14 -0
- data/lib/ruby_smb/field/stringz16.rb +3 -7
- data/lib/ruby_smb/field/utime.rb +11 -10
- data/lib/ruby_smb/fscc.rb +12 -0
- data/lib/ruby_smb/fscc/control_codes.rb +26 -0
- data/lib/ruby_smb/{field → fscc}/ea_info_array.rb +12 -14
- data/lib/ruby_smb/fscc/file_attributes.rb +29 -0
- data/lib/ruby_smb/{field → fscc}/file_full_ea_info.rb +5 -5
- data/lib/ruby_smb/fscc/file_information.rb +60 -0
- data/lib/ruby_smb/fscc/file_information/file_both_directory_information.rb +29 -0
- data/lib/ruby_smb/fscc/file_information/file_directory_information.rb +25 -0
- data/lib/ruby_smb/fscc/file_information/file_disposition_information.rb +15 -0
- data/lib/ruby_smb/fscc/file_information/file_full_directory_information.rb +26 -0
- data/lib/ruby_smb/fscc/file_information/file_id_both_directory_information.rb +31 -0
- data/lib/ruby_smb/fscc/file_information/file_id_full_directory_information.rb +28 -0
- data/lib/ruby_smb/fscc/file_information/file_names_information.rb +18 -0
- data/lib/ruby_smb/fscc/file_information/file_rename_information.rb +44 -0
- data/lib/ruby_smb/generic_packet.rb +40 -18
- data/lib/ruby_smb/gss.rb +49 -56
- data/lib/ruby_smb/impersonation_levels.rb +7 -2
- data/lib/ruby_smb/nbss.rb +16 -0
- data/lib/ruby_smb/nbss/negative_session_response.rb +30 -0
- data/lib/ruby_smb/nbss/session_header.rb +13 -0
- data/lib/ruby_smb/nbss/session_request.rb +13 -0
- data/lib/ruby_smb/smb1.rb +20 -17
- data/lib/ruby_smb/smb1/bit_field.rb +3 -0
- data/lib/ruby_smb/smb1/bit_field/create_options.rb +5 -5
- data/lib/ruby_smb/smb1/bit_field/file_status_flags.rb +18 -0
- data/lib/ruby_smb/smb1/bit_field/open2_access_mode.rb +11 -11
- data/lib/ruby_smb/smb1/bit_field/open2_open_mode.rb +1 -1
- data/lib/ruby_smb/smb1/bit_field/optional_support.rb +0 -1
- data/lib/ruby_smb/smb1/bit_field/security_flags.rb +15 -0
- data/lib/ruby_smb/smb1/bit_field/share_access.rb +2 -3
- data/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes.rb +21 -24
- data/lib/ruby_smb/smb1/bit_field/smb_file_attributes.rb +1 -1
- data/lib/ruby_smb/smb1/commands.rb +5 -0
- data/lib/ruby_smb/smb1/create_actions.rb +3 -5
- data/lib/ruby_smb/smb1/file.rb +289 -0
- data/lib/ruby_smb/smb1/oplock_levels.rb +2 -4
- data/lib/ruby_smb/smb1/packet.rb +10 -0
- data/lib/ruby_smb/smb1/packet/close_request.rb +31 -0
- data/lib/ruby_smb/smb1/packet/close_response.rb +28 -0
- data/lib/ruby_smb/smb1/packet/echo_request.rb +5 -7
- data/lib/ruby_smb/smb1/packet/echo_response.rb +5 -7
- data/lib/ruby_smb/smb1/packet/empty_packet.rb +1 -2
- data/lib/ruby_smb/smb1/packet/logoff_request.rb +1 -4
- data/lib/ruby_smb/smb1/packet/logoff_response.rb +1 -4
- data/lib/ruby_smb/smb1/packet/negotiate_response.rb +22 -0
- data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +22 -0
- data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +62 -0
- data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +66 -0
- data/lib/ruby_smb/smb1/packet/nt_trans.rb +1 -2
- data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +19 -13
- data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +8 -10
- data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +11 -11
- data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +10 -10
- data/lib/ruby_smb/smb1/packet/nt_trans/subcommands.rb +8 -1
- data/lib/ruby_smb/smb1/packet/read_andx_request.rb +84 -0
- data/lib/ruby_smb/smb1/packet/read_andx_response.rb +47 -0
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -6
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +1 -4
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -6
- data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/data_block.rb +6 -7
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +77 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +87 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_information_level.rb +32 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_information_level/find_file_full_directory_info.rb +45 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +77 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +86 -0
- data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +10 -10
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +10 -12
- data/lib/ruby_smb/smb1/packet/trans2/request.rb +15 -17
- data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +8 -10
- data/lib/ruby_smb/smb1/packet/trans2/response.rb +11 -13
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +66 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +57 -0
- data/lib/ruby_smb/smb1/packet/trans2/subcommands.rb +5 -2
- data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +4 -6
- data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +5 -7
- data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -4
- data/lib/ruby_smb/smb1/packet/write_andx_request.rb +68 -0
- data/lib/ruby_smb/smb1/packet/write_andx_response.rb +35 -0
- data/lib/ruby_smb/smb1/resource_type.rb +18 -0
- data/lib/ruby_smb/smb1/tree.rb +188 -5
- data/lib/ruby_smb/smb2.rb +16 -11
- data/lib/ruby_smb/smb2/bit_field.rb +1 -0
- data/lib/ruby_smb/smb2/bit_field/file_access_mask.rb +1 -1
- data/lib/ruby_smb/smb2/bit_field/session_flags.rb +1 -2
- data/lib/ruby_smb/smb2/bit_field/share_flags.rb +4 -6
- data/lib/ruby_smb/smb2/create_context.rb +29 -0
- data/lib/ruby_smb/smb2/file.rb +251 -0
- data/lib/ruby_smb/smb2/info_type.rb +21 -0
- data/lib/ruby_smb/smb2/packet.rb +16 -0
- data/lib/ruby_smb/smb2/packet/close_request.rb +22 -0
- data/lib/ruby_smb/smb2/packet/close_response.rb +29 -0
- data/lib/ruby_smb/smb2/packet/create_request.rb +54 -0
- data/lib/ruby_smb/smb2/packet/create_response.rb +35 -0
- data/lib/ruby_smb/smb2/packet/echo_request.rb +1 -3
- data/lib/ruby_smb/smb2/packet/echo_response.rb +1 -3
- data/lib/ruby_smb/smb2/packet/error_packet.rb +1 -3
- data/lib/ruby_smb/smb2/packet/ioctl_request.rb +54 -0
- data/lib/ruby_smb/smb2/packet/ioctl_response.rb +39 -0
- data/lib/ruby_smb/smb2/packet/logoff_request.rb +1 -4
- data/lib/ruby_smb/smb2/packet/logoff_response.rb +1 -4
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +1 -1
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +1 -1
- data/lib/ruby_smb/smb2/packet/query_directory_request.rb +35 -0
- data/lib/ruby_smb/smb2/packet/query_directory_response.rb +45 -0
- data/lib/ruby_smb/smb2/packet/read_request.rb +30 -0
- data/lib/ruby_smb/smb2/packet/read_response.rb +26 -0
- data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/session_setup_response.rb +4 -7
- data/lib/ruby_smb/smb2/packet/set_info_request.rb +58 -0
- data/lib/ruby_smb/smb2/packet/set_info_response.rb +20 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +3 -4
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +5 -9
- data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +1 -4
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -4
- data/lib/ruby_smb/smb2/packet/write_request.rb +29 -0
- data/lib/ruby_smb/smb2/packet/write_response.rb +26 -0
- data/lib/ruby_smb/smb2/tree.rb +163 -7
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +459 -120
- data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +14 -0
- data/spec/lib/ruby_smb/dcerpc/handle_spec.rb +31 -0
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +21 -0
- data/spec/lib/ruby_smb/dcerpc/response_spec.rb +15 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +13 -0
- data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +12 -0
- data/spec/lib/ruby_smb/dispatcher/base_spec.rb +26 -0
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +118 -18
- data/spec/lib/ruby_smb/field/extended_attribute_flag_spec.rb +0 -3
- data/spec/lib/ruby_smb/field/file_time_spec.rb +4 -2
- data/spec/lib/ruby_smb/field/security_descriptor.rb +0 -1
- data/spec/lib/ruby_smb/field/smb2_fileid_spec.rb +10 -0
- data/spec/lib/ruby_smb/field/smb_fea_list_spec.rb +3 -5
- data/spec/lib/ruby_smb/field/smb_gea_list_spec.rb +37 -0
- data/spec/lib/ruby_smb/field/smb_gea_spec.rb +22 -0
- data/spec/lib/ruby_smb/field/stringz16_spec.rb +7 -9
- data/spec/lib/ruby_smb/field/utime_spec.rb +4 -2
- data/spec/lib/ruby_smb/{field → fscc}/ea_info_array_spec.rb +7 -9
- data/spec/lib/ruby_smb/{field → fscc}/file_full_ea_info_spec.rb +2 -3
- data/spec/lib/ruby_smb/fscc/file_information/file_both_directory_information_spec.rb +71 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_directory_information_spec.rb +68 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_disposition_information_spec.rb +26 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_full_directory_information_spec.rb +69 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_id_both_directory_information_spec.rb +72 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_id_full_directory_information_spec.rb +70 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_names_information_spec.rb +41 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_rename_information_spec.rb +133 -0
- data/spec/lib/ruby_smb/fscc/fscc_file_attributes_spec.rb +143 -0
- data/spec/lib/ruby_smb/generic_packet_spec.rb +46 -21
- data/spec/lib/ruby_smb/nbss/negative_session_response_spec.rb +29 -0
- data/spec/lib/ruby_smb/nbss/session_header_spec.rb +30 -0
- data/spec/lib/ruby_smb/nbss/session_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/smb1/bit_field/create_options_spec.rb +9 -1
- data/spec/lib/ruby_smb/smb1/bit_field/directory_access_mask_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/file_access_mask_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/file_status_flags_spec.rb +35 -0
- data/spec/lib/ruby_smb/smb1/bit_field/open2_access_mode_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb1/bit_field/open2_flags_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/open2_open_mode_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/bit_field/optional_support_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/bit_field/security_flags_spec.rb +26 -0
- data/spec/lib/ruby_smb/smb1/bit_field/share_access_spec.rb +0 -3
- data/spec/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes_spec.rb +20 -39
- data/spec/lib/ruby_smb/smb1/bit_field/smb_file_attributes_spec.rb +0 -6
- data/spec/lib/ruby_smb/smb1/bit_field/smb_nmpipe_status_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/trans2_flags_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/tree_connect_flags_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/file_spec.rb +469 -0
- data/spec/lib/ruby_smb/smb1/packet/close_request_spec.rb +54 -0
- data/spec/lib/ruby_smb/smb1/packet/close_response_spec.rb +45 -0
- data/spec/lib/ruby_smb/smb1/packet/echo_request_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/echo_response_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb1/packet/logoff_request_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/logoff_response_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/negotiate_request_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb1/packet/negotiate_response_extended_spec.rb +37 -0
- data/spec/lib/ruby_smb/smb1/packet/negotiate_response_spec.rb +37 -0
- data/spec/lib/ruby_smb/smb1/packet/nt_create_andx_request_spec.rb +151 -0
- data/spec/lib/ruby_smb/smb1/packet/nt_create_andx_response_spec.rb +157 -0
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_request_spec.rb +13 -6
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_response_spec.rb +1 -7
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/request_spec.rb +1 -6
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/response_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/read_andx_request_spec.rb +149 -0
- data/spec/lib/ruby_smb/smb1/packet/read_andx_response_spec.rb +93 -0
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_request_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_response_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +3 -8
- data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +2 -4
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_request_spec.rb +180 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +104 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_information_level/find_file_full_directory_info_spec.rb +128 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_request_spec.rb +174 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +102 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_request_spec.rb +1 -6
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +2 -7
- data/spec/lib/ruby_smb/smb1/packet/trans2/request_secondary_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/trans2/request_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb +98 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +56 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_request_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +1 -6
- data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_request_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_response_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/write_andx_request_spec.rb +148 -0
- data/spec/lib/ruby_smb/smb1/packet/write_andx_response_spec.rb +54 -0
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +409 -7
- data/spec/lib/ruby_smb/smb2/bit_field/directory_access_mask_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb2/bit_field/file_access_mask_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb2/bit_field/share_capabilities_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb2/create_context_spec.rb +42 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +233 -0
- data/spec/lib/ruby_smb/smb2/packet/close_request_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb2/packet/close_response_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +101 -0
- data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +64 -0
- data/spec/lib/ruby_smb/smb2/packet/echo_request_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/echo_response_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/ioctl_request_spec.rb +48 -0
- data/spec/lib/ruby_smb/smb2/packet/logoff_request_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/logoff_response_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/query_directory_request_spec.rb +80 -0
- data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +64 -0
- data/spec/lib/ruby_smb/smb2/packet/read_request_spec.rb +43 -0
- data/spec/lib/ruby_smb/smb2/packet/read_response_spec.rb +50 -0
- data/spec/lib/ruby_smb/smb2/packet/session_setup_request_spec.rb +3 -4
- data/spec/lib/ruby_smb/smb2/packet/session_setup_response_spec.rb +2 -3
- data/spec/lib/ruby_smb/smb2/packet/set_info_request_spec.rb +205 -0
- data/spec/lib/ruby_smb/smb2/packet/set_info_response_spec.rb +32 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +3 -5
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +1 -2
- data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_request_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_response_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/write_request_spec.rb +51 -0
- data/spec/lib/ruby_smb/smb2/packet/write_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +191 -5
- data/spec/spec_helper.rb +1 -1
- metadata +195 -12
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/smb1/dispositions.rb +0 -36
- data/spec/lib/ruby_smb/dispatcher/dispatcher_base_spec.rb +0 -22
data/examples/negotiate.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# This script is for testing the NetBIOS Session Service Request on port 139/tcp.
|
4
|
+
# Example usage: ruby negotiate.rb 192.168.172.138 NBNAME
|
5
|
+
# This will connect to 192.168.172.138 (139/TCP) and request a NetBIOS session with NBNAME as the called name.
|
6
|
+
# If successful, a SMB negotiation is performed using this NetBIOS session.
|
7
|
+
# The default *SMBSERVER name is used if the NetBIOS name is not provided.
|
8
|
+
|
9
|
+
require 'bundler/setup'
|
10
|
+
require 'ruby_smb'
|
11
|
+
|
12
|
+
def run_negotiation(address, smb1, smb2, netbios_name)
|
13
|
+
sock = TCPSocket.new address, 139
|
14
|
+
dispatcher = RubySMB::Dispatcher::Socket.new(sock)
|
15
|
+
|
16
|
+
client = RubySMB::Client.new(dispatcher, smb1: smb1, smb2: smb2, username: 'msfadmin', password: 'msfadmin')
|
17
|
+
begin
|
18
|
+
client.session_request(netbios_name)
|
19
|
+
rescue RubySMB::Error::NetBiosSessionService => e
|
20
|
+
puts "NetBIOS Session refused with #{netbios_name}: #{e.message}"
|
21
|
+
return
|
22
|
+
end
|
23
|
+
puts "NetBIOS Session granted with #{netbios_name}, negotiating..."
|
24
|
+
smb_version = client.negotiate
|
25
|
+
puts "#{smb_version} successfully negotiated."
|
26
|
+
end
|
27
|
+
|
28
|
+
address = ARGV[0]
|
29
|
+
netbios_name = ARGV[1] || '*SMBSERVER'
|
30
|
+
|
31
|
+
# Negotiate with both SMB1 and SMB2 enabled on the client
|
32
|
+
run_negotiation(ARGV[0], true, true, netbios_name)
|
33
|
+
# Negotiate with only SMB1 enabled
|
34
|
+
run_negotiation(ARGV[0], true, false, netbios_name)
|
35
|
+
# Negotiate with only SMB2 enabled
|
36
|
+
run_negotiation(ARGV[0], false, true, netbios_name)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# This example script is used for testing NetShareEnumAll functionality
|
4
|
+
# It will attempt to connect to a host and enumerate shares.
|
5
|
+
# Example usage: ruby net_share_enum_all.rb 192.168.172.138 msfadmin msfadmin
|
6
|
+
# This will try to connect to \\192.168.172.138 with the msfadmin:msfadmin credentials
|
7
|
+
|
8
|
+
require 'bundler/setup'
|
9
|
+
require 'ruby_smb'
|
10
|
+
|
11
|
+
address = ARGV[0]
|
12
|
+
username = ARGV[1]
|
13
|
+
password = ARGV[2]
|
14
|
+
path = "\\\\#{address}\\IPC$"
|
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: false, smb2: true, username: username, password: password)
|
20
|
+
protocol = client.negotiate
|
21
|
+
status = client.authenticate
|
22
|
+
|
23
|
+
puts "#{protocol} : #{status}"
|
24
|
+
|
25
|
+
begin
|
26
|
+
shares = client.net_share_enum_all(address)
|
27
|
+
puts shares
|
28
|
+
rescue => e
|
29
|
+
puts "failed to enum shares: #{e.message}, #{e.backtrace_locations}"
|
30
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# This example script is used for testing the reading of a file.
|
4
|
+
# It will attempt to connect to a specific share and then read a specified file.
|
5
|
+
# Example usage: ruby read_file.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE short.txt
|
6
|
+
# This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials
|
7
|
+
# and read the file short.txt
|
8
|
+
|
9
|
+
require 'bundler/setup'
|
10
|
+
require 'ruby_smb'
|
11
|
+
|
12
|
+
address = ARGV[0]
|
13
|
+
username = ARGV[1]
|
14
|
+
password = ARGV[2]
|
15
|
+
share = ARGV[3]
|
16
|
+
file = ARGV[4]
|
17
|
+
path = "\\\\#{address}\\#{share}"
|
18
|
+
|
19
|
+
sock = TCPSocket.new address, 445
|
20
|
+
dispatcher = RubySMB::Dispatcher::Socket.new(sock)
|
21
|
+
|
22
|
+
client = RubySMB::Client.new(dispatcher, smb1: true, smb2: true, username: username, password: password)
|
23
|
+
protocol = client.negotiate
|
24
|
+
status = client.authenticate
|
25
|
+
|
26
|
+
puts "#{protocol} : #{status}"
|
27
|
+
|
28
|
+
begin
|
29
|
+
tree = client.tree_connect(path)
|
30
|
+
puts "Connected to #{path} successfully!"
|
31
|
+
rescue StandardError => e
|
32
|
+
puts "Failed to connect to #{path}: #{e.message}"
|
33
|
+
end
|
34
|
+
|
35
|
+
file = tree.open_file(filename: file)
|
36
|
+
|
37
|
+
data = file.read
|
38
|
+
puts data
|
39
|
+
file.close
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# This example script is used for testing the deleting of a file.
|
4
|
+
# It will attempt to connect to a specific share and then rename a specified file.
|
5
|
+
# Example usage: ruby rename_file.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE short.txt shortrenamed.txt
|
6
|
+
# This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials
|
7
|
+
# and rename the file short.txt
|
8
|
+
|
9
|
+
require 'bundler/setup'
|
10
|
+
require 'ruby_smb'
|
11
|
+
|
12
|
+
address = ARGV[0]
|
13
|
+
username = ARGV[1]
|
14
|
+
password = ARGV[2]
|
15
|
+
share = ARGV[3]
|
16
|
+
file = ARGV[4]
|
17
|
+
new_name = ARGV[5]
|
18
|
+
path = "\\\\#{address}\\#{share}"
|
19
|
+
|
20
|
+
sock = TCPSocket.new address, 445
|
21
|
+
dispatcher = RubySMB::Dispatcher::Socket.new(sock)
|
22
|
+
|
23
|
+
client = RubySMB::Client.new(dispatcher, smb1: true, smb2: true, username: username, password: password)
|
24
|
+
|
25
|
+
protocol = client.negotiate
|
26
|
+
status = client.authenticate
|
27
|
+
|
28
|
+
puts "#{protocol} : #{status}"
|
29
|
+
|
30
|
+
begin
|
31
|
+
tree = client.tree_connect(path)
|
32
|
+
puts "Connected to #{path} successfully!"
|
33
|
+
rescue StandardError => e
|
34
|
+
puts "Failed to connect to #{path}: #{e.message}"
|
35
|
+
end
|
36
|
+
|
37
|
+
file = tree.open_file(filename: file, write: true, delete: true)
|
38
|
+
|
39
|
+
data = file.rename(new_name)
|
40
|
+
puts data
|
41
|
+
file.close
|
data/examples/tree_connect.rb
CHANGED
@@ -19,7 +19,7 @@ dispatcher = RubySMB::Dispatcher::Socket.new(sock)
|
|
19
19
|
|
20
20
|
client = RubySMB::Client.new(dispatcher, smb1: true, smb2: true, username: username, password: password)
|
21
21
|
protocol = client.negotiate
|
22
|
-
status
|
22
|
+
status = client.authenticate
|
23
23
|
|
24
24
|
puts "#{protocol} : #{status}"
|
25
25
|
|
@@ -27,8 +27,6 @@ begin
|
|
27
27
|
tree = client.tree_connect(path)
|
28
28
|
puts "Connected to #{path} successfully!"
|
29
29
|
tree.disconnect!
|
30
|
-
rescue
|
30
|
+
rescue StandardError => e
|
31
31
|
puts "Failed to connect to #{path}: #{e.message}"
|
32
32
|
end
|
33
|
-
|
34
|
-
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# This example script is used for testing the writing to a file.
|
4
|
+
# It will attempt to connect to a specific share and then write to a specified file.
|
5
|
+
# Example usage: ruby write_file.rb 192.168.172.138 msfadmin msfadmin TEST_SHARE test.txt "data to write"
|
6
|
+
# This will try to connect to \\192.168.172.138\TEST_SHARE with the msfadmin:msfadmin credentials
|
7
|
+
# and write "data to write" the file test.txt
|
8
|
+
|
9
|
+
require 'bundler/setup'
|
10
|
+
require 'ruby_smb'
|
11
|
+
|
12
|
+
address = ARGV[0]
|
13
|
+
username = ARGV[1]
|
14
|
+
password = ARGV[2]
|
15
|
+
share = ARGV[3]
|
16
|
+
file = ARGV[4]
|
17
|
+
data = ARGV[5]
|
18
|
+
path = "\\\\#{address}\\#{share}"
|
19
|
+
|
20
|
+
sock = TCPSocket.new address, 445
|
21
|
+
dispatcher = RubySMB::Dispatcher::Socket.new(sock)
|
22
|
+
|
23
|
+
client = RubySMB::Client.new(dispatcher, smb1: true, smb2: true, username: username, password: password)
|
24
|
+
protocol = client.negotiate
|
25
|
+
status = client.authenticate
|
26
|
+
|
27
|
+
puts "#{protocol} : #{status}"
|
28
|
+
|
29
|
+
begin
|
30
|
+
tree = client.tree_connect(path)
|
31
|
+
puts "Connected to #{path} successfully!"
|
32
|
+
rescue StandardError => e
|
33
|
+
puts "Failed to connect to #{path}: #{e.message}"
|
34
|
+
end
|
35
|
+
|
36
|
+
file = tree.open_file(filename: file, write: true, disposition: RubySMB::Dispositions::FILE_OVERWRITE_IF)
|
37
|
+
|
38
|
+
result = file.write(data: data)
|
39
|
+
puts result.to_s
|
40
|
+
file.close
|
data/lib/ruby_smb.rb
CHANGED
@@ -8,8 +8,13 @@ require 'windows_error/nt_status'
|
|
8
8
|
# [[MS-SMB] Server Mesage Block (SMB) Protocol Version 1](https://msdn.microsoft.com/en-us/library/cc246482.aspx)
|
9
9
|
# [[MS-SMB2] Server Mesage Block (SMB) Protocol Versions 2 and 3](https://msdn.microsoft.com/en-us/library/cc246482.aspx)
|
10
10
|
module RubySMB
|
11
|
+
require 'ruby_smb/dispositions'
|
12
|
+
require 'ruby_smb/impersonation_levels'
|
11
13
|
require 'ruby_smb/gss'
|
12
14
|
require 'ruby_smb/field'
|
15
|
+
require 'ruby_smb/nbss'
|
16
|
+
require 'ruby_smb/fscc'
|
17
|
+
require 'ruby_smb/dcerpc'
|
13
18
|
require 'ruby_smb/generic_packet'
|
14
19
|
require 'ruby_smb/dispatcher'
|
15
20
|
require 'ruby_smb/error'
|
data/lib/ruby_smb/client.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module RubySMB
|
2
|
-
|
3
2
|
# Represents an SMB client capable of talking to SMB1 or SMB2 servers and handling
|
4
3
|
# all end-user client functionality.
|
5
4
|
class Client
|
@@ -8,20 +7,23 @@ module RubySMB
|
|
8
7
|
require 'ruby_smb/client/signing'
|
9
8
|
require 'ruby_smb/client/tree_connect'
|
10
9
|
require 'ruby_smb/client/echo'
|
10
|
+
require 'ruby_smb/client/utils'
|
11
11
|
|
12
12
|
include RubySMB::Client::Negotiation
|
13
13
|
include RubySMB::Client::Authentication
|
14
14
|
include RubySMB::Client::Signing
|
15
15
|
include RubySMB::Client::TreeConnect
|
16
16
|
include RubySMB::Client::Echo
|
17
|
+
include RubySMB::Client::Utils
|
17
18
|
|
18
19
|
# The Default SMB1 Dialect string used in an SMB1 Negotiate Request
|
19
|
-
SMB1_DIALECT_SMB1_DEFAULT =
|
20
|
+
SMB1_DIALECT_SMB1_DEFAULT = 'NT LM 0.12'.freeze
|
20
21
|
# The Default SMB2 Dialect string used in an SMB1 Negotiate Request
|
21
|
-
SMB1_DIALECT_SMB2_DEFAULT =
|
22
|
+
SMB1_DIALECT_SMB2_DEFAULT = 'SMB 2.002'.freeze
|
22
23
|
# Dialect value for SMB2 Default (Version 2.02)
|
23
24
|
SMB2_DIALECT_DEFAULT = 0x0202
|
24
|
-
|
25
|
+
# The default maximum size of a SMB message that the Client accepts (in bytes)
|
26
|
+
MAX_BUFFER_SIZE = 4356
|
25
27
|
|
26
28
|
# The dispatcher responsible for sending packets
|
27
29
|
# @!attribute [rw] dispatcher
|
@@ -54,6 +56,54 @@ module RubySMB
|
|
54
56
|
# @return [String]
|
55
57
|
attr_accessor :peer_native_os
|
56
58
|
|
59
|
+
# The Native LAN Manager of the Peer/Server.
|
60
|
+
# Currently only available with SMB1.
|
61
|
+
# @!attribute [rw] peer_native_lm
|
62
|
+
# @return [String]
|
63
|
+
attr_accessor :peer_native_lm
|
64
|
+
|
65
|
+
# The Primary Domain of the Peer/Server.
|
66
|
+
# Currently only available with SMB1 and only when authentiation
|
67
|
+
# without NTLMSSP is used.
|
68
|
+
# @!attribute [rw] primary_domain
|
69
|
+
# @return [String]
|
70
|
+
attr_accessor :primary_domain
|
71
|
+
|
72
|
+
# The Netbios Name of the Peer/Server.
|
73
|
+
# @!attribute [rw] default_name
|
74
|
+
# @return [String]
|
75
|
+
attr_accessor :default_name
|
76
|
+
|
77
|
+
# The Netbios Domain of the Peer/Server.
|
78
|
+
# @!attribute [rw] default_domain
|
79
|
+
# @return [String]
|
80
|
+
attr_accessor :default_domain
|
81
|
+
|
82
|
+
# The Fully Qualified Domain Name (FQDN) of the computer.
|
83
|
+
# @!attribute [rw] dns_host_name
|
84
|
+
# @return [String]
|
85
|
+
attr_accessor :dns_host_name
|
86
|
+
|
87
|
+
# The Fully Qualified Domain Name (FQDN) of the domain.
|
88
|
+
# @!attribute [rw] dns_domain_name
|
89
|
+
# @return [String]
|
90
|
+
attr_accessor :dns_domain_name
|
91
|
+
|
92
|
+
# The Fully Qualified Domain Name (FQDN) of the forest.
|
93
|
+
# @!attribute [rw] dns_tree_name
|
94
|
+
# @return [String]
|
95
|
+
attr_accessor :dns_tree_name
|
96
|
+
|
97
|
+
# The OS version number (<major>.<minor>.<build>) of the Peer/Server.
|
98
|
+
# @!attribute [rw] os_version
|
99
|
+
# @return [String]
|
100
|
+
attr_accessor :os_version
|
101
|
+
|
102
|
+
# The negotiated dialect.
|
103
|
+
# @!attribute [rw] dialect
|
104
|
+
# @return [Integer]
|
105
|
+
attr_accessor :dialect
|
106
|
+
|
57
107
|
# The Sequence Counter used for SMB1 Signing.
|
58
108
|
# It tracks the number of packets both sent and received
|
59
109
|
# since the NTLM session was initialized with the Challenge.
|
@@ -96,32 +146,48 @@ module RubySMB
|
|
96
146
|
# @return [String]
|
97
147
|
attr_accessor :user_id
|
98
148
|
|
149
|
+
# The maximum size of a SMB message that the Client accepts (in bytes)
|
150
|
+
# Its default value is equal to {MAX_BUFFER_SIZE}.
|
151
|
+
# @!attribute [rw] max_buffer_size
|
152
|
+
# @return [Integer]
|
153
|
+
attr_accessor :max_buffer_size
|
154
|
+
|
99
155
|
# @param dispatcher [RubySMB::Dispacther::Socket] the packet dispatcher to use
|
100
156
|
# @param smb1 [Boolean] whether or not to enable SMB1 support
|
101
157
|
# @param smb2 [Boolean] whether or not to enable SMB2 support
|
102
|
-
def initialize(dispatcher, smb1: true, smb2: true, username:,password:, domain:'.', local_workstation:'WORKSTATION')
|
103
|
-
raise ArgumentError, 'No Dispatcher provided' unless dispatcher.
|
158
|
+
def initialize(dispatcher, smb1: true, smb2: true, username:, password:, domain: '.', local_workstation: 'WORKSTATION')
|
159
|
+
raise ArgumentError, 'No Dispatcher provided' unless dispatcher.is_a? RubySMB::Dispatcher::Base
|
104
160
|
if smb1 == false && smb2 == false
|
105
161
|
raise ArgumentError, 'You must enable at least one Protocol'
|
106
162
|
end
|
107
163
|
@dispatcher = dispatcher
|
108
164
|
@domain = domain
|
109
165
|
@local_workstation = local_workstation
|
110
|
-
@password = password.encode(
|
166
|
+
@password = password.encode('utf-8') || ''.encode('utf-8')
|
111
167
|
@sequence_counter = 0
|
112
168
|
@session_id = 0x00
|
113
169
|
@session_key = ''
|
114
170
|
@signing_required = false
|
115
171
|
@smb1 = smb1
|
116
172
|
@smb2 = smb2
|
117
|
-
@username = username.encode(
|
173
|
+
@username = username.encode('utf-8') || ''.encode('utf-8')
|
174
|
+
@max_buffer_size = MAX_BUFFER_SIZE
|
175
|
+
|
176
|
+
negotiate_version_flag = 0x02000000
|
177
|
+
flags = Net::NTLM::Client::DEFAULT_FLAGS |
|
178
|
+
Net::NTLM::FLAGS[:TARGET_INFO] |
|
179
|
+
negotiate_version_flag
|
118
180
|
|
119
181
|
@ntlm_client = Net::NTLM::Client.new(
|
120
182
|
@username,
|
121
183
|
@password,
|
122
184
|
workstation: @local_workstation,
|
123
|
-
domain: @domain
|
185
|
+
domain: @domain,
|
186
|
+
flags: flags
|
124
187
|
)
|
188
|
+
|
189
|
+
@tree_connects = []
|
190
|
+
@open_files = {}
|
125
191
|
|
126
192
|
@smb2_message_id = 0
|
127
193
|
end
|
@@ -145,12 +211,12 @@ module RubySMB
|
|
145
211
|
# @param echo [Integer] the number of times the server should echo (ignored in SMB2)
|
146
212
|
# @param data [String] the data the server should echo back (ignored in SMB2)
|
147
213
|
# @return [WindowsError::ErrorCode] the NTStatus of the last response received
|
148
|
-
def echo(count: 1, data: ''
|
149
|
-
if smb2
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
214
|
+
def echo(count: 1, data: '')
|
215
|
+
response = if smb2
|
216
|
+
smb2_echo
|
217
|
+
else
|
218
|
+
smb1_echo(count: count, data: data)
|
219
|
+
end
|
154
220
|
response.status_code
|
155
221
|
end
|
156
222
|
|
@@ -161,8 +227,8 @@ module RubySMB
|
|
161
227
|
# @param packet [RubySMB::GenericPacket] the packet to set the message id for
|
162
228
|
# @return [RubySMB::GenericPacket] the modified packet
|
163
229
|
def increment_smb_message_id(packet)
|
164
|
-
if packet.smb2_header.message_id
|
165
|
-
packet.smb2_header.message_id =
|
230
|
+
if packet.smb2_header.message_id.zero? && smb2_message_id != 0
|
231
|
+
packet.smb2_header.message_id = smb2_message_id
|
166
232
|
self.smb2_message_id += 1
|
167
233
|
end
|
168
234
|
packet
|
@@ -170,20 +236,32 @@ module RubySMB
|
|
170
236
|
|
171
237
|
# Performs protocol negotiation and session setup. It defaults to using
|
172
238
|
# the credentials supplied during initialization, but can take a new set of credentials if needed.
|
173
|
-
def login(username: self.username, password: self.password, domain: self.domain, local_workstation: self.local_workstation
|
239
|
+
def login(username: self.username, password: self.password, domain: self.domain, local_workstation: self.local_workstation)
|
240
|
+
negotiate
|
241
|
+
session_setup(username, password, domain, true,
|
242
|
+
local_workstation: local_workstation)
|
243
|
+
end
|
244
|
+
|
245
|
+
def session_setup(user, pass, domain, do_recv=true,
|
246
|
+
local_workstation: self.local_workstation)
|
174
247
|
@domain = domain
|
175
248
|
@local_workstation = local_workstation
|
176
|
-
@password =
|
177
|
-
@username =
|
178
|
-
|
249
|
+
@password = pass.encode('utf-8') || ''.encode('utf-8')
|
250
|
+
@username = user.encode('utf-8') || ''.encode('utf-8')
|
251
|
+
|
252
|
+
negotiate_version_flag = 0x02000000
|
253
|
+
flags = Net::NTLM::Client::DEFAULT_FLAGS |
|
254
|
+
Net::NTLM::FLAGS[:TARGET_INFO] |
|
255
|
+
negotiate_version_flag
|
256
|
+
|
179
257
|
@ntlm_client = Net::NTLM::Client.new(
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
258
|
+
@username,
|
259
|
+
@password,
|
260
|
+
workstation: @local_workstation,
|
261
|
+
domain: @domain,
|
262
|
+
flags: flags
|
184
263
|
)
|
185
264
|
|
186
|
-
negotiate
|
187
265
|
authenticate
|
188
266
|
end
|
189
267
|
|
@@ -211,26 +289,22 @@ module RubySMB
|
|
211
289
|
# @return [String] the raw response data received
|
212
290
|
def send_recv(packet)
|
213
291
|
case packet.packet_smb_version
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
packet
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
else
|
226
|
-
packet = packet
|
292
|
+
when 'SMB1'
|
293
|
+
packet.smb_header.uid = user_id if user_id
|
294
|
+
packet = smb1_sign(packet)
|
295
|
+
when 'SMB2'
|
296
|
+
packet = increment_smb_message_id(packet)
|
297
|
+
packet.smb2_header.session_id = session_id
|
298
|
+
unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest)
|
299
|
+
packet = smb2_sign(packet)
|
300
|
+
end
|
301
|
+
else
|
302
|
+
packet = packet
|
227
303
|
end
|
228
304
|
dispatcher.send_packet(packet)
|
229
305
|
raw_response = dispatcher.recv_packet
|
230
306
|
|
231
|
-
if
|
232
|
-
self.sequence_counter += 1
|
233
|
-
end
|
307
|
+
self.sequence_counter += 1 if signing_required && !session_key.empty?
|
234
308
|
raw_response
|
235
309
|
end
|
236
310
|
|
@@ -240,11 +314,55 @@ module RubySMB
|
|
240
314
|
# @return [RubySMB::SMB1::Tree] if talking over SMB1
|
241
315
|
# @return [RubySMB::SMB2::Tree] if talking over SMB2
|
242
316
|
def tree_connect(share)
|
243
|
-
if smb2
|
317
|
+
connected_tree = if smb2
|
244
318
|
smb2_tree_connect(share)
|
245
319
|
else
|
246
320
|
smb1_tree_connect(share)
|
247
321
|
end
|
322
|
+
@tree_connects << connected_tree
|
323
|
+
connected_tree
|
324
|
+
end
|
325
|
+
|
326
|
+
# Returns array of shares
|
327
|
+
#
|
328
|
+
# @return [Array] of shares
|
329
|
+
# @param [String] host
|
330
|
+
def net_share_enum_all(host)
|
331
|
+
if smb2
|
332
|
+
smb2_net_share_enum_all(host)
|
333
|
+
else
|
334
|
+
smb1_net_share_enum_all(host)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
#
|
339
|
+
# SMB2 Methods
|
340
|
+
#
|
341
|
+
|
342
|
+
# Sends a request to connect to a remote host and returns the Array
|
343
|
+
# of shares
|
344
|
+
#
|
345
|
+
# @return [Array] List of shares
|
346
|
+
# @param [String] host
|
347
|
+
def smb2_net_share_enum_all(host)
|
348
|
+
|
349
|
+
tree = tree_connect("\\\\#{host}\\IPC$")
|
350
|
+
|
351
|
+
named_pipe = tree.open_file(filename: "srvsvc",
|
352
|
+
write: true,
|
353
|
+
read: true,
|
354
|
+
disposition: RubySMB::Dispositions::FILE_OPEN_IF)
|
355
|
+
|
356
|
+
handle = Dcerpc::Handle.new(named_pipe)
|
357
|
+
|
358
|
+
handle.bind(endpoint: Dcerpc::Srvsvc)
|
359
|
+
handle.request(
|
360
|
+
opnum: Dcerpc::Srvsvc::NetShareEnumAll::Opnum,
|
361
|
+
stub: Dcerpc::Srvsvc::NetShareEnumAll,
|
362
|
+
options:{host: host}
|
363
|
+
)
|
364
|
+
shares = Dcerpc::Srvsvc::NetShareEnumAll.parse_response(handle.response)
|
365
|
+
shares.map{|s|{name: s[0], type: s[1], comment: s[2]}}
|
248
366
|
end
|
249
367
|
|
250
368
|
# Resets all of the session state on the client, setting it
|
@@ -260,6 +378,41 @@ module RubySMB
|
|
260
378
|
self.smb2_message_id = 0
|
261
379
|
end
|
262
380
|
|
381
|
+
# Requests a NetBIOS Session Service using the provided name.
|
382
|
+
#
|
383
|
+
# @param name [String] the NetBIOS name to request
|
384
|
+
# @return [TrueClass] if session request is granted
|
385
|
+
# @raise [RubySMB::Error::NetBiosSessionService] if session request is refused
|
386
|
+
def session_request(name = '*SMBSERVER')
|
387
|
+
encoded_called_name = nb_name_encode("#{name.upcase.ljust(15)}\x20")
|
388
|
+
encoded_calling_name = nb_name_encode("#{''.ljust(15)}\x00")
|
389
|
+
|
390
|
+
session_request = RubySMB::Nbss::SessionRequest.new
|
391
|
+
session_request.session_header.session_packet_type = RubySMB::Nbss::SESSION_REQUEST
|
392
|
+
session_request.called_name = "\x20#{encoded_called_name}\x00"
|
393
|
+
session_request.calling_name = "\x20#{encoded_calling_name}\x00"
|
394
|
+
session_request.session_header.packet_length = session_request.do_num_bytes - session_request.session_header.do_num_bytes
|
395
|
+
|
396
|
+
dispatcher.send_packet(session_request, nbss_header: false)
|
397
|
+
raw_response = dispatcher.recv_packet(full_response: true)
|
398
|
+
session_header = RubySMB::Nbss::SessionHeader.read(raw_response)
|
399
|
+
if session_header.session_packet_type == RubySMB::Nbss::NEGATIVE_SESSION_RESPONSE
|
400
|
+
negative_session_response = RubySMB::Nbss::NegativeSessionResponse.read(raw_response)
|
401
|
+
raise RubySMB::Error::NetBiosSessionService, "Session Request failed: #{negative_session_response.error_msg}"
|
402
|
+
end
|
263
403
|
|
404
|
+
return true
|
405
|
+
end
|
406
|
+
|
407
|
+
def nb_name_encode(name)
|
408
|
+
encoded_name = ''
|
409
|
+
name.each_byte do |char|
|
410
|
+
first_half = (char >> 4) + 'A'.ord
|
411
|
+
second_half = (char & 0xF) + 'A'.ord
|
412
|
+
encoded_name << first_half.chr
|
413
|
+
encoded_name << second_half.chr
|
414
|
+
end
|
415
|
+
encoded_name
|
416
|
+
end
|
264
417
|
end
|
265
418
|
end
|