Hello everyone, let's welcome our next speaker, Dimitri and Mikhail who will be talking about finding
beggars using fuzz ink, it's your turn.
Thank you so much, so good afternoon everyone, so I'm Mikhail Makozy, I'm a researcher at
University of Paris-Seclet in France, and so yeah it's my very great pleasure to be here in
Phosem to tell you about our tool, Rosa, which you can actually find on GitHub and which is about
finding bug doors with fuzz ink, so this is a joint work with Emilia, Stefano who's just there
and Dimitri, which was the main developer of Rosa, and so yeah I will actually start to talk
by giving you a general overview about what Rosa is about, and then I will leave the flow to
Dimitri, we will give you more technical details, make a demo of the tool and talk about the
performance of the tool, so let's start by actually presenting you what what we mean by bug doors
and fuzz ink, so what is a bug door when we started this work we saw that it was yeah we had
a simple definition of it, but actually as we started digging we realized that people could
mean really a lot of different things because they can be bug doors in many parts of IT systems,
so for example it can be like a server which has been weekly configured on purpose so that people
are aware of that, can use it to get access to the server, it can be like you have a machine learning
model which is used to authenticate people and some guys if poison the training data so that
they will always be authenticated and yeah it can happen, it can be also like a in cryptography,
some mathematical flows that had been planted in the algorithm itself in the mat of the algorithm
so that if you are aware of this flow you can actually decipher more or less everything that is
encrypted with this algorithm and there are other other kind of bug doors in the IT stack,
but in our work we focus on what we call code level bug doors, so the idea is that you have like
hidden access which is hard coded in the program code, so the idea is that you have to feed the
program with a given input, a secret input value that you have to know and if you give the program
this input it will give you like it will enable you to bypass the authentication mechanism of the program
or also to give you access to like underlying system resources like a shell and yeah examples
to make things a bit more clear for the first first case like let's imagine the program is
Sudu that you use to like to get a root access on your on your new machine, so the the back door
could be like a password, a key password that has been hard coded in the code of Sudu,
so that like if you run Sudu and use this password value you get root access and can run commands
as as root, for the other example the program could be like a web server and if you send an
HTTP request with a given argument value a secret value it will create a reverse shell and you
will have for example root access to the the machine where the server is deployed and probably to
the private network behind behind this machine and so like this is not just like academics like
us dreaming in their ivory tower this is a real really huge so they've been examples real
examples of such back doors injections so you guys probably have heard about the famous
XZ uh back door injections but it's just the tip of the iceberg they've been other documented cases
like back doors and PHP, the STPD, ProFTPD and also yeah like here in fuzz them we are more about
open source software but there are also a lot of back doors that have been found like in
proprietary binary firmware of devices like routers and this kind of stuff and in all
these cases you have what we call the butterfly effect of supply chain attack because yeah these that
if you plant the back door uh like uh at the right place in the supply chain that it will infect
everything above like in a router you plant it in the firmware and all the people who get this
router get the back door if you plant it like in XZ uh all the the software which reuse XZ will
get the back door actually so it's it's it's really really bad and so to solve this this problem
the technique that we we have decided to use is gray box fuzzing so basically it's kind of
brute force testing of programs but with more less randomized inputs that you send to the program
but it's a bit more clever than that because you have some kind of a feedback loop that try to
cover more and more parts of more and more branches in your in your code actually and actually
it's coupled with a simple mechanism to detect uh code failures which is just crash detection
but in this way you can still with some sanitizers for example you can detect a lot of memory
errors like buffer flows and yeah that all these kind of steps and so like it's a line of work that
is getting a lot of traction with some modern fuzzers like AFL++ which we are using in this work
it's been gotten quite popular for a few reasons uh first like they have a good track
recourse of finding CVs in many different kind of codes they are efficient for exploring different
source of program including source or binary only programs and they've mitigated what in the
community we call the magic byte problem so the idea is that if you do some kind of randomized
testing of a program maybe at some point the code you will have an if statement saying if this part
of the input is equal to this long uh stream of bytes then you can enter uh inside the if statement
and obviously if you are trying to guess the right value to enter there by randomized testing
probably it will never happen and so you want to test this brick part of the code inside the
if statement and know like modern fuzzers like AFL++ if mechanism to quickly analyze the code
and recognize such uh hard-coded magic bytes value uh so yeah that was a bit what we meant about
what back doors and fuzzings are you know let's discuss our work to try to detect back doors
with uh with fuzzings so when we started this work our uh use cases the use cases that we
had in mind were more or less like vetting people willing to vet like some third party components
like libraries or uh firmware from some routers that's yeah they wanted to include in their
infrastructures as they want to to put the library in the software or the a router model
in there in their network stack and they want to make sure that the software is free of back doors
and yeah not currently we are working on another use case which is trying to prevent the injection
of back doors like in open source project like at a CI level like having some commit vetting mechanism
that tried to detect that at some point one guy tried to inject a back door and yeah if you want to
this comes with other other challenges and if you want to know more about that just come to
my route to our talk in the CI and testing uh track where the metry will tell you more about
this line uh so yeah so that was our use case and to try to solve this use case we started to
by looking at yeah what more or less was existing and um what we found it was it was mainly like
manual code reverse engineering to try to find the back door in the code but obviously that's
really royal pain and so most of the times people don't do it and they've also been a few
tools that have been developed to do that but it's basically just trying to automate a part of the
manual engineering effort and actually these tools they are more they are actually gathering dust
so most of them are not available anymore or they are available but they are not maintained
and they don't work there was just one we could try but the results were a bit terrible
and yeah and also another problem that we noticed is that there is a limited
back door sample availability problem because the report about back doors are rare and when you get one
it's usually like about artifacts that are lost or that do not work and so this is this is painful
because if you want to create a technique to develop to detect back door at some point you want to
test it to see if it works and detect real back doors and if you don't have samples it's it can
be a bit annoying and so yeah given that there was room to do something better we decided to go
with grey box fencing because it's largely automatic so it's better than just doing some manual
steps it can explore all types of program including if you want to vet like a binary
firmware and yeah it has already been very successful to fight cv's like buffer of the
flow so why not finding back doors? Actually there is a good reason is that actually they just
can't out of the box they can find back doors because what they detect is crash they detect
if the program crashes when you test them but usually if you've done your back door well it won't
crash because otherwise people will notice it quickly so obviously it won't work to detect
back doors in that way and the big challenge in our work was to find a way to teach the
fessor to recognize that at some point during program execution a back door triggered so that was
the big the big deal of our of our work and yeah here comes here come the contributions of our work
so the idea of Rosa is to take out of the box grey box fessor called fl++ and to
couple it with a mechanism called metamorphic oracle that actually enables detecting that
the back door is triggered and yeah I will just give you the intuition and then the metry will go
into the details so the idea is that if you first for example sedu with only one password value you
should observe always the same kind of behavior like seducing the password is wrong but if
suddenly your fessor find out the the hard-coated password value suddenly you will see something
totally divergent divergent by a behavior like a new process being created and other steps
and it's from these divergence that truly is divergent and the fessor can detect the back door in
Rosa and so the other things that we have introduced is Rosa room which is a long overdue
standard has since standardized back door benchmark with 17 programs seven with authentic real
back doors from real attack that we have we we have found and then where we have asked a researcher
to inject synthetic back doors in popular open source programs so yeah now the metry the mic is
yours so that you can give the technical details all right so let's go over a real example to see
how Rosa works right so there's this belkin router model that is fairly popular and people have
figured out that it runs a bullet server so they did this by manually digging into the server
this bullet web server seems to not be maintained anymore but belkin used it at the time
by adding some stuff on top of it and people actually figured out that they've added a back door
in the server so how does Rosa detect this back door well Rosa works in two phases so there's a first
very short phase where Rosa just runs a fessor and discovers what we call the representative inputs
so those are the most common inputs to the program so you know this is an HTTP server so the
fessor generates HTTP requests let's say it first starts with a get request at the root of the server
that yields some control flow graph edges in the server program and also amid some system
goals and that is saved in a database and the fessor goes on maybe you know it manages to
modify the string a little bit and generate a post request that yields slightly different edges so that's
a different input so that gets saved so one and so forth and then very quickly after about a minute
we switch to phase two where the fessor now intensively explores the program and every new behavior
is vetted individually so let's say the fessor again mutates the input a little bit and hits this
other endpoint and that produces some system calls so what we do is we first choose the most similar
representative input from the first phase so let's say that it's b in this case and we compare the
system call vectors and if they're the same then the behaviors are equivalent and since they're
representative inputs are considered to be the nine then we can assume that input c is also safe so that's
but at some point due to what Mikael said due to the guiding the fessor will end up hitting
some hard-coded endpoint that is special in the server and that will produce some different
system calls right so again we'll do the same thing which is the most similar input let's say it's a
from the first phase and the behavior is no longer equivalent so this is suspicious this might be a
background but this alone does not prove that there's indeed a background so a human expert has to
vet these findings and there's a semi-automatic method that allows us to do this fast so what you do
is basically you take the divergent system calls that Rosa gives you in this case you know there's
50 states and 59 if you know your system call numbers you know what those are and you run that through
esterase and then you look at the actual log that esterase gives you and you can basically immediately
see that there's a fork and exec of bin esth so reverse shell on the server without authentication
so obviously this is not right so let's actually do this in practice so huge disclaimer we've
biased the fessor a lot here for the purposes of the demo to go faster so this usually takes
about four hours but most of the overhead is about emulation we can talk about it later if you want
so let's do it so I have here a part of the actually b server that we've decompiled and if we open
it up so this is decompiled code right so it's going to look ugly but basically they've added this
bizarre function on top of the server and if we scroll down a little bit at some point there's a
system call that seems to arbitrarily execute some command right so but we don't know that yet we don't
want to have to reverse engineer the server so how could we find that with rosin well rosin only
really needs a simple configuration file to work fessing is pretty easy if you've done it before
and so there's a wizard basically to generate that config file it's just a simple tomofile
that mostly describes what settings to use in the fessor but that is automatically generated and
if I run it we can see rosin action so it will spin up the fessor in the background and it will
start trying to find the back door in the actual program so the interface looks like a fessor so
we built this with retitude if you're familiar it was really easy to build and the goal here is again
to collect some representative inputs first which it's already done and now we're trying to see if
there's any suspicious behaviors in the program and it should find a back door from roll
if not I'll re-run it but so yeah fessing is not easy to course but yeah basically you have a bunch
of stats and what interests you most is the top right quarter and there we go back or fun so
so I'll stop it here all right so all of that data of course is persisted to disk so we can
look at it at our leisure and so there's this output directory and if I look into it there's a bunch
of stats again if you've used the fessor this should look familiar so what I'm interested in is
the back door sub directory which stores inputs that lead to suspicious behavior so let's look at
what's in there so there's one input that was saved it saved in kind of a weird way because we
did duplicate findings as much as possible so you don't have to look through a ton of them
and how do I know why this is suspicious well there's an if you're a little tool called
Rosa explain where if I give it the name of the input it will explain why this is a back door so
basically it says that it's a back door because it found these system calls with this input but not
with the closest representative one so again I will do what I explained before I will run this through
esterase and I will only feed it I will tell it to only filter these inputs and to use the
back door input that I found before this will run it through esterase and now I can look at the
log and you know the log starts with the QMU fork that AFL uses to run the fessor and if I scroll
down at some point what do you know there's an exact V of SH something something pipes into something
that looks very fishy to me so I'm going to keep looking so actually next thing that I'm
going to do is I'm going to look at the input itself just to get an idea of like what is the input
look like so the input looks like this and again like that's very specific you know I'm hitting
a very specific endpoint and I'm passing a very specific parameter to it so let's slide for real
on the actual server so let's start the server so this is as if we're running on the actual
router I'm going to hit the endpoint right so I'm just going to hit dev oops I'm going to do curl
dev.cgi and then I'm going to hit it with ID whoops I'm roots on the server so I can run
every kind of commands is root on the server and there you go that's how you find the background
all right to wrap up so we went through this effort to build this back door evaluation benchmark
so we can actually see how Rosa phares in a variety of scenarios and we used standard
of fuzzing evaluation practices to do it the questions are can we detect all of these back
doors in different scenarios with enough automation robustness and so on and also how do we
compare to existing tools so as Macau said only one tool is surviving sadly and that tool is
a reverse engineering aid tool basically so we compared with that one so first of all fuzzing is
non-deterministic so you have to run it many times to see if you actually can detect things
reliably and we detect all back doors in the benchmark with an 87% success rate so this is in line
with most fuzzing approaches actually pretty good rate then in terms of time it takes Rosa
an hour and a half on average to detect a back door this is largely due to the emulation overhead
and as you can see the state of the art tool is much much faster because it kind of does
a glorified gripping of strings basically in the binary that allows it to go much faster
but it also cannot detect the vast majority of the back doors because not all backers are built
like that and where Rosa really shines is the automation part where it only reports seven inputs
to vet like I showed you semi-automatically whereas with the state of the art program you have to
look through over 300 strings and what I mean by that is you have to actually reverse the binary
and look through it so yeah in conclusion this is the first generic fuzzer-based back door detector
and also the first back door detection benchmark we detect all back doors in it in an hour
30 minutes on average with seven inputs to vet on average which is 44 times less positives without
reverse engineering without the source code thank you
well you got plenty of time for questions so I see some yeah I have a question about
is that yeah what one kind of techniques do you use to force the code to run through these
pause in general it's not computable probably you kind of even if you have the source code there's
no way to do it in in full generality so what kind of techniques are you using there to force Rosa
to find these you know the right state to enter these these back doors these potential back doors
right so the guidance is fully on the fuzzer side right so we don't actually
change how a fuzzer class in this case goes through the code a fuzzer has like a decades worth
of good heuristics to go through most of the code it possible all of the code so that alone seems to
be reliable enough to trigger all different behaviors have a very basic question you showed the
back in route as an example how did you get the back in route a software web server to run on
another system so that's thanks to you and you right so since we're in a binary only setting
a fuzzer like a couple of plus needs some feedback from the target obviously if you have a
binary you can't get that so you either rewrite it basically or you run it through an emulator
and that's what we use here so the advantage is that you get any piece of information you want
the disadvantage is that it's slow that's why it took four hours for for Belkin
I have two questions the first one is you mentioned it's very well detects like hard-coded credentials
what about like if like it's a little bit smarter like if the input is like an algorithm like a key
generator you know like if the input checks on to a specific thing or this is the first question
and the second one you your example shows a trace and like I assume like Rosa also uses a
trace or somehow to collect the system calls and it's quite common for like hidden back doors to detect
that the program is under a trace and to not reveal behavior so how is that addressed or that
so for the first question so the so we don't only design hardware the factor so and in fact
we have multiple factors in the benchmark that are done on purpose without using hard-coded
credentials the magic there is basically from the fuzzer right so the fuzzer has you risks
to help it solve this magic by problem where yeah you can depend on some lightweight
off-estation let's say something like that if you go much further than that there's actually
like fuzzer blocking techniques for example you can hide something behind a cryptographic check
there's no way for a fuzzer to go through that obviously but that is generally something that's
hard to detect with dynamic analysis and often times it might be also hard to detect by static
analysis for different reasons so that's kind of a general blocking point um for the second question
about estates so Rosa does not actually use estates Rosa relies on to a new and we just literally
like save the register value right when when it's this goes um and yeah sure you have programs that
use estates I mean that's another limitation let's say for the tool you can't maybe you can't
detect those but further ones that don't which honestly all of the real ones that we just said don't
you can do so yeah that's another idea yeah well I was working on a prototype actually with that
but then you're limited to specific systems so you have a trade-off
fuzzer for the presentation are really interesting approach really like it I've got one question
which is why the two repository are archived so um it's because the reason why we couldn't compare
to the state of the art is that none of them were archived so in my opinion if you want to do
signs and do a well you have to archive everything you have to make it available
style archive don't archive and make it out of sense right there are archived and the
proper sense so there are archived for forever there are kids for people to be able to use
far in the future so that you can replicate with the exact commitment hash that I used and so on
so that's the the point behind archiving okay thank you we are out of the time thank you for
the presentation thank you