<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            Buffer Overflow

            ABSTRACT

            該程序在分配的內存邊界之外寫入數據,這可能會損壞數據、引起程序崩潰或為惡意代碼的執行提供機會。

            EXPLANATION

            Buffer overflow 可能是人們最熟悉的一種軟件安全漏洞。雖然絕大多數軟件開發者都知道什么是 Buffer overflow 漏洞,但是無論是對繼承下來的或是新開發的應用程序來說,Buffer overflow 攻擊仍然是一種最常見的攻擊形式。對于這個問題出現的原因,一方面是造成 buffer overflow 漏洞的方式有很多種,另一方面是用于防止 buffer overflow 的技術也容易出錯。

            在一個典型的 buffer overflow 攻擊中,攻擊者將數據傳送到某個程序,程序會將這些數據儲存到一個較小的堆棧緩沖區內。結果,調用堆棧上的信息會被覆蓋,其中包括函數的返回指針。數據會被用來設置返回指針的值,這樣,當該函數返回時,函數的控制權便會轉移給包含在攻擊者數據中的惡意代碼。

            雖然這種類型的堆棧 buffer overflow 在某些平臺和開發組織中十分常見,但仍不乏存在其他各種類型的 buffer overflow,其中包括堆 buffer overflow 和 off-by-one 錯誤等。有關 buffer overflow 如何進行攻擊的詳細信息,許多優秀的著作都進行了相關介紹,如 Building Secure Software[1]、Writing Secure Code[2] 以及 The Shellcoder's Handbook[3]。

            在代碼層上,buffer overflow 漏洞通常會違反程序員的各種假設。C 和 C++ 中的很多內存處理函數都沒有執行邊界檢查,因而可以輕易地覆蓋緩沖區所操作的、已分配的邊界。即使是邊界函數(如 strncpy()),使用方式不正確也會引發漏洞。對內存的處理加之有關數據段大小和結構方面所存在種種錯誤假設,是導致大多數 buffer overflow 漏洞產生的根源。

            Buffer overflow 漏洞通常出現在以下代碼中:

            — 依靠外部的數據來控制行為的代碼。

            — 受數據屬性影響的代碼,該數據在代碼的臨接范圍之外執行。

            — 代碼過于復雜,以致于程序員無法準確預測它的行為。



            以下例子分別演示了上面三種情況。

            例 1:這是一個關于第二種情況的例子,代碼受未在本地校驗的數據屬性的影響。在本例中,名為 lccopy() 的函數將一個字符串作為其變量,然后返回一個堆分配字符串副本,并將該字符串的所有大寫字母轉化成了小寫字母。因為該函數認為 str 總是比 BUFSIZE 小,所以它不會對輸入執行任何邊界檢查。如果攻擊者避開對調用 lccopy() 代碼的檢查,或者如果更改代碼,使得程序員對 str 長度的原有假設與實際不符,那么 lccopy() 就會通過無邊界調用 strcpy() 溢出 buf


            char *lccopy(const char *str) {
            char buf[BUFSIZE];
            char *p;

            strcpy(buf, str);
            for (p = buf; *p; p++) {
            if (isupper(*p)) {
            *p = tolower(*p);
            }
            }
            return strdup(buf);
            }


            例 2.a:以下示例代碼顯示了簡單的 buffer overflow,它通常由第一種情況所導致,即依靠外部數據來控制行為的代碼。該代碼使用 gets() 函數將一個任意大小的數據讀取到堆棧緩沖區中。因為沒有什么方法可以限制該函數讀取數據的量,所以代碼的安全性就依賴于用戶始終輸入比 BUFSIZE 少的字符數量。


            ...
            char buf[BUFSIZE];
            gets(buf);
            ...


            例 2.b:這一例子表明模仿 C++ 中 gets() 函數的不安全行為是如此的簡單,只要通過使用 >> 運算符將輸入讀取到 char[] 字符串中。


            ...
            char buf[BUFSIZE];
            cin >> (buf);
            ...


            例 3:雖然本例中的代碼也是依賴于用戶輸入來控制代碼行為,但是它通過使用邊界內存復制函數 memcpy() 增加了一個間接級。該函數接受一個目標緩沖區、一個起始緩沖區和要復制的字節數。雖然輸入緩沖區由 read() 的邊界調用填充,但是 memcpy() 復制的字節數需要由用戶指定。


            ...
            char buf[64], in[MAX_SIZE];
            printf("Enter buffer contents:\n");
            read(0, in, MAX_SIZE-1);
            printf("Bytes to copy:\n");
            scanf("%d", &bytes);
            memcpy(buf, in, bytes);
            ...


            注:該類型的 buffer overflow 漏洞(程序可讀取數據,然后對剩余數據隨后進行的內存操作中的一個數值給予信任)已在圖像、音頻和其他的文件處理庫中頻繁地出現。

            例 4:以下代碼演示了第三種情況,代碼過于復雜,以致于程序員無法準確預測它的行為。本代碼來自于常用的 libPNG 圖象解碼器,這種解碼器被廣泛應用于許多應用程序中,包括 Mozilla 和某些 Internet Explorer 版本。

            該代碼似乎可以安全地執行邊界檢查,因為它檢測變量長度的大小,該變量長度會在之后用來控制 png_crc_read() 復制的數據量。然而,在測試長度前,該代碼會立即對 png_ptr->mode 執行檢查,如果檢查失敗,便會發出一個警告,然后會繼續進行處理。因為 length 測試在 else if 模塊中進行,如果針對該代碼的首次測試失敗,那么就不會再測試 length 了,而將其盲目地用于調用 png_crc_read(),因此很容易引起堆棧 buffer overflow。

            雖然本例中的代碼不是我們所遇見的代碼中最復雜的,但是它足以說明為什么要盡可能地降低執行內存操作代碼的復雜度。


            if (!(png_ptr->mode & PNG_HAVE_PLTE)) {
            /* Should be an error, but we can cope with it */
            png_warning(png_ptr, "Missing PLTE before tRNS");
            }
            else if (length > (png_uint_32)png_ptr->num_palette) {
            png_warning(png_ptr, "Incorrect tRNS chunk length");
            png_crc_finish(png_ptr, length);
            return;
            }
            ...
            png_crc_read(png_ptr, readbuf, (png_size_t)length);


            例 5:本例同樣演示了第三種情況,程序過于復雜,使其暴露出 buffer overflow 的問題。在這種情況下,問題出現的原因在于其中某個函數的接口不明確,而不是代碼結構(同上一個例子中描述的情況一樣)。

            getUserInfo() 函數采用一個定義為多字節字符串的用戶名和一個指向用戶信息結構的指針,這一結構由該用戶的相關信息填充。因為 Windows authentication 中的用戶名使用 Unicode,所以 username 參數首先要從多字節字符串轉換成 Unicode 字符串。然后,這個函數便會錯誤地將 unicodeUser 的長度以字節形式而不是字符形式傳遞出去。因此,可能會將調用 MultiByteToWideChar() 補寫為 (UNLEN+1)*sizeof(WCHAR) 寬字符,或者
            (UNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR) 字節補寫為 unicodeUser 數組,而僅分配 (UNLEN+1)*sizeof(WCHAR) 字節。如果 username 字符串包含了多于 UNLEN 的字符,那么調用 MultiByteToWideChar() 將會溢出 unicodeUser 緩沖區。


            void getUserInfo(char *username, struct _USER_INFO_2 info){
            WCHAR unicodeUser[UNLEN+1];
            MultiByteToWideChar(CP_ACP, 0, username, -1,
            unicodeUser, sizeof(unicodeUser));
            NetUserGetInfo(NULL, unicodeUser, 2, (LPBYTE *)&info);
            }

            REFERENCES

            [1] Standards Mapping - OWASP Top 10 2004 - (OWASP 2004) A5 Buffer Overflow

            [2] Standards Mapping - Security Technical Implementation Guide Version 3 - (STIG 3) APP3510 CAT I, APP3590.1 CAT I

            [3] Standards Mapping - Security Technical Implementation Guide Version 3.4 - (STIG 3.4) APP3510 CAT I, APP3590.1 CAT I

            [4] Standards Mapping - Web Application Security Consortium 24 + 2 - (WASC 24 + 2) Buffer Overflow

            [5] J. Viega, G. McGraw Building Secure Software Addison-Wesley

            [6] Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 787, CWE ID 120, CWE ID 129, CWE ID 131

            [7] Standards Mapping - Payment Card Industry Data Security Standard Version 1.2 - (PCI 1.2) Requirement 6.3.1.1

            [8] Standards Mapping - Payment Card Industry Data Security Standard Version 2.0 - (PCI 2.0) Requirement 6.5.2

            [9] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 - (PCI 1.1) Requirement 6.5.5

            [10] Standards Mapping - SANS Top 25 2009 - (SANS 2009) Risky Resource Management - CWE ID 119

            [11] Standards Mapping - SANS Top 25 2010 - (SANS 2010) Risky Resource Management - CWE ID 120, Risky Resource Management - CWE ID 129, Risky Resource Management - CWE ID 131

            [12] Standards Mapping - SANS Top 25 2011 - (SANS Top 25 2011) Risky Resource Management - CWE ID 120, Risky Resource Management - CWE ID 131

            [13] J. Koziol et al. The Shellcoder's Handbook:Discovering and Exploiting Security Holes John Wiley & Sons

            [14] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press


            Copyright 2013 Fortify Software - All rights reserved.
            (Generated from version 2013.1.1.0008 of the Fortify Secure Coding Rulepacks)
            desc.internal.cpp.buffer_overflow

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线