aboutsummaryrefslogtreecommitdiff
path: root/content/blog/msi-insecure-boot.pl.md
blob: 0ddc1a275976eeab610af3d14352eac34dfb872a (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
252
253
254
255
256
257
258
259
260
261
262
263
+++
title = "(in)Secure Boot MSI"
date = "2023-01-13"
lastmod = "2023-01-20"
+++

Chyba wreszcie znalazłem powód, aby napisać swój pierwszy post na blogu.

Zanim zaczniemy, może szybko wyjaśnię czym jest Secure Boot. Jest to
funkcja bezpieczeństwa, która pozwala naszemu komputerowi odmówić
uruchomienia systemów operacyjnych, które nie zostały podpisane kluczem,
któremu firmware ufa.

W dniu 2022-12-11, postanowiłem skonfigurować Secure Boot na moim PCecie
z pomocą [sbctl](https://github.com/Foxboron/sbctl). Niestety okazało
się, że mój firmware… akceptował każdy system operacyjny jaki mu dałem,
nie ważne czy był podpisany przez zaufane przez firmware klucze czy nie.
To nie był pierwszy raz, kiedy self-signowałem Secure Boot, nie robiłem
tego źle, coś było nie tak.

Jak później odkryłem w dniu 2022-12-16, to nie był tylko zepsuty
firmware, MSI zmieniło swoje domyślne ustawienia Secure Boot, aby
umożliwić bootowanie na naruszeniach Secure Boot(!!).

Można to zmienić przechodząc do miejsca, w którym znajdują się
ustawienia dla Secure Boot na Twojej płycie głównej. W moim przypadku
jest to w zakładce `Security\Secure Boot`. Z tego miejsca możemy
zobaczyć menu o nazwie "Image Execution Policy" które jest tego
winowajcą.

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

Po wejściu w menu widzimy rozczarowujące ustawienia domyślne. Secure
Boot nie przeprowadza żadnej weryfikacji. Jest on bezużyteczny. Jest tam
tylko po to, aby spełnić wymagania Windows 11. System nie ma pojęcia, że
Secure Boot nic nie robi, wie tylko, że jest "włączony".

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

Aby zmienić ustawienia na coś bardziej sensownego, musimy zmienić
"Always Execute" (zawsze uruchamiaj) na "Deny Execute" (zabraniaj
uruchamiania) dla "Removable Media" (nośniki wymienne) i "Fixed Media"
(wenętrzne dyski). Co zabawne, opcje "Allow Execute" (zezwól
uruchamianie) i "Query User" (zapytaj użytkownika)
[naruszają specyfikację UEFI](https://github.com/tianocore/edk2/blob/9ce09870e721efacc41fa7ee684e9e299f120350/SecurityPkg/SecurityPkg.dec#L267-L278),
chociaż nie jestem do końca pewien, jaka jest różnica między "Allow
Execute" (zezwalaj uruchamianie), a "Always Execute" (zawsze
uruchamiaj).

Możemy również zmienić "Option ROM", o którym więcej możecie przeczytać
więcej tutaj:

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

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

Sprawa zamknięta, można się rozejść, nie?

Cóż, nie do końca. Musiałem się dowiedzieć, czy problem ten dotyczy
tylko moją płytę główną czy też inne modele, a może nawet innych
producentów. A także musimy to udokumentować, nawet jeśli ja o tym wiem,
prawdopodobnie jest wiele osób ludzi, którzy nie wiedzą o tym problemie.

Poprosiłem 2 użytkowników B450 TOMAHAWK MAX (dzięki Sage Hane i Daniel
Nathan Gray) o sprawdzenie swojego firmware'u i co? Okazało się, że
również tam jest ta opcja. Udało nam się ustalić, że wersja `7C02v3C` z
2022-01-18 wprowadza ten problem.

*EDIT: Zauważyłem, że niektóre strony podały błędne informacje na temat
tego problemu, ponieważ nie przeczytały w pełni mojego artykułu. Ta
wersja firmware dotyczy tylko B450 TOMAHAWK MAX, inne płyty główne mają
inne wersje. `7C02` w tej wersji jest nazwą kodową dla B450 TOMAHAWK
MAX. Więcej informacji jest dostępnych poniżej.*

Czy jest to wspomniane w changelogu? Hah, nie.

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

Otrzymałem również informację od użytkownika B550-A PRO (CEC) (dzięki
Joseph Richey), że mają ten problem od `7C56vH1` (2021-12-20) w zwyż.

Chociaż byłem w stanie ekstrapolować te informacje, aby zgadnąć, które
wersje dla innych płyt wprowadziły ten problem, to nie jest to
wystarczające. Musimy sięgnąć głębiej.

Próbowałem wydobyć pewne informacje z plików firmware'u MSI ale
bezskutecznie. Próbowałem użyć binwalk, UEFITool i innych, ale nie
znalazłem tego, co chciałem. Aż pewnego dnia dowiedziałem się, że UEFI
ma rzecz zwaną "UEFI Internal Form Representation" lub w skrócie "IFR".
Jest to sposób na opisanie opcji konfiguracyjnych firmware. To jest
dokładnie to, czego muszę szukać! No i co teraz zrobimy z tą wiedzą?

Gdy już wyodrębnimy pliki z firmware za pomocą UEFIExtract z
[UEFITool](https://github.com/LongSoft/UEFITool), możemy znaleźć plik o
nazwie plik o nazwie
`Section_PE32_image_899407D7-99FE-43D8-9A21-79EC328CAC21_Setup_body.bin`.
Zawiera on większość elementów GUI UEFI i wydaje się być dostępny na
wszystkich firmware'ach od wszystkich dużych producentów płyt głównych,
chociaż ASUS postanowił usunąć "Setup" z nazwy z jakiegoś powodu, ale
może ma to związek z coś wspólnego z UEFIExtract, nie jestem pewien.

*EDIT (dzięki Nikolaj Schlej): "Setup" pochodzi z sekcji User Interface
pliku FFS z GUID `899407D7-99FE-43D8-9A21-79EC328CAC21`. Niektórzy
producenci nie mają sekcji UI, więc nie będzie "Setup" w jego nazwie,
ale większość z nich nie zmienia domyślnego GUID, który AMI wybrał dla
ich firmware.*

Teraz, gdy mamy już ten plik, musimy wyodrębnić z niego dane IFR. możemy
użyć [IFRExtractor RS](https://github.com/LongSoft/IFRExtractor-RS). Co
zabawne, jest on tworzony przez tych samych ludzi co UEFITool. Dzięki
koledzy za waszą ciężką pracę, inaczej musiałbym to zrobić sam ;p.

Teraz dzięki wyodrębnionemu IFR mamy to, czego chcieliśmy. Możemy
zobaczyć wszystkie ustawienia UEFI dostępne, w tym "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
```

Sprawdziłem, czy inni producenci (ASRock, ASUS, Biostar, EVGA, Gigabyte
i NZXT) mają to samo i nie udało mi się znaleźć niczego takiego w ich
IFR. Również laptopy MSI nie są dotknięte tym problemem. Zakładam, że
uznali, że Microsoft tego nie zaakceptuje i/lub że mieli mniej zgłoszeń
od ludzi dotyczących problemów związanych z Secure Boot dla ich
laptopów.

Robienie tego ręcznie byłoby trochę żmudne, więc zrobiłem mały mały
skrypt w shellu, który sprawdza czy menu "Image Execution Policy" jest
dostępne i czy któraś z trzech opcji jest ustawiona na "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
```

Na tym kończy się ta fajna część roboty. Teraz musiałem sprawdzić
firmware dla wmiare nowych płyt od MSI.

Podczas gdy większość firmware'u możemy zdobyć po prostu wchodząc na
stronę wsparcia płyty głównej stronie wsparcia, MSI zazwyczaj daje linki
do stabilnych wersji firmware'u i najnowszą beta. Problem polega na tym,
że muszę dowiedzieć się, kiedy zostało to dodane najwcześniej do
firmware'u dla każdej płyty, co oznacza, że muszę zgadywać, jak nazywały
się bety (jeśli w ogóle istniały). Przynajmniej MSI nie usuwa
*większości* swoich beta firmware'ów z serwerów, więc są one nadal
dostępne, jeśli znasz link.

Dla niektórych płyt AMD znalazłem listę beta firmware na jakimś
niemieckim forum. Na szczęście nie musiałem czytać żadnego niemieckiego,
bo wbrew powszechnej opinii, nie znam niemieckiego ani rosyjskiego,
jestem Polakiem, na imigracji co prawda ale no.

To… trwało wieki. Sprawdziłem każdą płytę główną z chipsetem:
- 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

To… jest wiele płyt głównych. Dla pełnej listy płyt głównych, których
dotyczy ten problem i ich wersje firmware'u, odwiedź
[sbctl#181](https://github.com/Foxboron/sbctl/issues/181).

A teraz czas na jakąś "zabawną" (nie dla mnie) statystykę:

```sh
# Ilość razy jaki uruchomiłem skrypt
$ history 0 | grep "  msi " | wc -l
1989
```

Według [Wikipedii w 1989](https://en.wikipedia.org/wiki/1989):

> W tym roku pojawili się pierwsi komercyjni dostawcy usług
> internetowych, jak również pierwsza pisemna propozycja dla World Wide
> Web oraz pierwsze połączenia internetowe w Nowej Zelandii, Japonii i
> Australii.

Cóż, to był błąd.

Można by zapytać, dlaczego tego nie zautomatyzowałem? Powodem jest…
nie jest to zbyt proste, ponieważ niektóre nazwy bety mają arbitralne
przyrostki co było szybsze dla mnie do zgadnięcia niż korzystanie ze
skryptu który bruteforce'owałby te nazwy. Również niektóre płyty nie
były wymienione na ich stronie z listą płyt głównych.

Teraz, po wykonaniu całej pracy dla MSI, myślę, że powinienem wystawić
im rachunek, albo powinni mi dać dożywotni zapas płyt głównych.

Jeśli jesteś ciekawy, tak, próbowałem skontaktować się z MSI w tej
sprawie, ale zignorowali moje emaile i inne formy komunikacji, których
próbowałem.

*EDIT: MSI wydało
[oświadczenie w tej sprawie](https://www.reddit.com/r/MSI_Gaming/comments/10g9v3m/msi_statement_on_secure_boot/).
Najdziwniejsze jest to, że jest to tylko na ich subreddicie. I tak jak
się domyśliłem, to była celowa zmiana.*

### Konkluzja

Nie ufaj, że jakiekolwiek zabezpieczenia, które włączyłeś, działają,
PRZETESTUJ JE! W jakiś sposób byłem pierwszą osobą, która to
udokumentowała, mimo że zostało to po raz pierwszy wprowadzone gdzieś w
3 kwartale 2021.

### Czas na quiz!

Jaka jest różnica między tymi 3 płytami:

- [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)

Kolor heatsinków i PCB! Są to te same płyty i mają ten sam firmware! Ale
hej, czerwony i biały jest tylko dla graczy, ale czarny jest tylko dla
"profesjonalistów".

**Dostępna jest kontynuacja tego postu,
["(in)Secure Boot MSI: Część 2"](/pl/2023/02/26/msi-insecure-boot-czesc-2/).**