Bypassing Bitlocker utilizing an affordable logic analyzer on a Lenovo laptop computer
Have you ever ever been advised that the corporate’s information on laptops is protected due to BitLocker? Nicely it seems that this is determined by BitLocker’s configuration…
The BitLocker partition is encrypted utilizing the Full Quantity Encryption Key (FVEK). The FVEK itself is encrypted utilizing the Quantity Grasp Key (VMK) and saved on the disk, subsequent to the encrypted information. This allows key rotations with out re-encrypting the entire disk.
The VMK is saved within the TPM. Thus the disk can solely be decrypted when booted from this laptop (there’s a restoration mechanism in Lively Listing although).
In an effort to decrypt the disk, the CPU will ask that the TPM sends the VMK over the SPI bus.
The vulnerability must be apparent: sooner or later within the boot course of, the VMK transits unencrypted between the TPM and the CPU. Which means that it may be captured and used to decrypt the disk.
We’ll be utilizing a mud low cost logic analyzer, DSLogic Plus. I purchased this for underneath $100 in 2021 (tax and transport included).
A be aware on sign seize: to comfortably purchase a sign the sampling frequency must be 3 to 4 instances the bus frequency. Which means that for our SPI 33MHz bus we should always pattern on the very least at 100MHz. Discover that the specs of the analyzer state that it could possibly do as much as 400MHz on as much as 16 channels. I’ll assist you to learn between the traces right here:
- the extra channels you seize at a time (by units of three), the decrease the sampling frequency
- it’s important to distinguish stream mode and buffer mode. The primary one will ship outcomes on to the host laptop and permits seize of enormous units, as much as a minute however it’s restricted to 100MHz on 3 channels. The buffer mode permits sampling at 400MHz however it would solely work for just a few milliseconds, so there’s no sensible use for it right here.
Which means that this {hardware} can barely do the job we’re asking it to do. For a extra skilled possibility each {hardware} and software-wise (but in addition 10x pricier) take a look at Saleae. In any other case there’s sigrok’s list of supported hardware.
As for plugging the analyzer to the board, keep in mind that SPI is a shared bus. Which means that there’s no must seize the sign proper on the tiny TPM pins if there’s a bigger SPI part on the board that the hooks could be latched on to. From expertise I recognized a neighbouring SPI flash, however thankfully all elements are marked so it’s somewhat straightforward to determine their use by trying up their datasheet.
SPI has a number of traces however solely 3 could be captured utilizing the DSLogic as a result of in any other case the sampling frequency drops. The three most necessary ones are the clock CLK and the 2 information traces MOSI and MISO.
The brink voltage (degree at which the analyzer decides that the road has modified states) must be round half of the sign’s voltage, right here the latter was measured at 3.3V so an acceptable threshold is round 1.6V.
The VMK key we’re searching for is used late within the POST stage. For the Lenovo L13 I labored with it was simply after the splash display screen, about 14 seconds into the boot course of out of a complete boot time of about 25 seconds. There are SPI operations earlier than that (principally to learn and confirm the early boot levels) however they’re not TPM. You would both begin the seize when booting the pc, or safely wait about 7 or so seconds to keep away from capturing pointless information.
There are 3 layers to decode:
- SPI, which is the bodily layer
- TIS
- TPM2.0, which accommodates the VMK
SPI
So far as SPI is anxious any logic analyzer ought to do that correctly, it’s a somewhat easy protocol:
The blue sq. wave is the clock, the opposite two traces (yellow and purple) are information traces, respectively used for communications from slave to grasp (MISO) and grasp to slave (MOSI).
When the clock sign goes up (transitioning from 0 to 1), the bit worth is no matter state the info traces are in at this particular time. In our case the purple line sits at 0 for 8 clock cycles, so the byte is 0. The yellow line solely has the primary bit set, so the decoded worth is b10000000 = 0x80.
The logic analyzer appropriately decodes SPI so we’ll simply belief its output.
TIS
TIS, which stands for TPM Interface Specification, is one other beast fully and that’s the place I had most of my troubles. I couldn’t discover a decoder that labored for my seize and determined to do it “manually”. Wanting appropriately decoding the info, the libsigrock decoders did at the very least point out a tough window for the TPM exchanges which was a welcome tip since every seize has a number of million bytes of information. Possibly the decoders fail be as a result of the seize is lacking Chip Choose (CS#) which is required within the TPM specification, possibly as a result of the clock is wrong, possibly as a result of some bytes are often lacking, possibly for another purpose, who is aware of.
Grasp to slave request:
Sending a request appears to occur on this order:
- the slave sends byte 80 to sign that it’s prepared
- the grasp sends a header we don’t care about (
D4 00 24
) after which sends the TPM byte in a loop (80
) - the slave acknowledges that it has learn the byte by sending 01 FF
- at this level the cycle begins anew with the subsequent byte
So this complete body is simply to ship the byte 0x80 from the grasp to the slave!
Slave to grasp response:
This can be a fully totally different course of that depends on setting and studying registers. The body is the results of studying one byte from a set deal with (D4 00 24
, which means register 24). Once more the slave appears to begin the transaction with byte 80, then writes the dimensions of the followong information which is only one byte (or it may very well be an ACK worth to the learn request, who is aware of) and eventually the worth we care about, right here 0x80. The subsequent TPM byte is 0x02.
TPM 2.0
The TPM command that requests the important thing be despatched again is the TPM2_Unseal
command. It’s described in part 3 of the TPM 2.0 specification.
You may ask how I remoted the frames beneath since no decoder would work. We don’t really care concerning the requests occurring on MOSI, we’re principally within the responses on the MISO line. As we’ve seen beforehand the TIS encoding round TPM bytes is somewhat easy, so the only technique to isolate all TPM transactions is to filter the uncooked SPI information utilizing the masks “80 00 00 00 01 ..” and solely preserve this wildcard final byte. The beginning of a TPM transaction can then be recognized by its personal 80 01
or 80 02
header. There ought to solely be just a few dozens TPM responses, the one with the important thing inside must be the longer authenticated one (begins with 80 02
).
There’s a 10 milliseconds delay between the unseal command and the response, which is large. That is most likely as a result of the request is authenticated (see beneath the 80 02
header indicating a password session versus most requests utilizing the plain 80 01
header) utilizing a HMAC so the slave has to confirm the signature after which reply utilizing a HMAC of its personal, which induces a notable delay.
The TPM command and its response are obtained by reassembling bytes one after the other utilizing the tactic beforehand defined.
Reconstituted Unseal command:
80 02 00 00 00 5B 00 00 01 5E 80 00 00 00 00 00 00 49 03 00 00 00 00 20 9D F7 05 43 7A 77 AE E4 20 92 66 17 EC DA BB A7 79 D2 47 0D 42 E5 D1 1C EB 4A 6B C1 C8 44 42 BC 00 00 20 D9 AF C7 DF 10 7A D4 30 C1 C5 28 63 5F CE CE 8A 24 1A 19 E5 DD 08 5F 77 AA 28 BE 75 16 16 91 F1
Decoded body utilizing this awesome tool:
Response (I’ve stripped continuation bytes 1F 00
, they turn into obvious in the event you seize a number of lengthy frames):
80 02 00 00 00 81 00 00 00 00 00 00 00 2E 00 2C 2C 00 05 00 01 00 00 00 03 20 00 00 57 61 A3 91 DF E1 B3 85 28 28 C6 DD A6 F9 A5 FE AC E9 71 A4 AA AE 44 25 18 F7 4A A7 FE D6 E0 FC 00 20 8D DD A1 AE 93 5D 98 E9 DA A8 18 6F D5 64 A8 66 E6 DE AA 56 9E 2F 50 A7 41 E1 27 BF A1 2C 4D 92 00 00 20 00 20 BA C9 8F 34 60 5F 4F D4 76 9B 6B AA 68 C7 6C 79 EF 36 7D 1D D3 19 33 78 55 47 B2 E1 40 D4
Decoded response:
Within the buffer lies our key, it begins with 5761
and is 32 bytes lengthy.
Mounting the disk reside in learn/write mode (in the event you’d somewhat work offline do a disk copy with dd after which mount this copy utilizing a loop gadget):
echo 5761A391DF1F00E1B3852828C6DDA6F9A5FEACE971A4AAAE442518F74AA7FED6E0FC | xxd -r -p > key
dislocker-fuse -Okay key /dev/sdd3 ./mnt/
mount ./mnt/dislocker-file ./mnt2/
Then the only backdoor is to simply overwrite the sticky keys program with cmd:
cp ./mnt2/Home windows/System32/cmd.exe ./mnt2/Home windows/System32/sethc.exe
Place the disk again within the laptop computer, boot and press shift 5 instances to get a SYSTEM shell:
I can not suggest utilizing the DSLogic for this activity:
- plenty of captures had been duds and needed to be thrown away
- sampling at 3 instances the bus pace was barely sufficient to have a coherent clock and a few bytes had been lacking
This pressured me to spend approach an excessive amount of time to grasp the protocols in an effort to decode the seize. In the long run time is cash, in the event you’re an employer studying this simply purchase an expert logic analyzer to your workers.
Using a discrete (bodily) TPM really decreases the safety of the system, utilizing a fTPM would remedy the issue.
If the discrete TPM needs to be used, then a PIN or passphrase on BitLocker is important.