Hello, everyone, welcome to our new video of our binary exploitation series today.
Let's talk about buffer overflow.
From its name, buffer, overflow is when we have a certain size of a variable replacement in memory
and we overflow that space.
So, for instance, if I have a C program that asks for name, this name will be stored on the stack.
But at the strength size is more than the size that we allocated for it on the stack, of course we
have, and it's the program itself that then it will overflow and overwrite, uh, other addresses like
the return address.
Right.
If you look at here.
This bunch of values that we put on the variable.
Is more than this tag can hold for the size that we allocated for it, then it will come here and it
will overwrite the return address at the function needs to return back to when it's done executing its
code.
If we can control the return address, that means we control the VIP register, which points to the
next instruction, let's take a look at the source code of a network program that we that only does
one thing.
It echoes back everything we send to it.
Let's make sure it's not running first.
Actually, it is.
OK, I'm going to kill it and then we run it.
Now I'm going to use Netcare to connect to the server.
It's a UDP socket, so that's fine.
So it echoes back everything we said, right?
Very simple.
OK, now let's take a look at the source code.
Let's go to the main function.
He starts from here.
This bank function, it will check for ports, but we don't need to know that from now.
Basically, it will open a socket.
Let's go all the way down here.
It will bind on a port.
It's kind of similar to what we did in Python before.
And then it will use a function which is receive from similar to our UDP socket from Python, remember?
And then after that, it will call the good time function and it will pass an argument, which is the
message.
But the message above is what we receive from the client.
So when we said hello or how are you?
Everything is actually stored in the message of a variable.
And then we'll pass.
It will be passed the good time function along with other two arguments, return string and receipt.
Then you go all the way up.
Check the good time function here.
This one here we receive our message both right.
And then we come here.
We have another variable time above current time.
We don't need to know that for now.
But if you look here, there's a if statement to check the site.
If the string length of the Fermat, which is the message buffer, this one, if it's larger than time,
both sides, which is only one twenty eight.
So it checks if we're only sending one three, eight or less bytes, then if it's greater than that
it will give us an error process error.
But if it's not, if it's less then you will use the mem copy function and then it will copy the format
to the memory.
And that's what we need.
Right.
We need to go to the memory.
We need to be able to be copied to the memory so we can manipulate the memory and overwrite it.
But how do we pass this one?
Because every time we we send something larger than type of size, it will come here and will send us
processor.
And we try that.
Let's try.
So, for instance, if I connect again and send a lot of characters, what will happen with it echoed
back to me.
I did that.
I think that's enough.
See, I got process error, that means I was able to get to this line where it checks for the size.
Right.
But how do I, you know, like pass or write this one?
They go back all the way to the bottom here.
There is a vulnerability in, um, in the received from.
So if we send a our strength from before and put a node by it, I know by dysfunctional will keep receding
until a node by its received or until it reads a node by.
But what if we put the node by it in the very beginning of our strength?
Can we do that?
Let's try again this just copyable this.
Well, it gives us the same thing, but really what happens in the memory is completely different.
Let's examine that.
First, let's kill our currently running program.
It's opening in GDP now.
Now we need to set our disassembling flavor, the syntax to be gentle,
and we need to follow each fork to the to the child
and also we need to turn off the attachment for.
OK.
So let's break on Main and then we need to run our program.
We use the run or are and then our arguments, one, two, three, four, which is our report.
OK, now we've got our hit our breakpoint.
So first, let's take a look at the main program, main function.
This symbol, main and in main.
What we need to take a look at is when we call our the good time function right here.
So we need also to take a look at the good time function.
So the good time function after it receives our strength, our buffer, it will come here to this line
is my address and then we'll call them and copy.
And once when he calls and copy, you will copy all our strength into the memory.
Right.
So we need to see a break after it copies everything
and then we need to do continue.
Now it's waiting us to send something.
But said the same thing again.
OK.
Um, nothing happened.
I think our buffer was truncated, um, because of the kept it didn't send the Xs or zero the nobut
so I'm going to fix this and I'll be right back.
All right.
I'm back.
So the only thing I did hear is just echo.
I use echo and then dash in and uh backslash x zero zero four, no bite and then a bunch of BS.
And the last of them is for B, B, B, B, B, and then pipe all of that to Ngarkat and send it to
the server.
Let's do that.
OK, now we hit our break point after the copy, that means it should be copied to the memory, right?
Let's examine the.
Let's look at the U.S. Oh, well, nice, so this stack pointer points here and our goal, our buffer
was copied.
If you see here, this is the very beginning of our buffer X zero zero.
It was copied here, zero zero and then forty one in Texas is eight.
So zero zero and in a and then all these days here and then the last four B's.
Right.
Let's see what happens if we continue.
Keep in mind that the return address of our main function, if we do, if we disassemble our main when
we called our good time here, we called it this line.
So when we return, we need to return to our next instruction, remember?
So this is our next sort of instruction.
If we take a look at the stack again, this is the memory address of the next instruction after the
good time, which is just one zero zero four three fifteen seven two one zero zero four three fifteen
seventy one.
It was pushed on the stack when we called good time function.
And then we have one address to three hour arguments, remember?
OK, now we need to be able to override this return address, right.
First, let's continue and see what happens if we just passed a string for function.
Let's take a look at the good time again.
Function at.
This function is very long, so we need to pass this one and break here.
Continue.
All right, so we started construction.
Well, the problem is we got segmentation fault sig here stopped why we were actually still inside our
strength for math function.
For some reason, it it was able to read our 40 to 40 to 40 to which over the last four BS as invalid
address for for some reason.
Right.
So let's see, what was this address before we overwrite it going to start again.
So here on the right side, I'm not going to overwrite this address.
I'm just going to remove the last four BS.
And then there's a simple good time again, and I'm going to stop this time here.
I'm going to break and then continue.
Send our puffer now, looks like we're good.
Let's check our STAC.
OK, so this is the address that we over we were we were able to overwrite last time when we got a segmentation
fault.
So let's check this address, see with what's this address it's mad about?
Actually, it's the time, both variables, so for some reason when we call this format in our program,
it needs this address to be a valid address.
And if it's not valid, they will crash.
So that's that's fine, right?
We can give it a valid address, but we will do that next time.
So far, we were able to crash our program and get segmentation fault, but we need to know how to bypass
the six-fold we just got from the string format function and overwrite the return address of the main
function.
Because even if we override the return address of the main function now, it still won't read it because
it will crash before it gets to the two that address.
Thank you for watching and see you in the next one.