Esempio n. 1
0
        public NTStatus DeviceIOControl(object handle, uint ctlCode, byte[] input, out byte[] output, int maxOutputLength)
        {
            if ((IoControlCode)ctlCode == IoControlCode.FSCTL_PIPE_TRANSCEIVE)
            {
                return(FsCtlPipeTranscieve(handle, input, out output, maxOutputLength));
            }

            output = null;
            NTTransactIOCTLRequest subcommand = new NTTransactIOCTLRequest();

            subcommand.FID          = (ushort)handle;
            subcommand.FunctionCode = ctlCode;
            subcommand.IsFsctl      = true;
            subcommand.Data         = input;

            NTTransactRequest request = new NTTransactRequest();

            request.Function            = subcommand.SubcommandName;
            request.Setup               = subcommand.GetSetup();
            request.TransParameters     = subcommand.GetParameters(m_client.Unicode);
            request.TransData           = subcommand.GetData();
            request.TotalDataCount      = (uint)request.TransData.Length;
            request.TotalParameterCount = (uint)request.TransParameters.Length;
            request.MaxParameterCount   = NTTransactIOCTLResponse.ParametersLength;
            request.MaxDataCount        = (uint)maxOutputLength;

            TrySendMessage(request);
            SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_NT_TRANSACT);

            if (reply != null)
            {
                if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is NTTransactResponse)
                {
                    NTTransactResponse      response           = (NTTransactResponse)reply.Commands[0];
                    NTTransactIOCTLResponse subcommandResponse = new NTTransactIOCTLResponse(response.Setup, response.TransData);
                    output = subcommandResponse.Data;
                }
                return(reply.Header.Status);
            }
            return(NTStatus.STATUS_INVALID_SMB);
        }
Esempio n. 2
0
        public void DeviceIOControl(NtHandle handle, uint ctlCode, byte[] input, out byte[]?output, int maxOutputLength)
        {
            if ((IoControlCode)ctlCode == IoControlCode.FSCTL_PIPE_TRANSCEIVE)
            {
                FsCtlPipeTranscieve(handle, input, out output, maxOutputLength);
                return;
            }
            NTTransactIOCTLRequest subcommand = new NTTransactIOCTLRequest
            {
                FID          = ((Smb1Handle)handle).FID,
                FunctionCode = ctlCode,
                IsFsctl      = true,
                Data         = input
            };

            NTTransactRequest request = new NTTransactRequest
            {
                Function        = subcommand.SubcommandName,
                Setup           = subcommand.GetSetup(),
                TransParameters = subcommand.GetParameters(m_client.Unicode),
                TransData       = subcommand.GetData()
            };

            request.TotalDataCount      = (uint)request.TransData.Length;
            request.TotalParameterCount = (uint)request.TransParameters.Length;
            request.MaxParameterCount   = NTTransactIOCTLResponse.ParametersLength;
            request.MaxDataCount        = (uint)maxOutputLength;

            TrySendMessage(request);
            SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_NT_TRANSACT);

            if (reply.Header.Status != NTStatus.STATUS_SUCCESS || !(reply.Commands[0] is NTTransactResponse ntTransactResponse))
            {
                throw new NtStatusException(reply.Header.Status);
            }
            NTTransactIOCTLResponse subcommandResponse = new NTTransactIOCTLResponse(ntTransactResponse.Setup, ntTransactResponse.TransData);

            output = subcommandResponse.Data;
        }
Esempio n. 3
0
        private static NTTransactIOCTLResponse GetSubcommandResponse(SMB1Header header, uint maxDataCount, NTTransactIOCTLRequest subcommand, ISMBShare share, SMB1ConnectionState state)
        {
            SMB1Session session = state.GetSession(header.UID);
            string      ctlCode = Enum.IsDefined(typeof(IoControlCode), subcommand.FunctionCode) ? ((IoControlCode)subcommand.FunctionCode).ToString() : ("0x" + subcommand.FunctionCode.ToString("X8"));

            if (!subcommand.IsFsctl)
            {
                // [MS-SMB] If the IsFsctl field is set to zero, the server SHOULD fail the request with STATUS_NOT_SUPPORTED
                state.LogToServer(Severity.Verbose, "IOCTL: Non-FSCTL requests are not supported. CTL Code: {0}", ctlCode);
                header.Status = NTStatus.STATUS_NOT_SUPPORTED;
                return(null);
            }

            OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID);

            if (openFile == null)
            {
                state.LogToServer(Severity.Verbose, "IOCTL failed. CTL Code: {0}. Invalid FID. (UID: {1}, TID: {2}, FID: {3})", ctlCode, header.UID, header.TID, subcommand.FID);
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }

            int maxOutputLength = (int)maxDataCount;

            byte[] output;
            header.Status = share.FileStore.DeviceIOControl(openFile.Handle, subcommand.FunctionCode, subcommand.Data, out output, maxOutputLength);
            if (header.Status != NTStatus.STATUS_SUCCESS && header.Status != NTStatus.STATUS_BUFFER_OVERFLOW)
            {
                state.LogToServer(Severity.Verbose, "IOCTL failed. CTL Code: {0}. NTStatus: {1}. (FID: {2})", ctlCode, header.Status, subcommand.FID);
                return(null);
            }

            state.LogToServer(Severity.Verbose, "IOCTL succeeded. CTL Code: {0}. (FID: {1})", ctlCode, subcommand.FID);
            NTTransactIOCTLResponse response = new NTTransactIOCTLResponse();

            response.Data = output;
            return(response);
        }
Esempio n. 4
0
        private static NTTransactIOCTLResponse GetSubcommandResponse(SMB1Header header, NTTransactIOCTLRequest subcommand, ISMBShare share, SMB1ConnectionState state)
        {
            SMB1Session             session  = state.GetSession(header.UID);
            NTTransactIOCTLResponse response = new NTTransactIOCTLResponse();

            if (subcommand.IsFsctl)
            {
                OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID);
                if (openFile == null)
                {
                    header.Status = NTStatus.STATUS_INVALID_HANDLE;
                    return(null);
                }
                int    maxOutputLength = UInt16.MaxValue;
                byte[] output;
                header.Status = share.FileStore.DeviceIOControl(openFile.Handle, subcommand.FunctionCode, subcommand.Data, out output, maxOutputLength);
                if (header.Status != NTStatus.STATUS_SUCCESS)
                {
                    return(null);
                }

                response.Data = output;
                return(response);
            }
            else
            {
                // [MS-SMB] If the IsFsctl field is set to zero, the server SHOULD fail the request with STATUS_NOT_SUPPORTED
                header.Status = NTStatus.STATUS_NOT_SUPPORTED;
                return(null);
            }
        }
        private static NTTransactIOCTLResponse GetSubcommandResponse(SMBHeader header, NTTransactIOCTLRequest subcommand)
        {
            const uint FSCTL_CREATE_OR_GET_OBJECT_ID = 0x900C0;

            NTTransactIOCTLResponse response = new NTTransactIOCTLResponse();

            if (subcommand.IsFsctl)
            {
                if (subcommand.FunctionCode == FSCTL_CREATE_OR_GET_OBJECT_ID)
                {
                    ObjectIDBufferType1 objectID = new ObjectIDBufferType1();
                    objectID.ObjectId = Guid.NewGuid();
                    response.Data     = objectID.GetBytes();
                    return(response);
                }
            }

            header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
            return(null);
        }