16-bit Hash Collisions in .xls Spreadsheets

Published: 2024-07-13. Last Updated: 2024-07-13 06:19:07 UTC
by Didier Stevens (Version: 1)
0 comment(s)

A couple years ago, in diary entry "Unprotecting Malicious Documents For Inspection" I explain how .xls spreadsheets are password protected (but not encrypted). And in follow-up diary entry "Maldocs: Protection Passwords", I talk about an update to my oledump plugin plugin_biff.py to crack these passwords using password lists (by default, an embedded password list is used that is taken from the 2011 public-domain default password list used by John The Ripper).

Since the hashing algorithm used for the protection of .xls files produces a 16-bit integer with its highest bit set, there are 32768 (0x8000) possible hash values (called verifier), and thus ample chance to generate hash collisions.

I generated such a list, and included it in an update of my oledump plugin plugin_biff.py:

I took care to generate passwords prioritizing letters and digits over special characters.

Here is an example of a .xls workbook with a protected sheet. The protection password I used for this sheet is azeqsdwxc, a weak password that is not in the embedded list. Thus this password is not found in the password list when plugin plugin_biff.py attempts to crack it:

With previous versions of plugin plugin_biff.py, the report would state that the password was not cracked. But in this new version, when a password can not be cracked with the embedded or provided password list, the password is taken from the embedded verifier table. In this case, that password is bbbbhz (the verifier is 0xd9b1).

This means that both password azeqsdwxc and bbbbhz hash to the same value: verifier 0xd9b1.

And thus that the sheet can also be unprotected with password bbbbhz too:

So with this new version of oledump plugin plugin_biff.py, a password will always be provided for protected .xls files, whatever the value of the verifier.

Of course, this is only useful if you don't want or can't alter the sheet to remove the protection. Since these passwords just offer protection, and are not actually used to encrypt, it's possible to remove the protection without knowing the password, as I explained in my blog post "Quickpost: oledump.py plugin_biff.py: Remove Sheet Protection From Spreadsheets".

 

Didier Stevens
Senior handler
blog.DidierStevens.com

0 comment(s)

Comments


Diary Archives