So, hello everybody, today I'm going to talk about something I've been hacking on for quite
some time now and it is called GALIA and it is an extendable pen testing framework mainly
in the automotive domain.
My talk is structured like this, it is divided into four parts, I will start with some metadata
about me and the project, then I will give you an overview of the status quo, I will
conclude with an outlook and I hope we have some time for a little short demo.
So that's me, on the left hand side you see my avatar and you might have spotted me on
GitHub, I'm Stefan and I'm a security researcher and I'm the maintainer of GALIA.
So what is GALIA, GALIA stems from the SACFORCAS project, it was a research project and we
received some funding.
On the YouTube link you can see a little demo we prepared last year, GALIA is implemented
in the Python programming language and we support the latest version minus one that is currently
the 3.10 release, it is free software and it is available on GitHub, it is licensed on
Apache 2 and we have two maintainers, the second maintainer hides in the audience, if
you have questions we have been around here for some time and it aims to be a modular
tool for automotive penetration tests.
So what is this, according to Wikipedia a penetration test is an authorized simulated
cyber attack on a computer system performed to evaluate the security of the system and
that basically means we connect our computer to a car or an automotive ECU and we send
some data and we keep on sending data until it breaks and hopefully it breaks and then
we try to figure out what we did in order to break it and after such tests the lab usually
looks like this.
What are the challenges to actually achieve this?
The reason why GALIA exists is that we were doing some penetration testing and we needed
a protocol stack for this and in the automotive domain there is usually the UDS protocol that
stands for unified diagnostic services and you can think of it as the HTTP of automotive
with the difference that UDS is stateful in contrast to a stateless protocol.
Of course we need post processing which means machine readable logs in order to analyze
data, everything needs to be reproducible, we solve this by a defined directory structure
for artifacts and of course the automotive guys are very, very creative in implementing
network protocols that means if you do expect an answer, the ECU doesn't answer, if you
expect no answer, the ECU does answer and that's quite a challenge and that's why we
decided to write our own protocol stack.
Since the automotive industry loves proprietary software and we do want to release the core
of GALIA, we created a plugin interface where we maintain our own proprietary plugins in
our own infrastructure which plugs nicely into the GitHub code and of course we need
the whole software stack to achieve these goals.
We did write a whole implementation of the UDS stack and the status quo is like this.
Here you plug it into the OBD port of your vehicle, OBD stands for onboard diagnosis
and several ECUs might be exposed on that port and you can use GALIA to discover this
whole tree.
For example, there might be three ECUs available and each ECU has different modes of operation.
These are called UDS sessions, GALIA can also discover these and each session might also
provide different UDS services.
What a UDS service does is up to the manufacturer of the ECU, it can be getting parameters,
it might be setting parameters, it might even be software updating, the UDS standard defines
just some basic facts what this actually is and it could be everything basically.
GALIA comes as a CLI tool and you can think of it as the end map for cars.
We provide some ready to use scanning modules, for example the discovery I already showed
and there are also modules to investigate these modules further.
We have an UDS stack including DOIP or ISOTP, these are little transport protocols beneath
UDS since UDS is on the application layer, DOIP for example is on top of TCP, ISOTP is
on top of the CAN bus and you can use all these setups.
The next one is that we are able to do some automation if you are testing some ECU on
its own, you can power cycle it during a scan, we power cycle the whole setup before
each scan and so on and of course we have machine readable logging which comes as JSON
logging and SQL logging, the SQL module is quite interesting since it can be used to
query logging information across different or multiple ECUs and for development we offer
a virtual ECU module.
The core concept of GALIA is a test run, it is basically the invocation on the command
line until it finishes and it always creates a directory structure which is always the
same in which contains some artifacts which can be used for scripting or similar and the
artifacts they always contain log files, always contains pcap files and it might contain
some something else.
The software is basically structured like this, there is a core module which can be
extended via plugins and you can build standalone modules or you can integrate into the CLI
system.
Basically, the architecture is like this, the main entry point is the scanner on top
which contains a module for optionally controlling power supplies and it contains an abstraction
module for an ECU which uses the whole UDS protocol stack and the protocol stack also
can be extended via plugins.
These plugins might look like this, this is a hello world module, basically you create
a class in Python, you need to implement the main method which could be basically anything
and then you plug it into an entry point and that's basically it.
For random facts, we use poetry for dependency management and in order to maintain a modern
Python code base async IO and async await is used everywhere, it is fully typed, it
passes mypy strict, it is extendable as mentioned via the Python entry point API and for configuring
the protocol stack, we use some URL strings which are verified by the pedantic module.
Yesterday there was a great talk about the pedantic module if you are interested in this.
So let's give some little outlook.
Of course, we need more power supplies, we need more transport modules, we need also
more scanner modules and also to we need extending the scope, we need more plugins, scanning
techniques and so on and of course more breakage and more memes and more testing.
And we need more packages, currently there is a package for the Arch Linux distribution,
we have a AUR package and it is included in the NixOS distribution in the unstable branch.
And if you are a package maintainer and if you are interested in this, just create a
package, file a ticket on Github and we would like to include this in the readme file.
I will conclude with a short demo, it can be downloaded on this link but I brought it
here and I will play it.
What we can see here is a T-Mark session with two tabs.
On the first tab, we will start a virtual ECU which is a testing device we will run
Gaelia against and on the second tab, we have the command line invocation, here we have
the configuration of the network stack, we have a transport module called TCP lines which
basically sends ASCII strings as TCP, on top of TCP, we use this for debugging and testing,
we have an Artifox where all the logging is placed and we try to discover what actual
UDS services this ECU exposes.
When you start it, it starts Dumbcap which records all the network traffic, then Gaelia
synchronizes with the ECU which means it sends a test a present packet that is something
like a ping message and when the Pong arrives, the scanner starts and it iterates over the
ECU and in this example, we have found a mode of operation, this session hex 52 and several
services are exposed in this session which can be exposed, which can be scanned further
with other scanning modules.
Now I have finished with my talk, thank you very much for your attention and if there
are any questions, I will be happy to answer them.
Yes, thank you Stefan.
So we have sometimes four questions here, yeah.
Hi, thank you for the talk.
Can you say anything about fuzzing or memory scan, what you did there?
We have some very basic fuzzer, it is included in the GitHub code, it is a PDU fuzzing,
but it just generates random data and you don't have any feedback loop for this since
this is quite complicated to implement for a car in a generic manner.
Internally we have some more sophisticated fuzzing modules but we are not allowed to
publish them because of the NDA stuff, unfortunately.
For the memory scan, there are a few services, blah, blah, blah, by memory address, we have
discovery modules for this published on GitHub, but they actually discover endpoints and that
is basically it.
So I have done a lot of testing and reverse engineering and you need a matrix of tests
of what you are testing against and the thing.
So I was just wondering for fits and giggles, is this virtual CPU sufficient to actually
plug it into the bus and actually run the car?
Because then it would be accurate enough to be able to be tested as a real world MCU.
I hope I did understand the question correctly, but our virtual ECU module offers a possibility
to clone ECUs so we can just record traffic and store this in the database and it just
answers what it has seen recently, but it does not cover any state.
The idea was that the virtual CPU is actually sufficient to replace the ECU in the car and
run, drive the car and that would give the enough accuracy of the ECU to be able to be
tested.
Maybe it's a bit too much, but that's not in the scope of Gator, I feel.
Okay, thank you, Stefan.
Thank you for listening and feel free to ask questions outside full speaker there.
Thank you.
You are welcome.