原文:exploiting format string vulnerabilities格式化函式是一類特殊的 ansi c 函式,接受可變數量的引數,其中的乙個就是所謂的格式化字串。當函式求解格式化字串時,它會訪問向函式提供的額外引數。它是乙個轉換函式,用於將原始的 c 資料型別表示為人類可讀的字串形式。它們在幾乎任何 c 程式中都會使用,來輸出資訊、列印錯誤資訊或處理字串。譯者:飛龍
日期:2001.9.1
版本:v1.2
這一章中,我們會涵蓋格式化函式使用中的典型漏洞,正確用法,它們的一些引數,以及格式化字串漏洞的一般概念。
如果攻擊者能夠向 ansi c 格式化函式提供字串,無論部分還是全部,就出現了格式化字串漏洞。由此,格式化函式的行為會改變,並且攻擊者就可能控制目標應用。
在下面的例子中,字串user
由攻擊者提供 – 他可以控制整個 asciiz 字串,例如通過使用命令列引數。
錯誤用法:
int func (char *user)
正確用法:
int func (char *user)
ansi c 規範中定義了大量格式化函式。有一些基本的格式化函式,複雜的函式基於它們,它們中的一些並不是標準的一部分,但是廣泛可用。
實際成員為:
近親:為了理解這個漏洞在 c 語言**的**,我們必須檢驗格式化函式的目的。
功能格式化函式工作原理
呼叫函式
需要知道它向棧中壓入了多少引數,因為它當格式化函式返回時需要清棧。
格式化字串是乙個 asciiz 字串,包含文字和格式化引數。
例如:
printf ("the magic number is: %d\n", 1911);
要列印的文字是the magic number is:
,後面是格式化引數%d
,它在輸出中會被引數1911
代替。所以輸出是這個樣子:he magic number is: 1911
。
一些格式化引數:
引數輸出
傳遞方式
%d
十進位制(int
)
傳值%u
無符號十進位制(unsigned int
)
傳值%x
十六進製制(unsigned int
)
傳值%s
字串((const) char*
)
傳址%n
目前為止寫入的位元組數(int *
)傳址
\
字元用於轉義特殊字元。它會被 c 編譯器在編譯使其替換,將轉義序列替換為二進位制中的適當字元。格式化函式並不會識別這些特殊的序列。實際上,它們並不對格式化字串做任何事情,但是有時會產生混淆,就像它們被編譯器求值一樣。
例如:
printf ("the magic number is: \x25d\n", 23);
上面的**可以工作,因為\x25
在編譯時期替換為%
,雖然0x25
(37)是百分號字元的 ascii 值。
格式化函式的行為由格式化字串控制。函式接受棧上的一些引數,它們由格式化字串請求。
printf ("number %d has no address, number %d has: %08x\n", i, a, &a);
從printf
來看,棧的樣子是:
其中:棧頂
+--------+
| ... |
| &a |
| a |
| i |
| a |
| ... |
+--------+
棧底
符號含義
a格式化字串的位址
i變數i
的值
a變數a
的值
&a變數a
的位址
格式化字串現在解析了格式化字串a
,一次讀取乙個字元。如果它不是%
,字元會複製到輸出中。否則,%
後面的字元規定了要求值的引數型別。字串%%
擁有特殊函式,用於列印轉義字元%
本身。其它每個引數都和資料相關,位於棧上。
格式化字串漏洞
在編寫程式時由於編寫的不規範有可能產生這個漏洞。下面乙個例子 includeint a 2 int main 編譯時使用 gcc test.c m32表示編譯成32位的程式上面這個例子便是乙個很簡單的格式化字串漏洞,產生格式化字串漏洞需要兩個條件 下面講解printf輸出的原理 eg name su...
格式化字串漏洞利用 七 工具
原文 exploiting format string vulnerabilities 譯者 飛龍 日期 2001.9.1 版本 v1.2 一旦利用完成,或者甚至在利用開發過程中,使用工具來獲取必要的偏移更加有用。一些工具也有主意識別漏洞,例如在閉源軟體中的格式化字串漏洞。我在這裡列出了四個工具,它...
格式化字串漏洞簡介
格式化字串,也是一種比較常見的漏洞型別。會觸發該漏洞的函式很有限。主要就是printf還有sprintf,fprintf等等c庫中print家族的函式。我們先來看看printf的函式宣告 int printf const char format,這個是每個學過c語言的人一定會知道 會使用的函式。先是...