MSI's (in)Secure Boot
I guess I have found a reason to write my first blog post.
Before we start, maybe I will quickly explain what Secure Boot is. It is a security feature, which allows our computer to decline booting operating systems that have not been signed by a key that the firmware trusts.
On 2022-12-11, I decided to setup Secure Boot on my new desktop with a help of sbctl. Unfortunately I have found that my firmware was… accepting every OS image I gave it, no matter if it was trusted or not. It wasn't the first time that I have been self-signing Secure Boot, I wasn't doing it wrong.
As I have later discovered on 2022-12-16, it wasn't just broken firmware, MSI had changed their Secure Boot defaults to allow booting on security violations(!!).
This can be changed by going to the place where the settings are for
Secure Boot on your motherboard. In my case it's in
Security\Secure Boot. From this place, we can see a menu called "Image Execution
Policy", which is the culprit.
When we enter the menu, we can see the disappointing default settings. It's doing no verification. It's useless. It's just there to satisfy Windows 11 requirements. OS has no idea that Secure Boot is doing nothing, it just knows that it's "enabled".
To change the settings to something saner, we have to change "Always Execute" to "Deny Execute" for "Removable Media" and "Fixed Media". What's funny is that "Allow Execute" and "Query User" options are breaking UEFI specification, though I'm not really sure what's the difference between "Allow Execute" and "Always Execute".
We can also change "Option ROM", about which you can read more about here:
Case closed, everyone can move on, right?
Well, not really. I needed to figure out if this is only affecting my motherboard or also other models and maybe even other vendors. And also we need to document this, because even if I know this, there is probably a lot of people that are not aware about this issue.
I had asked 2 users of B450 TOMAHAWK MAX (thanks Sage Hane and Daniel
Nathan Gray) to check their firmware and what? Unsurprisingly, it's also
there. We were able to determine that version
7C02v3C from 2022-01-18
introduced this issue.
EDIT: I have noticed that some websites have misreported about this
issue because they have not fully read my article. This firmware version
only affects B450 TOMAHAWK MAX, other motherboards have different
7C02 in the version is the codename for B450 TOMAHAWK MAX.
More information is available down below.
Is it mentioned in the changelog? Hah, nope.
I have also received information from a user of B550-A PRO (CEC) (thanks
Joseph Richey) that they have this issue from
While I was able to extrapolate this information to guess which versions for other boards have introduced this issue, that isn't really enough. We need to go deeper.
I have tried extracting some information from MSI's binary firmware files, but to no avail. I tried using binwalk, UEFITool and others, but I didn't really find what I wanted. Until one day I have found out that UEFI has a thing called "UEFI Internal Form Representation" or in short "IFR". It's a way to describe firmware configuration options. This is exactly what I need to look for! Now, what do I do with this knowledge?
Once we extract files from the firmware using UEFIExtract from
UEFITool project, we can find a
It contains most of UEFI GUI stuff and seems to be available on all
firmware from all major desktop motherboard makers, though ASUS decided
to remove "Setup" from the name for some reason or maybe it has to do
something to do with the UEFIExtract, not sure.
EDIT (thanks Nikolaj Schlej): "Setup" comes from User Interface section
of that FFS file with GUID
vendors don't provide any UI sections, so "Setup" will be missing from
the name, but most of them don't change the default GUID that AMI chose
for their firmware."
Now once we have this file, we have to extract IFR data from it, to do it we can use IFRExtractor RS. Funnily enough, it's made by the same people as UEFITool. Thanks guys for your hard work, otherwise I would have to do it myself ;p.
Now with IFR extracted, we have what we wanted. We can see all the UEFI settings available, including "Image Execution Policy".
Form FormId: 0x2A79, Title: "Image Execution Policy" Text Prompt: "Internal FV", Help: "", Text: "Always Execute" OneOf Prompt: "Option ROM", Help: "Image Execution Policy on Security Violation per Device Path", QuestionFlags: 0x10, QuestionId: 0x1116, VarStoreId: 0x28, VarOffset: 0x4, Flags: 0x10, Size: 8, Min: 0x0, Max: 0x5, Step: 0x0 Default DefaultId: 0x0 Value: 0 OneOfOption Option: "Always Execute" Value: 0 OneOfOption Option: "Always Deny" Value: 1 OneOfOption Option: "Allow Execute" Value: 2 OneOfOption Option: "Defer Execute" Value: 3 OneOfOption Option: "Deny Execute" Value: 4 OneOfOption Option: "Query User" Value: 5 End OneOf Prompt: "Removable Media", Help: "Image Execution Policy on Security Violation per Device Path", QuestionFlags: 0x10, QuestionId: 0x1117, VarStoreId: 0x28, VarOffset: 0x5, Flags: 0x10, Size: 8, Min: 0x0, Max: 0x5, Step: 0x0 Default DefaultId: 0x0 Value: 0 OneOfOption Option: "Always Execute" Value: 0 OneOfOption Option: "Always Deny" Value: 1 OneOfOption Option: "Allow Execute" Value: 2 OneOfOption Option: "Defer Execute" Value: 3 OneOfOption Option: "Deny Execute" Value: 4 OneOfOption Option: "Query User" Value: 5 End OneOf Prompt: "Fixed Media", Help: "Image Execution Policy on Security Violation per Device Path", QuestionFlags: 0x10, QuestionId: 0x1118, VarStoreId: 0x28, VarOffset: 0x6, Flags: 0x10, Size: 8, Min: 0x0, Max: 0x5, Step: 0x0 Default DefaultId: 0x0 Value: 0 OneOfOption Option: "Always Execute" Value: 0 OneOfOption Option: "Always Deny" Value: 1 OneOfOption Option: "Allow Execute" Value: 2 OneOfOption Option: "Defer Execute" Value: 3 OneOfOption Option: "Deny Execute" Value: 4 OneOfOption Option: "Query User" Value: 5 End End
I have checked if other vendors (ASRock, ASUS, Biostar, EVGA, Gigabyte and NZXT) have the same thing and I wasn't able to find anything like that in their IFR. Also MSI's laptops are not affected by this issue. I'm gonna assume that they figured that Microsoft wouldn't approve it and/or that they had less tickets from people about Secure Boot related issues for their laptops.
Now, doing this manually would be kinda annoying, so I made a small little shell script which checks if "Image Execution Policy" menu is available and if any of the three options are set to "Always Execute".
#!/bin/sh if [ ! -d "$1" ]; then [ ! -f "$1.zip" ] && curl "https://download.msi.com/bos_exe/mb/$1.zip" -O -# bsdtar xf "$1.zip" fi cd "$1" || exit UEFIExtract ./*MS.* unpack 1>/dev/null ifrextractor ./*.dump/Section_PE32_image_899407D7-99FE-43D8-9A21-79EC328CAC21_Setup_body.bin 1>/dev/null output="$(grep -A1 -E 'OneOf Prompt: "(Option ROM|Removable Media|Fixed Media)", Help: "Image Execution Policy' ./*.dump/Section_PE32_image_899407D7-99FE-43D8-9A21-79EC328CAC21_Setup_body.bin.*ifr.txt)" clear if echo "$output" | grep -q "DefaultId: 0x0"; then printf "\033[1;31m%s: Bad\033[0m\n" "$1" else printf "\033[1;32m%s: Good\033[0m\n" "$1" fi
Now this is where the fun part ends. Now I had to check firmware for MSI's somewhat recent boards.
While we can get most of the firmware just by going to motherboard's support page, MSI usually only lists stable firmware and the newest beta. The problem is that I need to figure out the earliest affected version of the firmware for each board, which means that I have to guess what the betas were called (if they even existed). At least MSI doesn't remove most of its beta firmware from their servers, so they are still accessible if you know the link.
For some AMD boards, I have found a list of beta firmware on some German forum. Thankfully, I didn't have to read any German, because contrary to the popular belief, I don't know German or Russian, I'm Polish.
This… took forever. I checked every motherboard for:
- AMD: TRX40, X399, X670, X570, X470, X370, B650, B550, B450, B350, A520, A320
- Intel: X299, Z790, Z690, Z590, Z490, Z390, Z370, B760, B660, B560, B460, B360, H670, H510, H410, H370, H310
It's… a lot of motherboards. For a full list of affected motherboards and their firmware versions, visit sbctl#181.
And now it's time for some "fun" statistic:
# The amount of times I ran the script $ history 0 | grep " msi " | wc -l 1989
According to Wikipedia in 1989:
The first commercial Internet service providers surfaced in this year, as well as the first written proposal for the World Wide Web and New Zealand, Japan and Australia's first Internet connections.
Well, that was a mistake.
You could ask me, why didn't I automate it? The reason is… well… some of it is not really easy to as some beta names have arbitrary suffixes which was faster for me to guess than having a script bruteforce its way in. Also some boards weren't listed on their motherboard list page.
Now, after doing all the work for MSI, I think I should bill them, that or they should give me a lifetime supply of their motherboards.
If you are curious, yes, I have tried contacting MSI about this issue, but they ignored my emails and other forms of communication I have tried.
EDIT: MSI have made a statement on the issue. What's weird is that it's only on their subreddit. And just like how I guessed it, it was an intentional change. Oh well.
Don't trust that whatever security features you enabled are working, TEST THEM! Somehow I was the first person to document this, even though it has been first introduced somewhere in 2021 Q3.
What's the difference between these 3 boards:
Heatsink and PCB colours! They are the same board and share the same firmware! But hey, the red and white one is only for gamers but black is only suitable for "professionals".
There is a continuation available of this post, "MSI's (in)Secure Boot: Part 2".