Encryption for Dashcams

Encryption for Dashcams
Research Seminar in Cryptography
Karl Tarbe
May 29, 2015
1
Introduction
Increasing number of drivers use dashcams to record their everyday driving, just
to have extra evidence when a traffic accident happens. Common dashcams just
record video / audio and some even have built-in GPS to also store location.
However all of that information is stored unencrypted, which means that a car
thief can learn a lot about the owners daily routine by just looking at recordings
stored in the dashcam.
The goal of this project was to add encryption to Prestigio RoadRunner 530.
1.1
Contributions
The author of this report contributed by analysing the existing information and
wrote a tool to generate ROM image from a directory. Arbitrary code execution
was achieved, but actual encryption was not.
2
Monopol
Many consumer cameras available in the market actually use system on a chip
(SoC) produced by the same company called Ambarella[2]. The firmware is also
quite similar because Ambarella has a software development kit, which helps
camera developers to work with Ambarella’s SoCs. Ambarella’s main focus
seems to be on designing chips that do video compression.
The camera used for testing was Prestigio RoadRunner 530[1]. The camera
is based on Amabrella A5S30 SoC. See Figure 1 for a block diagram of the A5S
SoC.
3
State of Ambarella firmware hacking
It turns out that different people have messed around with Ambarella firmwares
for quite some time now. Firmware on the devices can be updated by writing a
firmware file to the SD memory card and the system will update it’s firmware itself. There have been people who have managed to change parts of the firmware
image. One such project can be found in [3]. Another one is called the Ambarella Firmware Toolbox (AFT) and it even has a graphical user interface [4].
The author of AFT had access to some version of Ambarella SDK. AFT also
1
Figure 1: Block diagram of A5S SoC.
has an editor for the bitrate table, and it has been used to improve the video
quality. However AFT is distributed as an obfuscated Java archive, so it does
not offer much help. However on [3], the sources are available, and there is a
reference to [8], which from the code structure seems to be written by a more
experienced coder, and therefore seems to be the most trustworthy piece of
information about firmware file format.
Some devices also have a UART serial interface. This can be accessed by
soldering wires to the circuit board. However on the Prestigio RoadRunner 530
no UART signal was found on the circuit board. On the UART interface is a
shell for the bootloader[10]. After the bootloader another shell is present, it is
called ambsh and it is a unix like shell[9]. One of the most important programs
runnable from ambsh is t, because it can be used to control the behaviour of the
camera. The shell also has facilities for firmware updating, memory dumping
and raw memory access.
On some devices the firmware automatically executes the commands from
a script called autoexec.ash, when it is placed on the SD memory card. One
collector of such scripts is Konrad Iturbe [5]. The script is a easy way to alter
the behaviour of the camera without bricking it, because you can make the
changes non-persistent.
The most impressive work so far is a tetris game on a camera[6]. The author
of this hack manually searched for common functions inside the firmware image.
He wrote his code in C, but a used a custom linker script to place his code on
a specific memory address, that was free. The linker script was also responsible
for storing the addresses of the common functions that were used from the main
firmware.
4
Firmware
According to various sources the firmware consists of multiple parts. The most
readable description can be found on [4]. In detail, the firmware sections for
Prestigio RoadRunner 530 are
1. First stage bootloader.
2
2. Second stage bootloader - this even has a shell on the UART interface.
3. Hardware Abstraction Layer - device specific code.
4. Primary firmware - RTOS with all things included.
5. Read Only file system - some static files as sounds and logos.
6. Microcode for Digital Signal Processor.
Primary firmware consist of real time operating system called PrKERNELv4. File format of firmware is best described in [7].
4.1
Read only file system (ROM)
This is a very simple file system. Basically after header it just contains the files
padded with 0xff bytes to align each file to the start of a 2048 byte block.
All the words in the file are 4 bytes wide and stored in little-endian. The
first word of the file contains the number of files stored. The next word is a
magic word, which contains the value: 0x66fc328a. Magic in here means a file
signature to identify the file type. After that follows padding (0xff) to offset
0x800. On that offset is the list of file descriptions. All file descriptions are just
concatenated together.
A file description starts with 116 bytes, which are allocated for storing the
file name as a zero terminated C-string. Next there is one word to mark the
offset of the file, one word for the length of file and an another magic word,
which in this case is 0x2387ab76.
After the list of file descriptions is once again padding of 0xff till the start
of next 2048 byte block. Then comes the contents of the first file. Every file is
padded to the start of a 0x800 byte block. Even the last file is padded so that
the overall ROM file size is a multiple of 0x800.
For simple overview see Figure 2. For an concrete example see Table 1.
RFS
uint32 t number of files;
uint32 t magic;
header
file 1
file 2
..
.
char name[0x73];
uint32 t offset;
uint32 t file size;
uint32 t magic;
file n
Figure 2: Rough overview of the ROM file format.
3
Offset
0x000000
.
.
.
0x000800
.
.
.
0x000870
0x000880
.
.
.
0x0008f0
.
.
.
0x001000
.
.
.
0x001800
.
.
.
0x001ff0
Data
0200 0000 8a32 fc66 ffff ffff ffff ffff
Padding (ff)
6279 652e 7478 7400 0000 0000 0000 0000
Unused space for file name (00)
0000 0000 0010 0000 0400 0000 76ab 8723
6865 6c6c 6f2e 7478 7400 0000 0000 0000
Unused space for file name (00)
0000 0000 0018 0000 0600 0000 76ab 8723
Padding (ff)
6279 65ff ffff ffff ffff ffff ffff ffff
Padding (ff)
6865 6c6c 6fff ffff ffff ffff ffff ffff
Padding (ff)
ffff ffff ffff ffff ffff ffff ffff ffff
Table 1: Example of a Read only file system containing two simple text files:
bye.txt with contents ‘bye‘ and hello.txt with contents ‘hello‘.
4.2
Format of the firmware file
The firmware file starts with a header which describes the sections in it. The
first 128 bytes are used for an array of 4 byte words, which describe the start
offset of a section. At offset 0x80, there is an array of words, which describe
the end offset of the sections. From the size it appears that there might be a
total of 32 sections in the firmware file. However on Prestigio RoadRunner 530
there are only six sections and for the unused sections the start offset and the
end offset fields are set to zero.
At offset 0x100 until 0x210 are some data, which is currently unknown to
the author. The header is padded with zeros until the offset 0x800, which is the
start address of the first section.
Every section begins with a section header. Section header consists of several
words.
• CRC32 checksum of the section contents.
• Section version.
• Build date. The first byte is the build day, the next byte is the build
month and the last two bytes (little-endian) are the build year.
• Actual length of the section contents.
• Location in memory, where the section should be loaded to.
• Some flags, usually zero.
• Magic word, which is 0xa324eb90.
• And the next word seems to be the same as the flags word.
4
The rest of the header is padded with zeros. The actual section contents
begins at section start offset + 0x100. The sections are aligned at 0x800 byte
block boundaries, and zeros are used for padding. For an overview see Figure 3.
firmware.bin
header
uint32 t section start[32];
uint32 t section end[32];
section header 1
section contents 1
..
.
section header n
section contents n
uint32 t crc32;
uint32 t version;
uint8 t build day;
uint8 t build month;
uint16 t build year;
uint32 t length;
uint32 t load address;
uint32 t flags;
uint32 t magic;
uint32 t flags2;
Figure 3: Overview of the firmware file format.
5
Contents of the ROM
Inside the ROM there are many files. One of these is a file called strings.bin.
It contains the strings used in the camera user interface. There are many languages, because the user interface supports many languages. More info about
it is available on [4].
There are also a lot of .jpg files, and sounds. Some Windows executables
are also stored in ROM, the camera copies these files to the SD memory card so
that the user can view recordings on a Windows OS. There are also some other
binary files, the purpose of which remains a mystery.
It turns out that the logos displayed when powering on the device and powering it off, are also stored in the ROM. So to change them, you need to generate
a new ROM, which contains the JPG images you like, with the same names.
The names used are pre on h.jpg and pre off.jpg.
6
Code execution
The primary firmware image is just a huge binary blob. Disassembling showed
that code and data is mixed. However some things are identifiable. For an
example at the very start of the primary firmware image is the interrupt vector
table, which contains references to the interrupt handling functions.
The most common way of analysing a binary is by searching for strings.
And there are 22160 static strings inside the firmware. Some of these are error
messages, which give a hint at what function failed, or at which subprocess
they are from. However when you know the location of a string, finding the
5
code, which uses it, is not trivial. In the firmware it is common, that a string
address is loaded into a register by a instruction like “add r0, pc, 0x44;”. This
is translated as: take the program counter(pc), add 0x44 to that, and store it in
register 0 (r0). Now r0 contains the address of the string. However addressing
like that means, that just searching for the absolute address of the string in
question, will not give you results. However disassemblers usually can find some
of those references.
The easiest function to discover by strings is the printf function, because of
the specific format strings, which go hand in hand with printf. In the Prestigio
RoadRunner 530 firmware version PE3K7HGC.130523, the printf function
is located at address 0xc714. Looking at format strings, function arguments
and error messages, a few common function can be identified. Note that to
determine function arguments from assembly code, one needs to know the calling
convention used on ARM.
Function name
printf
sprintf
fopen
fwrite
address
0xc714
0xe9104
0x36b68
0x36eac
At the end of the firmware file there were some zeros, which seem to be
unused. That area can be used to write your own assembly without overwriting
anything else. However something needs to be changed to make sure that code
is executed. A printf call inside a function responsible for opening the GPS
data file was changed to a call to inserted assembly. Having the call in there
meant that the firmware functions normally until recording is started. This
avoids bricking the device. For payload, a simple function was made. The goal
of this function was to create a new file on the SD memory card and then write
“tere” to it.
The code was definitely executed, because when the code contained a bug,
the UI thread/process on the camera crashed. When the bug was fixed, the
process worked like nothing had happened. However no file was created on the
memory card. There could be several reasons why it did not work. It might be
that the systems only supports a handful of open file descriptors. Or it could
be that for the actual writing to take place one needs to call fflush and fclose
on the file stream.
7
Future work
More time needs to be spent on disassembling the firmware to find the actual data path for the video data. Maybe it goes through the ARM CPU, and
encryption can be implemented. The SoC even has some hardware crypto primitives. However it might be the case that, data is written to the SD memory
card directly by the DSP used for video encoding. If this is the case, there still
might be ways to encrypt the video on the CPU.
6
8
Conclusion
Device manufactures have not included encryption to their cameras. However
need for privacy is increasing in the age of information society. Fortunately the
community is working on taking matters to their own hands. Thanks to reverse
engineering, community has created firmwares that improve the cameras. When
there is greater demand for privacy the device manufactures or the community
will add encryption.
9
Acknowledgements
The author would like to thank Lauri Mihkels, for his help in trying to find
UART signal on the circuit board.
While writing this report, the author received scholarship from IT Academy.
References
[1] Prestigio RoadRunner 530
http://www.prestigio.com/catalogue/DVRs/Roadrunner_530GPS#
/product-specs?article=PCDVRR530A5GPS
[2] Ambarella fact sheet
http://www.ambarella.com/uploads/docs/company-fact-sheet.pdf
[3] Evilwombat’s github repository
https://github.com/evilwombat/gopro-fw-tools/
[4] Dashcam Hacking
http://dc.p-mc.eu/
[5] Konrad’s github repository
https://github.com/konradit/autoexechack
[6] Hacking the Kodak Zx3
http://spritesmods.com/?art=zx3hack
[7] DashCamTalk forum post
https://forum.dashcamtalk.com/threads/r-d-a7-r-d-thread.5119/
[8] Extractor for GoPro camera firmware
https://gist.github.com/nezza/2394361
[9] CHDK forum thread about GoPro HD HERO firmware
http://chdk.setepontos.com/index.php?topic=5890.0
[10] Forum post about the discovery of amboot
http://goprouser.freeforums.org/stickie-hero2-firmware-studies-t4961-30.
html
7