Buffer overflow - ianchen0119/About-Security GitHub Wiki
#include <stdio.h>
int main(){
char buffer[8];
gets(buffer)
puts(buffer)
return 0;
}
+-----------+
| ... |
+-----------+
| 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
比起沒有保護機制的 gets
, read()
能夠指定最大輸入長度,有效的避免了 bufferoverflow 的潛在疑慮。
ssize_t read(int fd, void *buf, size_t count);
注意! 最大輸入長度必須小於或等於 buffer 的大小。
一般來說,函式的區域變數也會存放在 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
?