-
*38C3 preroll music*
thank you all for being
-
here to be honest this is my first CCC is it
the case for somebody in the audience great
-
I usually cannot be here because of for family
reasons and the only way I could find to get here
-
is to get accepted as a speaker so here I am so as
the angel says I'm a security researcher I live in
-
the French speaking part of Switzerland I do a lot
of embedded devices I'm also part of uh organizing
-
a way smaller conference called BlackAlps in
Switzerland and also I'm responsible of the main
-
I'm the main core developer of the HydraBus
it's basically Hardware Swiss Army Knife
-
so the target that we will see today is
the Chipolo ONE it has been released in
-
2019 so 3 years before the air tag went so that
means that there's no specific protocol for the
-
Bluetooth tracker it was it's plain Bluetooth
device so it has the exact same functionalities
-
basically it's a Bluetooth tracker it has an
application that you can use to make it ring
-
*ring*
like that and it helps you
-
recover your keys your cats it's really in the on
the website it helps you recover your cats never
-
tested but I will first start by the end you will
see why later so at the end of This research on
-
September 15 we sent an email to Chipolo and on
September 20 we got an acknowledge from them they
-
asked for more details and we set up an online
meeting with the the Chipolo team so there was
-
eight different people from the engineering from
the management various people from Chipolo they
-
were really interested we did a presentation kind
of this one with a bit more context and several
-
questions the good thing was that they were
really open for discussion so we had some weird
-
things that we found in the firmware so we asked
questions and they were really kind and willing to
-
explain the issues some of them were let's say by
design some others were plain mistake by them
-
by the end of this meeting what what really
stand out was that the device they used had
-
a really small memory for storing the firmware
that means that they had to make some choices and
-
remove some features and some security checks
in order to make the firmware fit within the
-
microcontroller so this is why you will see some
of the the issues but they also acknowledge that
-
they did some mistakes and overlooked several
security features they were also kind enough
-
to let me present here the only thing is that
they asked me to not publish the encryption
-
keys so they will be redacted in those slides
okay back then so we got the device we crack this
-
is just a simple plastic case so we can just
crack it open and this will give us this small
-
white PCB here and there are three components
that are really interesting uh the first one
-
being the microcontroller itself the second one is
the sound driver it's mostly used for the beeping
-
and stuff and as you can see there are a lot of
various test points so this chip is the DA14580
-
I will just say the dialogue for now so it's
was produced by dialogue which has been bought
-
by Renesas nowadays uh it's a Cortex-M0 and one
interesting thing is there's no flash memory in
-
this chip there's only a one-time programmable
memory that means that you can flash it once
-
and then the firmware is stayed there forever you
cannot update it you cannot change it nothing but
-
the good thing for us is that this chip has a data
sheet available on the internet so the first thing
-
we did is to set the pin out and locate the debug
interface on the various test points we added some
-
wires very poorly to be honest *laughter* but
in the end it worked so that's perfectly fine
-
now I regret I regret registering for
the soldering challenge tomorrow
-
*laughter*
so we connected
-
uh debug probe and unfortunately for us the SWD
interface is unresponsive that means that there's
-
absolutely no access to the debug interface so
we cannot extract the firmware from the device
-
so back to the documentation we can see that in
the red square here it's written the debug lock
-
JTAG it's not JTAG it's say WG but whatever so it
supports this JTAG lock features that means that
-
apparently Chipolo did a good good job and
disabled the debug interface that's pretty
-
great for them but not for us because we really
want that firmware so what we did is start by the
-
fault injection when I say we I want just to thank
and give credit where it's due I had a friend who
-
who worked with me on the fault injection on all
the hardware side so thanks a lot to Azacs who
-
helped me on this so fault injection who everybody
knows about fault injection nobody great okay
-
so fault injection basically the idea of fault
injection is to perturbate the CPU or the
-
microcontroller to make it behave a bit weirdly
namely corrupting instructions or as we say is
-
skipping an instruction basically we make the CPU
do something different than what it's supposed to
-
do if we do it correctly this perturbation allows
us to just modify one or a few instructions and
-
then the CPU continues its processing that
means that we can just change a little bit of
-
uh execution and then it resumes the execution
that would be great for us because if we can
-
let's say corrupt the set the debug lock then that
would be great there are a lot of different fault
-
injection techniques that exist namely voltage
glitching electromagnetic fault injection and
-
for this one we went with the electromagnetic
fault injection using the ChipSHOUTER which is
-
showed here so this is a tool that has been
developed to especially to create a small
-
electromagnetic pulses that will perturbate the
CPU hence making some instructions go weird
-
but now we need to know exactly where to fault
that means that we have to to spot the exact
-
instructions that will that will enable or
disable the JTAG and how to do this first
-
with the documentation we know exactly the
boot process how it works so it first boots
-
setups the hardware then it will copy the OTP
so the firmware from the one-time programmable
-
memory into RAM and then it will remap the RAM
at address zero and then it will reset the CPU
-
so the CPU will start on the firmware that is
in RAM that's how this specific CPU boots
-
so our idea was to use power analysis the idea
is to monitor the power consumption of the the
-
microcontroller in order to see some patterns that
will help us know exactly where this copy from OTP
-
to RAM happens so what we did was simply add some
various devices to measure the power consumption
-
and use an oscilloscope to actually see the trace
and try to map the trace with what we see from
-
the documentation and this is how it looks like so
basically we have the boot start at the beginning
-
here and then from the data sheet it says that it
waits for 100 milliseconds and then it will start
-
the copy and if you squint the eyes a bit you will
see that you have a lot of activities right there
-
after the 100 millisecs so that's not that good
when you are doing fault injection because with
-
100 milliseconds that means that you have a lot
of jitter so when you want to be really precise
-
on one specific instruction that's quite difficult
to do so there are a lot of ways to synchronize
-
on the power consumption itself and this will
be covered later but the thing is that using
-
electromagnetic injection we have to be really
precise also on the parameters of the injections
-
that we will do basically if we put a fault if we
inject an EMP pulse too hard usually the target
-
resets or crashes or burns or doesn't work anymore
that happens or if you do it too softly that means
-
that the CPU won't behave differently and you
will basically have no effect at all so what we
-
usually do is we take the the development kit for
that specific microcontroller we create a small
-
firmware that we control so that we can actually
see whether we have some instruction corruption
-
or not in that specific case we didn't do it
first of all because we we didn't have any dev
-
kits available we didn't want to buy them and it
was pretty fun to actually test it as a blackbox
-
so using just the power analysis so the idea is
to take the trace set some various parameters
-
like the width of the EMP pulse the voltage
that you provide the actual coil that will
-
generate the EMP pulse and also the physical
location over the chip has some importance
-
so we tried to do this but what happens is that
during this small characterization phase suddenly
-
the SWD interface appeared so we were really lucky
really really lucky because it worked nearly after
-
2 or 3 hours of testing various parameters and we
we by luck found the exact timing that allowed us
-
to get access to the SWD so first of all we are
quite surprised of course but since it was still
-
open and the device was still working that means
it was the perfect conditions to actually dump
-
the RAM so we stopped the CPU we started the
dumping process from address zero because we
-
know that the firmware is located at address zero
and then we tried to replicate it of course and
-
remember when I said that the chip can die and
burn that's exactly what happens a few attempts
-
later so the chip just died and it didn't work
anymore so at least we have this firmware now
-
so that's pretty great and if we just have
a quick look at the RAM dump it's exactly 44
-
kiloby of data which is exactly the size of the
RAM available from the data sheet that's perfect
-
and if we dump the data we show some readable
strings like the company name and other other
-
strings that I unfortunately I cannot show you
for posterity this is the setup that we have so
-
as you can see there's no XY table it's just
a bunch of various devices connected together
-
in the middle there I think the German word is
cable salad that's correct *laughter* yeah and the
-
chip is right here so all the various components
around is just for triggering the fault doing the
-
power analysis monitoring etc etc it was a nice
afternoon with a lot of beers and a good friend
-
so now that we have this firmware what we usually
do when analyzing a firmware of an embedded device
-
is first to load the firmware at the correct
address in that case it's quite easy because it's
-
uh from address zero so it starts right there
we try to populate the known peripherals and
-
registers that's also very helpful to understand
what exactly some specific function do when they
-
trying to access some specific memory regions
and then we analyze the code that's usually how
-
it works to do this for the peripheral s registers
usually you have for arm chips you have something
-
that is called the CMSIS-SVD which is an XML
file that describes all the various registers and
-
memory regions for a specific chip it's usually
published by the manufacturers so that's great and
-
there's a nice plugin which is called SVD loader
for Ghidra and others that allows you to basically
-
take this XML file and populate all the memory
regions within your favorite disassembler that's
-
pretty great unfortunately of course there's no
SVD for this specific chip so what I would what
-
I did is get a simple idea is if we have the data
sheet with all the information there we just need
-
to pass the PDF generate a Ghidra script that will
just take those values and generate the python
-
script that can can just copy and paste into the
python console of Ghidra and that will be fine
-
except it just doesn't work because if you look
at those you can already see that I have two table
-
number ones that means that the PDF is absolutely
awful there's a lot of messed tables some cells
-
are merged together sometimes there are ghost
cells with no values inside of it so in the end
-
after the extractions I had to basically rewrite
everything by hand just to make sure that it works
-
correctly but after a lot of time I was able to
get something that looks quite nice so I first
-
already have all the registers and the memory
regions that's already a good result but we are
-
not there yet because looking at the code
I saw that uh there are a lot of calls to a
-
specific memory region that I haven't dumped and
I cannot either and those hardcoded functions
-
looking at the at the data sheet again it's in
a specific region in RAM so it's it's burned
-
directly within the chip and it has a lot
of helper functions and functions that are
-
used a lot so this these functions I couldn't
have them so I don't know their names I cannot
-
reverse them nothing but luckily for me uh I was
able to find a symdef file on GitHub a symdef
-
file is a way for the ARM compiler to have some
specific values some specific function names that
-
correspond to a specific address and the linker
will automatically convert those values to make
-
sure that you are calling the right function so
I wrote a Ghidra script the link is there uh it's
-
on GitHub if you need it because there was none
before that so with that specific Ghidra script
-
and if we pull that all together you'll start with
the function on the left and in the end you have
-
the function of the right you can see that they
implemented memcopy and memcmp directly in RAM
-
so that's pretty convenient so you don't need to
implement your own memcopy it's already written
-
into the chip and you have other functions and
other helpers that typically tell you okay this
-
is the Bluetooth address of the device
so now that we have everything the registers
-
the memory regions the function names a bit we
can start the reversing so after fiddling around
-
I found the main application logic which is this
nice graph on the right here so it's a huge state
-
machine that basically handles all the various
Bluetooth communication and depending on the state
-
it is it will call various functions and other
callbacks etc etc so it's pretty messy to do but
-
at first the first thing it does is some kind
of comparison and if the user sends a specific
-
Bluetooth value then the chip will enable all the
other functions looks like an authentication so
-
looking at how this authentication data is sent
basically it's a comparison between six byte that
-
the the user sends to the device and a value that
is stored within the device and that value that
-
is stored is first the CR the CRC32 of some random
16 byte buffer so they are using CRC32 it's quite
-
easy to find because you have those constant
values you can use Google you can just Google
-
for the values and it will directly tell you the
kind of function it is that's pretty great there's
-
also another script that is called FindCrypt that
will help you understand which constants are used
-
for specific crypto algorithm and that helps a
lot so it does a CRC32 over a 16 byte buffer and
-
that specific buffer comes from another function
that takes as an input the Bluetooth address a
-
fixed value that that I cannot tell you and some
other value that I cannot tell you but it's fixed
-
and that function again uses a specific constant
and if you Google for it you will see that it's
-
TEA so it's the tiny encryption algorithm so
basically this value this spe this secret that
-
you need to discover is only dependent on the
Bluetooth address that you can know but there's
-
even more because the CRC is only four bytes and
it compares to six bytes so that CRC the secret
-
uh that I will call secret is a 4 byte value
it is then mangled with a random value that
-
is generated at boot this value can be carried
over Bluetooth that's how the application knows
-
the random seed let's say let's call it that
way and how the seed is and how the password
-
is calculated it's based on the random and that
specific CRC you have all the the token values
-
the token positions and the formulas associated
and if you are quite decent at math especially
-
with source you will see that if you can sniff one
specific one valid authentication you can recover
-
the the CRC hence the secret key for
that authentication that also means that
-
with one authentication you can re-create any new
authentication it's even easier because after a
-
first a first successful authentication the random
value is incremented by one it's not regenerated
-
it's just incremented by one that means there are
only two bytes that change within the token
-
so that was also very nice what I did then is
I installed the application to confirm that
-
you can recover the the secret value and it
works perfectly fine and then I was thinking
-
okay so maybe there might be some other
vulnerabilities there so I installed the
-
app I used the Bluetooth snoop plug from Android
to access all the various Bluetooth traffic and
-
I found out that the protocol uses some kind of
TLV encoding so tag length and value so I looked
-
at how the TLV encoding the TLV decoding works
within the firmware and oh boy the thing is it
-
takes the whole input and it will split the input
in three different stack based buffer so the tags
-
will go in the tags buffer the length will go in
the length buffer and the values will go into the
-
values buffer there's absolutely no bounce check
so that means it's should be quite easy you just
-
send a very big packet and you will be able to
overflow any of those stack based buffers except
-
that on that specific chip the Bluetooth stack
does not support changing the size of the payload
-
in a Bluetooth packet so it's stuck to the default
of 23 bytes and unfortunately all the buffers are
-
larger enough they they thought about it so
unfortunately there's no way to really control
-
the data we can overflow we can still overflow by
setting a very large length value but you cannot
-
really control the exact values that you will
overflow so we have to go a bit deeper then in
-
the application you have a way to upload a custom
melody on the device some of you already see where
-
I'm going there so you have nine different
Melodies there so you can say you can ask
-
to upload a new melody at slot number from 0 to 8
fun fact those melodies are stored in an array so
-
there's a there's an array of pointer to melodies
structures and two of them are have a null pointer
-
it's a it's a bug they confirmed it's a bug it
it shouldn't happen but what's funny is that it
-
it allows you to overwrite directly the vector
table from the chip and that's a possibility
-
to have to have remote code execution but there's
even a simper way because once you say okay I want
-
to add to change the melody what you can do is you
will just send data as chunks to the device and it
-
will just copy it in the melody buffer of course
with absolutely no bounce checking whatever so
-
you can just overwrite up to the end of the RAM
if you want to fun fact also there's a way to
-
at the end in the application it will send a
check sum of all the melody data and if it's
-
valid then it allows you to play that specific
uh melody but in reality you don't need to send
-
that CRC and you can just ask to play the
melody that's I don't know why it's there
-
so once I know that I can overwrite basically
everything I want I scrolled in the in Ghidra
-
because remember since it's OTP copied to RAM all
the data that I copied is the RAM so you have both
-
the firmware and also all the buffers and pointers
that means that I just scrolled down in Ghidra
-
after the last melody structure and the exact
first value that is used lucky for me is a call
-
back function it's a pointer to a function that
is called after every received Bluetooth packet or
-
whenever I click on the button that means that I
have a way to trigger the the code execution and I
-
have a pointer to rewrite to points to exactly my
my own shell code so the strategy it's quite easy
-
you authenticate to the device using one of the
authentication bypasses I explained earlier then
-
you start to update the melody number five because
it's the furthest down in memory so you send a
-
huge NOP sled then the code and then you overwrite
this callback function and then you just send some
-
random Bluetooth packets and it will trigger your
payload every time that's quite easy to do so
-
the first payload I did is simply hello world by
reversing the firmware I also found the address of
-
the function that will send the notification so
it takes the different parameters there but you
-
can just give it a specific value then a pointer
to a buffer and then the length and it will start
-
it will send you a notification directly so now
it's time to a small demo hope it will work
-
*laughter*
just waiting for it to connect
-
of course
*laughter*
-
okay just in case let's do this
yeah don't blame me blame that device
-
*laughter*
okay so this will
-
basically wait until the connection even the demo
doesn't work that's even the backup doesn't oh no
-
it works okay really it works okay so now
it's uploading the NOP sled that's pretty
-
nice what I did is I changed a bit the
the the shell code this shell code will
-
uh complete the circle so it will dump the
firmware from the device over Bluetooth directly
-
to the user so if we wait a bit here after the
end once the NOP sled is written it will then
-
add the shell code then overwrite the function
pointer and now you have the device spitting its
-
firmware directly to the user
*applause*
-
so as a conclusions they say attackers only
need to be lucky once fortunately for me it
-
was lucky more than once to get everything
to be aligned and work perfectly that's great
-
the not so good news is that those devices
since they are using a one-time programmable
-
memory they cannot be updated that means
that you can still purchase them if you
-
want to test for yourself if you want thanks
again for to Chipolo because they sent us
-
several devices to play with that's
really nice to them and that's it
-
*applause*
-
-
so thank you very much for your talk and also
the demonstration do we have questions here so
-
I see someone lining up on the left
- yeah so I have a question you said
-
there's no way to update the firmware okay
fair but we can upload melodies right
-
- yes
- and it will be stored
-
I think with changing the battery right
- it will be stored in RAM yes
-
- yeah correct so is it possible to just insert
your own code on the melody store like we do the
-
remote code execution right and then store
our own custom code and like that's kind of
-
have our custom firmware is that possible
- that's possible the only thing is that if
-
the device reboots then the the patch will
be gone as well because it will restart then
-
reload the firmware from the OTP memory to
RAM etc so you you will have to exploit your
-
device every time it reboots
- oh okay yeah yeah and now
-
I understand okay thank you
- that was also quite helpful
-
because whenever the the the shell code
crashed and it crashed a lot at the beginning
-
every time the the the device crashes it
automatically reboots and does this small
-
oh there no melody now because it's exploited
but it does this this small melody every time
-
it reboots so I knew exactly when the the
exploit failed and I had to rewrite it etc
-
- okay thank you
- okay we also
-
have a question from the internet
- I think the question was already covered it was
-
if the melody feature is only working until the
device is rebooted so it's only stored in RAM and
-
lost after reboot
- yes
-
- okay thanks then we have a
question in the middle on the right
-
- question one question can you can you enable
JTAG or SWD debugging once you have your own
-
firmware loaded
- thank you
-
* laugher*
you yes you can basically I did
-
after I had this way of dumping every memory
region I dumped the RAM code so I looked at
-
the part of the code that is responsible
for locking or unlocking the chip and it
-
does exactly that so it's just sets a specific
bit in that specific register and you can do it
-
by using remote code execution as well yes so you
can create a shell code that will just update one
-
specific value at a specific memory location
and you have JTAG again SWD to be correct
-
- thanks
- thanks microphone 2
-
- hi thank you for this great talk and I have one
question just for the record so do you think they
-
used the same keys in every device so
- no idea
-
- they did they don't
- I have no idea
-
- did did you did you exploit more than one
- uh on this device it's the same key yes on
-
every on every device but on the other the other
models I honestly didn't have time to try them
-
already so I don't know
- all right thank you
-
- so I guess since no one is rushing to the
microphones again and we don't have any questions
-
from the internet I want to thank you again for
the wonderful talk and a warm applause please
-
- thank you
*applause*
-
thanks
*postroll music*