Buffer overflow - ianchen0119/About-Security GitHub Wiki

Example code

#include <stdio.h>
int main(){
  char buffer[8];
  gets(buffer)
  puts(buffer)
  return 0;
}

Stack Canary 保護機制

+-----------+
|   ...     |
+-----------+
|  buffer   |
+-----------+
|   ...     |
+-----------+
|  Canary   |
+-----------+
| Saved rbp |
+-----------+
| ret addr  |
+-----------+

在 buffer 的下方放置隨機字串,避免 overflow 時損壞重要的資料。 此外, Stack Canary 會在程式 return 之前檢查該隨機字串的內容是否有變,如果變動了就代表有 bufferoverflow 的問題,此時該程式就會 abort 。 如果要關閉 Canary ,需要在編譯時加入 -fno-stack-protector

gcc -fno-stack-protector -o test main.c

改用 read()

比起沒有保護機制的 getsread() 能夠指定最大輸入長度,有效的避免了 bufferoverflow 的潛在疑慮。

 ssize_t read(int fd, void *buf, size_t count);

注意! 最大輸入長度必須小於或等於 buffer 的大小。

bof 能幹嘛?

一般來說,函式的區域變數也會存放在 Stack 中,透過 bof 我們就可以修改 local variables 的數值。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int a = 8;
  char buffer[8];
  gets(buffer);
  if(a == 3){
    system("/bin/sh");
  }
  return 0;
}

程式運作時, Stack 會長成這樣:

+-----------+
|   buffer  |
+-----------+
|   ...     |
+-----------+
|  a == 8   |
+-----------+
|   ...     |
+-----------+
| Saved rbp |
+-----------+
| ret addr  |
+-----------+

如果我們輸入一堆 a ,那 Stack 會變成:

+-----------+
| aaaaaaaa  | <- buffer
+-----------+
| aaaaaaaa  |
+-----------+
| aaaaaaaa  | <- a == 0x6161616161616161
+-----------+
| aaaaaaaa  |
+-----------+
| Saved rbp |
+-----------+
| ret addr  |
+-----------+

如果我們要將 a 改成 3 ,我們需要覆蓋 16 個 a ,接著我們就能將 0x3 寫進 a 變數中。

  • usage: r2 <執行檔>
  • install:
git clone https://github.com/radare/radare2.git
cd radare2
sys/install.sh
  • 分析 越多 a ,分析越深。
aa
aaa
aaaa
  • 列出已分析的 Function list
afl
  • 移動到指定位址
s {address}
s {function_name}
  • help
?

看更多

⚠️ **GitHub.com Fallback** ⚠️