Buffer Overflow

임승섭·2023년 6월 14일
0

Computer Systems

목록 보기
6/7

Address space layout

General Memory Layout

  • Stack
    • local variables
  • Heap
    • Dynamically allocated as needed
    • malloc(), calloc(), new, ...
  • Statically allocated Data
    • Read/Write : global variables (Static Data)
    • Read-only : string literals (Literals)
  • Code / Instructions
    • Executable machine instructions
    • Read-only

x86-64 Linux Memory Layout

  • Stack
    • local variables
  • Heap
    • Dynamically allocated as needed
    • malloc(), calloc(), new, ...
  • Statically allocated Data
    • Read/Write : global variables (Static Data)
    • Read-only : string literals (Literals)
  • Code / Instructions
    • Executable machine instructions
    • Read-only

Memory Allocation Example


Input buffers on the stack

What is a Buffer?

  • A buffer is an array used to temporarily store data
  • Buffers can also store user input

x86-64/Linux Stack Frame

  • Caller's Stack Frame
    • Arguments (if more than 6 args) for this call
  • Current / Callee Stack Frame
    • Return address (pushed by call instruction)
    • Old frame pointer (optional)
    • Caller-saved pushed before setting up arguments for a function call
    • Callee-saved pushed before using long-term registers
    • Local variables (if can't be kept in registers)
    • "Argument build" area
      (need to call a function with >6 arguments? Put them here)

Overflowing buffers and injecting code

Buffer Overflow in a Nutshell

  • C does NOT check array bounds
    • Many Unix/Linux/C functions don't check argument sizes
    • Allows overflowing (writing past the end) of buffers (arrays)
  • "Buffur Overflow" : Writing past the end of an array

example

  • Stack grows down towards lower addresses
  • Buffer grows up towards higher addresses
  • If we write past the end of the array,
    we overwrite data on the stack


  • Buffer overflows on the stack can overwrite "interesting" data
    • Attackers just choose the right inputs
  • Simplest form ("stack smashing")
    • Unchecked length on string input into bounded array causes overwriting of stack data
    • Try to change the return address of the current procedure
  • Why is this a big deal?
    • It was the #1 technical cause of security vulnerablities

String Library Code

  • gets()
    • No way to specify limit on number of characters to read
    • Similar problems with other Unix functions :
      • strcpy, scanf, fscanf, sscanf with %s specifier

Vulnerable Buffer Code

  • code & input

  • dissassmbly

  • Stack

    • Before call to gets

    • After call to gets
      • Example 1
      • Example 2

Malicious Use of Buffer Overflow
: Code Injection Attacks

  • Input string contains byte representation of executable code
  • Overwrite return address A with address of buffer B
  • When bar() executes ret, will jump to exploit code

Defense against buffer overflows

System-Level Protections

  • non-executable code segments
  • Works well, but can't always use it
  • Many embedded devices do not have this protection
  • Some exploits still work!
    • return-oriented programming
    • return to libc attack
    • JIT-spray attack

Avoid Overflow Vulnerablities in Code

  • Use library routines that limits string lengths
    • fgets instead gets
      (2nd argument to fgets sets limit)
    • strncpy instead strcpy
    • Don't use scanf with %s conversation specification
      • Use fgets to read the string
      • Use %ns where n is a suitable integer
  • Don't use C.
    Use a language that does array index bounds check
    • Buffer overflow is impossible in Java
    • Rust language was designed with security in mind

Stack Canaries

  • Basic Idea : place special value('canary') on stack just beyond the buffer
    • Secret value that is randomized before main()
    • Placed between buffer and return address
    • Check for corruption before exiting function
  • GCC implementation
    • -fstack -protector

Disassembled

setting up canary

checking canary

0개의 댓글