您有多脆弱? 軟件安全速成

 軟件安全性依然是熱點話題。每個人,從老祖母到全球 500 強公司都聽說過由互聯網上的病毒和攻擊者所引起的盜竊身份、丟失數據,及一般性的傷害的事。在 2008 年第一季度,所有報告的 1,474 個不同的軟件脆弱點只有 64 個被解決。1分辨率大約爲 4%。伴隨所有關於軟件和系統安全的議論,計算機世界似乎處於一片混亂中,這會讓許多人不禁問道:“我有多脆弱?”

在本文中,我將介紹一些伍斯特工業學院(Worcester Polytechnic Institute,WPI)近期的安全項目的成果,以及額外的研究。我的目的是通過闡明公共術語並且提供一些典型的安全性使用的現實實例來說明什麼是軟件安全性。

本文不打算提供全面的計算機安全教育,而是介紹一些遼闊且擴展的信息安全領域中的關鍵主題。如果您想要進一步討論,那麼請通過 [email protected] 聯繫我。

背景

我早期對計算機安全的興趣實際上激發了我對計算機科學的最初興趣,並且從那時起就一直是我關注的焦點。所以不用說,我有一點失望的是 WPI 沒有提供大學軟件或系統安全課程。在沒有任何正式的安全課程的情況下,我和其他兩個計算機科學的學生決定進行獨立研究,瞭解更多關於軟件安全的知識。今年的早些日子,我們和 WPI 計算機科學的教授 Kathryn Fisler 談論關於開始一個涉及軟件安全的獨立研究項目的事。我們計劃開設一門首先在 08-09 學年度進行的安全軟件工程的課程。衆所周知,CS4400x 將成爲 WPI 提供的第一門大學計算機科學安全課程。

在開設該課程的過程中,我們發現許多關於沒有在標準課程中提到的軟件脆弱性和預防的事實。我們發現大部分脆弱點通常由小的邏輯錯誤或軟件開發人員沒發現或解決的情況所引起。一些脆弱點不太複雜,因而很容易被黑客利用。可以通過一些簡單的資源就能找到它們,像 Web 瀏覽器和文本編輯器。在軟件開發團隊出錯的其他情況下,安全性的破壞可能由最終用戶不恰當地配置或使用軟件所致。

我們的結論是,最大的安全缺陷源於開發人員錯誤地假設安全問題將在系統的其他地方處理 —— 舉例來說,他們假設可以相信輸入的數據。經驗教訓:我們不得不認識到安全是每個人的職責,不是其他人的。





脆弱性 101

脆弱性是什麼?“利用”、“攻擊”、“脆弱點”,和其它術語一般用於描述什麼適當的軟件安全目的在於糾正:系統中允許黑客特權訪問信息或破壞系統的缺陷。Mitre Corporation 將脆弱性定義爲“系統或網絡中允許黑客以另一個用戶的身份執行命令,訪問他們不應該訪問的數據,冒充某人,及/或執行拒絕服務的狀態”。2根據此定義,脆弱就意味着處於一種狀態,在這種狀態下,黑客(人或惡意程序,像病毒或間諜軟件)可以訪問到比他們應該可以訪問的要多的系統的部分。

脆弱點出現的範圍很廣,從明顯的 —— 像使用不健壯的密碼或存儲無保護的私有數據 —— 到更有細微差異的 —— 像未檢查的輸入。

溢出攻擊

最早遭受破壞的,且仍舊普遍的攻擊來源於開發人員對最終用戶輸入的數據可以信任的假設。大部分程序設計人員未預料在用戶名框中得到 40,000 行文本,或者從密碼框中獲得甚至非鍵盤輸入的模糊字符,因此,所輸入的數據從不會被驗證無誤。這種假設增加了溢出攻擊。舉例來說,使用本文編輯器並瞭解一些 Microsoft PowerPoint 文件格式的知識,3人們就可以手工編寫 PowerPoint 文件。編輯 PowerPoint 文件4,讓內部字段中擁有比格式允許的更多的數據會導致 Microsoft PowerPoint XP 崩潰,然後執行任何黑客想要執行的程序。在一個這種脆弱性的熟悉的實例中,內嵌的 Windows 計算器程序被執行,然而,被執行的程序很容易是更惡意的。這只是無數的這類利用中的一個實例。

實質上,溢出類攻擊是由於將太多的數據放入原始程序設計人員認爲足夠的空間中導致的。額外的數據溢出到預期存儲區附近的內存中,並且覆蓋與該區域的原始用途無關的數據。當執行餘下的程序時,它使用新被覆蓋的數據。如果黑客能夠用僞數據(也就是,NOP)填充足夠的空間,然後添加一點惡意代碼或值,那麼程序將執行惡意代碼或使用新值。這可能導致許多不同的後果。黑客可能能夠越過登錄5,獲得程序的管理員特權。如果受攻擊的程序是由系統管理員啓動的,那麼惡意代碼將作爲原始程序的一部分進行執行,給黑客系統中的管理員特權。溢出脆弱點,儘管不總是出現,但在一些情況下,可能很容易被補救,當開發應用程序時利用“安全”庫6,使用堆棧保護7(也就是,StackGuard8)或對輸入數據進行檢查,從而確保其是適當的大小或類型。這一類的利用總是以類似的方式進行,但會根據受影響的內存類型和預期效果而不同。

緩衝區溢出攻擊

在緩衝區溢出攻擊的實例中,程序的內部值溢出,從而改變程序的運行方式。9在程序的正常操作過程中,當調用一個函數時,被調用函數的所有參數以及返回位置的指針都放在棧中。當完成該函數之後,使用返回指針回到原來的位置並繼續程序。利用緩衝區溢出進行攻擊可以改變這個過程,並且允許黑客執行任何他們期望的函數。 這是通過輸入足夠的數據來用僞數據覆蓋參數,及輸入到不同函數的新返回指針來實現的,現在就執行新的函數了。10

SQL 注入

除了溢出的利用以外,SQL 注入是另一類依賴於開發人員沒測試輸入數據的疏漏的攻擊。大多數人擁有字母數字式密碼,或者有安全意識的人,擁有附帶其他鍵盤符號的字母數字式密碼。由於這種想法,開發人員可能允許輸入任何字符作爲密碼。這通常是沒問題的,除非他們忘記清潔或檢查輸入數據。這種情況比應該的要發生的頻繁得多。使用 SQL 數據庫的密碼系統(在許多網站上非常普遍的場景)可能運行這樣的查詢:

SELECT * FROM users WHERE 'username' = '$USER' AND 'password'='$PASS';

$USER 和 $PASS 會用用戶提供的用戶名和密碼來代替。那麼如果用戶輸入‘bob’和‘1234’,那麼結果的查詢是:

SELECT * FROM users WHERE 'username' = 'bob' AND 'password' = '1234';

,而來自數據庫的返回值會是所有用 bob 作爲用戶名且用 1234 作爲密碼的數據元組。如果黑客輸入 admin 和 <<'hi' 或 1=1>>--,那麼查詢是:

SELECT * FROM users WHERE 'username' = 'admin' and `password` = 'hi' OR 1=1--'

注意用戶輸入的引號如何與原始查詢中的第三個引號匹配。數據庫現在會返回用戶名爲 admin 的所有元組,並且會取消對密碼的檢查,因爲 'password' = 'hi' OR 1=1 命令數據庫尋找密碼是 hi 的元組或 1=1 的元組,而由於 1 總是 1,所以每行都是候選。-- 是 SQL 註釋標誌,取消查詢中原始的其他引號,並且還將取消任何額外的檢查,因此如果有額外的憑證(也就是,keyfob11或 captcha12)也會被忽略。現在黑客可以以管理員的身份進入系統並且不用不得不給出合法的密碼。通過利用越來越複雜的查詢,黑客可以變更、添加,或查詢數據。13對於數據庫,這令黑客具有同應用程序相同的特權。

這種類型的脆弱點被證實是對 Web 應用程序最有效的攻擊類型之一,並且隨着對 Web 應用程序的信任的增加,這種利用的力量甚至將更令人畏縮。幸運的消息是,像溢出類型的攻擊一樣,可以通過清潔輸入數據,並且從不立即相信用戶輸入(至少對於輸入的數據)來防止大部分這種脆弱點。





散列攻擊

任何處理在數據庫中存儲用戶憑證的人都會告訴您,首要的規則之一是從不直接存儲沒有首先加密的密碼或其它私有數據。如果數據庫暴露了,那麼使用加密方案將防止暴露用戶的密碼。爲了更多的利益,利用單向加密算法或散列,像 MD514或 Blowfish,15將使密碼的解密成爲不可能。這是因爲散列可以將輸入值轉化爲新的值,而這些新值不能從數學上逆向生成原始值。傳統上,攻擊以這種方式存儲的密碼的方式涉及用儘可能多的不同的密碼進行嘗試直到最終有效,這被稱之爲“蠻幹”技術。雖然這種類型的攻擊十分簡單,但通常是無效的,因爲需要絕對的時間來嘗試足夠的組合,有時候要上千年,統計上是成功的,一般是理論的。

每天您可能都在使用散列攻擊工具,而甚至不知道它。Google 真的非常擅長它所做的:在信息之間找到鏈接。舉例來說,Googling “Bob Breznak”將取出所有關於我的信息:我爲The Rational Edge 寫的最近的書評,我的個人站點(及廢棄的)等等。現在,如果您從這裏借鑑一下,那麼您將得到快速返回結果的許多想法。應用該想法來尋找散列。舉例來說,利用“foobar”的 MD5 散列:3858f62230ac3c915f300c664312c63f。現在將其輸入 Google,瞧!0.21 秒內,第一個結果是“Google Hash: md5(foobar) = 3858f62230ac3c915f300c664312c63f”。您將找到的大部分結果都是哈希索引站點 —— 有意地連接散列值和其相應關鍵字的站點。嘗試更復雜的字符串(舉例來說,“bobby”、“crayon”、“rational”)將生成混合的結果。如果您嘗試複雜的密碼(或者最好是傳遞階段),您可能沒有收穫。

這可能不是您需要擔心的最大安全漏洞,但令其危險的是,這種利用不太知名,並且沒有簡單的補救辦法。隨着越來越複雜的關鍵字被匹配到散列上,匹配到已知密碼上的可能性增加了。變更爲更復雜的算法,比方說從 MD5 變更爲 SHA-2,16對恢復祕密的完整性沒什麼作用。這是因爲儘管從不同的散列中獲得同一個字符串的返回值,但是將關鍵字鏈接到散列上也只是時間的問題。雖然加密法總是將利用時間來蠻幹作爲安全網,搜索減少所需的時間,從而成功地從幾千年到幾年,甚至幾個月。

現在,存在着兩種主要的爭論,它們將散列查找從年度最大的安全缺陷的競爭列表中去掉了。這種類型的攻擊只可能在數據庫或密碼存儲已經暴露的情況下進行。需要讀取數據庫、影子文件(UNIX 或 LINUX 系統保存用戶密碼的地方),或 I/O 流。在某些情況下,這可能和達到正確的 URL 或執行 SQL 注入一樣簡單,而在其他情況下,它可能需要比黑客多得多的工作。減小這種攻擊的潛在嚴重性的另一個爭論實際上源於散列的使用。由於許多字符串可以生成相同的散列,所以不能必然地確定原始的字符串(用戶的真實密碼)。然而,找到任何散列到相同值得字符串能夠再次生成相同的散列值。這意味着儘管黑客可能沒有獲得實際的密碼,但是由於系統使用存儲的散列,而黑客擁有能生成同等散列的字符串,所以系統會像黑客擁有原始密碼那樣響應。





最終用戶問題

即使有了最徹底地測試過的且安全的軟件,一旦打包並交給最終用戶,全部的賭都輸了。軟件如何配置和實現,像其他步驟那樣扮演者關鍵的安全性角色。

默認值的謬論

用戶犯的最大錯誤之一是當所使用的軟件沒有默認值時。許多軟件爲各種選項定義默認值,以便用戶可以儘可能快地運行。雖然有時候這可能非常有益,像 Web 服務器默認爲標準的 Web 服務器通信端口,這也會導致許多安全問題。舉例來說,許多路由器和其它網絡設備都有默認的登錄用戶名和密碼。當用戶不將這些默認值改爲獨特的值時就會出現問題。搜索“默認的路由器密碼”將得到許多列出市場上大部分路由器的默認用戶名和密碼的站點。如果黑客打算進入網絡,那麼還未接觸的用戶名、密碼、IP 地址,和其它默認值都是現成的鑰匙。

不可靠的系統

當最終用戶不確定他們添加的軟件如何符合系統的其他部分,並且需要採取什麼額外的安全量度時,會產生另一個問題。再次拿 Web 搜索舉例。搜索“view/index.shtml axis”將返回未保護的網絡攝像機的列表。在一些情況下,最終用戶成功地設置了他們想讓全世界都可見的網絡攝像機。在其他情況下,網絡攝像機被添加到某個網絡,並且沒有配置爲不公開。這種未保護的攝像機可以被互聯網上的每個人見到,並且可能快速地成爲侵犯隱私罪。一些書籍和網站致力於提供返回所有者沒猶豫過安全性並且現在公開了的數據搜索查詢。17

我們從這些新的搜索中得到一些經驗。第一,默認值到處都是,因此當不修改默認值時,考慮如果黑客知道此信息會有多有害。第二,您應該瞭解如何訪問系統的各個部分並且考慮這種訪問級別是否合適。第三,記住通過模糊的安全沒有用。不論多麼不重要或未公開的信息公開了,如果有人感興趣,不管通過自動的搜索或一些人力,都可以找到該數據。18





結束語

隨着越來越多的脆弱點日益被發現,這些威脅只是滄海一粟 。如同這些實例一樣,大部分脆弱點源於疏忽:忽略了實現安全實踐的開發人員,或者忽略改變配置的最終用戶。即使我提供的實例可能膚淺,並且似乎十分容易避免,但隨着項目的增長,對於簡單的未檢查的情況就有機會了。黑客可能只需要小小的機會就對系統進行攻擊並且引起永久性的損害。開發人員應該充分了解他們假設的影響,並且越過正常使用之外進行測試。通過充分地瞭解系統的工作方式,並且假定爲對於產品的黑客角色,開發人員應該定期審查他們的工作,並且在必要時發佈補丁。

個人可能說不出軟件有多大缺陷,並且雖然沒有那麼完全的安全系統,但是人們可以通過利用多層次的安全性將脆弱性最小化。健壯的密碼,讓軟件保持更新及適當地修補,並且當添加了每個軟件困擾時瞭解它的影響,是最終用戶添加保護層的小方法。最後,與軟件相關的每個人都有責任關注安全性,並試圖減少脆弱點。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章