[IT-Security-2] 記憶體相關之漏洞 Buffer Overflows and other Memory Corruptions

Buffer Overflows and other Memory Corruptions


Notes from RWTH Aachen University course 
“IT security 2” Wintersemester 2019/20
professor: Meyer, Ulrike Michaela

:cactus: Buffer Overflow

  • :droplet: 定義
    • A condition at an interface under which more input can be placed into a buffer than the capacity allocated for it, overwriting other information. Attackers exploit such a condition to crash a system or to insert specially crafted code that allows them to gain control of the system.
  • C語言
    • 預設programmer要負責data integrity
    • compiler不做integrity檢查
    • 可能造成超過memory space的capacity
      buffer會overwriting接下來的資料
      • 多數情況會crash program
      • ping of death
  • 基本buffer overflow
    • Variable corruption
      • 利用過長的input data複寫其他data
    • Corruption of program control addresses
      • 以更改程式執行順序
    • 攻擊者必須:
      • identify overflow vulnerability
      • buffer要存什麼資料
      • 要怎麼corrupt memory allocation

:cactus: Executable Program Segments

DynamicStack segment
Heap segment
StaticBss segment
Data segment
Text segment
  • :droplet: Text segment

    • code,儲存machine language instructions
    • nonlinear執行
    • 當程式執行時,Extended Instruction Pointer (EIP) 設為text segment的第一個instruction
      1. 讀取指向的instruction
      2. Adds the byte length of the instruction to EIP
        增加instruction的byte長度給EIP
      3. 執行instruction
      4. 回到步驟1
    • 不允許write (不允許修改code)
  • :droplet: Data segment

    • 初始化過的global和static變數
    • writable
    • fixed size
  • :droplet: Bss segment

    • 非初始化過的counter
    • writable
    • fixed size
  • :droplet: Heap segment

    • programmer 可以直接控制的memory片段
    • 被allocator和deallocator algorithm控制
      • reserve region of memory
      • release reservation
  • :droplet: Stack segment

    • 在 function calls 暫時儲存的空間

    • stack frame儲存

      • 輸入變數 (passed variables)
      • 2 pointers:
        • Saved frame pointer (SFP):
          恢復Extended stack pointer,指向stack的尾端
        • return address (RET):
          恢復EIP,指向下個instruction
      • 區域變數 (local variable)
    • 在每個function call時產生

    • Stack Example

      void test_function(int a, int b, int c, int d) { int flag; char buffer[10]; flag = 31337; buffer[0] = 'A'; } int main(){ test_function(1,2,3,4); }
      Stack

      d
      c
      b
      a
      RET
      SFP
      flag
      buffer
  • :droplet: Memory exploits

    • Buffer 是指memory中的data storage area (stack or heap)
    • 若 executable code 被當作 data 提供,使用者可能被騙執行
      • pointer assignment
      • format strings
      • memory allocation/ de-allocation
      • function pointers
      • calls to library routines via offset tables
    • 若buffer塞了過多東西
      • 原:
        void func(char *str){ char buf[126]; strcpy(buf, str); }


      • Overflow:
        複寫鄰近的stack區塊

        複寫的區域會被認為是 return address

      • 攻擊者利用此 return address 執行自己的input
        eg. execve("/bin/sh")
      • 則攻擊者可以得到 shell
        若victim program是 setuid root 則可得到 root shell

:cactus: Different ways of executing attack code

:one: Attack

  1. :droplet: 使return address改成指向attack code
  2. :droplet: return-to-libc: 用現有的instructions
    eg. system()exec()

  • stack理論上只能存data但攻擊者存了executable code
  • buffer的RET必有correct address of attack code
    • 否則程式會crash
    • 攻擊者要正確猜到在buffer的哪個位置

:cactus: Shell Code

  • buffer overflow攻擊的最重要的部分
    • transfer of execution to code
  • 因shell code用來執行user command-line interpreter
  • Unix: execve("/bin/sh")
  • Windows: system("command.exe")
  • 通常針對不同的OS攻擊,因為指令不一樣
  • buffer overflow需要
    • 避免library calls(execve():question:
    • position independent, 只有相對位址
    • 不能有NULL,否則會被視為string的結尾

:cactus: Format string in C

  • 沒有check input size
    • strcpy
    • strcat
    • gets
    • scanf
    • printf
  • Range checking:
    • strncpy
      只有最多n個字被複製
    • strncat
      n*src才能被複製到*dest
    • 可能的overflow:
      strcpy(record, user);
      strcat(record,":");
      strcat(record, cpw);
      
    • “fix”:
      strncpy(record, user, MAX_STRING_LEN-1);
      strcat(record,":");
      strncat(record, cpw, MAX_STRING_LEN-1);
      

      record = record||":"||cpw
      問題: 只有MAX_STRING_LEN-1長度的record被allocated

:two: Attack

  • :droplet: 修改function pointer指向attack code
  • :droplet: 任何memory可以被此儲存值進pointer的statement修改


:cactus: Off-by-one Overflow

  • for (i=0; i<=512; i++)
    會copy 513個字元

    不能change RET,但可能change SFP to前一個stack frame

:three: Attack

  • Overflow Frame Pointer 以取代 stack frame
  • 修改原本的 frame pointer 成 attacker-controlled memory
  • 可以用 off-by-one overflow 達成
  • 但attacker必須猜到fake frame的address


:cactus: Heap Overflow

  • 可能修改 function pointer 指向重要的資料
    • illegitimate privilege elevation: 若 program 有 root 權限,則攻擊者可以存取權限較高的檔案
  • Heap:
Buf[256]vtableptr
  • Bufoverflow,則會蓋住vtable
  • ptr指向的vtable的位址會變成overflow的data (eg. shell code)

  • :droplet: Heap Spraying
    • 用 Javascript 和 shellcode spray heap
    • 並在spray area任意地方指向vtable pointer
    • 指向任意在heap中的 function pointer 會執行shellcode

Dynamic Memory Management in C

  • malloc(size_t n)
    • 分配 n bytes 並回傳一個指標
    • memory不是乾淨的
  • free(void *p)
    • 釋放 p 指標指向的memory space
  • 錯誤:
    • Initialization errors
    • Failing to check return values
    • writing to already freed memory
    • freeing the same memory more than once
    • improperly paired memory management functions (eg. malloc/delete)
    • Failure to distinguish scalars and arrays
    • improper use of allocation functions

    all result in exploitable vulnerabilities

Variable Arguments in C

  • printf 可以有可變的輸入數量
    • printf("hello, world");
    • printf("length of '%s' = %d", str, str.length());
  • 在執行時多了變數va_startva_argva_end
  • Format Strings
    • 正確的: printf("foo = %d", foo);
    • Sloppy use: char buf[123]="hello world; printf(buf);
      (正確用法: printf("%s", buf);)
      • 若buffer裡面有 % ,則原本的stack pointer會以為是argument
      • :japanese_goblin: attacker可以用來移動stack pointer
    • %n: 印出的字元數量
    • char buf[16] = "overflow this!%n";
      printf(buf);
      
    • stack pointer指向的位置會被譯為number of characters將要被寫入的位址


      printf("overflow this!%n", &myVar);
      %n 為將要被寫入的位址


    • RET會指向attack code
      printf(buffer)會寫入 attackString 的number of characters 到 RET 中

      C 有一簡單的方式print出多個 symbols: %Mx 會print出剛好 M bytes
      attackString有足夠多的%Mx,長度等於attack code的address的most significant byte,則此byte會被寫入&RET
      再執行3次 &RET+1,&RET+2,&RET+3會得到所有attack code的address
      RET複寫為attack code的address


:cactus: Preventing Buffer Overflows

  • :droplet: 分為兩類
    • :one: Compile time:
      • 選擇不允許buffer overflow的high level programming language
        • 有些library仍vulnerable
        • 無法直接取得hardware resources
      • safe coding
      • safe libraries
      • additional code to detect(eg. stackGuard)
  • :bird: StackGuard
    • 在stack frame加入一個 Canary ,在function return前檢查 Integrity
    • bufCanarySFPRET
      若 buf overflow 的話會改變 Canary
    • 兩種 canary:
      1. Random number
      2. termination symbol: \0EOF
        就不會被strcpy就不會繼續copy
    • 需要code recompilation
    • 每個function都要檢查會降低performance
    • 放在buf 和 pointer 旁邊更降低performance
    • 可以被攻擊
  • :penguin: 攻擊StackGuard
    • strcpy 複寫pointer,指向RET
    • strcpy 可以複寫而且避開 Canary
  • :statue_of_liberty: LibSafe
    • 動態載入的library
    • 攔截calls eg.strcpy
      • 檢查現在的stack frame有沒有足夠的空間
      • |frame-pointer – dest| > strlen(src)
  • :point_up: PointGuard
    • attack: overflow a function pointer以指向attack code
    • 在memory中 Encrypt all pointers
      • 執行時產生一 random key
      • XOR each pointer
      • 攻擊者不能預測
      • 即使此key被攻擊者複寫,XOR 後此key會被 dereference to a random address

      根據被攻擊過的key decrypt過後,會指向一random address
      因為修改的key不會是attack code address本身

       
    • :two: Run-time:
      • attack: 利用 Code Injectoin
        • data的部分被植入executable code
      • 目標:使 stack 和其他 data area Non-executable
      • 變成OS中的standard
      • 但攻擊者用更精巧的方式攻擊
    • Write not Execute 無法避免:
      • 只要 Saved EIP 指向已存在的code
        此保障就無法阻止control transfer
      • return-to-libc 的攻擊基礎
        • 複寫 Saved EIP 指向某 library routine
        • 編排 stack 看起來像 routine 的 argument
    • :table_tennis_paddle_and_ball: ASLR Address Space Randomization
      • attacker原本要預測targeted buffer的location
        預測 return address
      • 目標:隨機擺放stack location使得預測困難
      • 隨機擺放standard library routines
      • 用 malloc 跟把standard library routines放在heap

Readings
    § Chapter 9 in Andrew Tanenbaum’s “Modern Operating Systems”
    § Chapter 10 in Stallings and Brown “Computer Security” 
Additional Reading on Defenses

留言

這個網誌中的熱門文章