HPQPswd Encrypted Passwords Decryption

HPQPswd Encrypted Passwords Decryption

Ever wondered how to decrypt HPQPswd encrypted passwords? So did I when, for the first time, I came across a strange file called password.bin with a magic value of _HPPW12_.

It was easy to establish a link between this strange file and HpqPswd.exe as the password.bin file was accompanied by BIOSConfigUtility64.exe (an HP BIOS/UEFI configuration utility part of the HP System Software Manager). HP describes the HPQPswd utility as a utility that accepts a user entered password, encrypts the password and then stores it in a file for use by the BIOS.

After looking at the HPQPswd import table, it was clear that it was leveraging the Windows cryptographic API. By using API Monitor it was possible to trace how the utility uses the API (tested with “thispassword” as the password).

 2CryptAcquireContextW ( 0x003eefc4, "HPQPswd2012", "Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_DELETEKEYSET )
 3CryptAcquireContextW ( 0x003eefc4, "HPQPswd2012", "Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_NEWKEYSET )
 4CryptImportKey ( 0x064f28a8, 0x064f0918, 44, NULL, 0, 0x003eeeec )
 5CryptEncrypt ( 0x0652d648, NULL, TRUE, 64, NULL, 0x003eeef0, 24 )
 6CryptEncrypt ( 0x0652d648, NULL, TRUE, 64, 0x0654be20, 0x003eeef0, 32 )
 7CryptDestroyKey ( 0x0652d648 )
 8WriteFile ( 0x000004d0, 0x0645abd0, 42, 0x003ed360, NULL )
 9CloseHandle ( 0x000004d0 )
10CryptReleaseContext ( 0x064f28a8, 0 )

Using the API Monitor memory editor on address 0x064f0918 (more information at CryptImportKey documentation) it was possible to obtain the byte array that contains the PUBLICKEYSTRUC blob header followed by the encryption key (in this case the key is in plaintext, but even if it wasn’t, it could be used as is).

10000  08 02 00 00 10 66 00 00  .....f..
20009  20 00 00 00 4a 14 b6 96   ...J...
30011  32 ff 83 6b 42 88 da 79  2..kB..y
40018  1c 0b d3 77 a5 49 ed 9d  .I.....w
50020  83 9f e2 d6 52 54 71 0c  ....RTq.
60024  3e bd 1e 33              >..3

Mapping the above hexadecimal dump to the structure results in the following.

1typedef struct _PUBLICKEYSTRUC {
2  BYTE   bType;    // 0x08, PLAINTEXTKEYBLOB
3  BYTE   bVersion; // 0x02, CUR_BLOB_VERSION
4  WORD   reserved; // 0x0000
5  ALG_ID aiKeyAlg; // 0x00006610, CALG_AES_256

This structure is followed by the length of the key 0x00000020 (starting at byte 9 of the hexadecimal dump) and the key itself (starting at byte 13). Now that the encryption key was obtained, the next step was to understand the format for the file that will store the encrypted password. Once again by using the API Monitor memory editor on address 0x0654be20 (more information at CryptEncrypt documentation) it was possible to obtain the test password in encrypted form. Follows the hexadecimal dump.

10000  b8 c2 ba e2 2f c8 3a c1  ..../.:.
20009  0d ba 00 57 5a a9 e7 59  ...WZ..Y
30011  c9 f6 01 b3 e7 84 24 66  ......$f
40014  8c 22 b8 b0 74 d9 ff fe  ."..t...

Looking at the resulting file hexadecimal dump.

10000  5f 48 50 50 57 31 32 5f 20 00  _HPPW12_ .
2000B  b8 c2 ba e2 2f c8 3a c1 0d ba  ..../.:...
30014  00 57 5a a9 e7 59 c9 f6 01 b3  .WZ..Y....
4001E  e7 84 24 66 8c 22 b8 b0 74 d9  ..$f."..t.
50028  ff fe                          ..

It was then possible to understand the file format:

  • Magic value _HPPW12_ (8 bytes)
  • Length of the encrypted password 0x0020 (32 bytes)
  • Encrypted password

With this information at hand, I created a small C# utility that is able to decrypt HPQPswd encrypted passwords. Suffice to say the decryption of the password.bin file was successful.

More information on the utility can be found in its project page. Hope it is helpful ;)