예제 #1
0
        public NtlmMessage(ReadOnlyMemory <byte> ntlm)
        {
            bool         canRead;
            BinaryReader reader;

            do
            {
                canRead = CanReadNtlmMessage(ntlm, out byte[] actualSignature, out reader, out AsnReader asnReader);

                if (!canRead)
                {
                    throw new InvalidDataException($"Unknown NTLM message signature. Actual: 0x{actualSignature:X}; Expected: 0x{MessageSignature:X}");
                }

                if (asnReader == null)
                {
                    break;
                }

                asnReader = asnReader.ReadSequence(NtlmContextTag);
                NegTokenResp.Decode(asnReader, out NegTokenResp resp);

                ntlm = resp.ResponseToken.Value;
            }while (canRead);

            MessageType = (NtlmMessageType)reader.ReadInt32();

            if (MessageType != NtlmMessageType.Challenge)
            {
                return;
            }

            Flags = (NtlmNegotiateFlag)reader.ReadInt32();

            var domainNameLength       = reader.ReadInt16();
            var domainNameMaxLength    = reader.ReadInt16();
            var domainNameBufferOffset = reader.ReadInt32();

            var workstationLength       = reader.ReadInt16();
            var workstationMaxLength    = reader.ReadInt16();
            var workstationBufferOffset = reader.ReadInt32();

            var version = reader.ReadInt64();

            if ((Flags & NtlmNegotiateFlag.NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) > 0)
            {
                reader.BaseStream.Seek(domainNameBufferOffset, SeekOrigin.Begin);

                DomainName = Encoding.ASCII.GetString(reader.ReadBytes(domainNameLength));
            }

            if ((Flags & NtlmNegotiateFlag.NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) > 0)
            {
                reader.BaseStream.Seek(workstationBufferOffset, SeekOrigin.Begin);

                Workstation = Encoding.ASCII.GetString(reader.ReadBytes(workstationLength));
            }

            reader.Dispose();
        }
예제 #2
0
        internal static void Decode <T>(AsnReader reader, out T decoded)
            where T : NegotiationToken, new()
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            decoded = new T();

            Asn1Tag   tag = reader.PeekTag();
            AsnReader explicitReader;

            if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
            {
                explicitReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
                NegTokenInit.Decode <NegTokenInit>(explicitReader, out NegTokenInit tmpInitialToken);
                decoded.InitialToken = tmpInitialToken;
                explicitReader.ThrowIfNotEmpty();
            }
            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
            {
                explicitReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
                NegTokenResp.Decode <NegTokenResp>(explicitReader, out NegTokenResp tmpResponseToken);
                decoded.ResponseToken = tmpResponseToken;
                explicitReader.ThrowIfNotEmpty();
            }
            else
            {
                throw new CryptographicException();
            }
        }