Black Hat USA 2000 - Compromising Web Servers, and Defensive Techniques
三句話摘要
深入淺出講解緩衝區溢位漏洞:從原理認識到遠端程式碼執行的完整利用過程。 緩衝區溢位透過精準控制記憶體覆蓋與返回位址劫持,將程式設計疏失轉化為完整的遠端程式碼執行權限——安全防護必須同時抓住源頭(安全的 C 函式如 strncpy)、執行環境(ASLR、DEP 等現代防禦)與部署管理(及時修補、最小權限執行)。 1. 堆疊結構與返回位址的關鍵角色
重點整理
重點- 1
1. 堆疊結構與返回位址的關鍵角色
- 2
程式執行時,每個函式呼叫都會將返回位址壓入堆疊。當溢位發生時,攻擊者提供的資料會覆蓋這個返回位址,讓處理器在函式返回時跳到攻擊者指定的記憶體位置,而非原本預期的位置。
- 3
2. C 語言字串處理的危險性
- 4
`gets()`、`strcpy()` 和 `strcat()` 等函式不檢查緩衝區大小,是溢位的主要來源。相比之下,`fgets()`、`strncpy()` 和 `strncat()` 允許指定複製位元組數,提供了更安全的替代方案。
- 5
3. 漏洞利用的關鍵技術:返回導向程式設計
- 6
找到記憶體中的「跳轉到 ESP」或「呼叫 ESP」指令,用其位址覆蓋返回位址,程式執行完後會跳回攻擊者的緩衝區執行植入的機械碼。
- 7
4. 隱藏執行意圖避開伺服器防護
- 8
某些 Web 伺服器(如 IIS)會對異常請求發出 500 錯誤,故攻擊者需對命令逐字元加 1 後發送,攻擊碼內再減 1 還原,並用特殊雙字(dword)分隔不同段落。
實用技巧與重點
乾貨- 關鍵數字與規格
- 32 位元程式位址空間:0 到 FF FF FF FF(4 GB)
- 實驗用緩衝區:100 位元組
- 溢位字串長度測試:超過 100 字元
- 返回位址覆蓋偏移量:300 位元組
- Kernel32.dll 基底位址(NT4):77F 00000
- 利用目標案例
- 系統:Oracle 應用伺服器搭配 Oracle WebListener、Apache、IIS 或 Netscape Enterprise Server
- 漏洞程式:oasetconf.exe
- 觸發方式:`GET /?-L <long_string> -S HTTP/1.1`
- 虛擬目錄:`/OWS/bin`(對應 C:\ORANT\OWS\4.0\bin)
- 函式位址(NT4 Service Pack 6A)
- GetCommandLineA:77F1A3F5
- WinExec:77F1A986
- ExitProcess:對應基底位址 + 偏移量
- 組件與工具
- 反組譯工具:UltraEdit(二進位編輯、搜尋 FF D4 / FF 4)
- 偵錯器:Microsoft Visual C++ 內建偵錯器
- 查詢工具:Quick View(取得 DLL 基底位址)
- 特殊編碼值
- 特殊雙字標記:7A 7A 7A 7A(隱藏:FF FF FF FF 減 85 85 85 85)
- 命令結尾標記:58(大寫 X)
- SW HIDE 參數值:0(隱藏視窗)
結論
結論“緩衝區溢位透過精準控制記憶體覆蓋與返回位址劫持,將程式設計疏失轉化為完整的遠端程式碼執行權限——安全防護必須同時抓住源頭(安全的 C 函式如 strncpy)、執行環境(ASLR、DEP 等現代防禦)與部署管理(及時修補、最小權限執行)。”
完整解析
詳細緩衝區溢位是古老卻致命的安全漏洞,源於程式設計語言與作業系統如何管理記憶體。講者從基本概念開始:當程式執行時,作業系統分配 4 GB 的位址空間。其中堆疊是一個動態區域,儲存函式的局部變數與控制資訊。每當呼叫函式時,處理器會將呼叫下一行指令的位址(返回位址)壓入堆疊,待函式完成後,處理器從堆疊取出這個位址,跳回原執行點。
C 語言在字串處理上特別脆弱。`gets()` 函式會不斷複製資料直到遇到空字元,完全不檢查目標緩衝區大小。若攻擊者輸入 200 位元組的資料到 100 位元組的緩衝區,溢位的 100 位元組會覆蓋記憶體中相鄰的內容——包括返回位址。攻擊者藉此將返回位址替換為攻擊碼所在的記憶體位置,達成任意程式碼執行。
實務利用分七步進行。以 Oracle 應用伺服器的 oasetconf.exe 為例,這個在 `/OWS/bin` 目錄可匿名存取的可執行檔存在溢位漏洞。首先找到漏洞點,再透過測試(逐漸增加輸入長度)確定需要多少位元組才能覆蓋返回位址。講者的例子中,300 位元組的字串會導致存取衝突。接著,利用偵錯器檢視記憶體,透過 ESP(堆疊指標)暫存器找到攻擊者的緩衝區位置。
關鍵一步是在 Kernel32.dll 中尋找「跳轉到 ESP」指令(機械碼 FF D4)。講者用 UltraEdit 的二進位搜尋功能找到位址 77F32836,將其反向編碼後(因 x86 採小端序,FF 77 F3 28 36 反寫為 36 28 F3 77 FF)覆蓋返回位址。程式執行完後會跳到該指令,進而跳入攻擊者的 ESP 指向的緩衝區。
攻擊碼用組合語言編寫,調用 GetCommandLineA 找到命令列,透過特殊標記(7A 7A 7A 7A 偽造法)掃描命令列,定位要執行的命令。為躲過 IIS 的異常檢查,攻擊者將命令的每個字元加 1,攻擊碼內再減 1 還原。最後呼叫 WinExec 執行命令,結束時呼叫 ExitProcess 避免存取衝突。
整個過程需要將彙編碼轉為機械碼。講者在 Visual C++ 內編譯彙編函式,逐步執行(F11)檢視每行指令的機械碼,手工提取成 16 進位串。如 `add EAX, 1` 的機械碼是 `83 C0 01`。最後將所有機械碼片段按順序拼接,加上緩衝區填充和返回位址覆蓋值,構成完整的溢位字串發送到目標伺服器。
實驗驗證顯示,攻擊可成功觸發記事本(notepad.exe)啟動,並執行 `net user` 列出帳號、建立檔案等管理命令——前提是 Web 伺服器進程有足夠權限。講者也強調,Oracle 後已發佈修補,可從 technet.oracle.com 取得;另外服務包版本會影響 DLL 基底位址,攻擊者可透過探測(如測試 Service Pack 6A 特有的目錄)識別目標環境並適配攻擊碼。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

