Hello and welcome back.
Our next project is "Funny Gopher's Stupid CrackMe"
So download this from the resource section and then unzip it.
The unzip password is crackinglessons.com.
Inside it, you will find two files.
One is the credits and the crackme.
This crackme you need to scan with DIE to find out whether it's 32-bit or 64-bit.
I've already scanned it. It is 32-bit, so let's just run it first and see what it does.
It asks you to find the password, so we don't know the password.
We assume it's this.
You hit enter and it says, "Uh oh, man.
Very bad.
Password not found."
So now we are going to use the string search method.
Look for the string phrase "the password."
So we open up our x32dbg.
I've already done this,
so I just refresh and we are going to scan for this word "password" here.
So let's go right-click on anywhere here.
Search for current module string references.
And then here you can see
the string that we are looking for.
So double-click to go there.
And that is your string.
So I've already put several breakpoints in. I've done this before, so I just disable all of them for
now.
I'll just remove everything,
start from fresh.
Okay, so now the string is found here. I'm going to close this one.
And the program is now running in the background.
This program—and I put a comment here to remind myself that this is the start of the function that
contains the bad string.
And then I can put a breakpoint here.
Now I will run until I hit this breakpoint.
So it has hit the breakpoint.
And then, if I wanted to, I could graph this.
And you can see here is a very simple crackme.
It goes straight down,
and then here it goes to the left or to the right.
On the left is the bad message.
On the right is the good message.
So now we are going to trace this and see what happens.
So let's step over and see the output here.
After this call,
it prints this message.
After this call,
it prints this message,
"Password."
But it is not waiting for input yet because the state is paused.
We need to go and step over until it becomes running.
So let's see.
After this call, it changes to the running state and that means it is waiting for our input.
So I have put a comment there: "read password."
So the input—we assume—is going to be a password or 123456789.
Just hit enter and now it's paused,
and we can continue debugging by stepping over.
And now before this call, we have this register value in -.
After this call, - becomes one.
And then I put a comment here.
And then sometimes it's negative one,
sometimes it's one.
I've done this before,
but for now it's one.
So let's step over and see what happens.
Now it's going to test it.
That means it is expecting - to be zero,
and again I put a comment here.
So let's step over.
I forgot to turn on the trace coverage.
Let's do that now.
So now click on this and you find that jump is taken.
That means it's going to go to the left
and print the message.
That means it is expecting - to be zero.
So since - is not zero, therefore it's going to go to the left.
That means this function is important.
This function sets the value of -.
We want to know why - is not zero.
So next iteration, we are going to put a breakpoint here.
Now I put a breakpoint and we are going to step into this.
For now,
just step over this and see the bad message printed on the screen.
Okay,
so now we know that this is the important function that we need to step into.
So now we restart and we run to our main function.
And then we will run to this part, right?
So we just step over.
Step over this, and now it's waiting for our input.
So again, we just put 123456789, hit enter.
Now it's back.
We're going to step over.
And now we are going to step into this call to see why - is not zero.
We need to find out which function—which instruction—sets - to become other than zero.
So we write—
so we now can step into this. Step into it.
Click again.
So now we are inside and we can graph it.
Like this.
So now we continue to step over.
So here it is just testing -, three.
Just ignore it,
continue.
And then over here, it is going to move this to -,
and then it's going to compare - with the first byte of -.
- has got our input—our password.
So the first byte is the character "one."
And then -, what is in -?
You can click on this line.
You can see - is the character "L."
That means the first character of the password is capital L.
So it is comparing capital L with our input "one."
That means we can now fish out
the first character of the password is capital L, right?
So this is our assumed password, which is the wrong password,
and now we fish out the first character.
So now let's see, because the first character is not L, therefore JNE will be jumping.
Click on this.
You will see jump is taken, so it's not going to go straight.
It's going to jump all the way down here.
And now let's see what happens to - when we come to the return.
Okay, so by the time we come to return, - is set to one.
So this is where - is set to one.
We expect the - to be zero.
Zero means good,
but because it is a wrong password,
so - is not zero, it's one.
So now we step over this and we right-click and set the IP.
We come back to the main function.
So now we can see it is going to test the -.
And because - is not zero, it's going to go to the left again and print the bad message.
See that bad message?
Okay,
so now we know the first character of the password is capital L.
We are going to restart this and run and step over this call.
So step over.
It's time for the call.
So now it's waiting for input.
So we managed to fish out the first character, capital L, so we know the first character of the password
is capital L, but the second character onwards we don't know.
So we just put 23456789, hit enter.
So now it's come here.
Let's step over, step over.
Continue to step over until it comes to this call and step into this.
And then step into it again, and then right-click and graph.
Now we're going to use tracing.
Okay, now it's testing the first character of the password, capital L, and our input is also capital
L for the first character.
Now notice here it's pointer byte,
pointer byte means you are reading one character, which is one character of the string.
So let's continue.
Step over. Because the password we entered for the first character is correct,
so it's not going to jump.
Let's see.
Click on this.
Jump is not taken.
Instead, you go straight.
Now this line here is also testing whether - is zero.
Now - zero,
in programming, means that null terminator. Every string ends with a null terminator,
and in the programming, null terminator is denoted by the hex value zero.
So in this case,
null terminator means the end of the string.
It is checking whether you have reached the end of the string.
So in this case, step over, because we haven't reached the end of the string,
it will go straight.
If you have reached the end of the string, it will come out and jump to this address, which is down
here,
down here.
So because it's not the end of the string,
it is going to go straight.
Now it's going to compare. Click on this.
You can see it's comparing - with "two."
"Two" is our second character,
and then it's comparing - with that.
That means the second character of the real password is "i."
So we can put "i" here.
We fished out the second character.
So now we continue.
And because we did not enter the correct character, it's going to jump to this part here,
and then it's going to set the value to one again.
So again, we have failed.
We have fished out the second character now.
So now we can restart and run to our main and step until we reach this call.
Step over and enter the first two characters which we have fished out, which is "Li."
So we type L, i, and then the third character onwards
we don't know,
so we type three, 456789, hit enter, and step over.
Come to this line,
step into it again.
Step into it again,
graph it, and trace it.
So continue to step over and trace. Again,
this part is checking for the first character, which is L.
Which we entered correctly, so it will go straight.
It will check whether we have come to the end of the string.
In this case, no,
so it will go straight.
Now it's checking for the second character, which is "i."
In this case, we entered "i" correctly,
so it will go straight.
And now it's checking whether we've come to the end of the string.
No,
so it goes straight.
And now step over.
And now it's checking for the third character.
The character is again L, but we entered 3—see 3?
We entered three instead of L, so this suggests that the third character of the password is capital
L.
So we fished out the third character of the password like that.
Okay, so at this point in time, you can see where we are going with this.
We are going to loop through over and over and over until we fish out the entire password.
So let's continue.
So now we fished out the first three characters,
and then let's continue with this.
So we continue to step over,
and because our third character is wrong,
so it's going to come to here and give the bad value, which is one.
So we restart now and run to our main, step until we come to this call, and step over it.
And now we enter the first three characters which we have fished out, which is L, i, L—L, i, L.
And the fourth one we don't know,
so we type four, five, six, seven, eight, nine, hit enter, and then continue to step over.
Step into this call.
Step into it again, right-click and graph.
And now we trace it.
Okay,
over here is capital L, which we got right.
Over here is lowercase i, which we also got right.
Over here again is capital L, which we got right.
L, i, L.
It's checking—is it the end of the string?
No, it's not the end of the string.
End of the string means when you press the enter key.
When you press the enter key after the input, that inserts a null terminator at the end. A null terminator
is simply the hex value zero.
So because it is not null terminator, therefore it's going to go straight.
Now it's going to check for the next character, which is the character "2,"
but we entered "4," so it's wrong.
So this suggests that the fourth character is "2."
So we put down here "2."
And then now, if we continue, because it is not "2," it is going to go to this part and give the bad
return value, which is this time negative one.
All right,
so this is how I know that the bad value is either 1 or -1.
The right value would be zero,
but in this case we are getting negative one.
So when it comes back, if you step over this and right-click "Set IP," go back to the main function.
As we come here, it is expecting zero, remember,
but because we are negative one, it is not zero,
so it's going to go to the left and show the bad message, as you can see.
All right,
so now let's restart again and I will continue this in the next lesson.
See you then.