But I come back, it's CTF time and therefore I pulled out my black hoodie and we are going to take
a look at this very hard reverse engineering challenge.
You can find this over here and I highly encourage you to register yourself on this website and also
take a look at the other challenges maybe after this course, because then I have weaponized you with
all the skills and knowledge on how to solve them.
In my case, I already did this, I guess, two years ago.
And this is not a flex.
This is something you might expect from me, right?
Absolutely.
And I'm glad that I didn't disappoint you right there.
The challenge we are going to solve with the flow graph is the UPS challenge.
And this is also the challenge with the highest amount of points and the least amount of solvers.
So this is definitely the hardest challenge in this whole box right there.
But what makes this challenge that hard?
It all starts with the APK itself.
My first attempt was okay, let's try decompile this application and get the Java sources out of this.
I opened up my terminal and neither ADCs nor text to job was able to compile or DE compile those classes
or text files.
Therefore I didn't have an Java source code right there.
And this was the time where I was looking for a different day compiler than, say, IDC's index to chart.
And I found one the did within the Android Guard tool.
And finally, Andrew, God was able to compile this application and I was like, great, maybe this
is the hardest part in this challenge to decompile this application and get back those sources.
Well, I was completely wrong about this because after they compiling this application, I did end up
with a bunch of methods that weren't that many, I guess three or four, but one method was really huge.
And this method did look like this multiplied by 20 times.
So this method was full of branch instruction.
We get our input, we pass it into a function, and then we get tons of branch instruction.
And you have to think of this.
One leads to this and one leads to this, and then we've got these and then over these and this multiplied
by 20.
And finally, in between all those branch instructions, there's this one, this one single solution,
which we have to reach.
But there were some little sneaky branch instruction in there.
It's not like that.
Always the true path is the correct one.
Sometimes there were checks like, does this flag contain the following value?
For example, you pause and you were like, Oh, okay, maybe you post has to be within our input and
you follow the correct branch instruction.
But it was left on defaults, branch instruction and things like this.
I guess there were also some anti Deepak mechanism there.
If you hooked up Frieda and you tried some runtime analysis, the application behaved in a different
way.
So this one was ridiculous, hard.
And after staring at this Java source code, I was like, okay, it's not possible for me to solve this
challenge by staring at this Java source code and figure out which branch instruction leads to the final
solution.
The solution itself, by the way, was not really hard to identify because there was this really long
hash and yeah, your input gets modified during all those branch instruction.
Afterwards the input gets hashed and those two values get compare.
So where we have to go, this was pretty clear.
But how do we get there?
Absolutely not.
And therefore, I figured out okay.
For me, the only way to solve this is creating a flow graph and you will see the benefit afterwards
if you have this.
And yeah, we can then eliminate all those sneaky and wrong branch instructions and afterwards we end
up with a clean way.
This isn't that easy at that silence, because this takes time.
I guess it did take over one hour to eliminate all those wrong branch instruction, but these are the
two main keys patience and time if you reverse engineer Android applications.
Alrighty.
The last thing I want to mention is the flow graph contains only smiley instructions.
So we do not get our java source code in this flow graph.
We do get our smiley source code in there.
For me at this time this was no problem because I was pretty familiar with the smiley.
But if you want to solve this challenge afterwards, you might have to wait until we have finished the
next chapter where we learn.
SMILEY If you're not familiar with this, of course, if you already know Smiley, then feel free to
go ahead with this approach and try solving this challenge and let me know about this.
If you could solve this with the flow graph, but please don't ask for a solution.
I'm not going to provide you the solution for this.
Okay?
The last funny thing about this challenge was after I have solved this, I talked with the author about
this and the output did also mention that he did not expect that the compiler is able to decompile all
those Java sources.
But even by having this Java sources, I did not get any benefit out of this because the flow graph
itself, which was the main concept in solving this challenge for me, was written or has this instruction
in Smiley.
So even if I did decompile this application, I did not get any advantage.
So this was pretty ridiculous for me, but it's super nice to see that different compilers give different
results.
So if you struggle with the compiler, try different tooling, for example, text to try it, and now
also Android.
Maybe one of them is able to solve it, or maybe one does better than the other.
So yeah, please try different tools.
Maybe one of them is able to solve this task.
All right.
Next, we are going to have a look in this challenge.
We are going to download, install it, and then we take it apart, but only until we get to the point
where we have created this flow graph, because I do not want to spoil that any further.
Okay.
Here we are now at our Ubuntu VM.
And if you want to download this challenge then please go to this website.
This is the website of the author, and you can find those challenges over here.
By the way, the author also put in some amazing slides which you can find over here.
So definitely also have a look into this one if you are interested in a certain topic which is super
nice from the author.
Okay.
You can find the challenges here.
And then you have register on this website with an email account and then you can finally download this
APK file.
I'm not able to provide you directly this epic file because I would circumvent this whole mechanism
of the order and this is something I don't want to do.
The author did put a lot of work into those challenges, and it would be absolutely fair if we at least
leave a registration for his website over here.
All right.
Okay.
You can pause this video and register your account over there and download this you posted APK file
and then you can move on with the video where I explain on how to create all the stuff or you can just
lean back and watch me doing this.
So I'm going to close this one.
And yeah, I already download this file, it's within the downloads directory and here we have it.
I copy, paste it and we create a new directory over here and we name this you post challenge very hard.
All righty.
Let's start there compiling this Android application with our textual chart approach.
Let's see how good this goes.
No, I don't want to update right now.
Therefore, we have to unzip this to get those classes to text file.
Here we have them.
We've got to.
So I would assume our interesting source code is over here in classes two dot x and to char.
And here we have our classes to protect channel.
If you run shady, gooey.
We can see we have a code over here.
Let's figure it out.
Yes.
Texas is still not able to decompile all those methods, as we can see right here.
So this one is the Czech flag method and we can see we only got this Java bytecode over here.
So we cannot do anything with this right now.
Maybe not.
Okay, but we do not have a choice.
All right, let's try say a Dick Cheney me on those UFOs I became.
And.
Yes.
Excuse seems not to be able to decompile anything, but this is an error which is regarding to using
the wrong Java version.
So in the last video we have changed the Java version.
Let's check this real quick.
Yes.
We've got Java version eight already installed or not installed already in use.
We have to switch back to java 11 if you want to use stadia exclusive.
All right.
So sudo.
Update Alternatives.
Dash dash config java.
Yes.
And then B I select version zero to use the Java 11.
And we also have to repeat this for the Java compiler.
And also zero.
Okay.
Now it should be fine.
Yes.
Now we are back on Java version 11.
Let's try this again.
Yes.
This is the window which we should at least get.
So if you get a blank window over there, then it's regarding to an outdated Java version.
It's annoying, I know, but unfortunately we have to deal with this.
Okay.
Let's see if Taye Diggs is doing this.
So we can see also trade X is not able to decompile this code.
All right, now let's try and out.
Android guard.
Dash.
Dash, help.
And here we have this decompile android.
God.
Decompile, dash, dash.
Help.
Yes.
And here we have now the options of Android.
They compile.
We can see, for example, we can define an output directory that contains then our Java source code.
So Android is the compiling those classes, the text with the D&D compiler, which is also mentioned
here and creates those single Java class files in this output directory.
And this one we will take a look in.
Yeah.
In a few seconds because this is now the flow graph we can create with the decompile code together.
Okay.
But for now let's only try compiling this application and logout decompile and then you pause and we
have to provide an output directory.
I simply name this out because out is not available over here.
So we didn't create this directory yet.
But if we provide it as a parameter, then android is going to create it and stores all this function
and they compiled code into this.
All righty.
This might now take some time because yeah, it's a lot of stuff going on there.
And I will come back if this decomposition process has been finished.
Now the decompensation process has been finished.
Let's figure out what we've got here.
Okay.
I'm going to open this in a file browser.
Then it's easier to see.
This seems to be our main package names.
We've got android, android, x and com.
So I would assume our code is within com because this sounds like the developer path.
Movies like you pause and there we go.
We capture the fights, but we do not know how good they are right now.
We've got also this directory and here we've got some HD files.
We would take a look into this later on.
Okay.
Here we have now the electric travel file.
Let's try opening this.
I open this in the terminal over here.
Then we are in this directory and I use and she added, for example, f fc fc Java.
And here we can see this looks like yes, this is Java code.
Nice.
So Android is able to decompile this file.
We have this check flag method over here and this is all Java code right now and you can see all those
branch instruction already and the sneaky traps.
So our input might have to start with more seq or might not be do not know.
Right now you have to go down the whole rabbit hole and you can see there's a lot of stuff going on.
If we scroll through all these instructions and here we can see this one is the final hash that our
input gets hashed and compared against afterwards.
But this is not the end right here.
So I guess, yes, there's a lot of stuff underneath this.
So there are some chop instruction upwards and things like this.
You can try solving this with this Java source code, but you would go absolutely crazy.
Therefore, we are going to create a flow graph.
But first let's install and run this application and have a quick look and how this looks like.
The view itself is pretty clean and easy and yeah, but it's good to know, yeah.
What we have to deal with.
So therefore going through our hoops, we go into our apps directory UCAS challenge and we are going
to make our connection by ADB.
Alrighty then we do adb install you post at apk and we are also going to get the screen over here.
Here.
We've got this UCAS application.
I'm going to start this.
And yeah, as already mentioned, we have to provide this flag over here, and then we have to check
this flag.
Okay.
I'm going to close this one and clean this up real quick.
Okay.
Now we want to create a flow graph for this application.
So let's have a look at the official documentation of Android, because we don't know how to do this
right now.
Therefore, we go into our web browser of choice and project Decompile and we take a look at this documentation
because within the Decompile command we have seen this dash option additional right control flow graphs
for each method.
The format is in PNG, JPEG or raw, which means a dot file.
All right.
If we scroll down a little bit, we can see the examples and there we have an Android Decompile dash
all output folder.
This is absolutely familiar to us.
Then we've got this F option, which means, okay, write this control flow graph in an S&P and g file.
We have to provide our APK.
And then there's also this nice parameter which is limit.
In the last section we have seen, we've got about 25,000 methods in our APK.
And if you are now going to create a control flow graph for each method which an output as in picture,
this will take up to an hour.
Therefore, we can limit the output to just a certain class names that we do not have to decompile and
provide pictures for every method in this application right now.
And this is a regular expression over there.
So we can define the beginning of our class name.
And I'm going to show you what this looks like for our case.
So if you go into the Z2 plus challenge back again and we can also use Chidgey to open those classes
to text to Char because we do not need the method name, we just need to know the class name.
And here we can see we've got this Android package which we are not interested in.
We've got this Android X package which we are not interested in.
And then we've got this common basic you post and we only want to filter or provide those code graphs
for these functions over here.
Therefore we provide our filter for this package name.
And Tim, you have to regulate expression for this.
The first child needs to be this big L, which is D type definition in Somali.
For now, there's a class name.
In our case it's not com elite.
It's com slash more basic slash.
We can also provide you post in our case, but more basic would be enough to only decompile and provide
those controlled flow graphs for these classes in this package over there.
All right.
We can also see we have to install two additional year dependencies.
We need to have graph width and pie dot installed.
Let's do this real quick.
So we run sudo apt get inside craft with.
Yes.
And regarding to the python, we stick to our Python three version because Android needs Python three
and therefore we are also using pip three PIP three install upgrade dose packages pilot.
OC both have now been installed.
We can now create our first flow graph.
So therefore we go into EPS.
There's the UPS challenge and.
Yeah.
Hmm.
We create a new directory, I would say.
Yes, we create a new directory.
So we say and regard decompile dash, dash, head.
And now we say, Andrew.
God, Decompile.
Let's see.
Our new directory is now you post underscore c g for control graph.
Oh no, it's flow graph.
Therefore f g.
Then we provide our format which is patchy and we want to limit it to the beginning.
It's like this y of com slash more basic.
All right, this should work.
Let's see.
Give one file to decode.
That's right.
We have to provide our APK.
Of course, this should work right now.
Okay.
It's starting the compiling list.
And even for these least amount of methods, this might take a while.
So I will be back if this process has been finished.
All right.
Finally, this process that finished and this went that many methods.
Now, let's imagine if we have decompile this whole application and created a flow graph for all methods.
This will take quite a while, I guess up to an hour.
So let's see what we've got here.
I'm opening this in a file browser.
And this one over here you post underscore efg we've got now com mobi seq you pos and here we've got
now still those files.
I'm going to show you this how they look like.
Let's see.
This, for example.
So if we've only got the compiled output, like if we have done this with text dump, this is just the
output which is stored in there.
It's pretty helpful if you want to go through this.
But yeah, I guess we are not ready for this right now.
We will learn on how to do this, but yeah, not yet.
Okay, beside this, we've got now these pictures over here.
Let's figure out where's our flag check.
Okay.
At the beginning, we've got this class name and then we've got this method name.
So let's have a look back real quick.
We can also use this one which was not able to decompile it.
We should have an FC file name with a check flag method.
So it should be here.
Let's see.
Here we have two.
So if we search for check, it's easier to find.
I didn't see this one right over here.
Okay.
And now we can open this.
I recommend you opening this with --, because this file is really large.
You can see this.
This is 32 and be large, which is ridiculous for picture like this.
And yeah, the best way to open this is using -- because otherwise you might hear run into trouble.
So we open a new terminal over here and then we say -- and we use F, C and I hit the top button multiple
times and now we have to search it again.
Oh, it's at the beginning.
That's maybe the reason why I didn't see it.
Okay, now, -- is opening this file right now and we can see it's loading slowly.
Let's see what we get at output here.
We have now finally the output of this file.
And if you zoom in, you might think, Oh, this looks absolutely like a mess, all those lines over
here.
But you can also see the whole branch instruction and yeah, how ridiculous this challenge is.
So if you scroll down, well, it doesn't get even better.
And yeah, we can see this looks absolutely like a mess, but it's impressing how good you can deal
with this file.
So if we scroll down a little bit, ooh, it seems to get worse.
And there we've got a huge plop.
So let's figure out what this one is here.
These are all Java exceptions.
So if we end up here, we might be definitely wrong.
And yeah, this is a good starting point because we know if we reach to this level, if we get to one
of these, we are wrong.
Therefore, we have to.
Therefore, we can exclude all of them already.
But let's figure out where's our solution?
And already here, we found this.
So here's our solution.
We need to get to this point over here.
And this is really not that hard to find, because you have to look at the end of this file and there
are not that many blocks.
So you have to go from right to left and then you.
Yeah.
Finally retrieve this one.
It could be also this one or this one, but that's all.
It's not buried in between those over here because then you would have reached this block much earlier.
All right, nice.
So now we know where we need to go.
And yeah, this is Smiley, and we do not understand Smiley right now, but we can see we've got a green
and a red line and we've got this.
If we do not know that any set stands for not equal zero.
So we just know, okay, there's an if statement and the green one is the right path and red one is
the wrong path.
But it doesn't even matter at this point for those two, because if we reach to this point over here,
we already have our flag compared against this value.
So at this point, we know if our flag is correct or not.
Therefore we can ignore all which is underneath this and we can graphically illustrate this by creating
a new layer.
So we click new layer.
And you can see this file as absolute, enormous, big.
So you might want to increase your RAM of your virtual machine to view this.
Okay, now we've got our layer, and now we can drag our pencil into this pencil.
Sorry, I choose yellow because green, red and blue are already chosen.
Blues, by the way, a single path.
So if you have a branch with true or false, we've got green and red and blue blues, a single instruction
and single champ.
Sorry.
This way.
Okay.
So now we can tell.
Okay, this one here, we need to get over here.
You can adjust the size of the brush over there.
So let's see, we make this a little bit smaller, maybe eight.
Therefore, we can ignore this and this and we can also ignore all those Java exceptions at the bottom.
This means we have to go to this one.
So let's see where we end up here.
We've got this wrong statement.
This wrong statement leads to this one and this leads to our exceptions over here.
We can eliminate this completely.
There we've got also an exception.
And here we've also got an exception.
And then we've got a true statement over here.
And this one.
Oh, sorry.
This one we have to take care about.
Interesting.
This one over here.
Let me clean this up real quick.
Hmm.
This one?
Yeah.
And this one got a bag connection over here.
So this block has the ability to go back this way until we hit our block.
Okay.
So we might have to take care about this.
BLOCK the wrong statement.
Also.
So we have to take care about the wrong statement because the wrong statement can upend this true statement
and then we can back to can go back to this one.
All right.
So this blog is important for us and this block is also important for us.
You will have to choose, I guess, different colors for others to eliminate things and accept them.
So let's take read to eliminate them.
I guess that's a better approach.
Okay.
So now we know this one.
Let's figure out where we do get here.
So here we can get over here.
Therefore, I choose the yellow path again.
This block is important, and this block ends up here, which is this one over here.
This one is also important.
This one is not important.
No.
At the first look, this one seems not to be important, but we can mark this differently that we have
to take a closer look later on this.
And by doing this, we end up on the final solution.
And by tracing this back, this takes a while.
But here at this block, you can already see the benefit of this.
Let's see.
So we've got this one over here.
This one.
GREENE So here the true statement is important.
And this means this one can be eliminated.
This one is not relevant.
This one default statement is not relevant.
So we have to go to this one, the screen one.
Then we have to go to this block and then we have to go to this block.
So at this block, we definitely know the fourth branch is the wrong branch.
And yeah, so we can trace this back and you can see we did not make that much progress or it's okay.
I would assume there's a lot of work still we have to do, but yeah, it's possible.
Or in my case, the only solution to do it in this way.
Because if you stay at the Java source code and get all those curly brackets, it's a super mess on
how to do this.
This looks also messy, but if you try this challenge with this approach, you will be definitely able
to solve it.
All right.
That's all about the code graph.
I'm not going to spoil a further solution right now.
If you have any question about this topic, write me a message.
I'm super glad if I get feedback on this and yeah, otherwise we have a last section until we get to
this large chapter in our course, the smiley part, and afterwards.
Then we will be able to understand what's going on there, what all these instructions mean, which
is super ridiculous, nice, and gives you unlimited power in hacking android applications.
So I see you there.