緩衝區溢位是最常見的軟體弱點之一。駭客透過精心構造的輸入覆寫堆疊上的返回位址,劫持程式執行流程,進而控制進程、電腦甚至整個網域。歷年著名蠕蟲病毒 (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); // 溢位破壞堆疊
| 版本 | 編譯器 | 保護機制 |
|---|---|---|
| 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 等關鍵資料。

/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;
}
/GS 屬軟體強制 DEP。現代 CPU (支援 NX/XD 位元) 可標記記憶體頁為不可執行,硬體阻止資料區程式碼執行。Windows XP SP2、Server 2003 起支援。多層防禦 (編譯器 /GS + 硬體 DEP + ASLR) 才能有效降低風險。
/GS 只是防禦深度的一環,無法根除所有溢位風險。但成本極低、相容性佳,配合安全編碼規範 (使用 strcpy_s, StringCchCopy 等安全函式)、最小權限原則、硬體 DEP,可大幅提升應用程式安全性。所有 C/C++ 專案建議預設開啟 /GS。