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!