[Intro. to Computer Security Course Note] Ch 10

Ch10. Buffer Overflow

Buffer overrun
Buffer overwrite


Buffer overflow basics

  • Programming error: a process attempts to store data beyond the limits of a fixed sized buffer

Needs for the Attacker: Exploiting a Buffer Overflow

  • To identify a buffer overflow vulnerability in some program
  • To understand how that buffer will be stored in the process memory

How to Identify Vulnerable Programs

  • Inspecting the program source
  • Tracing the execution of programs as they process oversized input
  • Using tools to automatically identity potentially vulnerable programs

Why Programs are not Necessarily Protected

  • Basic machine level
    • Data’s interpretation: entirely determined by the function of the instructions
    • Responsibility on the assembly language programmer: ensuring that the correct interpretation is placed on any saved value
  • Assembly language programs
    • The greatest access to the resources
  • Modern high-level programming languages (e.g., Java, Python)
    • Not vulnerable to buffer overflows: flexibility and safety
      • More data to be saved are not allowed
    • Costs in resource use
    • Limiting the usefulness in writing code
  • Between these two extremes: C and related languages
    • Have many modern high-level control structures and data type abstractions
    • But, allow direct access to low-level resources

Stack overflows

Stack Buffer Overflows

  • Also referred to as stack smashing

Some Common Unsafe C Standard Library

1
2
3
4
5
gets(char *str)
sprintf(char *str, char *format, ...)
strcat(char *dest, char *src)
strcpy(char *dest, char *src)
vsprintf(char *str, char *fmt, va_list ap)

Shellcode

  • Code supplied by the attacker
    • Often save in buffer being overflowed
    • Traditionally transferred control to a user command-line interpreter (shell)
  • Simply machine code
    • Specific to processor and operating system
  • Many sites and tools have been developed that automate this process

Defending against buffer overflows

  • Two broad defense approaches
    • Compile-time defenses
      • Aim to detect harden programs to resist attacks in new programs
      • Choice of programming languages
        • Use modern high-level language
        • Pros: not vulnerable to buffer overflow (上面有提到)
        • Cons: Access to some low-level instructions and hardware resources is lost (上面有提到)
      • Safe coding techniques
        • C designers placed much more emphasis on space efficiency and performance considerations than on type safety
          • Assumed programmers would exercise due care in writing code
        • Programmers need to inspect the code and rewrite any unsafe coding
        • Codes not only for normal successful execution
          • But, constantly aware of how things might go wrong
      • Languages extensions and use of safe libraries
        • Handling dynamically allocated memory: more problematic
          • The size of info. is not available at compile time
        • Requiring an extension and the use of library routines
          • Cons:
            • Generally, there is a performance penalty
            • Programs and libraries need to be recompiled with the modified compiler
            • Feasible for new OSes, but likely to have problems with third-party apps
      • Stack protection mechanisms
        • Add function entry and exit code to check for signs of corruption
          • Stackguard: best known protection mechanism -> a GCC compiler extension
          • Function entry code: writing a canary value below the old frame pointer address
          • Function exit code: checking that the canary value has not changed
          • The canary value: unpredictable and different on different systems
          • Cons:
            • All programs needing protection need to be recompiled
            • The structure of the stack frame has changed: causing problems with programs, e.g., debuggers
          • Has been used to recompiled an entire Linux distribution
        • Another variants: Stackshield and Return Address Defender (RAD)
          • Also GCC extension: including additional function entry and exit code
          • Do not alter the structure of the stack frame
          • Function entry code: writing a copy of the return address to a safe region of memory
          • Function exit code: checking the return address in the stack frame against the save copy
          • Compatible with unmodified debuggers Why?
          • Programs must be recompiled
    • Run-time defenses
      • Aim to detect and abort attacks in existing programs
      • Can be deployed as OS updates to provide protection
        • Compile-time approaches: usually requires recompilation of existing programs
        • Involving changes to the memory management
      • Executable Address Space Protection
        • Block the execution of code on the stack
          • Against the attacks: copying machine code into the targeted buffer and then transferring execution to it
        • Tag pages of virtual memory as being nonexecutable
          • Requires support from memory management unit (MMU)
          • Long existed on SPARC used by Solaris
          • Recent addition of the no-execute bit in the x86 family
          • A standard feature in recent Oses
        • Cons:
          • Unable to support executable stack code
      • Address space randomization
        • Manipulate location of key data structure
          • Stack, heap, global data
          • Using random shift for each process
          • Large address range on modern systems: wasting some has negligible impact
        • Randomize location of heap buffers
        • Random location of standard library functions
      • Guard pages
        • Place guard pages between critical regions of memory
          • Flagged in MMU as illegal addresses
          • Any attempted access aborts process
        • Further extension places guard pages between stack frames and heap buffers
          • Cost in execution time to support the large number of page mappings necessary

Other forms of overflow attacks

Replacement stack frame

Return to system call

Heap overflows

  • Attack buffer located in heap
    • Typically located above program code
    • Memory is requested by programs to use in dynamic data structures (such as linked lists of records)
  • No return address
    • Hence no easy transfer of control
    • May have function pointers to be exploited
    • Or manipulate management data structure
  • Defenses
    • Making the heap non-executable
    • Randomizing the allocation

Global data area overflows

  • Attacks buffer located in global data

    • Aim to overwrite function pointer later called
  • Defenses

    • Non executable or random global data region
    • Move function pointers or use guard pages

Other types of overflows