Disabling Buffer Overflows protections by Mohamed Ahmed

Sep 10, 2017 10:01 PM
Sep 10, 2017 10:02 PM

Disabling Buffer overflow protections

When it is time to scan a program for vulnerabilities or just exploit them under GNU / Linux, there are two simple protections that you should keep in mind when it comes to systems with Kernels version 2.6 and higher , and over all if compiled with GCC. There are more protections such as the patch grsecurity or exec-shield (of which I may speak later), even there is protection from hardware called StackGuard .

Virtual Address Space Randomization

The first protection is the creation of random virtual address space in the process , which change with each invocation of the process. By changing this, exploits created for absolute addresses (bone, constants) would be obsolete since they change the addresses with each execution of the program and its libraries in a range of 8MB. This applies only to ELF (Executable and Linkable Format) binaries .

The method to enable and disable it is simple, I will demonstrate the change of addresses in memory with the following code:

Code: C ++

#include

unsigned long esp ( void ) {

_asm_ ( "movl% esp,% eax" ) ;

}

int main ( int argc, char * argv ) {

printf ( "0x% 08x \ n " , esp ( ) ) ;

return 0 ;

}

--------------------------------------------------------------------

This code would give me the exact address of ESP at the time of execution. Now with this code we are going to test the protection in itself of the kernel in question. The system file that controls this option is located in / proc / sys / kernel / randomizevaspace (only manipulated by a superuser or root ) and we could say that it is controlled by a TRUE (1) or FALSE (0). Then, let's try:

Code: Text

mohamed @ mohamed -desktop: ~ / Desktop $ cat / proc / sys / kernel / randomizevaspace

1

mohamed @ mohamed -desktop: ~ / Desktop $ cat> esp.c << END

> #include

>

> unsigned long esp (void) {

> _asm _ ("movl% esp,% eax");

>}

>

> int main (int argc, char * argv ) {

> printf ("0x% 08x \ n", esp ());

> return 0;

>}

>

> END

mohamed @ mohamed -desktop: ~ / Desktop $ gcc esp.c -o esp

mohamed @ mohamed -desktop: ~ / Desktop $ ./esp

0xbfef2448

--------------------------------------------------------------------------------------------------------------

By enabling this "patch" we can see that the addresses are changing and making it almost impossible to know the virtual address of ESP (in this case ..) until the moment of execution. Now let's disable this function and let's see what happens:

Code: Text

root @ mohamed -desktop: ~ # echo 0> / proc / sys / kernel / randomizevaspace

...

mohamed @ mohamed -desktop: ~ / Desktop $ cat / proc / sys / kernel / randomizevaspace

0

mohamed @ mohamed -desktop: ~ / Desktop $ ./esp

0xbffff558

mohamed @ mohamed -desktop: ~ / Desktop $ ./esp

0xbffff558

mohamed @ mohamed -desktop: ~ / Desktop $ ./esp

0xbffff558

mohamed @ mohamed -desktop: ~ / Desktop $

------------------------------------------------------------------------------------------------------------------

After disabling the patch we can see that the address of ESP is constant in the executable, without even recompiling it!

But do not be frightened, as history has taught us! Behind every security system is someone trying to break it .. 1

GCC StackGuard (ProPolice) Protection

Well, this is a security protection implemented in the ultra renoted compiler and found in every GNU / Linux distribution, I speak of GCC (GNU Compiler Collection) . This compiler comes with a protection system called "StackGuard" developed by Immunix and now called ProPolice 2. This protection detects a buffer overflow attack (always on the stack) by creating a value called "Canary" between the created buffers and the frame pointer (EBP) & "return address" (EIP), then when a buffer attempts overwriting these values ??must in one way or another overwrite the value "Canary" and this serves as a trigger for protection that gives an alert and takes action against it, for example, stopping the process.

Well, let's see how it reacts to a simple overflow like this:

Code: C ++

#include

#include

void overflow ( char * badbeef ) {

char buffer 32 ;

strcpy ( buffer, badbeef ) ;

}

int main ( int argc, char * argv ) {

overflow ( argv 1 ) ;

return 0 ;

}

--------------------------------------------------------------------------------------

As we see, there is a 32-byte buffer and not a single check when doing the string copy to the buffer. We already know that we have 32 bytes of buffer + EBP + EIP, but if the protection is enabled we would not allow or pass the frame pointer:

Code: Text

mohamed @ mohamed-desktop: ~ / Desktop $ cat> vulnerable.c << END

> #include

> #include

>

> void overflow (char * badbeef) {

> char buffer 32;

> strcpy (buffer, badbeef);

>}

>

> int main (int argc, char * argv ) {

> overflow (argv 1);

> return 0;

>}

>

> END

mohamed @ mohamed-desktop: ~ / Desktop $ gcc vulnerable.c -o vulnerable

mohamed@ mohamed-desktop: ~ / Desktop $ ./vulnerable $ (perl -e 'print "A" x32')

mohamed @ mohamed-desktop: ~ / Desktop $ ./vulnerable $ (perl -e 'print' A "x36 # EBP ')

* stack smashing detected *: ./vulnerable terminated

========= Backtrace =========

/lib/tls/i686/cmov/libc.so.6(_fortify_fail+0x48)0xb7f69138

/lib/tls/i686/cmov/libc.so.6(_fortify_fail+0x0)0xb7f690f0

./vulnerable0x80483fe

./vulnerable0x8048421

0x41414141

======= Memory map: ========

08048000-08049000 r-xp 00000000 08:02 534536 / home /mohamed/ Desktop / vulnerable

08049000-0804a000 rw-p 00000000 08:02 534536 / home / mohamed / Desktop / vulnerable

0804a000-0806b000 rw-p 0804a000 00:00 0 heap

b7e70000-b7e7a000 r-xp 00000000 08:02 197220 /lib/libgcc_s.so.1

b7e7a000-b7e7b000 rw-p 0000a000 08:02 197220 /lib/libgcc_s.so.1

b7e7b000-b7e7c000 rw-p b7e7b000 00:00 0

b7e7c000-b7fc5000 r-xp 00000000 08:02 1425929 /lib/tls/i686/cmov/libc-2.7.so

b7fc5000-b7fc6000 r-p 00149000 08:02 1425929 /lib/tls/i686/cmov/libc-2.7.so

b7fc6000-b7fc8000 rw-p 0014a000 08:02 1425929 /lib/tls/i686/cmov/libc-2.7.so

b7fc8000-b7fcb000 rw-p b7fc8000 00:00 0

b7fe1000-b7fe3000 rw-p b7fe1000 00:00 0

b7fe3000-b7fe4000 r-xp b7fe3000 00:00 0 vdso

b7fe4000-b7ffe000 r-xp 00000000 08:02 196676 /lib/ld-2.7.so

b7ffe000-b8000000 rw-p 00019000 08:02 196676 /lib/ld-2.7.so

bffeb000-c0000000 rw-p bffeb000 00:00 0 stack

Cancelled

mohamed @ mohamed-desktop: ~ / Desktop $ ./vulnerable $ (perl -e 'print' A 'x44 # EIP')

* stack smashing detected *: ./vulnerable terminated

========= Backtrace =========

/lib/tls/i686/cmov/libc.so.6(_fortify_fail+0x48)0xb7f69138

/lib/tls/i686/cmov/libc.so.6(_fortify_fail+0x0)0xb7f690f0

./vulnerable0x80483fe

0x41414141

======= Memory map: ========

08048000-08049000 r-xp 00000000 08:02 534536 / home / mohamed / Desktop / vulnerable

08049000-0804a000 rw-p 00000000 08:02 534536 / home / mohamed / Desktop / vulnerable

0804a000-0806b000 rw-p 0804a000 00:00 0 heap

b7e70000-b7e7a000 r-xp 00000000 08:02 197220 /lib/libgcc_s.so.1

b7e7a000-b7e7b000 rw-p 0000a000 08:02 197220 /lib/libgcc_s.so.1

b7e7b000-b7e7c000 rw-p b7e7b000 00:00 0

b7e7c000-b7fc5000 r-xp 00000000 08:02 1425929 /lib/tls/i686/cmov/libc-2.7.so

b7fc5000-b7fc6000 r-p 00149000 08:02 1425929 /lib/tls/i686/cmov/libc-2.7.so

b7fc6000-b7fc8000 rw-p 0014a000 08:02 1425929 /lib/tls/i686/cmov/libc-2.7.so

b7fc8000-b7fcb000 rw-p b7fc8000 00:00 0

b7fe1000-b7fe3000 rw-p b7fe1000 00:00 0

b7fe3000-b7fe4000 r-xp b7fe3000 00:00 0 vdso

b7fe4000-b7ffe000 r-xp 00000000 08:02 196676 /lib/ld-2.7.so

b7ffe000-b8000000 rw-p 00019000 08:02 196676 /lib/ld-2.7.so

bffeb000-c0000000 rw-p bffeb000 00:00 0 stack

Cancelled

-------------------------------------------------------------------------------------------------------------------------------------

DETECTED! If we analyze more closely this ./vulnerable0x80483ef , that address tells us at what time the program executes the buffer overflow:

Code: Text

mohamed@ mohamed-desktop: ~ / Desktop $ gdb -q vulnerable

(gdb) disas 0x80483ef

Dump of assembler code for function overflow:

0x080483c4 : push% ebp

0x080483c5 : mov% esp,% ebp

0x080483c7 : sub $ 0x48,% esp

0x080483ca : mov 0x8 (% ebp),% eax

0x080483cd : mov% eax, -0x34 (% ebp)

0x080483d0 : mov% gs: 0x14,% eax

0x080483d6 : mov% eax, -0x4 (% ebp)

0x080483d9 : xor% eax,% eax

0x080483db : mov -0x34 (% ebp),% eax

0x080483from : mov% eax, 0x4 (% esp)

0x080483e2 : read -0x24 (% ebp),% eax

0x080483e5 : mov% eax, (% esp)

b 0x080483e8 : call 0x8048320 / b

0x080483ed : mov -0x4 (% ebp),% eax

0x080483f0 : xor% gs: 0x14,% eax

0x080483f7 : je 0x80483fe

0x080483f9 : call 0x8048330 <_ stackchkfail @ plt>

0x080483fe : leave

0x080483ff : ret

End of assembler dump.

--------------------------------------------------------------------------------------------------------------------------------------------

As shown stops the program in - instructional leave that (so I understand) is responsible for moving ( mov ) to% ebp to% esp and remove ( pop ) to% ebp stack, that would mean intends to return to ESP and with the copied buffer ( call 0x8048320 ). It is there where the canary is overwritten and the entire procedure is stopped after the check. The check is done using the _stackchkfail () function .

Now let's try the program sin this protection. For that we are going to compile the program with the flag --no-stack-protector :

Code: Text

mohamed @ mohamed-desktop: ~ / Desktop $ gcc --no-stack-protector vulnerable.c -o vulnerable

mohamed @ mohamed-desktop: ~ / Desktop $ ./vulnerable $ (perl -e 'print' A 'x44 # EIP')

Targeting failure

mohamed @ mohamed-desktop: ~ / Desktop $ gdb -q vulnerable

(gdb) r $ (perl -e 'print "A" x36, "B" x4')

The program being debugged has already started.

Start it from the beginning? (and or n) and

Starting program: / home /mohamed/ Desktop / vulnerable $ (perl -e 'print "A" x36, "B" x4)

Program received signal SIGSEGV, Segmentation fault.

0x42424242 in ?? ()

(gdb) ir eip ebp

eip 0x42424242 0x42424242

ebp 0x41414141 0x41414141

(gdb)

--------------------------------------------------------------------------------------------------------------------------

And without this protection we were able to overwrite EBP and EIP without any difficulty, which would be easy to exploit even more if the protection of which you speak before is disabled to be able to get the constant address of ESP and overwrite the process flow. In itself, I only talk about a single method of protection of this extension, which for what I know are 5.

Related Articles

637263493835297420.jpg

How to Use Zero-Width Characters to Hide Secret Messages in Text (& Even Reveal Leaks)

636455706472146367.jpg

How to Hide DDE-Based Attacks in MS Word

Comments

No Comments Exist

Be the first, drop a comment!