KDBX 4.1 recovered by PhotoRec opens correctly but shows empty entries — URLs visible in raw strings, protected fields may be affected by inner stream cipher misalignment #13184
Unanswered
otavio-cyber
asked this question in
Q&A
Replies: 1 comment 3 replies
-
|
This seems impossible. Running strings across a real kdbx file would return nothing, especially not urls. When you open this kdbx file in kepassxc gui, what happens? You only mentioned command line tools. |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone,
I'm trying to recover a KeePass 4.1 database that was accidentally overwritten on a Debian Linux system (single disk, no backup). I used PhotoRec to recover deleted files and obtained ~44 .kdbx files. After extensive analysis, I believe this may be related to how KDBX 4.1 handles the inner random stream cipher for protected fields.
Environment:
OS: Debian Linux
KeePass client: KeePassXC (KDBX 4.1)
Recovery tool: PhotoRec (default options, only kdbx extension selected)
Analysis library: pykeepass 4.1.1
What works:
All recovered files open successfully with the correct password
Group structure is intact: ['Raíz', 'Falcone', 'Factoria', 'Duo', 'Alligare']
The largest file (44MB) decrypts without errors
Meta and Root nodes are present and well-formed
The problem:
pykeepass and keepassxc-cli both report 0 entries across all large files
Direct XML inspection confirms this:
pythonkp = PyKeePass(arq, password='...')
tree = kp.tree.getroot()
print(len(tree.findall('.//Entry'))) # returns 0
print(len(tree.findall('.//Group'))) # returns 5 (correct groups)
strings f142409728.kdbx | grep -i "http|url|@"
Output includes real URLs like brasilverdelonas.com.br, nfmotors.com.br, adsmanager.facebook.com with specific account IDs, etc.
Technical hypothesis based on KDBX spec:
After reading the KDBX XML payload spec, I noticed:
KDBX 4.1 uses an inner random stream cipher to protect sensitive fields (Password, Notes) marked as Protected=True
URL fields are not marked as protected — which explains exactly why URLs appear in the raw strings output but entries don't show up through the XML parser
PhotoRec likely recovered a version of the file where the inner stream cipher state is misaligned — the outer decryption works (password accepted, groups visible), but the inner cipher fails silently on protected fields, causing pykeepass to return 0 entries
Question:
Is it possible that PhotoRec recovered a file where the outer AES/ChaCha20 decryption succeeds but the inner random stream cipher (ChaCha20/Salsa20) is in a corrupted or misaligned state — causing the XML parser to silently drop all entries that contain protected fields?
If so, is there any known technique or tool to:
Inspect the raw decrypted XML before inner cipher processing
Attempt to re-align or brute-force the inner stream cipher state
Extract entries that have at least some unprotected fields (URL, Title, Username) even if Password/Notes are unrecoverable
The original database had ~200 entries across 4 groups (Falcone, Factoria, Duo, Alligare). Even recovering titles, usernames and URLs without passwords would be enormously helpful.
Any guidance on the low-level KDBX 4.1 binary structure or tools for this scenario would be greatly appreciated.
Thank you.
Beta Was this translation helpful? Give feedback.
All reactions