Пример #1
0
    async def create(
        self,
        path: Union[str, PureWindowsPath],
        session: SMBv2Session,
        tree_id: int,
        requested_oplock_level: OplockLevel = OplockLevel.
        SMB2_OPLOCK_LEVEL_BATCH,
        impersonation_level: ImpersonationLevel = ImpersonationLevel.
        IMPERSONATION,
        desired_access: Union[FilePipePrinterAccessMask,
                              DirectoryAccessMask] = FilePipePrinterAccessMask(
                                  file_read_data=True,
                                  file_read_attributes=True),
        file_attributes: FileAttributes = FileAttributes(normal=True),
        share_access: ShareAccess = ShareAccess(read=True),
        create_disposition: CreateDisposition = CreateDisposition.FILE_OPEN,
        create_options: CreateOptions = CreateOptions(non_directory_file=True),
        create_context_list: CreateContextList = None
    ) -> AsyncContextManager[CreateResponse]:
        """
        Create/open a file or directory in an SMB share and close it once finished with it.

        The default parameters reflect read only access to an existing file.

        :param path: The share relative path of the file or directory which to operate on.
        :param session: An SMB session with to access the file or directory.
        :param tree_id: The tree ID of the SMB share where the specified file or directory will be or is located.
        :param requested_oplock_level:
        :param impersonation_level:
        :param desired_access:
        :param file_attributes:
        :param share_access:
        :param create_disposition:
        :param create_options:
        :param create_context_list:
        :return:
        """

        create_response: CreateResponse = (await self._create(
            path=path,
            session=session,
            tree_id=tree_id,
            requested_oplock_level=requested_oplock_level,
            impersonation_level=impersonation_level,
            desired_access=desired_access,
            file_attributes=file_attributes,
            share_access=share_access,
            create_disposition=create_disposition,
            create_options=create_options,
            create_context_list=create_context_list))

        yield create_response

        await self.close(session=session,
                         tree_id=tree_id,
                         file_id=create_response.file_id)
Пример #2
0
    async def create_dir(
            self,
            path: Union[str, PureWindowsPath],
            session: SMBv2Session,
            tree_id: int,
            requested_oplock_level: OplockLevel = OplockLevel.
        SMB2_OPLOCK_LEVEL_NONE,
            impersonation_level: ImpersonationLevel = ImpersonationLevel.
        IMPERSONATION,
            desired_access: DirectoryAccessMask = DirectoryAccessMask(
                file_list_directory=True, file_read_attributes=True),
            file_attributes: FileAttributes = FileAttributes(directory=True),
            share_access: ShareAccess = ShareAccess(read=True),
            create_disposition: CreateDisposition = CreateDisposition.
        FILE_OPEN,
            create_options: CreateOptions = CreateOptions(directory_file=True),
            create_context_list: CreateContextList = None):
        """

        :param path:
        :param session:
        :param tree_id:
        :param requested_oplock_level:
        :param impersonation_level:
        :param desired_access:
        :param file_attributes:
        :param share_access:
        :param create_disposition:
        :param create_options:
        :param create_context_list:
        :return:
        """

        create_response: CreateResponse = (await self._create(
            path=path,
            session=session,
            tree_id=tree_id,
            requested_oplock_level=requested_oplock_level,
            impersonation_level=impersonation_level,
            desired_access=desired_access,
            file_attributes=file_attributes,
            share_access=share_access,
            create_disposition=create_disposition,
            create_options=create_options,
            create_context_list=create_context_list))

        yield create_response

        await self.close(session=session,
                         tree_id=tree_id,
                         file_id=create_response.file_id)
Пример #3
0
    async def _create(
            self,
            path: Union[str, PureWindowsPath],
            tree_id: int,
            requested_oplock_level: OplockLevel = OplockLevel.
        SMB2_OPLOCK_LEVEL_BATCH,
            impersonation_level: ImpersonationLevel = ImpersonationLevel.
        IMPERSONATION,
            desired_access: Union[
                FilePipePrinterAccessMask,
                DirectoryAccessMask] = FilePipePrinterAccessMask(
                    file_read_data=True,
                    file_read_ea=True,
                    file_read_attributes=True),
            file_attributes: FileAttributes = FileAttributes(normal=True),
            share_access: ShareAccess = ShareAccess(read=True),
            create_disposition: CreateDisposition = CreateDisposition.
        FILE_OPEN,
            create_options: CreateOptions = CreateOptions(
                non_directory_file=True),
            create_context_list: CreateContextList = None) -> CreateResponse:
        create_context_list = create_context_list if create_context_list is not None else CreateContextList(
        )

        if self.connection.negotiated_details.dialect is not Dialect.SMB_2_1:
            raise NotImplementedError

        create_response: CreateResponse = await self.connection._obtain_response(
            request_message=CreateRequest(
                header=SMB210SyncRequestHeader(
                    command=SMBv2Command.SMB2_CREATE,
                    session_id=self.session_id,
                    tree_id=tree_id,
                ),
                requested_oplock_level=requested_oplock_level,
                impersonation_level=impersonation_level,
                desired_access=desired_access,
                file_attributes=file_attributes,
                share_access=share_access,
                create_disposition=create_disposition,
                create_options=create_options,
                name=str(path),
                create_context_list=create_context_list),
            sign_key=self.session_key)

        # TODO: I need to add stuff to some connection table, don't I?
        # TODO: Consider what to return from this function. There is a lot of information in the response.
        return create_response
Пример #4
0
    async def make_smbv2_transport(
        self,
        session: SMBv2Session,
        # TODO: Is this the correct name?
        pipe: str,
        # TODO: This argument does not make much sense to me...
        server_address: Optional[Union[str, IPv4Address, IPv6Address]] = None,
    ):

        async with self.tree_connect(
                share_name='IPC$', session=session,
                server_address=server_address) as (tree_id, share_type):
            if share_type is not ShareType.SMB2_SHARE_TYPE_PIPE:
                # TODO: Use proper exception.
                raise ValueError

            create_options: Dict[str, Any] = dict(
                path=pipe,
                session=session,
                tree_id=tree_id,
                requested_oplock_level=OplockLevel.SMB2_OPLOCK_LEVEL_NONE,
                desired_access=FilePipePrinterAccessMask(file_read_data=True,
                                                         file_write_data=True),
                file_attributes=FileAttributes(normal=True),
                share_access=ShareAccess(),
                create_disposition=CreateDisposition.FILE_OPEN,
                create_options=CreateOptions(non_directory_file=True))

            async with self.create(**create_options) as create_response:
                yield (
                    partial(
                        self.read,
                        file_id=create_response.file_id,
                        # TODO: Not sure about this value.
                        file_size=self.negotiated_details.max_read_size,
                        session=session,
                        tree_id=tree_id,
                        use_generator=False),
                    partial(self.write,
                            file_id=create_response.file_id,
                            session=session,
                            tree_id=tree_id,
                            offset=0,
                            remaining_bytes=0,
                            flags=WriteFlag()))
async def dump_reg(
    rpc_connection: RPCConnection,
    smb_session: SMBv2Session,
    root_key_handle: bytes,
    tree_id: int,
    sub_key_name: str,
    save_path: Optional[PureWindowsPath] = None,
    sam_desired: Regsam = Regsam(maximum_allowed=True),
    delete_file_on_close: bool = True
) -> bytes:
    save_path = save_path or PureWindowsPath(f'C:\\Windows\\Temp\\{uuid4()}')

    base_reg_open_key_options = dict(
        rpc_connection=rpc_connection,
        request=BaseRegOpenKeyRequest(key_handle=root_key_handle, sub_key_name=sub_key_name, sam_desired=sam_desired)
    )
    async with base_reg_open_key(**base_reg_open_key_options) as lsa_key_handle:
        await base_reg_save_key(
            rpc_connection=rpc_connection,
            request=BaseRegSaveKeyRequest(
                key_handle=lsa_key_handle,
                save_path=save_path
            )
        )

    create_kwargs = dict(
        path=PureWindowsPath(*save_path.parts[1:]),
        tree_id=tree_id,
        create_options=CreateOptions(non_directory_file=True, delete_on_close=delete_file_on_close),
        desired_access=FilePipePrinterAccessMask(file_read_data=True, delete=delete_file_on_close)
    )
    async with smb_session.create(**create_kwargs) as create_response:
        return await smb_session.read(
            file_id=create_response.file_id,
            file_size=create_response.endof_file,
            tree_id=tree_id
        )