This time we will start from some sample/vulnerable code I found online. I changed it a little bit ;) So now we should be somewhere here:
This example is pretty obvious.
Let's compile it*:
*(I hope you're familiar with gdb-peda because we will use it below ;))
As you can see I disabled NX-bit (also feel free to disable ASLR using:
# echo 0 > /proc/sys/kernel/randomize_va_space
# cat /proc/sys/kernel/randomize_va_space
0
) Now, let's prepare a pattern to use it as an input:
As you can see (in my case) RSP points to 0x7fffffffe4a8. Let's get an offset:
So far, so good. We can start preparing our skeleton-poc:
Checking:
Great, we have some control over registers ;] Next case is to put a shellcode in the stack and jump to it using our overwrite. Let's try here:
Preparing new skeleton:
I like to set a breakpoint on the value we are looking to jump for. Checking:
Looks good. ;] Checking:
Ok, I believe at this stage we can continue the flow of the program to see a SIGSEGV. Next stage is to use a shellcode to takeover the program's flow. I used this one in the next skeleton-poc:
...and after few more changes and calculations:
Another good idea is to use a different approach:
Shellcode exported to the environment as a variable can be later located and use just like we did it above.
Checking:
Again...
Checking output address from the C-code:
Still no. But then I realised that export is wrong (I missed' and ` ;)) and maybe (after I restarted VM few times) it will be a good idea to turn off ASLR again, hm? ;)
So again:
Yep, now the value looks better. ;]
Good.
Now we can move to something more interesting - to example of bypass NX-bit on 64bit linux. :)
Let's try with the same example vulnerable code but this time we will exclude -z execstack during compilation:
Ok, even if we try the same trick, we will not be able to run /bin/sh:
To bypass NX-bit you can use multiple ways (for example using mprotect() or return-into-lib-C. Idea is pretty the same - prepare a valid shellcode. ;)
Today we will use ret2libC :)
Here we go:
Reproducing steps just like for 'normal' buffer overflow described as a first case:
So far, so good.
Now we need to remove return address and prepare our own one. To do that I used ropper:
Now we need address of system() and /bin/sh string. Let's collect it:
Checking our new skeleton-poc:
Verifying:
Looks like it's done. ;)
See you next time!
Cheers
Brak komentarzy:
Prześlij komentarz