internal static TransactionTransactNamedPipeResponse GetSubcommandResponse(SMBHeader header, TransactionTransactNamedPipeRequest subcommand, NamedPipeShare share, StateObject state) { string openedFilePath = state.GetOpenedFilePath(subcommand.FID); if (openedFilePath == null) { header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } TransactionTransactNamedPipeResponse response = new TransactionTransactNamedPipeResponse(); RemoteService service = share.GetService(openedFilePath); if (service != null) { RPCPDU rpcRequest = RPCPDU.GetPDU(subcommand.WriteData); RPCPDU rpcReply = RemoteServiceHelper.GetRPCReply(rpcRequest, service); response.ReadData = rpcReply.GetBytes(); return(response); } // This code should not execute unless the request sequence is invalid header.Status = NTStatus.STATUS_INVALID_SMB; return(null); }
public override void Write(byte[] buffer, int offset, int count) { // [MC-CIFS] In message mode, the system treats the bytes read or written in each I/O operation to the pipe as a message unit. RPCPDU rpcRequest = RPCPDU.GetPDU(buffer, offset); ProcessRPCRequest(rpcRequest); }
public static List <string> ListShares(INtFileStore namedPipeShare, ShareType?shareType) { NamedPipeHelper.BindPipe(namedPipeShare, ServerService.ServicePipeName, ServerService.ServiceInterfaceGuid, ServerService.ServiceVersion, out NtHandle? pipeHandle, out int maxTransmitFragmentSize).IsSuccessElseThrow(); NetrShareEnumRequest shareEnumRequest = new NetrShareEnumRequest { InfoStruct = new ShareEnum { Level = 1, Info = new ShareInfo1Container() }, PreferedMaximumLength = uint.MaxValue, ServerName = "*" }; byte[] data = shareEnumRequest.GetBytes(); RequestPDU requestPdu = new RequestPDU { Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment, DataRepresentation = { CharacterFormat = CharacterFormat.ASCII, ByteOrder = ByteOrder.LittleEndian, FloatingPointRepresentation = FloatingPointRepresentation.IEEE }, OpNum = (ushort)ServerServiceOpName.NetrShareEnum, Data = data, AllocationHint = (uint)data.Length }; byte[] input = requestPdu.GetBytes(); namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out byte[]? output, maxTransmitFragmentSize); if (!(RPCPDU.GetPDU(output, 0) is ResponsePDU responsePdu)) { throw new NtStatusException(NTStatus.STATUS_NOT_SUPPORTED); } byte[] responseData = responsePdu.Data; while ((responsePdu.Flags & PacketFlags.LastFragment) == 0) { namedPipeShare.ReadFile(out output, pipeHandle, 0, maxTransmitFragmentSize); if (!(RPCPDU.GetPDU(output, 0) is ResponsePDU responsePdu2)) { throw new NtStatusException(NTStatus.STATUS_NOT_SUPPORTED); } responseData = ByteUtils.Concatenate(responseData, responsePdu2.Data); } namedPipeShare.CloseFile(pipeHandle); NetrShareEnumResponse shareEnumResponse = new NetrShareEnumResponse(responseData); if (shareEnumResponse.InfoStruct.Info is ShareInfo1Container shareInfo1 && shareInfo1.Entries != null) { return((from entry in shareInfo1.Entries where !shareType.HasValue || shareType.Value == entry.ShareType.ShareType select entry.NetName.Value).ToList()); } throw new NtStatusException(shareEnumResponse.Result == Win32Error.ERROR_ACCESS_DENIED ? NTStatus.STATUS_ACCESS_DENIED : NTStatus.STATUS_NOT_SUPPORTED); }
public override void Write(byte[] buffer, int offset, int count) { int lengthOfPDUs = 0; do { RPCPDU rpcRequest = RPCPDU.GetPDU(buffer, offset); lengthOfPDUs += rpcRequest.FragmentLength; RPCPDU rpcReply = RemoteServiceHelper.GetRPCReply(rpcRequest, m_service); byte[] replyData = rpcReply.GetBytes(); Append(replyData); }while (lengthOfPDUs < count); }
public static NTStatus ExecuteCall <I, O>(INTFileStore namedPipeShare, object pipeHandle, ushort OpNum, I inputArgs, out O outputData) where I : IRPCRequest { byte[] output; NTStatus status; outputData = default(O); RequestPDU requestPDU = new RequestPDU(); requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment; requestPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII; requestPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian; requestPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE; requestPDU.OpNum = OpNum; requestPDU.Data = inputArgs.GetBytes(); requestPDU.AllocationHint = (uint)requestPDU.Data.Length; byte[] input = requestPDU.GetBytes(); int maxOutputLength = MaxTransmitFragmentSize; status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, maxOutputLength); if (status != NTStatus.STATUS_SUCCESS) { return(status); } ResponsePDU responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU; if (responsePDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(status); } byte[] responseData = responsePDU.Data; while ((responsePDU.Flags & PacketFlags.LastFragment) == 0) { status = namedPipeShare.ReadFile(out output, pipeHandle, 0, maxOutputLength); if (status != NTStatus.STATUS_SUCCESS) { return(status); } responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU; if (responsePDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(status); } responseData = ByteUtils.Concatenate(responseData, responsePDU.Data); } outputData = (O)Activator.CreateInstance(typeof(O), new object[] { responseData }); return(NTStatus.STATUS_SUCCESS); }
public static NTStatus BindPipe(INTFileStore namedPipeShare, string pipeName, Guid interfaceGuid, uint interfaceVersion, out object pipeHandle, out int maxTransmitFragmentSize) { maxTransmitFragmentSize = 0; FileStatus fileStatus; NTStatus status = namedPipeShare.CreateFile(out pipeHandle, out fileStatus, pipeName, (AccessMask)(FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA), 0, ShareAccess.Read | ShareAccess.Write, CreateDisposition.FILE_OPEN, 0, null); if (status != NTStatus.STATUS_SUCCESS) { return(status); } BindPDU bindPDU = new BindPDU(); bindPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment; bindPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII; bindPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian; bindPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE; bindPDU.MaxTransmitFragmentSize = 5680; bindPDU.MaxReceiveFragmentSize = 5680; ContextElement serviceContext = new ContextElement(); serviceContext.AbstractSyntax = new SyntaxID(interfaceGuid, interfaceVersion); serviceContext.TransferSyntaxList.Add(new SyntaxID(RemoteServiceHelper.NDRTransferSyntaxIdentifier, RemoteServiceHelper.NDRTransferSyntaxVersion)); bindPDU.ContextList.Add(serviceContext); byte[] input = bindPDU.GetBytes(); byte[] output; status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, 4096); if (status != NTStatus.STATUS_SUCCESS) { return(status); } BindAckPDU bindAckPDU = RPCPDU.GetPDU(output, 0) as BindAckPDU; if (bindAckPDU == null) { return(NTStatus.STATUS_NOT_SUPPORTED); } maxTransmitFragmentSize = bindAckPDU.MaxTransmitFragmentSize; return(NTStatus.STATUS_SUCCESS); }
public static NTStatus BindPipe(INtFileStore namedPipeShare, string pipeName, Guid interfaceGuid, uint interfaceVersion, out NtHandle?pipeHandle, out int maxTransmitFragmentSize) { maxTransmitFragmentSize = 0; namedPipeShare.CreateFile(out pipeHandle, out _, pipeName, (AccessMask)(FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA), 0, ShareAccess.Read | ShareAccess.Write, CreateDisposition.FILE_OPEN, 0, null); BindPDU bindPdu = new BindPDU { Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment, DataRepresentation = { CharacterFormat = CharacterFormat.ASCII, ByteOrder = ByteOrder.LittleEndian, FloatingPointRepresentation = FloatingPointRepresentation.IEEE }, MaxTransmitFragmentSize = 5680, MaxReceiveFragmentSize = 5680 }; ContextElement serviceContext = new ContextElement { AbstractSyntax = new SyntaxID(interfaceGuid, interfaceVersion) }; serviceContext.TransferSyntaxList.Add(new SyntaxID(RemoteServiceHelper.NDRTransferSyntaxIdentifier, RemoteServiceHelper.NDRTransferSyntaxVersion)); bindPdu.ContextList.Add(serviceContext); byte[] input = bindPdu.GetBytes(); namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out byte[]? output, 4096); if (!(RPCPDU.GetPDU(output, 0) is BindAckPDU bindAckPDU)) { return(NTStatus.STATUS_NOT_SUPPORTED); } maxTransmitFragmentSize = bindAckPDU.MaxTransmitFragmentSize; return(NTStatus.STATUS_SUCCESS); }
public static uint PerformWrite(SMBHeader header, object share, ushort FID, ulong offset, byte[] data, StateObject state) { OpenedFileObject openedFile = state.GetOpenedFileObject(FID); if (openedFile == null) { header.Status = NTStatus.STATUS_INVALID_HANDLE; return(0); } string openedFilePath = openedFile.Path; if (share is NamedPipeShare) { RemoteService service = ((NamedPipeShare)share).GetService(openedFilePath); if (service != null) { RPCPDU rpcRequest = RPCPDU.GetPDU(data); RPCPDU rpcReply = RemoteServiceHelper.GetRPCReply(rpcRequest, service); byte[] replyData = rpcReply.GetBytes(); state.StoreNamedPipeReply(FID, replyData); return((uint)data.Length); } // This code should not execute unless the SMB request (sequence) is invalid header.Status = NTStatus.STATUS_INVALID_SMB; return(0); } else // FileSystemShare { FileSystemShare fileSystemShare = (FileSystemShare)share; IFileSystem fileSystem = fileSystemShare.FileSystem; if (openedFile.IsSequentialAccess && openedFile.Cache.Length > 0) { openedFile.Cache = new byte[0]; // Empty cache } try { Stream stream = fileSystem.OpenFile(openedFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.Seek((long)offset, SeekOrigin.Begin); stream.Write(data, 0, data.Length); stream.Close(); return((uint)data.Length); } catch (IOException ex) { ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex); if (errorCode == (ushort)Win32Error.ERROR_DISK_FULL) { header.Status = NTStatus.STATUS_DISK_FULL; return(0); } else if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION) { // Returning STATUS_SHARING_VIOLATION is undocumented but apparently valid header.Status = NTStatus.STATUS_SHARING_VIOLATION; return(0); } else { header.Status = NTStatus.STATUS_DATA_ERROR; return(0); } } catch (ArgumentOutOfRangeException) { header.Status = NTStatus.STATUS_DATA_ERROR; return(0); } catch (UnauthorizedAccessException) { // The user may have tried to write to a readonly file header.Status = NTStatus.STATUS_ACCESS_DENIED; return(0); } } }
public static List <string> ListShares(INTFileStore namedPipeShare, ShareType?shareType, out NTStatus status) { object pipeHandle; int maxTransmitFragmentSize; status = NamedPipeHelper.BindPipe(namedPipeShare, ServerService.ServicePipeName, ServerService.ServiceInterfaceGuid, ServerService.ServiceVersion, out pipeHandle, out maxTransmitFragmentSize); if (status != NTStatus.STATUS_SUCCESS) { return(null); } NetrShareEnumRequest shareEnumRequest = new NetrShareEnumRequest(); shareEnumRequest.InfoStruct = new ShareEnum(); shareEnumRequest.InfoStruct.Level = 1; shareEnumRequest.InfoStruct.Info = new ShareInfo1Container(); shareEnumRequest.PreferedMaximumLength = UInt32.MaxValue; shareEnumRequest.ServerName = "*"; RequestPDU requestPDU = new RequestPDU(); requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment; requestPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII; requestPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian; requestPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE; requestPDU.OpNum = (ushort)ServerServiceOpName.NetrShareEnum; requestPDU.Data = shareEnumRequest.GetBytes(); requestPDU.AllocationHint = (uint)requestPDU.Data.Length; byte[] input = requestPDU.GetBytes(); byte[] output; int maxOutputLength = maxTransmitFragmentSize; status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, maxOutputLength); if (status != NTStatus.STATUS_SUCCESS) { return(null); } ResponsePDU responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU; if (responsePDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } byte[] responseData = responsePDU.Data; while ((responsePDU.Flags & PacketFlags.LastFragment) == 0) { status = namedPipeShare.ReadFile(out output, pipeHandle, 0, maxOutputLength); if (status != NTStatus.STATUS_SUCCESS) { return(null); } responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU; if (responsePDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } responseData = ByteUtils.Concatenate(responseData, responsePDU.Data); } namedPipeShare.CloseFile(pipeHandle); NetrShareEnumResponse shareEnumResponse = new NetrShareEnumResponse(responseData); ShareInfo1Container shareInfo1 = shareEnumResponse.InfoStruct.Info as ShareInfo1Container; if (shareInfo1 == null || shareInfo1.Entries == null) { if (shareEnumResponse.Result == Win32Error.ERROR_ACCESS_DENIED) { status = NTStatus.STATUS_ACCESS_DENIED; } else { status = NTStatus.STATUS_NOT_SUPPORTED; } return(null); } List <string> result = new List <string>(); foreach (ShareInfo1Entry entry in shareInfo1.Entries) { if (!shareType.HasValue || shareType.Value == entry.ShareType.ShareType) { result.Add(entry.NetName.Value); } } return(result); }
public static List <string> ListShares(INTFileStore namedPipeShare, ShareType?shareType, out NTStatus status) { object pipeHandle; FileStatus fileStatus; status = namedPipeShare.CreateFile(out pipeHandle, out fileStatus, ServerService.ServicePipeName, (AccessMask)(FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA), 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, null); if (status != NTStatus.STATUS_SUCCESS) { return(null); } BindPDU bindPDU = new BindPDU(); bindPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment; bindPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII; bindPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian; bindPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE; bindPDU.MaxTransmitFragmentSize = 5680; bindPDU.MaxReceiveFragmentSize = 5680; ContextElement serverServiceContext = new ContextElement(); serverServiceContext.AbstractSyntax = new SyntaxID(ServerService.ServiceInterfaceGuid, ServerService.ServiceVersion); serverServiceContext.TransferSyntaxList.Add(new SyntaxID(RemoteServiceHelper.NDRTransferSyntaxIdentifier, RemoteServiceHelper.NDRTransferSyntaxVersion)); bindPDU.ContextList.Add(serverServiceContext); byte[] input = bindPDU.GetBytes(); byte[] output; status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, 4096); if (status != NTStatus.STATUS_SUCCESS) { return(null); } BindAckPDU bindAckPDU = RPCPDU.GetPDU(output, 0) as BindAckPDU; if (bindAckPDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } NetrShareEnumRequest shareEnumRequest = new NetrShareEnumRequest(); shareEnumRequest.InfoStruct = new ShareEnum(); shareEnumRequest.InfoStruct.Level = 1; shareEnumRequest.InfoStruct.Info = new ShareInfo1Container(); shareEnumRequest.PreferedMaximumLength = UInt32.MaxValue; shareEnumRequest.ServerName = "*"; RequestPDU requestPDU = new RequestPDU(); requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment; requestPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII; requestPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian; requestPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE; requestPDU.OpNum = (ushort)ServerServiceOpName.NetrShareEnum; requestPDU.Data = shareEnumRequest.GetBytes(); requestPDU.AllocationHint = (uint)requestPDU.Data.Length; input = requestPDU.GetBytes(); int maxOutputLength = bindAckPDU.MaxTransmitFragmentSize; status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, maxOutputLength); if (status != NTStatus.STATUS_SUCCESS) { return(null); } ResponsePDU responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU; if (responsePDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } byte[] responseData = responsePDU.Data; while ((responsePDU.Flags & PacketFlags.LastFragment) == 0) { status = namedPipeShare.ReadFile(out output, pipeHandle, 0, maxOutputLength); if (status != NTStatus.STATUS_SUCCESS) { return(null); } responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU; if (responsePDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } responseData = ByteUtils.Concatenate(responseData, responsePDU.Data); } NetrShareEnumResponse shareEnumResponse = new NetrShareEnumResponse(responseData); ShareInfo1Container shareInfo1 = shareEnumResponse.InfoStruct.Info as ShareInfo1Container; if (shareInfo1 == null || shareInfo1.Entries == null) { if (shareEnumResponse.Result == Win32Error.ERROR_ACCESS_DENIED) { status = NTStatus.STATUS_ACCESS_DENIED; } else { status = NTStatus.STATUS_NOT_SUPPORTED; } return(null); } List <string> result = new List <string>(); foreach (ShareInfo1Entry entry in shareInfo1.Entries) { if (!shareType.HasValue || shareType.Value == entry.ShareType.ShareType) { result.Add(entry.NetName.Value); } } return(result); }