예제 #1
0
        private static IEnumerable <SecurityIdentifier> ParseAttributes(NdrBinaryReader pacStream, int count, int pointer)
        {
            var attributes = new List <SecurityIdentifier>();

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

            int realCount = pacStream.ReadInt();

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

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

                var sid = pacStream.ReadRid();

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

            return(attributes);
        }
예제 #2
0
        private void ReadValues(NdrBinaryReader Stream)
        {
            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;
                }
            }
        }
예제 #3
0
        public PacSignature(byte[] infoBuffer, ref byte[] signatureData)
        {
            var pacStream = new NdrBinaryReader(infoBuffer);

            Type = (ChecksumType)pacStream.ReadUnsignedInt();

            SignaturePosition = (int)pacStream.Position;

            switch (Type)
            {
            case ChecksumType.KERB_CHECKSUM_HMAC_MD5:
                Signature = pacStream.Read(16);
                Validator = new HmacMd5PacValidator(Signature, ref signatureData);
                break;

            case ChecksumType.HMAC_SHA1_96_AES128:
                Signature = pacStream.Read(12);
                Validator = new HmacAes128PacValidator(Signature, ref signatureData);
                break;

            case ChecksumType.HMAC_SHA1_96_AES256:
                Signature = pacStream.Read(12);
                Validator = new HmacAes256PacValidator(Signature, ref signatureData);
                break;
            }

            if (pacStream.Position < pacStream.Length)
            {
                RODCIdentifier = pacStream.ReadShort();
            }
        }
예제 #4
0
        internal void ReadValue(NdrBinaryReader 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}.");
            }

            if (Type == ClaimType.CLAIM_TYPE_STRING)
            {
                var ptr = stream.ReadInt();

                if (count > 1 && ptr != 0)
                {
                    stream.Seek(8);
                }
            }

            ReadValues(stream);
        }
예제 #5
0
        private void ReadCommonHeader(NdrBinaryReader 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}");
            }
        }
예제 #6
0
        public ClaimsArray(NdrBinaryReader stream)
            : base(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++)
            {
                claims.Add(new ClaimEntry(Stream));
            }

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

            ClaimEntries = claims;
        }
예제 #7
0
        public RpcHeader(NdrBinaryReader pacStream)
        {
            ReadCommonHeader(pacStream);

            pacStream.Read(4);
            pacStream.Read(8);
            pacStream.Read(4);
        }
예제 #8
0
        public ClaimEntry(NdrBinaryReader pacStream)
        {
            pacStream.Seek(4);

            Type = (ClaimType)pacStream.ReadShort();

            pacStream.Align(4);

            Count = pacStream.ReadUnsignedInt();

            pacStream.Seek(4);
        }
예제 #9
0
        public ClaimEntry(NdrBinaryReader stream)
            : base(stream)
        {
            Stream.Seek(4);

            Type = (ClaimType)Stream.ReadShort();

            Stream.Align(4);

            Count = Stream.ReadUnsignedInt();

            Stream.Seek(4);
        }
예제 #10
0
        public string ReadString(NdrBinaryReader 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);
        }
예제 #11
0
        private IEnumerable <ClaimsArray> ReadClaimsArray(NdrBinaryReader pacStream)
        {
            var count = pacStream.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++)
            {
                claims.Add(new ClaimsArray(pacStream));
            }

            return(claims);
        }
예제 #12
0
        public ClaimsSet(byte[] claims)
        {
            var pacStream = new NdrBinaryReader(claims);

            Header = new RpcHeader(pacStream);

            Count = pacStream.ReadInt();

            pacStream.Seek(4);

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

            ReservedField = pacStream.Read(ReservedFieldSize);

            pacStream.Align(8);

            ClaimsArray = ReadClaimsArray(pacStream);
        }
예제 #13
0
        private static SecurityIdentifier[] ParseExtraSids(NdrBinaryReader pacStream, int extraSidCount, int extraSidPointer)
        {
            if (extraSidPointer == 0)
            {
                return(new SecurityIdentifier[0]);
            }

            int realExtraSidCount = pacStream.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]   = pacStream.ReadInt();
                attributes[i] = (SidAttributes)pacStream.ReadUnsignedInt();
            }

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

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

                extraSidAtts[i] = sid;
            }

            return(extraSidAtts);
        }
예제 #14
0
        public PacLogonInfo(byte[] node)
        {
            var pacStream = new NdrBinaryReader(node);

            Header = new RpcHeader(pacStream);

            LogonTime         = pacStream.ReadFiletime();
            LogoffTime        = pacStream.ReadFiletime();
            KickOffTime       = pacStream.ReadFiletime();
            PwdLastChangeTime = pacStream.ReadFiletime();
            PwdCanChangeTime  = pacStream.ReadFiletime();
            PwdMustChangeTime = pacStream.ReadFiletime();

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

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

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

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

            UserFlags = (UserFlags)pacStream.ReadInt();

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

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

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

            UserAccountControl = (UserAccountControlFlags)pacStream.ReadInt();

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

            // reserved3
            pacStream.ReadInt();

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

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

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

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

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

            if (domainIdPointer != 0)
            {
                DomainSid = pacStream.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(pacStream, extraSidCount, extraSidPointer).Select(e => e.AppendTo(DomainSid)).ToList();
            }

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

            if (UserFlags.HasFlag(UserFlags.LOGON_RESOURCE_GROUPS))
            {
                ResourceGroups = ParseAttributes(
                    pacStream,
                    resourceGroupCount,
                    resourceGroupPointer
                    ).Select(g => g.AppendTo(DomainSid)).ToList();
            }
        }