Chapter 8. Exploitation Concepts

Client-side attacks characteristically require user interaction. A careless visit to a website can result in devastation. Generally speaking, a client-side attack will be focused on the "client" machine used by individuals at home or in the office. In a properly secured environment, these hosts will be protected using a combination of security mechanisms and practices, such as white listing, network segmentation, host-based firewalls, file integrity monitors, system configuration hardening, and antivirus.

With proper training, users are well aware that clicking on unknown links, opening e-mail attachments, or even plugging in an untrusted device, may have the potential to be harmful. Unfortunately, convenience often supersedes common sense, and as such, users will continue to repeat old mistakes. After all, shouldn't all of these protection mechanisms installed by the administrators protect the user from everything?

In large environments, desktops, workstations, and even printers are typically considered noncritical. The focus is on expensive servers and systems that are essential to keeping the business running. A skilled attacker will be well aware of this mentality. If unable to effortlessly penetrate the network using web application vulnerabilities, the attacker may often move on to using a blend of social engineering and client-side attacks. If successful, these attacks will cut through a perimeter as quickly as a hot knife cuts through butter. Additionally, a fully compromised client machine can then be set up as a gateway into the otherwise secured network.

In this chapter, we will investigate methods that assist us in testing the effectiveness of a corporation's security awareness training and client-side protection mechanisms. The research performed during the information gathering stages of your testing will finally be used to the fullest extent. Furthermore, we look at some of the techniques and tools used by security researchers and crafty attackers to bypass even those system controls that at first glance seem theoretically sound.

In this chapter, we will cover the following topics:

  • Buffer overflows—a refresher
  • "C"ing is believing—create a vulnerable program
  • Turning ASLR on and off in Kali
  • 64-bit exploitation
  • Introducing vulnserver
  • Fuzzing tools included in Kali
  • Social Engineering Toolkit
  • Fast-Track
  • Reader challenge

Buffer overflows – a refresher

Buffer overflows are the bread and butter of attackers in the wild. When this type of vulnerability is properly exploited, an attack may lead to complete system compromise in mere seconds. Ideally, many of these vulnerabilities may be prevented by the proper implementation of a security development lifecycle. If your client does not have such practices, you may be required to perform steps that are above and beyond standard penetration testing, and prove that there are flaws in the (often internally developed) applications being deployed across the enterprise.

Tip

Not all buffer overflow vulnerabilities can be used to create remote exploits. Also note that not all buffer overflows are exploitable.

More often than not, programming errors that allow for buffer overflows are not intentional or due to lazy developers. Frequently, buffer overflow vulnerabilities are missed during the application development stages because of either the complexity of the application or the fact that the original codebase is decades old and yet is still being built upon. Considering the fact that software developers are regularly faced with unreasonable deadlines and demands from their management chain, we should not be surprised that sometimes security flaws can be overlooked or missed during the software development lifecycle. It is not shocking for a developer to receive requirements based on eleventh-hour decisions. Logically, this is counterproductive to ensuring the security of the application being developed. As with any other technology, security needs to be built into the entire process and not added as an afterthought. The priority of the developer becomes pumping out code modifications rather than focusing on both stability and security.

To address these types of errors, code compilers and operating systems will include mechanisms that are meant to prevent the exploitation of this type of code. In order to fully understand how to bypass these mechanisms, you will need to have at minimum a basic understanding of what buffer overflows are and how you can verify that your clients are fully protected against this type of attack.

Memory basics

Before we start writing vulnerable code and attempting exploits, we will cover the basics of how a program is displayed in memory. An example of this is shown in the following diagram:

Memory basics

The text segment contains the program code to be executed. Data, as its name suggests, contains the global data for the program. The stack is static and fixed in size, and created at run time. It stores the local variables and functions of the program, and the heap is dynamic. We will focus on the stack within this chapter. There are a number of registers that can store data when we run the program, and we will not cover them here. We will look at the ones that are interesting for us, and that is the ESP (stack pointer), EBP (base pointer), and EIP (instruction pointer). ESP and EBP track the stack frame of the existing function. ESP points to the top of the stack frame at its lowest address, and EBP points to the highest memory address at the bottom of the stack frame. Finally, EIP holds the memory address of the next instruction to be executed. Our task is to take over program execution by getting EIP to point to the code of our choice.

"C"ing is believing – Create a vulnerable program

To fully comprehend just how simple it can be to overlook these errors, we will be producing our own vulnerable program. Open up a 32-bit Kali virtual system and take the opportunity to connect to the Internet and perform your updates. After updating, you will more than likely need to download the debugger we will be using. As of now, it is not included as part of Kali 32 bit.

We will be using the GNU Debugger. You can learn additional information about this tool at: http://www.gnu.org/software/gdb/.

Tip

The following examples use the 32-bit version of Kali.

To get the GNU debugger, you will need to install it using the apt-get install command:

# apt-get install gdb

Once you have installed gdb, disconnect the Internet connection to your Kali virtual machine again.

The first order of business is to compile a small program that will be used to demonstrate a buffer overflow in action. We take advantage of a well-known flaw in the strcpy function for this purpose. Open up a terminal session in Kali and create a file named bovrflow.c in nano:

# nano bovrflow.c
  /* This program contains an intentional vulnerability for learning purposes. */

  #include <stdio.h>
  #include <string.h>

  //This function will copy the string input

  Void copy_string(char *str)
{
      char buffer[5];
      strcpy(buffer, str);
      printf("You entered: %s
" , buffer);
}


  void main(int argc, char *argv[])
  {



      copy_string(argv[1]);
/*Print out the string that was typed*/

}

Be sure to save your work before exiting to the terminal. In this program, we have intentionally used strcpy() because it does not sanitize the input to ensure that it does not exceed the size of the assigned buffer.

Due to safety restrictions built into the GCC compiler, we must use -fno-stack-protector to compile this code. At the command prompt, issue the following command:

# gcc -o bovrflow -fno-stack-protector –z execstack bovrflow.c

In the previous command, we invoked the gcc compiler, chose the output filename to be bovrflow, disabled the stack protector functionality of the compiler, executed on the stack, and targeted the bovrflow.c source code.

Tip

Because we are running as root in Kali, we do not have to worry about changing the file permissions to executable before attempting to run it.

Turning ASLR on and off in Kali

Linux uses Address Space Layout Randomization (ASLR) by default. You should understand how to check to see if this is enabled, as well as if it has the ability to turn it on and off. Let's take a look at the ldd command. This command will list a program's shared library dependencies. If you have ASLR enabled, the memory addresses will change each time they are invoked:

# root@kali:~ # ldd bovrflow
  linux-gate.so.1 =>  (0xb786e000)
  libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7701000)
     /lib/ld-linux.so.2 (0xb786f000)
# root@kali:~ # ldd bovrflow
  linux-gate.so.1 =>  (0xb780a000)
  libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb769d000)
     /lib/ld-linux.so.2 (0xb780b000)
# root@kali:~ # ldd bovrflow
  linux-gate.so.1 =>  (0xb78b5000)
  libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7748000)
     /lib/ld-linux.so.2 (0xb78b6000)

On closer inspection, it becomes obvious that the memory addresses are changing each time. Now, let's turn off ASLR (off is 0, on is 2), by changing the randomize_va_space value, and compare the results:

# root@kali:~ #sysctlkernel.randomize_va_space=0
# root@kali:~ # ldd bovrflow
  linux-gate.so.1 =>  (0xb7fe4000)
  libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e77000)
     /lib/ld-linux.so.2 (0xb7fe5000)
# root@kali:~ # ldd bovrflow
  linux-gate.so.1 =>  (0xb7fe4000)
  libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e77000)
     /lib/ld-linux.so.2 (0xb7fe5000)
# root@kali:~ # ldd bovrflow
  linux-gate.so.1 =>  (0xb7fe4000)
  libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e77000)
     /lib/ld-linux.so.2 (0xb7fe5000)

The memory addresses are identical regardless of how many times you attempt to run the command. This indicates that you turned off the randomization produced by ASLR.

Understanding the basics of buffer overflows

Assuming that the bovrflow.c compiled properly and ASLR is turned off, we can now execute our intentionally vulnerable program:

# ./bovrflow AAAAAAAAAA
You entered: AAAAAAAAAA

By entering ten characters, the program executed the instructions and exited properly after displaying the characters you had typed. Now, let's overflow the buffer to analyze the result. This time run the program, but type more than 14 characters:

# ./bovrflow AAAAAAAAAAAAAA
You entered: AAAAAAAAAAAAAA
Segmentation fault

Tip

Your addressing will more than likely not match the following examples; therefore, ensure that you change the addresses to match the ones you discover in your analysis.

By entering more data than the buffer could handle, we generated segmentation fault. This is exactly what we are looking for. Let's take a look at what is occurring in memory space when this program is running. At the prompt, invoke the gdb debugger:

gdbb ovrflow
  GNU gdb (Debian7.7.1+dfsg-5)
  Copyright (C) 2014 Free Software Foundation, Inc.
  License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  This is free software: you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
  and "show warranty" for details.
  This GDB was configured as "i486-linux-gnu".
  For bug reporting instructions, please see:
  <http://www.gnu.org/software/gdb/bugs/>...
  Reading symbols from /root/overload/bovrflow...(no debugging symbols found)...done.
  (gdb)

The debugger will provide us with detailed memory information about the bovrflow program. Let's take a look at what happens when we run the program from within gdb without overflowing the buffer. We type r at the gdb prompt to run the program:

(gdb) r AAAAA
  Starting program: /root/bovrflow

  You entered: AAAAAA

  [Inferior 1 (process 19568) exited with code 06]
(gdb)

Nothing interesting to see here, but this test is a good sanity check to ensure everything is working properly. Now, we need to take a look at what occurs when we cause the segmentation error:

(gdb) r AAAAAAAAAAAAAA
  Starting program: /root/bovrflow
  You entered: AAAAAAAAAAAAA

  Program received signal SIGSEGV, Segmentation fault.
0x8048487 in main ()

Once again, we run the program; this time however, we use a sequence of 14 characters and intentionally cause segmentation fault. When reviewing the results, it becomes obvious that something is not quite right. Take note of the reference to the SIGSEGV, segmentation fault. We will need to take advantage of this error and exploit the evident vulnerability. Unfortunately, there is a bit more that we need to understand before moving on to creating our shellcode. After all, so far all we know is that we can cause the application to crash. To progress, we must look at our registered addresses to further comprehend what occurred in memory space during the crash. Type i r at the prompt:

eax0x1b    27
ecx0xb7ff389f    -1208010593
edx0xb7fcb878    -1208174472
ebx0xb7fca000    -1208180736
esp0xb7ff389f    0xb7ff389f<_dl_unload_cache+47>
ebp0x0  0x0
esi0x0  0
edi0x0  0
eip0x2c31  0x2c31
eflags0x10286    [ PF SF IF RF ]
cs0x73  115
ss0x7b  123
ds             0x7b    123
es0x7b  123
fs             0x0    0
gs0x33  5114 characters

We have successfully smashed the stack, but we do not see any of our characters that we entered in the registers. So, we need to try more data and see if we can identify our characters in the register. The next input we will use is 20 characters.

Enter r AAAAAAAAAAAAAAAAAAAA to restart the program within the debugger:

The program being debugged has been started already.
Start it from the beginning? (y or n) y

Press y to let the debugger know you would like to completely restart:

Starting program: /root/bovrflow

We need to look at the registers again. Type i r at the prompt:

gdb) i r
eax0x21    33
ecx0x0  0
edx0xb7fcb878    -1208174472
ebx0xb7fca000    -1208180736
esp0xbffff3e0    0xbffff3e0
ebp0x41414141    0x41414141
esi0x0  0
edi0x0  0
eip0x8004141  0x8004141
eflags0x10286    [ PF SF IF RF ]
cs0x73  115
ss0x7b  123
ds             0x7b    123
es0x7b  123
fs             0x0    0
gs0x33  51

As the output of the command shows, the content of the registers in this example shows our 0x41, but it is not complete in the location of the EIP. Let's do a little bit more work and get the EIP to point to the 0x41 characters, enter the following in gdb, and accept the fact that you are restarting the program when prompted. An example of this is as follows:

(gdb) r AAAAAAAAAAAAAAAAAAAAAAAA
  Program received signal SIGSEGV, Segmentation fault.
  0x080484a0 in main ()

Let's look at our registered addresses to further comprehend what occurred in the memory space during the crash. Type i r at the prompt:

gdb) i r
eax0x25    37
ecx0x0  0
edx0xb7fcb878    -1208174472
ebx0xb7fca000    -1208180736
esp0xbffff3d0    0xbffff3d0
ebp0x41414141    0x41414141
esi0x0  0
edi0x0  0
eip0x41414141    0x41414141
eflags0x10282    [ SF IF RF ]
cs0x73  115
ss0x7b  123
ds             0x7b    123
es0x7b  123
fs             0x0  0
gs0x33  51

We can see our input at EIP as 0x41414141. This is exactly what we wanted with the control of EIP.

Tip

If you do not understand what we are looking at when we see 0x41414141, perform a quick search on the Internet for "ASCII conversion chart", find one that you are comfortable with, and print it out. Additionally, you can access a conversion chart in Kali by entering man ascii.

At this point, we have covered the basic concept of how the stack can be manipulated. Advanced attackers will understand and take advantage of these flaws whenever possible. Under many circumstances, you will not have time to fully check every single application for vulnerabilities such as buffer overflows, but it is good to understand the basic premise of the attacks we will be using as we move further into the chapter. If you find that you might enjoy vulnerability research, it is highly recommended that you check out the following resources:

Excellent resources to learn more about buffer overflow vulnerabilities and more:

Smashing The Stack For Fun And Profit by Aleph One

http://insecure.org/stf/smashstack.html

Buffer Overflow Tutorial by Mudge

http://insecure.org/stf/mudge_buffer_overflow_tutorial.html

The Corelan Team's website. This team is amazing. Check out their tutorials and forums!

http://www.corelan.be/

ihazomgsecurityskillz blog by "sickn3ss"–impressive write ups that are easy to follow along with. Check out the tutorials.

http://ihazomgsecurityskillz.blogspot.in/

Even though some of these are dated, many are considered classics in stack-based buffer overflow.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset