This repository has been archived by the owner on Sep 14, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Security_Advisory-Ref_IPVR2018-0001-U-Boot_verified_boot_bypass.txt
317 lines (235 loc) · 11 KB
/
Security_Advisory-Ref_IPVR2018-0001-U-Boot_verified_boot_bypass.txt
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
Security advisory: U-Boot verified boot bypass
==============================================
The Universal Boot Loader - U-Boot [1] verified boot feature allows
cryptographic authentication of signed kernel images, before their execution.
This feature is essential in maintaining a full chain of trust on systems which
are secure booted by means of an hardware anchor.
Multiple techniques have been identified that allow to execute arbitrary code,
within a running U-Boot instance, by means of externally provided
unauthenticated data.
All such techniques spawn from the lack of memory allocation protection within
the U-Boot architecture, which results in several means of providing
excessively large images during the boot process.
Some implementers might find the following issues as an intrinsic
characteristic of the U-Boot memory model, and consequently a mere aspect of
correct U-Boot configuration and command restrictions.
However in our opinion the inability of U-Boot to protect itself when loading
binaries is an unexpected result of non trivial understanding, particularly
important to emphasize in trusted boot scenarios.
This advisory details two specific techniques that allow to exploit U-Boot lack
of memory allocation restrictions, with the most severe case also detailing a
workaround to mitigate the issue.
It must be emphasized that cases detailed in the next sections only represent
two possible occurrences of such architectural limitation, other U-Boot image
loading functions are extremely likely to suffer from the same validation
issues.
To a certain extent the identified issues are similar to one of the findings
reported as CVE-2018-1000205 [2], however they concern different functions
which in some cases are at a lower level, therefore earlier in the boot image
loading stage.
Again all such issues are a symptom of the same core architectural limitation,
being the lack of memory allocation constraints for received images.
It is highly recommended, for implementers of trusted boot schemes, to review
use of all U-Boot booting/loading commands, and not merely the two specific
ones involved in the findings below, to apply limitations (where
applicable/possible) to the size of loaded images in relation to the available
RAM.
It should also be emphasized that any trusted boot scheme must also rely on an
appropriate lockdown of all possibilities for interactive consoles, by boot
process interruption or failure, to ever be prompted.
U-Boot insufficient boundary checks in filesystem image load
------------------------------------------------------------
The U-Boot bootloader supports kernel loading from a variety of filesystem
formats, through the `load` command or its filesystem specific equivalents
(e.g. `ext2load`, `ext4load`, `fatload`, etc.)
These commands do not protect system memory from being overwritten when loading
files of a length that exceeds the boundaries of the relocated U-Boot memory
region, filled with the loaded file starting from the passed `addr` variable.
Therefore an excessively large boot image, saved on the filesystem, can be
crafted to overwrite all U-Boot static and runtime memory segments, and in
general all device addressable memory starting from the `addr` load address
argument.
The memory overwrite can directly lead to arbitrary code execution, fully
controlled by the contents of the loaded image.
When verified boot is implemented, the issue allows to bypass its intended
validation as the memory overwrite happens before any validation can take
place.
The following example illustrates the issue, triggered with a 129MB file on a
machine with 128MB or RAM:
```
U-Boot 2018.09-rc1 (Oct 10 2018 - 10:52:54 +0200)
DRAM: 128 MiB
Flash: 128 MiB
MMC: MMC: 0
# print memory information
=> bdinfo
arch_number = 0x000008E0
boot_params = 0x60002000
DRAM bank = 0x00000000
-> start = 0x60000000
-> size = 0x08000000
DRAM bank = 0x00000001
-> start = 0x80000000
-> size = 0x00000004
eth0name = smc911x-0
ethaddr = 52:54:00:12:34:56
current eth = smc911x-0
ip_addr = <NULL>
baudrate = 38400 bps
TLB addr = 0x67FF0000
relocaddr = 0x67F96000
reloc off = 0x07796000
irq_sp = 0x67EF5EE0
sp start = 0x67EF5ED0
# load large file
=> ext2load mmc 0 0x60000000 fitimage.itb
# In this specific example U-Boot falls in an infinite loop, results vary
# depending on the test case and filesystem/device driver used. A debugging
# session demonstrates memory being overwritten:
(gdb) p gd
$28 = (volatile gd_t *) 0x67ef5ef8
(gdb) p *gd
$27 = {bd = 0x7f7f7f7f, flags = 2139062143, baudrate = 2139062143, ... }
(gdb) x/300x 0x67ef5ef8
0x67ef5ef8: 0x7f7f7f7f 0x7f7f7f7f 0x7f7f7f7f 0x7f7f7f7f
```
It can be seen that memory address belonging to U-Boot data segments, in this
specific case the global data structure `gd`, is overwritten with payload
originating from `fitimage.itb` (filled with `0x7f7f7f7f`).
### Impact
Arbitrary code execution can be achieved within a U-Boot instance by means of
unauthenticated binary images, loaded through the `load` command or its
filesystem specific equivalents.
It should be emphasized that all load commands are likely to be affected by the
same underlying root cause of this vulnerability.
### Workaround
The optional `bytes` argument can be passed to all load commands to restrict
the maximum size of the retrieved data.
The issue can be therefore mitigated by passing a `bytes` argument with a value
consistent with the U-Boot memory regions mapping and size.
U-Boot insufficient boundary checks in network image boot
---------------------------------------------------------
The U-Boot bootloader supports kernel loading from a variety of network
sources, such as TFTP via the `tftpboot` command.
This command does not protect system memory from being overwritten when loading
files of a length that exceeds the boundaries of the relocated U-Boot memory
region, filled with the loaded file starting from the passed `loadAddr`
variable.
Therefore an excessively large boot image, served over TFTP, can be crafted to
overwrite all U-Boot static and runtime memory segments, and in general all
device addressable memory starting from the `loadAddr` load address argument.
The memory overwrite can directly lead to arbitrary code execution, fully
controlled by the contents of the loaded image.
When verified boot is implemented, the issue allows to bypass its intended
validation as the memory overwrite happens before any validation can take
place.
The issue can be exploited by several means:
- An excessively large crafted boot image file is parsed by the
`tftp_handler` function which lacks any size checks, allowing the memory
overwrite.
- A malicious server can manipulate TFTP packet sequence numbers to store
downloaded file chunks at arbitrary memory locations, given that the
sequence number is directly used by the `tftp_handler` function to calculate
the destination address for downloaded file chunks.
Additionally the `store_block` function, used to store downloaded file
chunks in memory, when invoked by `tftp_handler` with a `tftp_cur_block`
value of 0, triggers an unchecked integer underflow.
This allows to potentially erase memory located before the `loadAddr` when
a packet is sent with a null, following at least one valid packet.
The following example illustrates the issue, triggered with a 129MB file on a
machine with 128MB or RAM:
```
U-Boot 2018.09-rc1 (Oct 10 2018 - 10:52:54 +0200)
DRAM: 128 MiB
Flash: 128 MiB
MMC: MMC: 0
# print memory information
=> bdinfo
arch_number = 0x000008E0
boot_params = 0x60002000
DRAM bank = 0x00000000
-> start = 0x60000000
-> size = 0x08000000
DRAM bank = 0x00000001
-> start = 0x80000000
-> size = 0x00000004
eth0name = smc911x-0
ethaddr = 52:54:00:12:34:56
current eth = smc911x-0
ip_addr = <NULL>
baudrate = 38400 bps
TLB addr = 0x67FF0000
relocaddr = 0x67F96000
reloc off = 0x07796000
irq_sp = 0x67EF5EE0
sp start = 0x67EF5ED0
# configure environment
=> setenv loadaddr 0x60000000
=> dhcp
smc911x: MAC 52:54:00:12:34:56
smc911x: detected LAN9118 controller
smc911x: phy initialized
smc911x: MAC 52:54:00:12:34:56
BOOTP broadcast 1
DHCP client bound to address 10.0.0.20 (1022 ms)
Using smc911x-0 device
TFTP from server 10.0.0.1; our IP address is 10.0.0.20
Filename 'fitimage.bin'.
Load address: 0x60000000
Loading: #################################################################
...
####################################
R00=7f7f7f7f R01=67fedf6e R02=00000000 R03=7f7f7f7f
R04=7f7f7f7f R05=7f7f7f7f R06=7f7f7f7f R07=7f7f7f7f
R08=7f7f7f7f R09=7f7f7f7f R10=0000d677 R11=67fef670
R12=00000000 R13=67ef5cd0 R14=02427f7f R15=7f7f7f7e
PSR=400001f3 -Z-- T S svc32
```
It can be seen that the program counter (PC, r15) is set to an address
originating from `fitimage.itb` (filled with `0x7f7f7f7f`), as the result of
the U-Boot memory overwrite.
### Impact
Arbitrary code execution can be achieved within a U-Boot instance by means of
unauthenticated binary images, passed through TFTP and loaded through the
`tftpboot` command, or by a malicious TFTP server capable of sending arbitrary
response packets.
It should be emphasized that all network boot commands are likely to be
affected by the same underlying root cause of this vulnerability.
### Workaround
The `tftpboot` command lacks any optional argument to restrict the maximum size
of downloaded images, therefore the only workaround at this time is to avoid
using this command on environments that require trusted boot.
Affected version
----------------
All tests have been performed against U-Boot version 2018.09-rc1.
CVE-2018-18439 fixed in commit a156c47e39ad7d007c88919103ee0ee131c6203b
CVE-2018-18440 fixed in commit aa3c609e2be5a837e7b81e308d47f55b67666bd6
Both fixes are included in U-Boot v2019.04.
Credit
------
Vulnerabilities discovered and reported by the Inverse Path team at F-Secure,
in collaboration with Quarkslab.
CVE
---
CVE-2018-18440: U-Boot insufficient boundary checks in filesystem image load
CVE-2018-18439: U-Boot insufficient boundary checks in network image boot
Timeline
--------
2018-10-05: network boot finding identified during internal security audit
by Inverse Path team at F-Secure in collaboration with Quarkslab.
2018-10-10: filesystem load finding identified during internal security audit
by Inverse Path team at F-Secure.
2018-10-12: vulnerability reported by Inverse Path team at F-Secure to U-Boot
core maintainer and Google security, embargo set to 2018-11-02.
2018-10-16: Google closes ticket reporting that ChromeOS is not affected due
to their specific environment customizations.
2018-10-17: CVE IDs requested to MITRE and assigned.
2018-11-02: advisory release.
2019-04-09: U-Boot v2019.04 is released.
References
----------
[1] https://www.denx.de/wiki/U-Boot
[2] https://lists.denx.de/pipermail/u-boot/2018-June/330487.html
Permalink
---------
https://github.com/f-secure-foundry/usbarmory/blob/master/software/secure_boot/Security_Advisory-Ref_IPVR2018-0001.txt