Beispiel #1
0
        private void ReadCommonHeader(NdrBinaryStream pacStream)
        {
            Version = pacStream.Read(1)[0];

            if (Version != NdrConstants.PROTOCOL_VERSION)
            {
                throw new InvalidDataException($"Unknown Protocol version {Version}");
            }

            var headerBits = pacStream.Read(1)[0];

            var endian = headerBits >> 4 & 0x0F;

            if (endian != 0 && endian != 1)
            {
                throw new InvalidDataException($"Unknown endianness {endian}");
            }

            Endian = Convert.ToBoolean(endian);

            Encoding = (byte)(headerBits & 0x0F);

            if (Encoding != 0 && Encoding != 1)
            {
                throw new InvalidDataException($"Unknown encoding {Encoding}");
            }

            Length = pacStream.ReadShort();

            if (Length != NdrConstants.COMMON_HEADER_BYTES)
            {
                throw new InvalidDataException($"Unknown common header length {Length}");
            }
        }
Beispiel #2
0
        public override void ReadBody(NdrBinaryStream stream)
        {
            ClaimSource = (ClaimSourceType)stream.ReadInt();
            Count       = stream.ReadUnsignedInt();

            var claims = new List <ClaimEntry>();

            stream.Seek(4);

            var count = stream.ReadInt();

            if (Count != count)
            {
                throw new InvalidDataException($"Claims count {Count} doesn't match actual count {count}");
            }

            for (var i = 0; i < Count; i++)
            {
                var claim = new ClaimEntry();
                claim.ReadBody(stream);

                claims.Add(claim);
            }

            foreach (var entry in claims)
            {
                entry.ReadValue(stream);
            }

            ClaimEntries = claims;
        }
Beispiel #3
0
        private static IEnumerable <SecurityIdentifier> ParseAttributes(NdrBinaryStream Stream, int count, int pointer)
        {
            var attributes = new List <SecurityIdentifier>();

            if (pointer == 0)
            {
                return(attributes);
            }

            int realCount = Stream.ReadInt();

            if (realCount != count)
            {
                throw new InvalidDataException($"Expected count {count} doesn't match actual count {realCount}");
            }

            for (int i = 0; i < count; i++)
            {
                Stream.Align(4);

                var sid = Stream.ReadRid();

                attributes.Add(new SecurityIdentifier(sid, (SidAttributes)Stream.ReadInt()));
            }

            return(attributes);
        }
Beispiel #4
0
        public virtual void Decode(ReadOnlyMemory <byte> data)
        {
            var stream = new NdrBinaryStream(data.ToArray());

            Header = stream.ReadNdrHeader();

            ReadBody(stream);
        }
Beispiel #5
0
        public override void WriteBody(NdrBinaryStream stream)
        {
            stream.WriteUnsignedInt((int)Type);

            stream.WriteBytes(Signature.Span);

            stream.WriteShort(RODCIdentifier);
        }
Beispiel #6
0
        public RpcHeader(NdrBinaryStream pacStream)
        {
            ReadCommonHeader(pacStream);

            pacStream.Read(4);
            pacStream.Read(8);
            pacStream.Read(4);
        }
Beispiel #7
0
        public override void WriteBody(NdrBinaryStream stream)
        {
            stream.WriteUnsignedInt(ClaimsArray.Count());
            stream.WriteDeferredArray(ClaimsArray);

            stream.WriteShort(ReservedType);
            stream.WriteUnsignedInt(ReservedFieldSize);
            stream.WriteBytes(ReservedField);
        }
Beispiel #8
0
 internal void EncodeType(object val, ClaimType type, NdrBinaryStream stream)
 {
     if (type == ClaimType.CLAIM_TYPE_STRING)
     {
         stream.WriteString(val.ToString());
     }
     else
     {
         stream.WriteUnsignedLong(Convert.ToInt64(val));
     }
 }
Beispiel #9
0
        public override void ReadBody(NdrBinaryStream stream)
        {
            stream.Seek(4); // offset for Id

            Type = (ClaimType)stream.ReadShort();

            stream.Align(4);

            Count = stream.ReadUnsignedInt();

            stream.Seek(4); // offset to values
        }
Beispiel #10
0
        public virtual void Encode(NdrBinaryStream stream)
        {
            if (Header == null)
            {
                Header = new RpcHeader();
            }

            Header.WriteCommonHeader(stream);

            WriteBody(stream);

            stream.WriteDeferred();
        }
Beispiel #11
0
        public override void ReadBody(NdrBinaryStream stream)
        {
            Type = (ChecksumType)stream.ReadUnsignedInt();

            SignaturePosition = (int)stream.Position;
            Signature         = SetSignatureValue(Type, size => stream.Read(size));

            Validator = CryptoService.CreateChecksumValidator(Type, Signature, signatureData);

            if (stream.Position < stream.Length)
            {
                RODCIdentifier = stream.ReadShort();
            }
        }
Beispiel #12
0
        public void WriteCommonHeader(NdrBinaryStream stream)
        {
            stream.WriteBytes(new byte[] { NdrConstants.PROTOCOL_VERSION });

            byte headerBits = 0;

            headerBits |= Convert.ToByte(Encoding);
            headerBits |= (byte)((1 << 4) & Convert.ToByte(Endian));

            stream.WriteBytes(new byte[] { headerBits });

            stream.WriteShort(NdrConstants.COMMON_HEADER_BYTES);
            stream.WriteBytes(Enumerable.Repeat((byte)0, 4 + 8 + 4).ToArray());
        }
Beispiel #13
0
        public override void ReadBody(NdrBinaryStream stream)
        {
            Count = stream.ReadInt();

            stream.Seek(4);

            ReservedType      = stream.ReadShort();
            ReservedFieldSize = stream.ReadInt();

            ReservedField = stream.Read(ReservedFieldSize);

            stream.Align(8);

            ClaimsArray = ReadClaimsArray(stream);
        }
Beispiel #14
0
        public virtual ReadOnlyMemory <byte> Encode()
        {
            if (cachedEncodedValue.Length <= 0 || IsDirty)
            {
                var stream = new NdrBinaryStream();

                WriteBody(stream);

                cachedEncodedValue = stream.ToMemory();

                IsDirty = false;
            }

            return(cachedEncodedValue);
        }
Beispiel #15
0
        internal void ReadValue(NdrBinaryStream stream)
        {
            Id = stream.ReadString();

            stream.Align(4);

            var count = stream.ReadInt();

            if (count != Count)
            {
                throw new InvalidDataException($"ValueCount {Count} doesn't match actual count {count} for claim {Id}.");
            }

            ReadValues(stream);
        }
Beispiel #16
0
        public string ReadString(NdrBinaryStream reader)
        {
            if (pointer == 0)
            {
                return(null);
            }

            var result = reader.ReadString(maxLength);

            int expected = length / 2;

            if (result.Length != expected)
            {
                throw new InvalidDataException($"Read length {result.Length} doesn't match expected length {expected}");
            }

            return(result);
        }
Beispiel #17
0
        private IEnumerable <ClaimsArray> ReadClaimsArray(NdrBinaryStream stream)
        {
            var count = stream.ReadInt();

            if (count != Count)
            {
                throw new InvalidDataException($"Array count {Count} doesn't match actual count {count}");
            }

            var claims = new List <ClaimsArray>();

            for (var i = 0; i < Count; i++)
            {
                var array = new ClaimsArray();
                array.ReadBody(stream);

                claims.Add(array);
            }

            return(claims);
        }
Beispiel #18
0
        private static SecurityIdentifier[] ParseExtraSids(NdrBinaryStream Stream, int extraSidCount, int extraSidPointer)
        {
            if (extraSidPointer == 0)
            {
                return(new SecurityIdentifier[0]);
            }

            int realExtraSidCount = Stream.ReadInt();

            if (realExtraSidCount != extraSidCount)
            {
                throw new InvalidDataException($"Expected Sid count {extraSidCount} doesn't match actual sid count {realExtraSidCount}");
            }

            var extraSidAtts = new SecurityIdentifier[extraSidCount];

            var pointers   = new int[extraSidCount];
            var attributes = new SidAttributes[extraSidCount];

            for (int i = 0; i < extraSidCount; i++)
            {
                pointers[i]   = Stream.ReadInt();
                attributes[i] = (SidAttributes)Stream.ReadUnsignedInt();
            }

            for (int i = 0; i < extraSidCount; i++)
            {
                SecurityIdentifier sid = null;

                if (pointers[i] != 0)
                {
                    sid = new SecurityIdentifier(Stream.ReadSid(), attributes[i]);
                }

                extraSidAtts[i] = sid;
            }

            return(extraSidAtts);
        }
Beispiel #19
0
        private void ReadValues(NdrBinaryStream stream)
        {
            if (Type == ClaimType.CLAIM_TYPE_STRING)
            {
                var pointers = new int[Count];

                for (var i = 0; i < Count; i++)
                {
                    pointers[i] = stream.ReadInt();
                }
            }

            values = new object[Count];

            for (var i = 0; i < Count; i++)
            {
                switch (Type)
                {
                case ClaimType.CLAIM_TYPE_BOOLEAN:
                    values[i] = Convert.ToBoolean(stream.ReadLong());
                    break;

                case ClaimType.CLAIM_TYPE_INT64:
                    values[i] = stream.ReadLong();
                    break;

                case ClaimType.CLAIM_TYPE_UINT64:
                    values[i] = (ulong)stream.ReadLong();
                    break;

                case ClaimType.CLAIM_TYPE_STRING:
                    values[i] = stream.ReadString();
                    break;
                }
            }
        }
Beispiel #20
0
        public override void WriteBody(NdrBinaryStream stream)
        {
            stream.WriteFiletime(LogonTime);
            stream.WriteFiletime(LogoffTime);
            stream.WriteFiletime(KickOffTime);
            stream.WriteFiletime(PwdLastChangeTime);
            stream.WriteFiletime(PwdCanChangeTime);
            stream.WriteFiletime(PwdMustChangeTime);

            stream.WriteRPCUnicodeString(UserName);
            stream.WriteRPCUnicodeString(UserDisplayName);
            stream.WriteRPCUnicodeString(LogonScript);
            stream.WriteRPCUnicodeString(ProfilePath);
            stream.WriteRPCUnicodeString(HomeDirectory);
            stream.WriteRPCUnicodeString(HomeDrive);

            stream.WriteShort((short)LogonCount);
            stream.WriteShort((short)BadPasswordCount);

            stream.WriteRid(UserSid);
            stream.WriteRid(GroupSid);

            WriteSidArray(stream, GroupSids);

            if (ExtraSids != null)
            {
                UserFlags |= UserFlags.LOGON_EXTRA_SIDS;
            }

            if (ResourceGroups != null)
            {
                UserFlags |= UserFlags.LOGON_RESOURCE_GROUPS;
            }

            stream.WriteUnsignedInt((int)UserFlags);

            stream.WriteBytes(new byte[16]);

            stream.WriteRPCUnicodeString(ServerName);
            stream.WriteRPCUnicodeString(DomainName);

            stream.WriteSid(DomainSid, "DomainSid");

            stream.WriteBytes(new byte[8]);

            stream.WriteUnsignedInt((int)UserAccountControl);
            stream.WriteUnsignedInt(SubAuthStatus);

            stream.WriteFiletime(LastSuccessfulILogon);
            stream.WriteFiletime(LastFailedILogon);
            stream.WriteUnsignedInt(FailedILogonCount);

            // reserved3
            stream.WriteUnsignedInt(0);

            WriteExtraSids(stream, ExtraSids);

            stream.WriteSid(ResourceDomainSid, "ResourceDomainSid");

            WriteSidArray(stream, ResourceGroups);

            // write GroupSids
            // write DomainSid
            // write ExtraSids
            // write ResourceDomainSid
            // write ResourceGroups
        }
Beispiel #21
0
        public override void ReadBody(NdrBinaryStream stream)
        {
            LogonTime         = stream.ReadFiletime();
            LogoffTime        = stream.ReadFiletime();
            KickOffTime       = stream.ReadFiletime();
            PwdLastChangeTime = stream.ReadFiletime();
            PwdCanChangeTime  = stream.ReadFiletime();
            PwdMustChangeTime = stream.ReadFiletime();

            var userName        = stream.ReadRPCUnicodeString();
            var userDisplayName = stream.ReadRPCUnicodeString();
            var logonScript     = stream.ReadRPCUnicodeString();
            var profilePath     = stream.ReadRPCUnicodeString();
            var homeDirectory   = stream.ReadRPCUnicodeString();
            var homeDrive       = stream.ReadRPCUnicodeString();

            LogonCount       = stream.ReadShort();
            BadPasswordCount = stream.ReadShort();

            var userSid  = stream.ReadRid();
            var groupSid = stream.ReadRid();

            // Groups information
            var groupCount   = stream.ReadInt();
            var groupPointer = stream.ReadInt();

            UserFlags = (UserFlags)stream.ReadInt();

            // sessionKey
            stream.Read(new byte[16]);

            var serverNameString = stream.ReadRPCUnicodeString();
            var domainNameString = stream.ReadRPCUnicodeString();
            var domainIdPointer  = stream.ReadInt();

            // reserved1
            stream.Read(new byte[8]);

            UserAccountControl = (UserAccountControlFlags)stream.ReadInt();

            SubAuthStatus        = stream.ReadInt();
            LastSuccessfulILogon = stream.ReadFiletime();
            LastFailedILogon     = stream.ReadFiletime();
            FailedILogonCount    = stream.ReadInt();

            // reserved3
            stream.ReadInt();

            // Extra SIDs information
            var extraSidCount   = stream.ReadInt();
            var extraSidPointer = stream.ReadInt();

            var resourceDomainIdPointer = stream.ReadInt();
            var resourceGroupCount      = stream.ReadInt();
            var resourceGroupPointer    = stream.ReadInt();

            UserName        = userName.ReadString(stream);
            UserDisplayName = userDisplayName.ReadString(stream);
            LogonScript     = logonScript.ReadString(stream);
            ProfilePath     = profilePath.ReadString(stream);
            HomeDirectory   = homeDirectory.ReadString(stream);
            HomeDrive       = homeDrive.ReadString(stream);

            // Groups data
            var groupSids = ParseAttributes(stream, groupCount, groupPointer);

            // Server related strings
            ServerName = serverNameString.ReadString(stream);
            DomainName = domainNameString.ReadString(stream);

            if (domainIdPointer != 0)
            {
                DomainSid = stream.ReadSid();
            }

            UserSid  = userSid.AppendTo(DomainSid);
            GroupSid = groupSid.AppendTo(DomainSid);

            GroupSids = groupSids.Select(g => g.AppendTo(DomainSid)).ToList();

            if (UserFlags.HasFlag(UserFlags.LOGON_EXTRA_SIDS))
            {
                ExtraSids = ParseExtraSids(stream, extraSidCount, extraSidPointer).ToList();
            }

            if (resourceDomainIdPointer != 0)
            {
                ResourceDomainSid = stream.ReadSid();
            }

            if (UserFlags.HasFlag(UserFlags.LOGON_RESOURCE_GROUPS))
            {
                ResourceGroups = ParseAttributes(
                    stream,
                    resourceGroupCount,
                    resourceGroupPointer
                    ).Select(g => g.AppendTo(ResourceDomainSid)).ToList();
            }
        }
Beispiel #22
0
 public override void WriteBody(NdrBinaryStream stream)
 {
 }
Beispiel #23
0
 private void WriteSidArray(NdrBinaryStream stream, IEnumerable <SecurityIdentifier> sids)
 {
     stream.WriteRids(sids);
 }
Beispiel #24
0
 private void WriteExtraSids(NdrBinaryStream stream, IEnumerable <SecurityIdentifier> extraSids)
 {
     stream.WriteSids(extraSids, "ExtraSids");
 }
Beispiel #25
0
 public override void WriteBody(NdrBinaryStream stream, Queue <Action> deferredFurther)
 {
     stream.WriteClaimEntry(this, deferredFurther);
 }
Beispiel #26
0
 public override void WriteBody(NdrBinaryStream stream)
 {
     stream.WriteClaimsArray(this);
 }
Beispiel #27
0
 public abstract void ReadBody(NdrBinaryStream stream);
Beispiel #28
0
 public virtual void WriteBody(NdrBinaryStream stream, Queue <Action> deferredFurther)
 {
     WriteBody(stream);
 }
Beispiel #29
0
 public abstract void WriteBody(NdrBinaryStream stream);