0:00:09.029,0:00:12.320 Herald: So, in this talk we will hear about 0:00:12.320,0:00:15.730 what UEFI is, how it can be used, 0:00:15.730,0:00:18.560 and how it can be executed in userspace, 0:00:18.560,0:00:20.259 and our speaker is Jethro Beekman, 0:00:20.259,0:00:25.649 and... the stage is yours. 0:00:25.649,0:00:27.820 Jethro Beekman: Thank you for the introduction. 0:00:27.820,0:00:32.499 applause 0:00:32.499,0:00:34.790 Alright, thank you for the introduction. 0:00:34.790,0:00:38.180 So, I'm a PhD student at UC Berkeley, 0:00:38.180,0:00:40.070 and in my copious amounts of free time, 0:00:40.070,0:00:43.440 I like to reverse-engineer things. 0:00:43.440,0:00:45.270 In particular, this time, 0:00:45.270,0:00:47.250 I reverse-engineered UEFI, 0:00:47.250,0:00:49.620 which is the modern BIOS replacement. 0:00:49.620,0:00:52.820 And, in this talk, I will discuss some tools 0:00:52.820,0:00:55.030 that you can use - that you too can use 0:00:55.030,0:00:57.140 to reverse-engineer UEFI, 0:00:57.140,0:00:58.750 including some tools that I wrote, 0:00:58.750,0:01:01.670 and tools that other people wrote. 0:01:01.670,0:01:04.860 So, this whole project started 0:01:04.860,0:01:08.040 when I bought a new SSD for my laptop 0:01:08.040,0:01:10.670 and, as you might know, modern SSDs have 0:01:10.670,0:01:13.510 built-in encryption capabilities, 0:01:13.510,0:01:16.310 whether this is secure or not is a question, 0:01:16.310,0:01:18.310 is a good question, but really, 0:01:18.310,0:01:19.850 reverse-engineering SSD firmware 0:01:19.850,0:01:23.300 is a talk for another day. 0:01:23.300,0:01:27.810 So, I decided to use this encryption, 0:01:27.810,0:01:31.460 and use it using the built-in 0:01:31.460,0:01:32.990 hardware password option 0:01:32.990,0:01:35.950 of my UEFI firmware. 0:01:35.950,0:01:38.560 This is the password I chose, 64 characters, 0:01:38.560,0:01:42.120 "correct horse battery staple galaxy[br]piece position require house". 0:01:42.120,0:01:47.520 It's very secure, obviously. 0:01:47.520,0:01:49.790 So this all seemed to be working fine, 0:01:49.790,0:01:51.390 and I was trusting that my hard drive 0:01:51.390,0:01:53.880 was encrypted properly, 0:01:53.880,0:01:54.909 but once you start to think about 0:01:54.909,0:01:56.159 how it actually works, 0:01:56.159,0:01:59.480 there's a small discrepancy, really, 0:01:59.480,0:02:02.500 because the way this password's input 0:02:02.500,0:02:04.720 to the hard drive is using 0:02:04.720,0:02:06.970 the ATA security feature set, 0:02:06.970,0:02:09.408 the security-unlock command. 0:02:09.408,0:02:11.489 And if you look at the unlock command, 0:02:11.489,0:02:12.930 you clearly see that the password 0:02:12.930,0:02:16.889 is supposed to be 32 bytes. 0:02:16.889,0:02:21.310 How are these 64 characters[br]turned into 32 bytes? 0:02:21.310,0:02:22.709 That is my question, 0:02:22.709,0:02:25.450 because if my laptop dies 0:02:25.450,0:02:28.310 but my SSD is still functional, 0:02:28.310,0:02:29.650 I want to be able to take my SSD 0:02:29.650,0:02:31.680 and put it into another computer 0:02:31.680,0:02:34.430 to get access to my data. 0:02:34.430,0:02:36.349 I tried all the standard things, 0:02:36.349,0:02:40.629 like truncating it, or using a standard 0:02:40.629,0:02:42.980 hash function like SHA-256 0:02:42.980,0:02:44.909 that has 32-byte output, 0:02:44.909,0:02:47.680 but these things all didn't work. 0:02:47.680,0:02:49.540 So then I decided to, you know, 0:02:49.540,0:02:52.989 really dive into the firmware 0:02:52.989,0:02:54.609 to figure out how it works. 0:02:54.609,0:02:56.249 So this talk will also be called 0:02:56.249,0:03:00.480 "How to turn 64 characters into 32 bytes". 0:03:00.480,0:03:06.759 applause 0:03:07.629,0:03:09.120 So what are some challenges 0:03:09.120,0:03:12.010 when reverse-engineering UEFI? 0:03:12.010,0:03:14.109 So first of all, this is the first thing 0:03:14.109,0:03:17.510 that runs when your computer is booted up. 0:03:17.510,0:03:18.919 So that means you will not be able 0:03:18.919,0:03:21.230 to use a standard debugger. 0:03:21.230,0:03:24.200 Surely people who develop firmware for a living 0:03:24.200,0:03:27.069 have some kind of hardware debugger 0:03:27.069,0:03:30.510 but that's unlikely to work on a commodity[br]system 0:03:30.510,0:03:34.620 such as this laptop,[br]which is all I got from the store. 0:03:34.620,0:03:37.309 Maybe you think you can emulate the firmware 0:03:37.309,0:03:39.340 using qemu or something like that, 0:03:39.340,0:03:41.120 but the hardware that the firmware 0:03:41.120,0:03:42.590 is designed to support 0:03:42.590,0:03:45.999 is unlikely to be correctly emulated by qemu. 0:03:45.999,0:03:50.309 So that is also probably not a viable way 0:03:50.309,0:03:52.249 to debug this. 0:03:52.249,0:03:57.629 Also, because UEFI is basically one big process, 0:03:57.629,0:04:01.299 using one address space, 0:04:01.299,0:04:02.329 there's no operating system 0:04:02.329,0:04:04.849 so there's no system calls. 0:04:04.849,0:04:07.089 Also there's no dynamic linker, 0:04:07.089,0:04:09.029 so there's no dynamic symbols, 0:04:09.029,0:04:10.439 there's no symbol table that you can use 0:04:10.439,0:04:13.290 as a starting point in your reverse-engineering. 0:04:13.290,0:04:16.478 You know, if you were reverse-engineering 0:04:16.478,0:04:20.099 a standard password utility in userspace 0:04:20.099,0:04:22.009 or something, you might start at 0:04:22.009,0:04:24.190 the read system call for, 0:04:24.190,0:04:26.900 that would be displayed to the user 0:04:26.900,0:04:28.280 to enter the password. 0:04:28.280,0:04:35.150 But in UEFI, no, that is not an option. 0:04:35.150,0:04:36.930 And even though there's no dynamic linker, 0:04:36.930,0:04:38.500 the whole firmware consists 0:04:38.500,0:04:42.030 of 281 different modules, in my case, 0:04:42.030,0:04:46.030 and it could be similar numbers[br]on your UEFI laptop. 0:04:46.030,0:04:50.589 And these modules all need to interact[br]in some way. 0:04:50.589,0:04:54.300 So, let's take a look at these different modules. 0:04:54.300,0:04:56.680 There's a tool called UEFITool, 0:04:56.680,0:04:58.729 written by Nikolaj Schlej, and 0:04:58.729,0:05:00.300 this really should be in your bag of tricks 0:05:00.300,0:05:01.840 if you're interested in doing anything 0:05:01.840,0:05:05.389 with UEFI firmware. 0:05:05.389,0:05:11.430 So, here I'll just go and use UEFIExtract, 0:05:11.430,0:05:15.300 which is a command line utility 0:05:15.300,0:05:17.020 included with UEFITool 0:05:17.020,0:05:20.229 that allows you to extract a firmware blob, 0:05:20.229,0:05:21.800 so in this case I took the firmware blob 0:05:21.800,0:05:26.460 from the Lenovo firmware update CD 0:05:26.460,0:05:29.949 and we're going to extract that. 0:05:29.949,0:05:34.240 After extracting it, we get this nice[br]directory structure 0:05:34.240,0:05:37.979 with one subdirectory per module 0:05:37.979,0:05:40.419 and as you can see, there's quite a few of[br]them. 0:05:40.419,0:05:44.720 Here's, there's system management[br]mode control module, 0:05:44.720,0:05:47.560 timer module, things like that. 0:05:47.560,0:05:48.700 And as you can see, 0:05:48.700,0:05:50.569 each module has a bunch of subdirectories 0:05:50.569,0:05:51.589 for the different sections 0:05:51.589,0:05:53.199 that are included in that module. 0:05:53.199,0:05:57.060 And one that appears a lot is the PE32+ image. 0:05:57.060,0:05:59.110 This is a portable execution image, 0:05:59.110,0:06:02.580 this is a format that Windows uses for executables. 0:06:02.580,0:06:05.840 So, you might think you might be able to run 0:06:05.840,0:06:11.419 these modules, and that is true. 0:06:11.419,0:06:14.110 But first, let's take a look at 0:06:14.110,0:06:16.169 what happens when you run a module like that. 0:06:16.169,0:06:19.639 Each module has an entry point, main, 0:06:19.639,0:06:22.930 and the main function gets passed 0:06:22.930,0:06:24.659 a pointer to the system table. 0:06:24.659,0:06:26.860 The system table is just... 0:06:26.860,0:06:30.050 contains more pointers to other structures. 0:06:30.050,0:06:32.370 For example, for the terminals, 0:06:32.370,0:06:34.639 cons in, cons out, standard error, 0:06:34.639,0:06:38.099 the standard text inputs and outputs, 0:06:38.099,0:06:41.259 and also the boot services structure. 0:06:41.259,0:06:43.069 The boot services structure contains 0:06:43.069,0:06:44.960 a bunch of function pointers, 0:06:44.960,0:06:47.909 including these install protocol interface 0:06:47.909,0:06:51.259 and locate protocol functions. 0:06:51.259,0:06:53.060 The install protocol interface allows 0:06:53.060,0:06:56.080 a module to install a protocol interface 0:06:56.080,0:07:00.300 using, specified by a particular GUID 0:07:00.300,0:07:03.169 and the interface is specified by just some[br]pointer. 0:07:03.169,0:07:05.719 Then, later, another module can call 0:07:05.719,0:07:08.810 a locate protocol function with the same GUID 0:07:08.810,0:07:10.840 and it will receive a pointer 0:07:10.840,0:07:12.849 to this interface that was previously installed 0:07:12.849,0:07:14.199 by the other modules. 0:07:14.199,0:07:17.840 So, most modules in their main function 0:07:17.840,0:07:20.759 start by loading a bunch of protocols 0:07:20.759,0:07:24.389 and then, after that, installing one more 0:07:24.389,0:07:28.050 of their own protocols. 0:07:28.050,0:07:29.189 This is all done at runtime. 0:07:29.189,0:07:31.129 So there's really no static way of 0:07:31.129,0:07:32.650 viewing the dependencies 0:07:32.650,0:07:34.749 between the different modules. 0:07:34.749,0:07:36.290 Luckily, we might be able to 0:07:36.290,0:07:37.349 execute these modules, 0:07:37.349,0:07:40.810 as I was alluding to before. 0:07:40.810,0:07:42.089 These modules, they're written 0:07:42.089,0:07:44.280 for the hardware you're currently using, 0:07:44.280,0:07:47.039 with your current operating system. 0:07:47.039,0:07:49.060 So they have a compatible instruction set. 0:07:49.060,0:07:50.259 So in order to execute them, 0:07:50.259,0:07:51.539 you just need a compatible 0:07:51.539,0:07:54.659 application binary interface, or ABI. 0:07:54.659,0:07:55.860 This is what I've written, 0:07:55.860,0:07:58.229 with the efiperun tool. 0:07:58.229,0:08:01.909 You can think of efiperun as WINE for UEFI. 0:08:01.909,0:08:03.889 Just like WINE allows you to run 0:08:03.889,0:08:06.189 Windows applications on Linux, 0:08:06.189,0:08:08.650 efiperun allows you to run EFI modules 0:08:08.650,0:08:11.850 on Linux. 0:08:11.850,0:08:19.310 applause 0:08:22.000,0:08:24.990 So, efiperun has a bunch of features, 0:08:24.990,0:08:29.129 it includes many of the standard EFI APIs 0:08:29.129,0:08:31.609 and it's very easy to add implementations 0:08:31.609,0:08:33.280 for missing APIs. 0:08:33.280,0:08:35.919 Also, at runtime, a missing API 0:08:35.919,0:08:37.380 will be generated automatically 0:08:37.380,0:08:39.600 with some stub functions. 0:08:39.600,0:08:41.309 It supports memory map annotations, 0:08:41.309,0:08:45.570 so that you can see which parts of memory 0:08:45.570,0:08:47.720 have been allocated by which module 0:08:47.720,0:08:49.810 and you can all run these in your standard 0:08:49.810,0:08:53.420 debugger environments, like gdb. 0:08:53.420,0:08:55.450 Also, as an interesting aside, 0:08:55.450,0:08:56.830 I think this the only project 0:08:56.830,0:08:58.060 I could find online 0:08:58.060,0:09:00.060 that uses the cross-stdarg header 0:09:00.060,0:09:02.620 which is used for calling 0:09:02.620,0:09:04.130 variable-argument functions 0:09:04.130,0:09:07.310 across calling conventions. 0:09:07.310,0:09:14.010 So, let's do a little demo of efiperun. 0:09:14.010,0:09:15.970 In this demo, I will just 0:09:15.970,0:09:20.970 run efiperun on each different module 0:09:20.970,0:09:24.150 to see which other modules it interacts with. 0:09:33.740,0:09:35.780 So, I just wrote this little Ruby script 0:09:35.780,0:09:37.530 which traverses the directory tree 0:09:37.530,0:09:41.710 that we just saw from the UEFIExtract utility 0:09:41.710,0:09:44.270 and then it executes efiperun 0:09:44.270,0:09:47.300 for each different module. 0:09:47.300,0:09:48.040 Whee! 0:09:50.500,0:09:52.400 Assertion error that I've never seen before, 0:09:52.400,0:09:53.580 that's always fun. 0:09:53.580,0:09:56.500 As you can see, 281 processes are launched, 0:09:56.500,0:09:58.000 most modules return 0:09:58.000,0:09:59.760 from the main function, normally, 0:09:59.760,0:10:01.400 but some of them get stuck 0:10:01.400,0:10:04.040 in an infinite loop, 0:10:04.040,0:10:06.230 so efiperun will automatically terminate 0:10:06.230,0:10:07.840 after 10 seconds in this case. 0:10:07.840,0:10:10.100 Let's look at the output of 0:10:10.100,0:10:13.980 all these different efiperun modules. 0:10:16.680,0:10:18.430 You can see a bunch of them segfault, 0:10:18.430,0:10:21.340 which, you know, can be, is understandable 0:10:21.340,0:10:23.400 because they might be expecting 0:10:23.400,0:10:26.410 some memory setup from the early boot 0:10:26.410,0:10:28.810 that is not existent anymore, 0:10:28.810,0:10:32.430 but there are a bunch of modules that do work 0:10:32.430,0:10:36.770 such as system boot manager. 0:10:36.770,0:10:40.480 You can see that it prints out[br]a bunch of stuff, 0:10:40.480,0:10:43.580 version information, copyright information, 0:10:43.580,0:10:45.570 then it requests a protocol, 0:10:45.570,0:10:48.060 this protocol has a GUID that is specified 0:10:48.060,0:10:50.200 by the EFI specification, 0:10:50.200,0:10:53.380 so we can interpret that GUID 0:10:53.380,0:10:56.060 and then it calls some stub functions 0:10:56.060,0:10:57.910 that we have not implemented 0:10:57.910,0:10:58.930 and then afterwards, 0:10:58.930,0:11:00.190 it installs its own protocol, 0:11:00.190,0:11:02.190 which is also a protocol specified 0:11:02.190,0:11:07.080 by the EFI specification. 0:11:07.080,0:11:08.040 Another interesting module 0:11:08.040,0:11:12.170 is the system splash module, 0:11:12.170,0:11:15.630 which we see over here. 0:11:15.630,0:11:18.760 As you can see, it actually requests 0:11:18.760,0:11:21.480 a bunch of protocols that are not implemented 0:11:21.480,0:11:22.910 by efiperun and you will see 0:11:22.910,0:11:24.640 it will automatically generate 0:11:24.640,0:11:27.950 a dummy interface for that purpose. 0:11:27.950,0:11:30.560 And then you will see that it calls 0:11:30.560,0:11:31.910 a function in this dummy interface 0:11:31.910,0:11:34.360 that was created here, 0:11:34.360,0:11:35.930 namely function number 2, 0:11:35.930,0:11:39.760 and because we are unable to handle this function 0:11:39.760,0:11:43.480 we just abort. 0:11:43.480,0:11:46.480 Okay, so now that I've shown you 0:11:46.480,0:11:48.680 that we can run these different modules, 0:11:48.680,0:11:50.040 we really need to get started with 0:11:50.040,0:11:51.930 the reverse-engineering of my BIOS 0:11:51.930,0:11:54.210 to figure how to turn those 64 characters 0:11:54.210,0:11:56.600 into 32 bytes. 0:11:56.600,0:12:00.060 You might remember this picture[br]from slide 2. 0:12:00.060,0:12:01.620 You can see that there's a little graphic 0:12:01.620,0:12:03.890 displayed in the password prompt. 0:12:03.890,0:12:05.100 So this graphic needs to be stored 0:12:05.100,0:12:05.940 somewhere in the BIOS, 0:12:05.940,0:12:08.180 and it needs to be coded to display 0:12:08.180,0:12:11.940 this graphic to the user at some point. 0:12:11.940,0:12:13.690 So, let's take a look at the different modules 0:12:13.690,0:12:15.200 that might have something to do with images 0:12:15.200,0:12:17.810 and graphics and things like that. 0:12:17.810,0:12:19.610 Turns out there's only 4 of the 281 0:12:19.610,0:12:22.310 that have a file names that seems to correspond 0:12:22.310,0:12:24.440 to something with graphics or images. 0:12:24.440,0:12:28.350 And if this, the first module is called 0:12:28.350,0:12:30.440 by another module, 0:12:30.440,0:12:32.370 which is Lenovo prompt service. 0:12:32.370,0:12:34.350 And Lenovo prompt service contains 0:12:34.350,0:12:36.000 in one of its data sections, 0:12:36.000,0:12:38.080 this image over here. 0:12:38.080,0:12:40.070 So now we know that we've found something 0:12:40.070,0:12:44.510 that has to do with the password prompt. 0:12:44.510,0:12:47.040 This prompt module is called by only one 0:12:47.040,0:12:47.980 other module, which is 0:12:47.980,0:12:49.820 the Lenovo password CP module, 0:12:49.820,0:12:51.130 which probably means something like 0:12:51.130,0:12:55.550 password control panel or something like that. 0:12:55.550,0:12:57.010 The password CP module also calls 0:12:57.010,0:12:59.500 into 3 other modules, namely 0:12:59.500,0:13:01.700 the sound service module, presumably to 0:13:01.700,0:13:04.130 play beeps if the user does something wrong 0:13:04.130,0:13:05.990 while entering the password, 0:13:05.990,0:13:08.440 the translate service module, which is used 0:13:08.440,0:13:10.340 to translate characters, 0:13:10.340,0:13:11.880 which I've reverse-engineered, 0:13:11.880,0:13:16.030 I've figured out that it's used to translate 0:13:16.030,0:13:20.470 ascii characters back into keyboard scan codes. 0:13:20.470,0:13:22.460 Keyboard scan codes are codes that are assigned 0:13:22.460,0:13:24.450 to each different key on your keyboard. 0:13:24.450,0:13:26.440 It's the way the hardware keyboard 0:13:26.440,0:13:29.860 communicates with your computer. 0:13:29.860,0:13:32.420 And then there's the Lenovo crypt service[br]module, 0:13:32.420,0:13:34.130 which turns out to be 0:13:34.130,0:13:36.550 standard SHA-256 hash function. 0:13:40.400,0:13:42.280 Right, so let's see and have a demo, 0:13:42.280,0:13:43.830 in which we are going to call 0:13:43.830,0:13:45.220 one of the functions in 0:13:45.220,0:13:48.470 this Lenovo password CP module. 0:13:53.790,0:13:58.130 So, efiperun allows you to write code 0:13:58.130,0:14:00.030 to interact with the EFI modules 0:14:00.030,0:14:02.930 that are loaded at runtime. 0:14:02.930,0:14:04.700 Here I've written this Lenovo-specific 0:14:04.700,0:14:07.420 debug module and you can specify 0:14:07.420,0:14:09.810 two functions that will be called. 0:14:09.810,0:14:11.500 The first function in it will be called 0:14:11.500,0:14:14.980 before all the EFI modules are loaded, 0:14:14.980,0:14:16.790 the second function will be called after 0:14:16.790,0:14:18.710 all the EFI functions are loaded. 0:14:18.710,0:14:20.260 So in this case, we'll first call 0:14:20.260,0:14:21.950 the install something function, and then 0:14:21.950,0:14:24.360 call, after loading the EFI modules, 0:14:24.360,0:14:26.830 the call something function. 0:14:26.830,0:14:30.760 The install function installs a stub 0:14:30.760,0:14:34.060 Lenovo crypt service protocol. 0:14:34.060,0:14:35.690 This is necessary because the standard 0:14:35.690,0:14:37.390 Lenovo crypt service calls into system 0:14:37.390,0:14:39.290 management mode to do the hashing, 0:14:39.290,0:14:41.130 which is currently not possible from 0:14:41.130,0:14:43.540 Linux userspace. 0:14:43.540,0:14:48.390 The second function,[br]call_LenovoPasswordCp_8cc, 0:14:48.390,0:14:50.890 will determine the address of the function 0:14:50.890,0:14:52.480 in the Lenovo password CP module 0:14:52.480,0:14:55.100 at offset 8cc and then call it. 0:14:55.100,0:14:57.480 It will take two parameters, in and out. 0:14:57.480,0:15:01.490 In will use this unicode string, my password, 0:15:01.490,0:15:02.470 and for the output, 0:15:02.470,0:15:05.770 we'll just pass this array buffer. 0:15:06.970,0:15:10.440 Then we'll just print the output 0:15:10.440,0:15:13.150 of the buffer after calling the function. 0:15:29.510,0:15:31.850 So, as you can see here, 0:15:31.850,0:15:33.600 the Lenovo translate service module 0:15:33.600,0:15:37.260 installs this protocol E3AB-etc. 0:15:37.260,0:15:39.280 and then later Lenovo password CP module 0:15:39.280,0:15:43.260 requests the same protocol E3AB-etc. 0:15:43.260,0:15:46.100 Also, you will see that 0:15:46.100,0:15:48.190 the Lenovo password CP module 0:15:48.190,0:15:52.050 requests the protocol C73E4-etc. 0:15:52.050,0:15:53.530 which is the Lenovo crypt service protocol 0:15:53.530,0:15:55.800 that we installed earlier. 0:15:55.800,0:15:57.780 Then it does a bunch of memory operations, 0:15:57.780,0:15:59.550 and at the end, we get the output. 0:15:59.550,0:16:02.340 So I reverse-engineered this function 0:16:02.340,0:16:07.570 at offset 8cc, and it turns out that 0:16:07.570,0:16:10.170 it is, in fact, the following function: 0:16:10.170,0:16:12.660 it takes the input password and 0:16:12.660,0:16:15.050 converts it into scan codes, 0:16:19.650,0:16:25.560 and then it pads it to 64 characters, 0:16:25.560,0:16:30.360 and then it takes a SHA-256 hash 0:16:30.360,0:16:33.520 and then it displays the first half of that. 0:16:36.580,0:16:40.390 Alright, here we go, so... 0:16:40.390,0:16:46.250 applause 0:16:46.250,0:16:47.450 We have reverse-engineered to 0:16:47.450,0:16:51.470 the first half of the password algorithm. 0:16:51.470,0:16:52.870 Took me about three weeks to decode 0:16:52.870,0:16:54.840 the entire algorithm, 0:16:54.840,0:16:57.530 and here it is. 0:16:57.530,0:16:59.060 So this is the hash that we just saw 0:16:59.060,0:17:01.580 of the password, and then this hash is 0:17:01.580,0:17:03.740 concatenated with the serial number and 0:17:03.740,0:17:06.050 model number of the hard drive. 0:17:06.050,0:17:08.800 That all is then hashed again, 0:17:08.800,0:17:12.300 and that is then passed to the SATA drive 0:17:12.300,0:17:13.569 over the ATA protocol. 0:17:13.569,0:17:15.349 Now this is actually quite a good idea 0:17:15.349,0:17:17.770 because it means that if you sniff 0:17:17.770,0:17:20.530 the password on the SATA bus 0:17:20.530,0:17:22.569 you will only be able to then later 0:17:22.569,0:17:24.449 unlock the same drive. 0:17:24.449,0:17:25.480 Because other drives, even though 0:17:25.480,0:17:26.900 they might be using the same password, 0:17:26.900,0:17:28.050 will have a different serial number 0:17:28.050,0:17:29.640 and model number. 0:17:29.640,0:17:33.390 So this hash will not work for them. 0:17:33.390,0:17:35.820 Unfortunately, the algorithm is 0:17:35.820,0:17:40.750 a little more complex than this. 0:17:40.750,0:17:43.490 The password hash, as I said, actually 0:17:43.490,0:17:45.350 uses the scan codes of the password, which 0:17:45.350,0:17:47.260 means that there is no distinguishing in 0:17:47.260,0:17:49.030 case of the letters. 0:17:49.030,0:17:51.980 Also, after hashing it, it truncates it 0:17:51.980,0:17:54.150 to only 12 bytes. Which means that 0:17:54.150,0:17:56.550 there's a maximum of 96 bits of entropy 0:17:56.550,0:18:00.050 in this password hash. 0:18:00.050,0:18:02.090 This is quite unfortunate. 0:18:02.090,0:18:05.240 But most human passwords have less than 0:18:05.240,0:18:08.100 96 bits of entropy to start with, 0:18:08.100,0:18:11.550 so it's probably not that big of a deal. 0:18:11.550,0:18:15.170 Okay, then again this part of the hash is 0:18:15.170,0:18:17.050 concatenated with the serial number 0:18:17.050,0:18:18.170 and the model number, 0:18:18.170,0:18:19.490 except the bytes are swapped. 0:18:19.490,0:18:21.720 And I really can't figure out why 0:18:21.720,0:18:22.990 the bytes are swapped here. 0:18:22.990,0:18:24.930 But it probably has to do something with 0:18:24.930,0:18:27.510 the fact that the ATA protocol uses 0:18:27.510,0:18:30.310 16-bit words while this model number and 0:18:30.310,0:18:32.740 serial number are 8-bit character strings. 0:18:32.740,0:18:35.240 So maybe they did some endianness mess-up 0:18:35.240,0:18:36.990 or something like that. 0:18:36.990,0:18:40.650 Alright, so in this talk, I've shown you 0:18:40.650,0:18:43.760 how you too can reverse-engineer UEFI 0:18:43.760,0:18:45.190 with some tools that you can use 0:18:45.190,0:18:47.320 in this including the efiperun tool 0:18:47.320,0:18:49.290 which allows you to run EFI modules 0:18:49.290,0:18:50.860 in linux userspace. 0:18:50.860,0:18:52.680 The code of this is of course available 0:18:52.680,0:18:55.000 under GPL license on github, 0:18:55.000,0:18:56.140 and if you want to read about 0:18:56.140,0:18:58.010 the second part of reverse-engineering 0:18:58.010,0:18:59.210 the algorithm, you can find more 0:18:59.210,0:19:00.850 information on my blog. 0:19:00.850,0:19:02.650 Thank you very much. 0:19:02.650,0:19:11.980 applause 0:19:11.980,0:19:14.560 H: So, thank you, Jethro, and we have 0:19:14.560,0:19:17.240 more than ten minutes' time for Q&A. 0:19:17.240,0:19:19.370 Is there a question from the Internet, 0:19:19.370,0:19:21.340 signal angel? 0:19:21.340,0:19:22.850 Signal: Not right now. 0:19:22.850,0:19:23.950 H: And do we have questions 0:19:23.950,0:19:25.210 from the audience? 0:19:25.210,0:19:31.100 Please line up at the microphones. 0:19:31.100,0:19:35.380 Then we'll start with microphone 2, please. 0:19:35.380,0:19:37.520 Q: Thanks a lot for making your tools available, 0:19:37.520,0:19:38.710 as someone else who does a lot of 0:19:38.710,0:19:41.640 UEFI reversing, I've been through similar 0:19:41.640,0:19:44.800 rabbit holes of trying to track this down. 0:19:44.800,0:19:46.760 You mentioned that SMM is not supported 0:19:46.760,0:19:48.670 and I assumed also the real mode 0:19:48.670,0:19:50.980 in the transition into long mode 0:19:50.980,0:19:51.850 is not supported. 0:19:51.850,0:19:53.640 Is that on your roadmap or something, 0:19:53.640,0:19:55.920 that you're interested in continuing 0:19:55.920,0:19:57.340 development on? 0:19:57.340,0:20:00.030 A: Yeah, I'm interested in it, but 0:20:00.030,0:20:02.300 I'm not quite sure how to do it, 0:20:02.300,0:20:05.840 especially calling into[br]system management mode, 0:20:05.840,0:20:07.180 protected mode should probably, 0:20:07.180,0:20:08.540 you know, also be possible, 0:20:08.540,0:20:11.250 but currently I'm also doing 64-bit mode 0:20:11.250,0:20:15.070 but, yeah, if anyone wants to help me 0:20:15.070,0:20:23.570 implement it, obviously I welcome your support. 0:20:23.570,0:20:25.370 H: Okay, and from the Internet, please. 0:20:25.370,0:20:27.059 Q: Yes. The Internet wants to know 0:20:27.059,0:20:32.510 what is the advantage of UEFI[br]compared to coreboot? 0:20:32.510,0:20:33.470 A: I'm sorry, I didn't... 0:20:33.470,0:20:35.300 Q: The Internet wants to know 0:20:35.300,0:20:38.030 what is the advantage of UEFI compared 0:20:38.030,0:20:40.110 with coreboot, for example? 0:20:40.110,0:20:41.840 A: The advantage of UEFI compared to what? 0:20:41.840,0:20:44.800 Q: To coreboot, coreboot, this open source 0:20:44.800,0:20:46.030 BIOS replacement. 0:20:46.030,0:20:48.160 A: Oh okay. coreboot is UEFI, 0:20:48.160,0:20:49.780 coreboot is Intel's open source 0:20:49.780,0:20:51.330 implementation of UEFI. 0:20:51.330,0:20:53.800 Q: Actually, well, actually it's not. 0:20:53.800,0:20:56.220 A: Oh, it's not, no, that's tianocore, 0:20:56.220,0:20:59.940 you're right. 0:20:59.940,0:21:03.430 The only advantage is, 0:21:03.430,0:21:05.050 I don't know what the advantage is, 0:21:05.050,0:21:06.910 this is just what's supported on my laptop. 0:21:06.910,0:21:08.910 So that's what I was interested in. 0:21:08.910,0:21:14.850 laughter, applause 0:21:14.850,0:21:17.520 H: Okay. Microphone 3, please. 0:21:17.520,0:21:19.620 Q: Hi. Thank you for your talk. 0:21:19.620,0:21:20.980 Have you looked at any other firmware 0:21:20.980,0:21:24.740 besides your Lenovo? 0:21:24.740,0:21:27.550 A: I've not personally, but 0:21:27.550,0:21:32.740 I know other people have. 0:21:32.740,0:21:34.710 H: Okay. 4, please. 0:21:34.710,0:21:37.059 Q: Thank you for the talk. How did you 0:21:37.059,0:21:42.059 come out how to get the password, the hash 0:21:42.059,0:21:47.680 with the combination of the serial number 0:21:47.680,0:21:50.210 and the module number? 0:21:50.210,0:21:53.200 A: So, the full details of this 0:21:53.200,0:21:55.600 are in my blog post, but in short, 0:21:55.600,0:21:58.880 there is a EFI protocol for talking 0:21:58.880,0:22:01.180 to the hard drive, which is 0:22:01.180,0:22:02.270 the ATA support protocol, 0:22:02.270,0:22:04.430 if I remember correctly, 0:22:04.430,0:22:05.630 there's a special module, 0:22:05.630,0:22:06.640 there are only a few modules, 0:22:06.640,0:22:08.650 that invoke this protocol, 0:22:08.650,0:22:12.110 so I just disassembled those, and looked 0:22:12.110,0:22:13.470 at what they did, and what commands 0:22:13.470,0:22:15.220 they sent to the ATA drive. 0:22:15.220,0:22:16.650 Q: Thank you. 0:22:16.650,0:22:19.280 H: And there is another question[br]from the chat. 0:22:19.280,0:22:22.390 Q: Yes. The chat wants to know if you found 0:22:22.390,0:22:24.790 any other unexpected bugs and 0:22:24.790,0:22:28.510 if it is possible to check UEFI code, 0:22:28.510,0:22:31.170 for example, when running it with valgrind 0:22:31.170,0:22:34.520 or something. 0:22:34.520,0:22:36.740 A: I've not really run into any other 0:22:36.740,0:22:39.140 unexpected bugs, but I must say I also 0:22:39.140,0:22:42.250 really wasn't looking for them. 0:22:42.250,0:22:44.040 H: Okay. 2, please. 0:22:44.040,0:22:48.600 Q: I have little understanding of EFI, but 0:22:48.600,0:22:55.400 I had the idea to look into trying to get 0:22:55.400,0:23:00.570 boot ROMs from PC graphic cards 0:23:00.570,0:23:04.340 to be running on a MacOS computer, 0:23:04.340,0:23:09.520 old Mac Pros when they[br]still were having cards, 0:23:09.520,0:23:12.320 and I was wondering,[br]I wanted to figure out... 0:23:12.320,0:23:15.870 these cards run, apparently, the old BIOS, 0:23:15.870,0:23:19.020 real mode, and I wanted to figure out 0:23:19.020,0:23:23.380 if I can write a stub that gets loaded 0:23:23.380,0:23:27.050 by the EFI system and then that... 0:23:27.050,0:23:31.000 my code would then invoke[br]the initialization boot ROM 0:23:31.000,0:23:33.940 for the graphics card[br]and provide the functions. 0:23:33.940,0:23:38.360 Would your toolset, would that help me in 0:23:38.360,0:23:40.929 tracing that while my Mac is running, 0:23:40.929,0:23:43.360 because I can't do it while it's booting? 0:23:43.360,0:23:48.230 A: I don't... it sounds like a,[br]quite a complex setup, 0:23:48.230,0:23:49.890 I think it would be possible to write 0:23:49.890,0:23:52.050 an EFI module to do what you're saying, 0:23:52.050,0:23:53.179 but I'm not sure if you'll be able 0:23:53.179,0:23:57.200 to run that while your operating system[br]is also running. 0:23:57.200,0:24:01.660 So... I'm not sure, I'll have to talk more 0:24:01.660,0:24:05.560 offline to discuss your specific situation. 0:24:05.560,0:24:07.920 H: Okay, and microphone 3, please. 0:24:07.920,0:24:16.240 Q: Hi. Have you looked into using[br]SerialICE for emulation of the UEFI 0:24:16.240,0:24:22.850 which is essentially qemu but it has,[br]does forward all of the hardware accesses 0:24:22.850,0:24:25.770 to real hardware, so you can just trace it 0:24:25.770,0:24:29.780 and run arbitrary BIOS or UEFI code in it? 0:24:29.780,0:24:31.420 A: I've not looked into that, but that 0:24:31.420,0:24:33.970 sounds a very interesting[br]avenue to explore. 0:24:33.970,0:24:36.009 Q: Thank you. 0:24:36.009,0:24:37.909 H: Okay. I see no more questions. 0:24:37.909,0:24:39.920 Thank you to our speaker. 0:24:39.920,0:24:41.250 applause 0:24:41.250,0:24:53.000 subtitles created by c3subtitles.de[br]Join, and help us!