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
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
#+title: Memory Management and Booting
#+date: 2026-03-02 Mon
#+author: W. Kosior
#+email: wkosior@agh.edu.pl
* A Sample Program
#+begin_src C
#include <stdio.h>
int main(int argc, char * * argv) {
unsigned char * memory = (char *) 0;
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 20; j++) {
printf("%hhx ", memory[20 * i + j]);
}
putchar('\n');
}
return 0;
}
#+end_src
* Virtual Memory
| address process uses | real address accessed |
|----------------------+-----------------------|
| 76bd91485000 | 1030ba |
| 76bd91486000 | 1030b9 |
| 76bd91487000 | 10347b |
| 76bd91488000 | 1030b8 |
| 76bd91489000 | 44e2c1 |
| 76bd9148a000 | 40e5ff |
| 76bd9148b000 | 430272 |
| 76bd9148c000 | 42848a |
* Mapping of Physical Memory Pages
- hardware-backed
- paging set up by kernel
- *per-process* address space
- used by all modern non-embedded OSes
- not the only address translation in a typical computer system
* MMU
- required* by Linux
- present in x86, ARM, MIPS, PowerPC, etc. processors meant "for
application-level computing"
- no MMU in, e.g., ARM Cortex-M
- *MPU* instead of MMU in ARM Cortex-R
* Other Restrictrions to Non-Kernel Code
- privileged CPU instructions, IO
- rings 0-3 in x86
- returning control to kernel (sw interrupts)
* Privilege Levels in x86 and ARM
| | x86 | ARM 7 | ARM 8 |
|-----------+--------+-------+-------|
| OS kernel | ring 0 | PL1 | EL1 |
| | ring 1 | | |
| | ring 2 | | |
| userspace | ring 3 | PL0 | EL0 |
* Software in a Computer
- code typically on hard drive
- bootloader
- OS kernel & userspace apps
- code typically on flash memory chip
- firmware (BIOS)
- services provided to other code
* Privilege Levels in x86 and ARM (corrected)
| | x86 | ARM 7 | ARM 8 |
|-----------+--------+-------+-------|
| firmware | SMM | | EL3 |
| OS kernel | ring 0 | PL1 | EL1 |
| | ring 1 | | |
| | ring 2 | | |
| userspace | ring 3 | PL0 | EL0 |
* Software in a Computer, cont.
- code typically on hard drive
- hypervisor
- code typically on flash memory chip
- EC ← not very interesting in our case
- microcode
- Intel ME
- AMD PSP
- Google Titan M2
* Privilege Levels in x86 and ARM (corrected)
| | x86 | ARM 7 | ARM 8 |
|----------------------+-------------------+-------+--------|
| "security" subsystem | varies |
| firmware | SMM | | EL3 |
| hypervisor | Intel VT-x, AMD-V | PL2 | EL2 |
| OS kernel | ring 0 | PL1 | EL1 |
| | ring 1 | | |
| | ring 2 | | |
| userspace | ring 3 | PL0 | EL0 |
* About "Subsystems" and "Coprocessors"
- some execeute on separate SoCs
- often with a different instruction set
- some do have full control over the system
- some do not
* System Startup in x86 (Legacy)
- BIOS initializes RAM
- BIOS initializes other peripherals
- boot sequence
- initial 512 bytes of drive's data loaded
- boot signature presence check
- initial MBR bytes executed as code
- 16-bit real mode
- bootstrap code loads the bootloader
- bootloader loads the OS kernel
- use of ramdisks
- paging gets set up by the kernel
* UEFI
- "Unified Extensible Firmware Interface"
- replacement for the "Legacy BIOS"
- developed from Intel's EFI
- open standard
- freely-licensed and proprietary implementations
- TianoCore
* System Startup in x86 (UEFI)
- BIOS initializes RAM
- BIOS initializes other peripherals
- boot sequence
- EFI System Partition
- FAT 12/16/32
- .efi executables
- PE format :(
- bootloader → .efi
- OS kernel → .efi
- ties to GPT partitioning
* UEFI BIOS Services
- EFI variables
- name+GUID+value
- typically in NVRAM
- configuration (e.g., boot order)
- network stack
- more
* EFI Variables
- types
- bootservice access
- runtime access
- "secure"
- volatile / nonvolatile
- =/sys/firmware/efi/efivars=
* Signing
- X.509
- standard for certs
- TLS
- certificates, signatures, key exchange
- PKCS #7
- standard and format for certs, keys, etc.
- can be used as a wrapper for X.509
- DER, PEM
- PE binaries
- PGP
- GPG — a PGP implementation
- private and public keys
* Secure Boot
- assumption: all ring 0 code signed
- stop ring 0 rootkits
- securing network booting
- an attacker with hard drive access
- what about, e.g., malicious non-kernel code?
- verification: UEFI BIOS → bootloader → kernel → modules
- root public key held by BIOS
* Keys, Certs and Hashes
- EFI variables
- "secure" — not normally writable by an OS
- can be made writable in some scenarios
- PK → KEK (1 or more cert) → db & dbx
- db: certs *&* hashes
* EFI Verification
- PE binary verified with cert from db: OK
- PE binary with hash in db: OK
- PE binary with hash in dbx: not OK
- on mainstream systems:
- motherboard vendor's cert in PK
- MS cert in KEK
- MS cert in db
- Windows bootloader signed by known key
* We Want Other OSes!
Go into BIOS settings, enroll your own PK, KEK and db.
- *usually* doable
- we'll go through that as well
- not needed for popular distributions
* shim
- an EFI application
- can load other EFIs
- verification
- GRUB, etc.
- gives machine owner control
- Machine Owner Key
- binaries in many GNU+Linux distros
- signed by Microsoft
- *most* hardware respects it
- often built reproducibly
* MokList EFI Variable
- managed and used by shim
- made inaccessible when OS is booted
- contents exposed in MokListRT
- holds certs/hashes added be hardware *owner*
- owner-created certs
- OS distribution certs
- modification → physical access needed
* Secure Boot with Debian, Ubuntu, Fedora, etc.
- shim → EFI application → bootloader → OS kernel
- GRUB *still* the most popular
- when software stack follows the Secure Boot concepts
- bootloader verifies kernel
- kernel verifies its modules
- SB → Linux kernel lockdown
* Post-shim Verification
- GRUB
- typically signed by distro
- can call back to shim to verify kernel using MokList
- more on GRUB later ;)
- Linux kernel
- uses (signed) modules
- in-tree modules
- the "official" ones
- public key in the kernel itself
- out-of-tree modules
- proprietary NVidia, etc.
* Secure Boot and Out-of-Tree Modules
- public key cannot be stored on-disk
- public key → PE file → verified using MokList
- patch rejected by Linus Torvalds…
- …yet applied by some distros
* Lockdown Mode
- Secure Boot → automatically enabled
- kernel mandates module verification
- =/dev/mem=
- hibernation
- more…
- SysRq+x
* Other Systems / Configurations
- Das U-Boot
- many ARM boards
- has "Verified Boot"
- UEFI & Secure Boot also available
- Coreboot
- includes a payload in firmware
- GRUB as payload
- verification with PGP (public key in GRUB image)
- Depthcharge as payload (Chromebooks)
- verification present
- TianoCore as payload
- UEFI & Secure Boot as described
* Dangers
- does hw ship with MS cert for shim?
- if not, does hw allow replacing the entire key chain?
- "Restricted Boots™® It's for your safety!"
- are cert dates checked?
- key expiration
|