What is NX and W^X? Code execution bugs?

CODE EXECUTION BUGS | NX VS W^X

 

 Code execution bugs and its exploitation was very popular that even operating system vendors did something about it.

They started introducing various protection mechanisms, not to remove code execution bugs but to make its exploitation nearly impossible. NX and W^X are some of the popular protection mechanisms out there.


*What is code execution bugs?

*Is it really impossible to exploit code execution bugs with the above mechanisms?


 

 

THE ONLY USEFUL ADVERTISEMENT:

Hey, if you want clear a understanding on this topic then first learn the basics / prerequisites. CLICK_HERE_TO_LEARN (learn about stack / what's inside a compiled program / memory segmentation)

 

 

 

I will first explain how each works with a few popular methods to bypass the protection. Towards the end hopefully the above question will be answered.


 

*When do we call a program vulnerable to code execution (the basic general idea)?

Here is a sample C program:


#include<stdio.h>

#include<string.h>

int myfunc(char * q)

    {

        char buff[10];

        strcpy(buff, q);

        return 0;

    }

void main(int c , char **v)

    {

        myfunc(v[1]);

    }



The above program is vulnerable to code execution. BUT why?

 

From the above code, it is pretty obvious that we totally control the data that is copied in our buff[10]  char array.

 

Since our buffer size is limited to 10 bytes only, if we copy more than 10 bytes our data will overwrite some special stack data (as local variables are on stack) and crash our application. But if we craft our input properly we can inject code of our choosing to the above array and redirect execution to the array (where our code resides). Now the vulnerable program will execute our code instead of what it is meant to.


The above scenario of executing code on stack also known as stack based buffer overflow was so popular that NX was introduced.



 

* NX (non-executable stack):

As you might have probably guessed NX or non-executable stack makes the stack non-executable thereby making the above exploitation technique rendered useless.


Ever wondered when did the idea of NX was first introduced? 

Roughly....1996.

I know that's quite an old thing but still now it is in action.

 

Fortunately or Unfortunately almost immediately after NX started its action, several techniques to bypass the NX protection were introduced.

And all of the techniques rely on the very simple fact that stack is marked non-execution but code can still be executed anywhere else (where execution is allowed)

 


Return-into-libc (or ret2libc) was the most popular technique that was introduced in response to NX.


Short note on ret2libc: 

libc? 

"Standard C library", a library of standard functions that can be used by all C programs and sometimes by programs in other languages.

As the name suggests we are returning execution into some useful libc functions like system() instead of the stack.


Later, ret2libc was improved into ret2plt, ret2strcpy, ret2text, ret2data, ret2gets, etc.


One of the very interesting technique from the above list would be the ret2strcpy.

Execution flow of ret2strcpy:

1. Execution returns to strcpy() function.

2. We will use strcpy to copy our code in any executable marked area of memory (like if heap or data section is marked executable then we will write our code there).

3. Finally jump execution to our written code.


Enough of NX. Let's move on to W^X protection mechanism.




*W^X (Either Writable or Executable) Memory:

This protection technique is like an extension to non-executable stacks. W^X makes the writable memory non-executable and executable memory non-writable.

 

So, W^X theoretically makes it impossible to inject foreign code and execute, as writable memory is always non-executable and vice-versa.


When properly implemented, W^X is a very efficient protection technique against foreign code execution. However, this doesn't mean the end of code execution exploits.


Even with W^X protection, when you are in stack based buffer overflow situation you can still use chained ret2code attack which will still perform many interesting attacks (this should be enough for most attacker).

However, if you really want to discuss the possibility of foreign code execution with W^X then you will need to do some research.

 

Let me give you some hint:

* Check if there is any W+X (writable and executable) memory.

* Use functions like VirtualProtect (for windows) or mmap (for linux) to create or make an existing memory region W+X. This can be shortened into return to mmap-strcpy-code attack.



I think it's a good time to end here. Hope you learn at-least something about NX vs W^X and code execution bugs.

Post a Comment (0)
Previous Post Next Post