Ethical Hacking
Version 5
Module XX
Buffer Overflows
       Scenario
   It was a job that Tim wanted right from the start of his
   career. Being a Project Manager at a well-known software
   firm was definitely a sign of prestige. But now, his
   credibility was at stake.
   The last project that Tim handled failed to deliver because
   the application crashed. The customer of Tim's company
   suffered a huge financial loss.
   At the back of his mind, something was nagging Tim...
   Had he asked his Test Engineers to do a thorough testing of
   the delivered package, this would not have happened.
                                                                                     Copyright © by EC-Council
EC-Council                                                 All Rights reserved. Reproduction is strictly prohibited
        Module Objective
    This module will familiarize you with the following:
    ~   Buffer Overflows
    ~   Reasons for buffer overflow attacks
    ~   Types of buffer overflow
    ~   Stacks
    ~   Shell code
    ~   Detecting buffer overflows in a program
    ~   Mutating buffer Overflow exploit
    ~   Buffer overflow countermeasures
    ~   Code Analysis
                                                                            Copyright © by EC-Council
EC-Council                                        All Rights reserved. Reproduction is strictly prohibited
       Module Flow
                                        Detecting Buffer Overflows
                Buffer Overflows               In a Program
                  Reasons for           Attacking a Real Program
             Buffer Overflow Attacks
                                                Mutating
             Types of Buffer Overflow    Buffer Overflow Exploit
                                             Defense against
                     Stacks                  Buffer Overflows
                   Shell Code                   Code Analysis
                                                                     Copyright © by EC-Council
EC-Council                                 All Rights reserved. Reproduction is strictly prohibited
       Real World Scenario
             On Oct. 19, 2000, hundreds of flights were grounded or delayed because
               of a software problem in the Los Angeles air traffic control system. The
               cause was attributed to a controller typing nine (instead of five)
               characters of flight-description data, resulting in a buffer overflow
                                                                                        Copyright © by EC-Council
EC-Council                                                    All Rights reserved. Reproduction is strictly prohibited
         Why are Programs/Applications
         Vulnerable?
   ~ Since   there is lot of pressure to maintain the turnaround of
       deliverables, programmers are bound to make mistakes that
       are often overlooked
   ~   Boundary checks are not done fully or, in most cases, they are
       skipped entirely
   ~   Programming languages, such as C, which programmers use
       to develop packages or applications, have errors in it
   ~   The strcat(), strcpy(), sprintf(), vsprintf(), bcopy(), gets(), and
       scanf() calls in C language can be exploited because these
       functions do not check to see if the buffer, allocated on the
       stack, is large enough for the data copied into the buffer
   ~   Good programming practices are not adhered to
                                                                                          Copyright © by EC-Council
EC-Council                                                      All Rights reserved. Reproduction is strictly prohibited
         Buffer Overflows
     ~   A buffer overrun is when a program allocates a block of memory of a certain length
         and then tries to stuff too much data into the buffer, with extra overflowing and
         overwriting possibly critical information crucial to the normal execution of the
         program
     ~   Consider the following source code. When the source is compiled and turned into a
         program and the program is run, it will assign a block of memory 32 bytes long to
         hold the name string
                #include<stdio.h>
                int main ( int argc , char **argv)
                  {
                             char target[5]=”TTTT”;
                             char attacker[11]=”AAAAAAAAAA”;
                             strcpy( attacker,” DDDDDDDDDDDDDD”);
                             printf(“% \n”,target);
                             return 0;
                  }
     ~       This type of vulnerability is prevalent in UNIX- and NT-based systems
                                                                                             Copyright © by EC-Council
EC-Council                                                         All Rights reserved. Reproduction is strictly prohibited
       Reasons for Buffer Overflow Attacks
   ~ Buffer    overflow attacks depend on two things: the lack of
     boundary testing and a machine that can execute code that
     resides in the data/stack segment
   ~ The     lack of boundary is very common and, usually, the
     program ends with segmentation fault or bus error. In
     order to exploit buffer overflow to gain access to or
     escalate privileges, the offender must create the data to be
     fed to the application
   ~ Random      data will generate a segmentation fault or bus
     error, never a remote shell or the execution of a command
                                                                                       Copyright © by EC-Council
EC-Council                                                   All Rights reserved. Reproduction is strictly prohibited
       Knowledge Required to Program
       Buffer Overflow Exploits
    1. C functions and the stack
    2. A little knowledge of assembly/machine language
    3. How system calls are made (at the machine code level)
    4. exec( ) system calls
    5. How to guess some key parameters
                                                                      Copyright © by EC-Council
EC-Council                                  All Rights reserved. Reproduction is strictly prohibited
       Types of Buffer Overflows
     ~       Stack-based Buffer Overflow
     ~       Heap/BSS-based Buffer Overflow
                                                                     Copyright © by EC-Council
EC-Council                                 All Rights reserved. Reproduction is strictly prohibited
        Stack-based Buffer Overflow
    ~   Buffer is expecting a maximum number of guests
    ~   Send the buffer more than x guests
    ~   If the system does not perform boundary checks, extra guests
        continue to be placed at positions beyond the legitimate locations
        within the buffer. (Java does not permit to run off the end of an array
        or string as C and C++ do)
    ~   Malicious code can be pushed on the stack
    ~   The overflow can overwrite the return pointer so that the flow of
        control switches to the malicious code
                                                                                 Copyright © by EC-Council
EC-Council                                             All Rights reserved. Reproduction is strictly prohibited
       Understanding Assembly Language
     The two most important operations in a stack:
             • 1. Push – put one item on the top of the stack
             • 2. Pop – "remove" one item from the top of the stack
             • Typically, returns the contents pointed to by a pointer and
               changes the pointer (not the memory contents)
                                                                                   Copyright © by EC-Council
EC-Council                                               All Rights reserved. Reproduction is strictly prohibited
         Understanding Stacks
     ~   The stack is a (LIFO)
         mechanism that computers
         use both to pass arguments to
         functions and to reference                                                                    SP
                                                                                                       points
         local variables                      BP
                                                                                                       here
                                              anywhere
     ~   It acts like a buffer, holding all   within the
                                              stack
         of the information that the          frame
         function needs
     ~   The stack is created at the                                                            Stack
                                                                                                growth
         beginning of a function and                                                            direction
         released at the end of it
                                                                                     Copyright © by EC-Council
EC-Council                                                 All Rights reserved. Reproduction is strictly prohibited
       A Normal Stack
                                                  Copyright © by EC-Council
EC-Council              All Rights reserved. Reproduction is strictly prohibited
       Shellcode
     ~   Shellcode is a method used to exploit stack-based
         overflows
     ~   Shellcodes exploit computer bugs in how the stack is
         handled
     ~   Buffers are soft targets for attackers as they overflow
         very easily if the conditions match
     "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"
       "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"
       "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\xaa\x10\x3f\xff"
       "\x91\xd5\x60\x01\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd5\x60\x01"
                                                                                         Copyright © by EC-Council
EC-Council                                                     All Rights reserved. Reproduction is strictly prohibited
        Heap-based Buffer Overflow
    ~   Variables that are dynamically allocated with functions,
        such as malloc(), are created on the heap
    ~   Heap is a memory that is dynamically allocated. It is
        different from the memory that is allocated for stack and
        code
    ~   In a heap-based buffer overflow attack, an attacker
        overflows a buffer that is placed on the lower part of
        heap, overwriting other dynamic variables, which can
        have unexpected and unwanted effects
                                                                        Copyright © by EC-Council
EC-Council                                    All Rights reserved. Reproduction is strictly prohibited
       How to Detect Buffer Overflows in a
       Program
   There are two ways to detect buffer overflows:
        • One way is to look at the source code. In this case, the hacker can
             look for strings declared as local variables in functions or methods
             and verify the presence of boundary checks. It is also necessary to
             check for improper use of standard functions, especially those
             related to strings and input/output
        • Another way is to feed the application with huge amounts of data
             and check for abnormal behavior
                                                                                   Copyright © by EC-Council
EC-Council                                               All Rights reserved. Reproduction is strictly prohibited
        Attacking a Real Program
    ~   Assuming that a string function is being exploited, the attacker can
        send a long string as the input
    ~   This string overflows the buffer and causes a segmentation error
    ~   The return pointer of the function is overwritten, and the attacker
        succeeds in altering the flow of execution
    ~   If he has to insert his code in the input, he has to:
         • Know the exact address on the stack
         • Know the size of the stack
         • Make the return pointer point to his code for execution
                                                                                    Copyright © by EC-Council
EC-Council                                                All Rights reserved. Reproduction is strictly prohibited
         NOPS
     ~   Most CPUs have a No           ~   Attacker pads the beginning of the
                                           intended buffer overflow with a
         Operation (NOP)
                                           long run of NOP instructions (a
         instruction – it does             NOP slide or sled) so the CPU will
         nothing but advance the           do nothing until it gets to the 'main
         instruction pointer               event' (which preceded the 'return
                                           pointer')
     ~   Usually, we can put some of
                                       ~   Most intrusion detection systems
         these ahead of our program        (IDSs) look for signatures of NOP
         (in the string)                   sleds. ADMutate (by K2) accepts a
                                           buffer overflow exploit as input
     ~   As long as the new return         and randomly creates a
         address points to a NOP,          functionally equivalent version
         we are OK                         (polymorphism)
                                                                                 Copyright © by EC-Council
EC-Council                                             All Rights reserved. Reproduction is strictly prohibited
       How to Mutate a Buffer Overflow
       Exploit
    For the NOP portion
        Randomly replace the NOPs with functionally equivalent segments of
        code (e.g.: x++; x-; ? NOP NOP)
    For the "main event"
        Apply XOR to combine code with a random key unintelligible to IDS.
        The CPU code must also decode the gibberish in time in order to run
        the decoder. By itself, the decoder is polymorphic and, therefore,
        hard to spot
    For the "return pointer"
        Randomly tweak LSB of pointer to land in the NOP-zone
                                                                                 Copyright © by EC-Council
EC-Council                                             All Rights reserved. Reproduction is strictly prohibited
       Once the Stack is Smashed...
    Once the vulnerable process is commandeered, the attacker has the
      same privileges as the process and can gain normal access. He can
      then exploit a local buffer overflow vulnerability to gain super-user
      access
    Create a backdoor
        Using (UNIX-specific) inetd
        Using Trivial FTP (TFTP) included with Windows 2000 and some
        UNIX flavors
    Use Netcat to make raw, interactive connections
         Shoot back an Xterminal connection
         UNIX-specific GUI
                                                                                Copyright © by EC-Council
EC-Council                                            All Rights reserved. Reproduction is strictly prohibited
        Defense Against Buffer Overflows
    ~        Manual auditing of code
    ~        Disabling stack execution
    ~        Safer C library support
    ~        Compiler techniques
                                                                   Copyright © by EC-Council
EC-Council                               All Rights reserved. Reproduction is strictly prohibited
       Tool to Defend Buffer Overflow:
       Return Address Defender (RAD)
     ~       RAD is a simple patch for the compiler that
         automatically creates a safe area to store a copy of
         return addresses
     ~   After that, RAD automatically adds protection code into
         applications that it compiles to defend programs against
         buffer overflow attacks
     ~       RAD does not change the stack layout
                                                                           Copyright © by EC-Council
EC-Council                                       All Rights reserved. Reproduction is strictly prohibited
         Tool to Defend Buffer Overflow:
         StackGuard
     ~   StackGuard: Protects systems from stack smashing attacks
     ~   StackGuard is a compiler approach for defending programs and
         systems against "stack smashing" attacks
     ~   Programs that have been compiled with StackGuard are largely
         immune to stack smashing attacks
     ~   Protection requires no source code changes at all. When a
         vulnerability is exploited, StackGuard detects the attack in progress,
         raises an intrusion alert, and halts the victim program
              http://www.cse.ogi.edu/DISC/projects/immunix/StackGuard/
                                                                                 Copyright © by EC-Council
EC-Council                                             All Rights reserved. Reproduction is strictly prohibited
       Tool to Defend Buffer Overflow:
       Immunix System
   ~   Immunix System is an Immunix-enabled RedHat Linux distribution
       and suite of application-level security tools
   ~   Immunix secures a Linux OS and applications
   ~   Immunix works by hardening existing software components and
       platforms so that attempts to exploit security vulnerabilities will fail
       safe. That is, the compromised process halts instead of giving control to
       the attacker, and then is restarted
                               http://immunix.org
                                                                                  Copyright © by EC-Council
EC-Council                                              All Rights reserved. Reproduction is strictly prohibited
       Vulnerability Search – ICAT
                                                         Copyright © by EC-Council
EC-Council                     All Rights reserved. Reproduction is strictly prohibited
        Simple Buffer Overflow in C
   ~   Vulnerable C Program overrun.c
   #include <stdio.h>
   main() {
       char *name;
       char *dangerous_system_command;
       name = (char *) malloc(10);
       dangerous_system_command = (char *) malloc(128);
       printf("Address of name is %d\n", name);
       printf("Address of command is %d\n", dangerous_system_command);
       sprintf(dangerous_system_command, "echo %s", "Hello world!");
       printf("What's your name?");
       gets(name);
       system(dangerous_system_command);
   }
                                                                            Copyright © by EC-Council
EC-Council                                        All Rights reserved. Reproduction is strictly prohibited
         Code Analysis
     ~   The first thing the program does is declare two string variables and
         assign memory to them
     ~   The "name" variable is given 10 bytes of memory (which will allow
         it to hold a 10-character string)
     ~   The "dangerous_system_command" variable is given 128
         bytes
     ~   You have to understand that, in C, the memory chunks given to
         these variables will be located directly next to each other in the
         virtual memory space given to the program
                                                                                  Copyright © by EC-Council
EC-Council                                              All Rights reserved. Reproduction is strictly prohibited
       Code Analysis (cont’d)
      ~ To compile the overrun.c program
      ~ Run this command in Linux:
             • gcc overrun.c –o overrun
                                                                    Copyright © by EC-Council
EC-Council                                All Rights reserved. Reproduction is strictly prohibited
       Code Analysis (cont’d)
      [XX]$ ./overrun
      Address of name is 134518696
      Address of command is 134518712
      What's your name?xmen
      Hello world!
      [XX]$
      ~      The address given to the "dangerous_system_command"
             variable is 16 bytes from the start of the "name" variable
      ~      The extra 6 bytes are overhead used by the "malloc" system call to
             allow the memory to be returned to general usage when it is freed
                                                                                    Copyright © by EC-Council
EC-Council                                                All Rights reserved. Reproduction is strictly prohibited
       Code Analysis (cont’d)
     ~   The "gets", which reads a string from standard input to the
         specified memory location, does not have a "length" specification
     ~   This means it will read as many characters as it takes to get to the
         end of the line, even if it overruns the end of the memory allocated
     ~   Knowing this, a hacker can overrun the "name" memory into the
         "dangerous_system_command" memory, and run whatever
         command he wishes
                                                                                 Copyright © by EC-Council
EC-Council                                             All Rights reserved. Reproduction is strictly prohibited
       Code Analysis (cont’d)
         [XX]$ ./overrun
         Address of name is 134518696
         Address of command is 134518712
         What's your name?0123456789123456cat /etc/passwd
         root:x:0:0:root:/root:/bin/bash
         bin:x:1:1:bin:/bin:
         daemon:x:2:2:daemon:/sbin:
         adm:x:3:4:adm:/var/adm:
         lp:x:4:7:lp:/var/spool/lpd:
         sync:x:5:0:sync:/sbin:/bin/sync
         shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
         halt:x:7:0:halt:/sbin:/sbin/halt
         mail:x:8:12:mail:/var/spool/mail
                                                                            Copyright © by EC-Council
EC-Council                                        All Rights reserved. Reproduction is strictly prohibited
       What happened Next?
  Since the project was running behind schedule, he had to
  hurry through testing.
  Tim had worked with the same team for his previous
  projects, and all of the other projects had successful
  conclusions. Therefore, he thought that nothing would
  possibly go wrong with this one. This notion made him
  overconfident about the testing of this project.
  But this time, he was not lucky. The web server of the
  client company had succumbed to a buffer overflow
  attack. This was due to a flaw in coding because bounds
  were not checked.
  Is Tim's decision justified?
                                                                                       Copyright © by EC-Council
EC-Council                                                   All Rights reserved. Reproduction is strictly prohibited
        Summary
    ~   A buffer overflow occurs when a program or process tries to store more data in a buffer
        (temporary data storage area) than it was intended to hold
    ~   Buffer overflow attacks depend on: the lack of boundary testing, and a machine that
        can execute code that resides in the data/stack segment
    ~   Buffer overflow vulnerability can be detected by skilled auditing of the code as well as
        boundary testing
    ~   Once the stack is smashed, the attacker can deploy his payload and take control of the
        attacked system
    ~   Countermeasures include checking the code, disabling stack execution, safer C library
        support, and using safer compiler techniques
    ~   Tools like stackguard, Immunix, and vulnerability scanners help in securing systems
                                                                                             Copyright © by EC-Council
EC-Council                                                         All Rights reserved. Reproduction is strictly prohibited
                                       Copyright © by EC-Council
EC-Council   All Rights reserved. Reproduction is strictly prohibited
                                       Copyright © by EC-Council
EC-Council   All Rights reserved. Reproduction is strictly prohibited