kkamagui / bitleaker

This tool can decrypt a BitLocker-locked partition with the TPM vulnerability
Other
181 stars 35 forks source link

TPM2_Load failure #14

Open edmcman opened 1 year ago

edmcman commented 1 year ago

I'm having a somewhat similar problem to #9. I'm attaching my bitleaker log: log.txt

I'm fairly new to TPM, so I've been trying to understand what is happening. As far as I can tell, bitleaker reads a binary blob from dislocker, and that is supposed to contain 220 bytes of the priv/pub object, and the rest is something else.

Here is the snippet that dislocker is returning:

Tue May  2 10:34:49 2023 [DEBUG] Total datum size: 0x012e (302) bytes
Tue May  2 10:34:49 2023 [DEBUG] Datum entry type: 0
Tue May  2 10:34:49 2023 [DEBUG]    `--> ENTRY TYPE UNKNOWN 1
Tue May  2 10:34:49 2023 [DEBUG] Datum value type: 6
Tue May  2 10:34:49 2023 [DEBUG]    `--> TPM_ENCODED -- Total size header: 12 -- Nested datum: no
Tue May  2 10:34:49 2023 [DEBUG] Status: 0x1
Tue May  2 10:34:49 2023 [DEBUG] Unknown: 0x815
Tue May  2 10:34:49 2023 [DEBUG] Payload:
Tue May  2 10:34:49 2023 [DEBUG] 0x00000000 00 aa 00 20 5d 12 f2 03-70 ef 92 d1 a5 05 e7 c6 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000010 a9 5f 6f 24 e9 d1 66 c6-be 0a a8 d9 c6 07 24 cf 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000020 57 9e cd 47 00 10 7d 34-bb d9 51 a9 aa aa 33 6b 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000030 6c c7 b1 c6 ac ae 7b 43-66 80 ab a9 cb 50 08 f1 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000040 53 84 f5 ac 2f ae 0b d1-54 60 df 71 39 2b 95 31 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000050 99 e3 45 1b cc a8 f6 da-d4 b0 05 e0 60 09 ce 89 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000060 5f c0 8e 72 86 03 62 7d-1c 1d 3e b5 9a 02 67 0b 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000070 35 23 a1 e8 33 e6 f0 ef-38 5d 7d e1 bd ce 48 32 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000080 e9 ca 0a ff a8 87 ab 89-53 fa d7 eb 51 0f 9c c2 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000090 56 b3 b3 f2 a4 41 50 7a-5a d0 b8 06 7f 84 8c 59 
Tue May  2 10:34:49 2023 [DEBUG] 0x000000a0 1b c5 05 69 ed 16 f2 85-49 04 06 03 00 4e 00 08 
Tue May  2 10:34:49 2023 [DEBUG] 0x000000b0 00 0b 00 00 04 12 00 20-f5 10 e7 eb cb a2 25 bc 
Tue May  2 10:34:49 2023 [DEBUG] 0x000000c0 21 68 c2 23 d6 eb 84 1e-7c 03 2c f1 28 1f e5 ab 
Tue May  2 10:34:49 2023 [DEBUG] 0x000000d0 23 c3 73 7e 8a d2 f7 ef-00 10 00 20 75 ff bf 4e 
Tue May  2 10:34:49 2023 [DEBUG] 0x000000e0 cd c7 63 24 ba 6b b7 96-e3 b6 ef 36 e8 80 89 fe 
Tue May  2 10:34:49 2023 [DEBUG] 0x000000f0 57 17 6d d2 a2 be 41 92-42 6b d3 cb 00 20 0a 5b 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000100 7b 84 98 30 8a dc 33 ea-b7 6f 81 6b 7a cb 9d 0d 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000110 91 ab 73 a2 13 74 a3 2b-06 c5 93 7f c9 da 03 15 
Tue May  2 10:34:49 2023 [DEBUG] 0x00000120 08 00 
Tue May  2 10:34:49 2023 [DEBUG] Header safe: 0x12e, 0, 0x6, 0x1
Tue May  2 10:34:49 2023 [DEBUG] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The private portion is 0xaa bytes long. So the public portion should start at 0xac. The size of the public portion is then 0x4e, and so it should end at 0xae + 0x4e = 0xfc. But 0xfc > 0xdc == 220. So it seems like maybe my keys are 0x20 bytes larger than usual, and bitleaker is truncating them, which causes the TPM2_Load to fail?

I am not sure if it is relevant, but I have SecureBoot disabled, and I am running Windows 11.

I'll try to change 220 to 0xfc in bitleaker.py and see if that fixes the TPM error.

edmcman commented 1 year ago

So I believe my hunch about the key sizes was correct. After I changed 220 to 0xfc and also adjusted the command size in the TPM2_Load header, it produced a command that the TPM 2.0 command parser was actually able to parse:

Command: 80020000011700000157810000010000000940000009000000000000aa00205d12f20370ef92d1a505e7c6a95f6f24e9d166c6be0aa8d9c60724cf579ecd4700107d34bbd951a9aaaa336b6cc7b1c6acae7b436680aba9cb5008f15384f5ac2fae0bd15460df71392b953199e3451bcca8f6dad4b005e06009ce895fc08e728603627d1c1d3eb59a02670b3523a1e833e6f0ef385d7de1bdce4832e9ca0affa887ab8953fad7eb510f9cc256b3b3f2a441507a5ad0b8067f848c591bc50569ed16f28549040603004e0008000b000004120020f510e7ebcba225bc2168c223d6eb841e7c032cf1281fe5ab23c3737e8ad2f7ef0010002075ffbf4ecdc76324ba6bb796e3b6ef36e88089fe57176dd2a2be4192426bd3cb

Header:
Tpm2Lib.CommandHeader
  Tag                   Sessions                  TpmSt
  CommandSize           279 (0x117)               uint
  CommandCode           Load                      TpmCc

Command Parameters:
Tpm2Lib.Tpm2LoadRequest
  parentHandle          -                         TpmHandle
    handle              2164260865 (0x81000001)   uint
  inPrivate             -                         TpmPrivate
    buffer              0x00205d12f20370ef..
                          ed16f28549040603        byte[170]
  inPublic              -                         TpmPublic
    type                Keyedhash                 TpmAlgId
    nameAlg             Sha256                    TpmAlgId
    objectAttributes    FixedTPM|
                          FixedParent|
                          NoDA                    ObjectAttr
    authPolicy          0xf510e7ebcba225bc..
                          23c3737e8ad2f7ef        byte[32]
    parameters          -                         KeyedhashParms
      schemeScheme      Null                      TpmAlgId
      scheme            -                         NullSchemeKeyedhash
    unique              -                         Tpm2bDigestKeyedhash
      buffer            0x75ffbf4ecdc76324..
                          a2be4192426bd3cb        byte[32]

Sessions [1]
0: 0xTpm2Lib.SessionIn
  handle                -                         TpmHandle
    handle              1073741833 (0x40000009)   uint
  nonceCaller           0x                        byte[0]
  attributes            None                      SessionAttr
  auth                  0x                        byte[0]

Unfortunately, the command still fails with the same error code 0x018b, suggesting that something is wrong with the handle.

edmcman commented 1 year ago

If I carve out the pub and priv files, I can use tpm2_load successfully..... :thinking:

m/e/e/bitleaker $ sudo tpm2_load -C 0x81000001 -u pub.bin -r priv.bin -c key.ctx                                                                                                                                                                                                                                                                                                   12:19:52
name: 000bf325093fd7907253ed86deecb9ca6dce799389bc85afc0858f78cc95149baaa9
edmcman commented 1 year ago

I wonder if the error message is referencing the 0x40000009 handle (instead of 0x81000001, which was implied in #9)

edmcman commented 1 year ago

So I was having the same problem as #3 in that the orderly bit was clear, and I guess that causes TPM2_Load to fail.

roboknight commented 1 year ago

Yes. I had code to “clear” the flag in some instances, but Intel/Dell may have fixed that. Basically, it has to save the “empty” state to clear it. But I have found this doesn’t always work. If not, your device is ACTUALLY secure.

edmcman commented 1 year ago

@roboknight Your trick seemed to work -- unloading the bitleaker kernel module and suspending again.

However my PolicyPCR command fails. One thing that has been confusing me is that Bitleaker appears to extend some PCRs -- I saw you post about this as well -- but these doesn't appear in Bitleaker's event log. Did you experience that?

Also, how did you know that your setup was using SHA1 hashes if you don't mind me asking?

Thanks, your notes, code and comments have been very helpful for me!

edmcman commented 1 year ago

Although I got around the original TPM2_Load problem, PolicyPCR is failing.

I think I understand why now.

If I understand correctly, BitLocker with Secure Boot enabled uses PCRs 7 & 11. In https://github.com/kkamagui/bitleaker/issues/11#issuecomment-1090308544, @roboknight noted that EV_Separator is extended to PCRS 0-7. Since this extending happens in BitLocker, BitLeaker's bootloader would not see it in the log. But that is OK since we have to manually set PCR 7 anyway. So basically BitLeaker only needs to leak PCR 11 correctly.

I do not have Secure Boot enabled, and per manage-bde -protectors -get C: my machine is using PCRs 0, 2, 4, and 11.

I think there are two problems:

TLDR: Bitleaker will not work as is for my PCRs, because 0, 2, and 4 are extended by Bitlocker after Bitleaker reads the event log. Probably the easiest thing for me to do is try to extract the PCR values I need to extend from the TPM event logs from Windows rather than the ones in Bitleaker. And then figure out how to compute the differences, sort of how Bitleaker does now with PCR 7.

TLDR TLDR: Bitleaker won't work without secure boot.

edmcman commented 1 year ago

After enabling secure boot and redoing bitlocker, I was able to get bitleaker to work. It was a bit of a pain because of the orderly TPM problem. I ended up running bitleaker in Ubuntu 18.04 to get the .bin TPM command files. I then booted into Ubuntu focal and used the following script to set my PCRs to the right values:

https://gist.github.com/edmcman/35c1b830854804a1847949795409d163

I then used tpm2_send to send the .bin TPM commands files that bitleaker produced. And then I manually carved out the key from the response and used it with dislocker.

Hopefully that helps someone in the future.

roboknight commented 1 year ago

I have an updated Bitleaker that uses a later version of Ubuntu. I got it to work with EFI, so you don’t need the initial loader. It was a bit tricky, but it works and has some instructions. I have an image somewhere. As to the SHA1 question, it’s the hash lengths. They were 0x14 bytes, not 0x20 (SHA256).

roboknight commented 1 year ago

PS: As you discovered, Bitleaker doesn’t manage non-secure boot Bitlocker. Only Bitlocker with secure boot. As for PCR11, its only purpose is to prevent someone from getting the key after Bitlocker. Bitlocker extends PCR11 after booting to lock the key in the TPM. You can’t replay the hashes for Bitlocker from recording them through Bitleaker if you don’t use secure boot because one of the PCRs deals with boot order I think. However, recording the PCRs from PCPTool should let you replay them.

edmcman commented 1 year ago

I have an updated Bitleaker that uses a later version of Ubuntu. I got it to work with EFI, so you don’t need the initial loader. It was a bit tricky, but it works and has some instructions.

Oh cool! Can you point me to that? I don't think I found that in your repo.

roboknight commented 1 year ago

It isn’t in there. I can see if my image is still in Google drive or Dropbox. I probably should update the repo, but I was working on this elsewhere offline for a while. Now I’m kinda on other things, so updating that fell off the priority bandwagon.

roboknight commented 1 year ago

@edmcman, hopefully you got my message.

hoxitfoxave commented 1 year ago

I have an updated Bitleaker that uses a later version of Ubuntu. I got it to work with EFI, so you don’t need the initial loader. It was a bit tricky, but it works and has some instructions. I have an image somewhere. As to the SHA1 question, it’s the hash lengths. They were 0x14 bytes, not 0x20 (SHA256).

@roboknight Can you please share your updated Bitleaker with me? I am attempting to recover my personal data, my system uses sha1.