SecureBoot flaw for all WP devices

⬅️ Go back

Last updated: January 5, 2019


First of all, Welcome to 2019, and happy new year everyone!

Edit: This post has been updated by Rafael Rivera because it was very rough, thank you!

Rene Lergner's WPinternals tool supports Microsoft Lumia devices out of the box. But thanks to a newly surfaced production-signed EFI application, all the others - like the Alcatel Idol 4S, HP Elite x3, and HTC One M8 - can join the party too.

Note: the author of this post takes no responsibility for what happens with your device. Moreover the author of this post does not take credit for the original exploit found by @HeathCliff74. Credit goes where it's due, and he did a wonderful job with this variable storage hack for Lumias, which is what this is based off, alongside with WPinternals. Be sure to follow him on twitter and check out wpinternals.net for more about his work.

Recently, an efi file has been leaked to the internet

This file is one of many production signed developermenu.efi files, but what does this mean?

developermenu.efi is an EFI application that can alter EFI variables and kickstart the EFI mass storage application on all newer generation Qualcomm-based devices. Of course, mass storage access is only step one of many to successfully disable SecureBoot.

Generally, to disable SecureBoot on a device, one needs to:

Before we can exploit EFI variable storage, however, some additional set up is required:

Now, we just need to make a quick change to Rene's WPInternals tool to fiddle with variable storage:


PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel();
Notifier.Start();

await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage);
MassStorage MassStorage = (MassStorage)Notifier.CurrentModel;

bool GPTChanged = false;
var GPTChunk = MassStorage.ReadSectors(0, 256);
var GPT = new GPT(GPTChunk);

// Now add NV partition
Partition BACKUP_BS_NV = GPT.GetPartition("BACKUP_BS_NV");
Partition UEFI_BS_NV;
if (BACKUP_BS_NV == null)
{
                BACKUP_BS_NV = GPT.GetPartition("UEFI_BS_NV");
                Guid OriginalPartitionTypeGuid = BACKUP_BS_NV.PartitionTypeGuid;
                Guid OriginalPartitionGuid = BACKUP_BS_NV.PartitionGuid;
                BACKUP_BS_NV.Name = "BACKUP_BS_NV";
                BACKUP_BS_NV.PartitionGuid = Guid.NewGuid();
                BACKUP_BS_NV.PartitionTypeGuid = Guid.NewGuid();
                UEFI_BS_NV = new Partition();
                UEFI_BS_NV.Name = "UEFI_BS_NV";
                UEFI_BS_NV.Attributes = BACKUP_BS_NV.Attributes;
                UEFI_BS_NV.PartitionGuid = OriginalPartitionGuid;
                UEFI_BS_NV.PartitionTypeGuid = OriginalPartitionTypeGuid;
                UEFI_BS_NV.FirstSector = BACKUP_BS_NV.LastSector + 1;
                UEFI_BS_NV.LastSector = UEFI_BS_NV.FirstSector + BACKUP_BS_NV.LastSector - BACKUP_BS_NV.FirstSector;
                GPT.Partitions.Add(UEFI_BS_NV);
                GPTChanged = true;
}

if (GPTChanged)
{
            GPT.Rebuild();
            MassStorage.WriteSectors(0, GPTChunk);
}

Partition TargetPartition = GPT.GetPartition("UEFI_BS_NV");
string SBRes = "WPinternals.SB";
var streamdata = new SeekableStream(() =>
{
            var assembly = System.Reflection.Assembly.GetExecutingAssembly();

            // Magic!
            // The SB(A) resource is a compressed version of a raw NV-variable-partition.
            // In this partition the SecureBoot variable is disabled.
             // It overwrites the variable in a different NV-partition than where this variable is stored usually.
            // This normally leads to endless-loops when the NV-variables are enumerated.
            // But the partition contains an extra hack to break out the endless loops.
            var stream = assembly.GetManifestResourceStream(SBRes);

             return new DecompressedStream(stream);
});

MassStorage.WriteSectors((UInt32)TargetPartition.FirstSector, new BinaryReader(streamdata).ReadBytes((int)streamdata.Length));
LogFile.Log("Phone is unlocked!", LogType.FileAndConsole);

At this point, SecureBoot is off, regardless of what the OS wants/reports. Beware, however: Your only eMMC access is via developermenu.efi. Be very careful on devices with no flashing/recovery mechanism other than the "lightning cog". You can easily brick your phone. For safer reflashes, the tool already backed up the original variable storage.

Happy 2019 and happy hacking!