首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 利用 /GS 編譯器選項防禦緩衝區溢位攻擊

     編輯:VC 教學

緩衝區溢位威脅概述

緩衝區溢位是最常見的軟體弱點之一。駭客透過精心構造的輸入覆寫堆疊上的返回位址,劫持程式執行流程,進而控制進程、電腦甚至整個網域。歷年著名蠕蟲病毒 (Code Red、Blaster、Sasser) 均源於 C/C++ 緩衝區溢位。若受害進程以高權限 (如 Administrator、Local System) 執行,破壞力極大。

堆疊緩衝區溢位原理

函式呼叫時,返回位址存放於堆疊。若本地緩衝區被溢位覆寫,返回位址即被竄改。攻擊者可導向:

  • 已知位址的現有函式 (如 system, WinExec)。
  • 注入緩衝區中的殼碼。

簡單範例:

char* source = "A reasonably long string"; // 25 字元含結尾
char dest[10]; // 僅 10 位元組
strcpy(dest, source); // 溢位破壞堆疊

/GS 編譯器保護機制演進

版本編譯器保護機制
VC++ 7.0 (VS .NET 2002)引入 /GS在返回位址下方插入 Cookie (Canary),函式結束前驗證 Cookie 完整性,偵測堆疊破壞並拋出安全例外。
VC++ 7.1 (VS .NET 2003)強化 /GS將例外處理器指標等敏感結構移至緩衝區下方,防止繞過 Cookie 攻擊。連結器支援 /SAFESEH,驗證例外處理器有效性。
VC++ 8.0 (VS 2005)進一步強化針對函式指標參數,編譯器自動複製參數至本地變數區下方,防止參數被溢位竄改導致間接呼叫劫持。

堆疊佈局示意

堆疊邏輯佈局對比

堆疊由高位址向低位址增長。緩衝區溢位會向高位址覆寫,威脅返回位址、儲存框架指標、Cookie 等關鍵資料。

啟用 /GS 與 /SAFESEH

專案屬性設定 /GS

  • 專案屬性 → C/C++ → 程式碼產生 → 緩衝區安全性檢查 設為 是 (/GS)。
  • 預設:Debug 關閉,Release 開啟。
  • /SAFESEH:連結器選項,預設開啟。若需關閉,命令列指定 /SAFESEH:NO (IDE 無介面設定)。

安全例外處理範例

void _cdecl sec_handler(int code, void*)
{
    if (code == _SECERR_BUFFER_OVERRUN)
    {
        printf("偵測到緩衝區溢位!\n");
        exit(1);
    }
}

int main()
{
    _set_security_error_handler(sec_handler);
    // 主程式邏輯...
    return 0;
}

硬體層面的 DEP (Data Execution Prevention)

/GS 屬軟體強制 DEP。現代 CPU (支援 NX/XD 位元) 可標記記憶體頁為不可執行,硬體阻止資料區程式碼執行。Windows XP SP2、Server 2003 起支援。多層防禦 (編譯器 /GS + 硬體 DEP + ASLR) 才能有效降低風險。

結語

/GS 只是防禦深度的一環,無法根除所有溢位風險。但成本極低、相容性佳,配合安全編碼規範 (使用 strcpy_s, StringCchCopy 等安全函式)、最小權限原則、硬體 DEP,可大幅提升應用程式安全性。所有 C/C++ 專案建議預設開啟 /GS。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved