Sunday, October 13, 2013

A simple explanation about NX/Pax works.

This is nothing more then just to recap how NX/PAX  works why it's important for us to understand for beginners on exploitation, writing CTF flags :p , and other interesting people paper.

Below is a simplest code on a bad example on how to execute a shellcode.

unsigned char code[] = "\xcc";
int main(int argc, char **argv)
{
  int (*func)();
  func = (int (*)()) code;
  (int)(*func)();
}


Explanation:
1. We declare a pointer called func*
2. Func are pointed out to the location of memory code.
3. Execute watever being pointed by func() which is to say watever code resides in code.
Try compile and run:
gcc example1.c -o example ; ./example
Segmentation fault
Why? To understand this problem . Modern compilers by default will enfoce a NX bit on the stack region of the process. Any "local  variable" that we declared will be loaded in the stack region of the memory. And what does it mean to us ? To generalize our understanding , we know a region of memory in a computer can have 3 propeties:-
1. Read ; we can read and have access to the memory
2. Write: We ca write data to the particular region.
3. Execute: The code in that particular region can be executed.
cat /proc/3976/maps 
08048000-08049000 r-xp 00000000 08:01 1447191    /root/bypassav/example
08049000-0804a000 rw-p 00000000 08:01 1447191    /root/bypassav/example
b7e62000-b7e63000 rw-p 00000000 00:00 0 
b7e63000-b7fbf000 r-xp 00000000 08:01 1311258    /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b7fbf000-b7fc0000 ---p 0015c000 08:01 1311258    /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b7fc0000-b7fc2000 r--p 0015c000 08:01 1311258    /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b7fc2000-b7fc3000 rw-p 0015e000 08:01 1311258    /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b7fc3000-b7fc6000 rw-p 00000000 00:00 0 
b7fdf000-b7fe1000 rw-p 00000000 00:00 0 
b7fe1000-b7fe2000 r-xp 00000000 00:00 0          [vdso]
b7fe2000-b7ffe000 r-xp 00000000 08:01 1311294    /lib/i386-linux-gnu/ld-2.13.so
b7ffe000-b7fff000 r--p 0001b000 08:01 1311294    /lib/i386-linux-gnu/ld-2.13.so
b7fff000-b8000000 rw-p 0001c000 08:01 1311294    /lib/i386-linux-gnu/ld-2.13.so
bffdf000-c0000000 rw-p 00000000 00:00 0          [stack]
As u can see right now the stack region is mark as read-write ..... no x means dat code in that region couldn`t be executed..
Now that we understand the stack region is protected, attacker evolves their attack into ROP or ret2/wateverlib  style programming. But that's beyond the scope of this post.  Having said that it's still possible to make your code executed by using mmap trick .  To make everyone happy here i cheat a litte using execstack just to see the difference..
gcc example1.c -o example ; execstack -s example; ./example 
Trace/breakpoint trap
cat /proc/4125/maps
08048000-08049000 r-xp 00000000 08:01 1447203    /root/bypassav/example
08049000-0804a000 rwxp 00000000 08:01 1447203    /root/bypassav/example
b7e62000-b7e63000 rwxp 00000000 00:00 0 
b7e63000-b7fbf000 r-xp 00000000 08:01 1311258    /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b7fbf000-b7fc0000 ---p 0015c000 08:01 1311258    /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b7fc0000-b7fc2000 r-xp 0015c000 08:01 1311258    /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b7fc2000-b7fc3000 rwxp 0015e000 08:01 1311258    /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b7fc3000-b7fc6000 rwxp 00000000 00:00 0 
b7fdf000-b7fe1000 rwxp 00000000 00:00 0 
b7fe1000-b7fe2000 r-xp 00000000 00:00 0          [vdso]
b7fe2000-b7ffe000 r-xp 00000000 08:01 1311294    /lib/i386-linux-gnu/ld-2.13.so
b7ffe000-b7fff000 r-xp 0001b000 08:01 1311294    /lib/i386-linux-gnu/ld-2.13.so
b7fff000-b8000000 rwxp 0001c000 08:01 1311294    /lib/i386-linux-gnu/ld-2.13.so
bffdf000-c0000000 rwxp 00000000 00:00 0          [stack]


Oh Hitb 2013 Kul starts tomorrow.. See you there soon!

No comments: