電腦安全-L11
Software Security Issues
- 許多漏洞是由不良的程式設計實務所造成的
- 程式中
對資料與錯誤代碼缺乏足夠的檢查/驗證,會導致各種後果- Unvalidated input
- Cross-site scripting
- Buffer overflow
- Injection flaws
- Improper error handling
- 分類:
- 元件之間的不安全互動
- SQL injection, cross-site scripting, open redirect
- 危險的資源管理
- classical buffer overflow, path traversal, download of code without integrity check
- 脆弱的防禦機制
- missing authentication for critical function, authorization, or encryption of sensitive data
- 元件之間的不安全互動
Software Security: Software Quality/Reliability?
Software Quality and Reliability- 關注程式的意外失敗
- 重點不只是 bug 數量,而是它多常被觸發
- 改善方式: 透過結構化設計與測試找出並消除 bug
Software Security- 攻擊者會專門尋找可被利用的 bug
- 透過與正常情況完全不同的輸入來觸發
- 不容易被一般測試方法發現
Defensive or Secure Programming
- 在設計與實作軟體時,讓系統即使遭受攻擊仍能持續運作的過程
- 能偵測因攻擊造成的錯誤狀況
- 安全地繼續執行,或優雅地失敗 (fail gracefully)
- Key rule:
永遠不要假設任何事情- 檢查所有假設,並處理所有可能的錯誤狀態
- 一般程式設計師:
- 注意力放在如何成功完成功能
- 只關注程式正常執行流程
- 但不會考慮所有可能失敗點
- 常常對輸入與環境做假設
- 注意力放在如何成功完成功能
Defensive Programming- 程式必須驗證所有假設
- 所有可能失敗都要安全且優雅地處理
- 會增加程式碼與開發時間:
Conflicts with business pressures Requiring a changed mindset to traditional programming practices(改變傳統程式設計思維)
Handling Program Input
- 錯誤的輸入處理是最常見的失敗原因之一
- 輸入是任何來自外部、且其值並非程式設計師明確知道的資料來源
- 必須辨識所有輸入資料來源
- 在使用前,必須明確驗證對資料大小與型別的假設
- 兩個主要關注點:
size與interpretation(解讀方式)
Input Size & Buffer Overflow
- 程式設計師常常會
假設輸入的最大長度- 沒有確認配置的 buffer 大小是否足夠
- 可能導致 buffer overflows
- 測試可能無法發現這種漏洞
- 測試輸入通常不會大到足以觸發 overflow
- 安全程式設計實務: 使用安全的字串與 buffer 複製函式
Safe coding regards any input as dangerous- 以不讓程式暴露於危險中的方式處理輸入
Interpretation of Program Input
- 程式輸入可能是 binary 或 textual
- binary: 取決於
encoding,而且通常是 app-specific 的
- binary: 取決於
- 若未進行驗證,可能導致可被利用的漏洞
- 越來越多不同的
character sets被使用 (ex: ASCII)- 必須小心辨識目前使用的是哪一個 set,以及實際讀取到的是哪些字元
Injection Attacks
- 當程式輸入資料可能意外地/故意地影響程式的執行流程時
- 最常見的情況: 輸入資料被當作參數傳遞給另一個輔助程式
- 常發生於使用
scripting languages(腳本語言) 時- ex: perl、PHP、python
- 應對方法: 驗證輸入只包含英文字母與數字
Cross-site Scripting (XSS) Attacks
某位使用者提供給程式的輸入,之後被輸出給另一位使用者- script code 可能需要存取與其他頁面相關的資料
- 假設: 來自同一網站的所有內容都同樣可信,因此被允許與該網站的其他內容互動
- 攻擊會利用這個假設,並試圖繞過瀏覽器的安全檢查
- 最常見於使用腳本的 Web 應用程式
- 涉及將 script code 包含在 Web 頁面的 HTML 內容中,並由使用者的瀏覽器顯示
- ex: JavaScript, ActiveX, VBScript, Flash
- 變種:
XSS Reflection- 考慮 guestbook (留言板) 程式的廣泛使用
- 允許存取網站的使用者留下留言,而這些留言之後會被其他使用者查看
- 預防方式: 任何由使用者提供的輸入都應該被檢查
Validating Input Syntax
- 在後續使用資料之前,必須確保資料符合對該資料所做的任何假設
- 輸入資料應該與真正想要的內容進行比較
- 只接受 valid input →
whitelisting
- 只接受 valid input →
- 將輸入資料與已知危險值進行比較
blacklisting
- 只接受已知安全的資料,可以讓程式更有可能維持安全
- 使用
regular expressions
- 使用
Validating Numeric Input
- 數值在內部是以固定大小儲存的
- 8, 16, 32, 64-bit integers
- floating point numbers 取決於所使用的處理器
- 32, 64, 96 bits
- Values may be signed or unsigned
- 必須正確解讀 text form 的數值
- 在比較 signed 與 unsigned 時會有問題
- 輸入作為 unsigned 時,可能被當成 signed value
- 可能被用來
thwart (繞過) buffer overflow 檢查- input size (unsigned): s=1xxxxxxx
- 被當成 signed: 負數 < max buffer size 通過檢查
Input Fuzzing
- 一種軟體測試技術: 使用
隨機產生的資料作為程式輸入 - 以非常低的成本產生大量測試
- 輸入可以是完全隨機產生的,或者依照某些模板隨機產生
- 使用模板:
- 優點: 提高找到漏洞的機率
- 缺點: 對輸入做出了假設;可能會遺漏某些問題
- 為了完整性,需要結合兩種方法
- 使用模板:
- 概念上非常簡單,但通常
只能識別較簡單類型的錯誤- 可能遺漏在極少數特定輸入值下才會被觸發的漏洞
Writing Safe Program Code
Key issues:
- 正確的演算法實作: 正確解決指定的問題
- 將演算法正確地轉換成機器指令
- 合法且正確地操作資料
Correct Algorithm Implementation
- 未正確實作問題的所有情況或變體
- 對程式輸入的不當解讀或處理
- 早期 Netscape Web 瀏覽器中的漏洞
隨機數產生器: 用於產生 session keys- 假設: 這些數字應該是不可預測的
- Bug:
seed 選擇不佳導致相對容易被預測 - Fix: 重新實作隨機數產生器
- TCP Session Spoof/Hijack Attack
- 欺騙伺服器接受 spoofed source address 的封包
- Bug:
initial sequence numbers 可預測- Sequence number: 封包的識別與驗證資訊
Hijack attack: 猜測 Sequence number,構造適當的 ACK 封包並送給伺服器Hijack variant- 等待某個已授權的外部使用者連線並登入伺服器
- 猜測正在使用的 sequence number,並 inject 具有偽造資訊的封包
DoS attack: 觸發伺服器送出 RST 封包,以終止該連線- Fix:
truly randomized產生初始 sequence numbers
- 程式設計師在程式中加入額外程式碼,以協助 test and debug
- 不適當地向程式使用者釋出資訊
- 允許使用者
繞過安全檢查 Morris Internet Worm利用 sendmail mail delivery program 中 DEBUG 指令的漏洞
- 中高階語言的 interpreter (直譯器)
未能充分反映語言語意: 造成漏洞- 早期 JVM 實作中的問題: 對遠端程式碼的安全檢查
- 允許攻擊者遠端注入程式碼,並欺騙 JVM 直譯器將其視為本地來源的程式碼
Correct Machine Instructions for Algorithm
- 大多數程式設計師通常會忽略這個問題
- 假設: 編譯器或直譯器會產生或執行能正確實作語言敘述的程式碼
- 惡意的編譯器開發者: 在編譯器中加入指令,使其
產生額外的程式碼 - 對策: 仔細
比較機器碼與原始碼- 緩慢且困難
Correct Data Interpretation
- 電腦中的所有資料都是以 groups of binary bits 儲存
- 這些資料會被解讀為: character, integer, floating-point number?
- 不同程式語言對於
限制與驗證資料 interpretation的能力有所不同Strong typing (強型別): 限制較多,但也較安全- 對資料採取較寬鬆的解讀方式: 允許程式碼明確地改變資料的解讀方式
- ex: C 語言
- 對系統層級程式設計具有顯著好處
- 可能造成許多錯誤
- 正確使用記憶體
dynamic memory storage (heap)的配置與管理問題- 用來操作未知大小的資料
- 在需要時配置,使用完成後釋放
Memory leak- heap 中可用記憶體會持續減少,直到完全耗盡
- DoS attack: 導致程式 crash
- 許多較舊的語言 (包括 C) 沒有對動態配置記憶體提供明確支援
- 容易發生問題
- 現代語言 (例如 Java 與 C++) 會自動處理這些問題
Preventing Race Conditions with Shared Memory
Race condition- 多個 processes 與 threads 競爭,以取得對某些資源的非受控存取
- 解決方式:
正確選擇並使用適當的同步機制(synchronization primitives) deadlock仍然可能是一個問題- 攻擊者可能觸發 deadlock,以發動 DoS
Interacting with the OS and Other Programs
- 一般而言,在大多數電腦系統上,程式並不是獨立執行的
- 多個使用者/程式
- 各種共享檔案與裝置
- 作業系統負責仲介對系統資源的存取
- 作業系統會在所有執行中的程式之間共享這些資源的使用
- 重要議題:
- Environment variables
- Using appropriate, least privileges
- Systems calls and standard library functions
- Preventing race conditions with shared system resources
- Safe temporary file use
- Interacting with other programs
System Calls and Standard Library Functions
- 程式會使用系統呼叫與標準函式庫函式來完成常見操作
- 程式的實際行為可能不如預期
對系統呼叫與標準函式庫函式的操作方式做出了錯誤假設- 可能是因為系統會
最佳化對共享資源的存取 - 為了最佳化系統使用,服務請求可能會被 buffered、重新排序,或以其他方式修改
- 這些最佳化可能與程式本身的目標互相衝突
Example
How to Securely Delete a File?
- 標準 file delete: simply removes the linkage between the file’s name and its contents (移除連結)
- 想要安全的移除檔案,避免又被讀取:
- 錯誤假設:
- System will write the new data to same disk blocks
- Data are written immediately to disk
- When the I/O buffers are flushed and the file is closed, the data are then written to disk
- 修正後:
- 改用
open file for update: 寫到相同 disk blocks - 增加
flush application write buffers: 馬上寫入 disk - 增加
sync file system write buffers with device: 將 file system 的資料與 device 同步
- 改用
Handling Program Output
- 程式輸出
- May be stored for future use, sent over net, displayed
- May be binary or text
- 必須
符合預期的格式與解讀方式 - 程式必須辨識哪些內容是允許的輸出
- 過濾任何可能不可信的資料,以確保只有合法輸出會被顯示
- 明確指定
Character set





