Decoding a gMSA Password Blob

  //https://msdn.microsoft.com/en-us/library/hh881234.aspx
    public class msDSManagedPassword
    {

        public short Version
        {
            get;
            set;
        }


        public string CurrentPassword
        {
            get;
            set;
        }


        public string OldPassword
        {
            get;
            set;
        }


        public DateTime dtNextQueryTime
        {
            get;
            set;
        }


        public DateTime dtPwdGoodUntil
        {
            get;
            set;
        }

        //https://msdn.microsoft.com/en-us/library/hh881234.aspx
        public msDSManagedPassword(byte[] blob)
        {

            using (Stream stream = new MemoryStream(blob))
            {
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    this.Version = reader.ReadInt16();

                    short reserved = reader.ReadInt16();

                    //size of blob
                    int length = reader.ReadInt32();

                    if (length != blob.Length)
                    {
                        throw new Exception("Blob is malsized");
                    }

                    short curPwdOffset = reader.ReadInt16();

                    this.CurrentPassword = getUnicodeString(blob, curPwdOffset);

                    short oldPwdOffset = reader.ReadInt16();
                    if (oldPwdOffset > 0)
                    {
                        this.OldPassword = getUnicodeString(blob, oldPwdOffset);
                    }

                    short queryPasswordIntervalOffset = reader.ReadInt16();
                    long queryPasswordIntervalTicks = BitConverter.ToInt64(blob, queryPasswordIntervalOffset);
                    this.dtNextQueryTime = DateTime.UtcNow + TimeSpan.FromTicks(queryPasswordIntervalTicks);


                    short unchangedPasswordIntervalOffset = reader.ReadInt16();
                    long unchangedPasswordIntervalTicks = BitConverter.ToInt64(blob, unchangedPasswordIntervalOffset);
                    this.dtPwdGoodUntil = DateTime.UtcNow + TimeSpan.FromTicks(unchangedPasswordIntervalTicks);
                }
            }
        }



        public static string getUnicodeString(byte[] blob, int index)
        {


            string stOut = "";

            for (int i = index; i < blob.Length; i += 2)
            {
                char ch = BitConverter.ToChar(blob, i);
                if (ch == Char.MinValue)
                {
                    //found the end  .    A null-terminated WCHAR string
                    return stOut;
                }
                stOut = stOut + ch;


            }

            return null;
        }
    }

No comments:

Inputting falsified referrals to this site violates the terms of service of this site and is considered unauthorized access (hacking).