aboutsummaryrefslogtreecommitdiff
path: root/content/blog/msi-insecure-boot.en.md
blob: 302b1c22365872a432bf45645fcf7d5b17ca965f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
+++
title = "MSI's (in)Secure Boot"
date = "2023-01-13"
lastmod = "2023-01-20"
+++

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](https://github.com/Foxboron/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.

![Firmware Screenshot 0](/img/blog/msi-insecure-boot/firmware0.webp)

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".

![Firmware Screenshot 1](/img/blog/msi-insecure-boot/firmware1.webp)

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](https://github.com/tianocore/edk2/blob/9ce09870e721efacc41fa7ee684e9e299f120350/SecurityPkg/SecurityPkg.dec#L267-L278),
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:

- https://github.com/Foxboron/sbctl/wiki/FAQ#option-rom
- https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/uefi-validation-option-rom-validation-guidance

![Firmware Screenshot 2](/img/blog/msi-insecure-boot/firmware2.webp)

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
versions. `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.

![Firmware Screenshot 3](/img/blog/msi-insecure-boot/firmware3.webp)

I have also received information from a user of B550-A PRO (CEC) (thanks
Joseph Richey) that they have this issue from `7C56vH1` (2021-12-20)
onwards.

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](https://github.com/LongSoft/UEFITool) project, we can find a
file called
`Section_PE32_image_899407D7-99FE-43D8-9A21-79EC328CAC21_Setup_body.bin`.
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 `899407D7-99FE-43D8-9A21-79EC328CAC21`. Some
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](https://github.com/LongSoft/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".

```sh
#!/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](https://github.com/Foxboron/sbctl/issues/181).

And now it's time for some "fun" statistic:

```sh
# The amount of times I ran the script
$ history 0 | grep "  msi " | wc -l
1989
```

According to [Wikipedia in 1989](https://en.wikipedia.org/wiki/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](https://www.reddit.com/r/MSI_Gaming/comments/10g9v3m/msi_statement_on_secure_boot/).
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.*


### Conclusion

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.

### Quiz time!

What's the difference between these 3 boards:

- [MSI B360 GAMING ARCTIC](https://www.msi.com/Motherboard/B360-GAMING-ARCTIC/Specification)
- [MSI B360 GAMING PLUS](https://www.msi.com/Motherboard/B360-GAMING-PLUS/Specification)
- [MSI B360-A PRO](https://www.msi.com/Motherboard/B360-A-PRO/Specification)

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".