OWASP(Open Web Application Security Project)專門研究網站應程式的弱點組織,歸納出開發人員常犯前十大弱點,本章節以.NET程式為範本說明。
包含了SQL Injection、Command Injection、XML Injection、LDAP Injection等…注入式攻擊手法,SQL Injection簡單說程式碼的SQL語法字串將傳入的變數作為條件組合引發問題,我們以登入網頁為例,輸入使用者帳號以及密碼並傳入SQL語法組合如圖5.所示。
由於輸入介面上並無任何驗證處理,當攻擊手發現此問題則輸入一些不當資料,如圖6.所示,我們看到使用者帳號輸入了 John' or '1'='1字串,組合結果SQL命令為可執行恆等式成立('1'='1')語法,密碼即使輸入錯誤也是可正常登入運作,避開帳號密碼上的驗證。
進階攻擊再利用Second Order SQL Injection取得權限上提升或變更系統管理者的密碼,甚至摧毀資料庫造成重大影響,對於程式開發者來說,要處理SQL Injection有很多種選擇作法,如:參數化查詢、過濾掉SQL溢出字元、使用ORM技術等皆可避免此弱點,其他Injection處理方式一樣別輕易相信資料來源,可使用白名單或黑名單方式進行過濾驗證。
早期設計忘記密碼功能會以提示方式來告知,系統會要求您輸入最喜愛的「台灣城市」,因台灣的城市屈指可數,若您輸入為Taipei,那麼就很好猜測到提示答案,並取得正確密碼,造成了身分驗證上的缺失弱點,因此建議採用two factor authentication(2FA)加強驗證上安全,也就是至少包含以下兩種認證因子。
密碼存入資料庫需以雜湊(Hash)單向加密方式儲存,確保密碼隱密性是不可被解密,通常開發人員會忽略掉雜湊加密需要加上「鹽巴」如圖7.所示,經過Salt變化即使輸入密碼都是bob但我們可以看到雜湊後的結果是不同,避免駭客使用字典檔方式來破解密碼。
Session是記錄有關網頁上的狀態資訊,當我們登入系統後Session ID會記錄在Cookie中,如我們從登入系統後Session ID都一維持不變,攻擊者可以透過釣魚網站方式誘騙使用者連入,藉此透過Script抓取Cookie並取得受害者的Session ID圖8.所示,攻擊者即利用固定Session ID(Session Fixation)成功進入系統,因此程式開發者相對必須注意保護Cookie,可調整系統設定檔(web.config)將httpOnlyCookies設定true讓javascript無法讀取Cookie避免釣魚網站竊取,另外Cookie傳輸過程將requireSSL設定true,並設定Session timeout時間最久建議以15分鐘為限,在使用者登入成功後,立即更換 Session ID以避免固定值問題,如圖9.範本程式碼。
只要是網站型應用系統大部分都會發生此弱點。當使用瀏覽器造訪有此弱點網站,執行攻擊者已先在網站上注入惡意腳本程式碼(Script),通常為JavaScript語言,瀏覽器會讀取惡意腳本程式碼執行,利用此弱點竊取用戶的cookie,上述我們提到若允許Javascript存取cookie則Session ID會被抓取冒用使用者身份,甚至可做到鍵盤側錄(key log)將重要輸入資料記下,此弱點可分為兩種類型。
Reflected XSS,當直接於畫面輸入腳本程式碼馬上影響,例如:全文檢索是一個輸入文字框,當輸入資料為<script>alert('XSS Testing')</script>,若網站有XSS弱點會直接顯示對話框XSS Testing訊息,如圖10.所示,再進一步檢視網頁原始碼,即可發現輸入網頁內容被嵌入了程式碼,如圖11.所示。
Stored XSS或稱Persistent XSS,腳本程式碼來源透過資料庫或檔案而來所造成的影響。例如:留言板功能,或是部落格之類的網站資料來源透過資料庫而來,當攻擊先留惡意腳本內容如圖12.所示,並存入資料庫,使用者觀看留言板時從資料庫讀取出惡意程式碼,造成使用者執行惡意程式碼。
由此可見不論是哪種XSS類型都須防範,對開發者而言懂得其中原理是非常容易可解決,以.NET開發平台微軟提供Encoder處理對應XSS問題,參考圖13.所示,如:HtmlEncode、JavaScriptEncode等.. ,其中以HtmlEncode來說將<字元轉換為<以及其他字源轉換來避免輸入惡意腳本程式碼。
當我們在設計上傳檔案功能的網頁,如果不限定其上傳檔案類型,攻擊手把惡意程式傳入系統並且透過釣魚信件方式將此URL給受害者,如圖14.所示,若受害者沒注意到信件的連結網址是惡意程式並執行。
另一類常犯問題是下載路徑參照,提供了一個下載檔案頁面,並以參數設定路徑及下載檔案,例如:http://mywebsite.com/download.aspx?fn=userguide.pdf,對攻擊手而言將fn參數改為http://mywebsite.com/download.aspx?fn=/web.config,我們可看到操控了路徑(Path Traversal)回至根目錄下抓取系統設定檔案,竊取設定檔的資料庫連線密碼及帳號等資訊。
一般而言系統皆有系統設定頁面 且為「預設值」出廠設定,但對使用者來說修改預設值常常被忽略,以路由器或是網路監視器設備為例,一出廠預設帳號以及密碼皆是admin,若使用者未更換密碼,就很容易猜測,再加上大多設備都沒要求使用者第一次登入必須更改預設密碼,簡直是門戶大開,哪天看到網路監視器鏡頭亂移動時才發現大事不妙!網站應用伺服器常犯的是將錯誤訊息顯示在畫面上,對開發人員來說是很好的除錯方式,並未配置錯誤訊息對應的頁面,因此錯得越多越讓駭客得到更多的資訊,其中包含了資料表的名稱及結構,如圖15.所示。
如同A5所述將系統錯誤訊息包含資料表結構呈現於畫面上,以及密碼在傳輸的過程中使用明碼方式傳遞時,駭客透過封包竊聽造成外洩,手機App一旦同意了使用條款,App會存取定位資訊、Gmail以及Google doc的資料給予廣告商,開發商利用使用者薄弱安全意識,如此輕易獲得個人重要機敏資料,然而大多數人還不理解這些有價資料最後「一定」會遭到洩漏,因此對於我們的定位資訊以及個資上需加以保護,避免自主性的外流,對開發者而言這些敏感的機密資料需要進行加密、資料遮罩、去識別化方式予以保護,微軟.NET平台提供了內附System.Security.Cryptography方法,我們更要仔細考慮那些資訊是可以公開分享,避免自主性提供敏感資料,我們所處的大數據(Big Data)世界,難保哪天不會回咬我們。
這弱點對於駭客來說在高興不過了,不需要繁雜耗時的破密分析即可直接造成權限提升。例如本來應該是給系統管理者權限的管理頁面,因未驗證使用者角色只透過URL即可進入管理頁面,此為Forced Browsing,上述提到web.config透過操控path即可存取也是相同問題。
早期網銀轉帳交易設計3個重要參數,Account帳戶、Amount金額 、To轉帳對象,其URL為http://RichBank.com/Transfer.aspx ?Account=User1&Amount=10,000&To=User2 即完成一筆轉帳交易,若當駭客知道此運作原理只要透過這三個關鍵參數,此時使用者還未登出網銀,駭客發送釣魚信件給受害者,Email內有一個圖示標籤為<img src= " http://RichBank.com/Transfer.aspx?Account=User1&Amount=10,000&To=hacker">,當使用者只要一開啟信件,則會進行網銀轉帳給hacker,如圖16.所示。
攻擊者已先研究網銀轉帳所需具備的參數值,才有機會下手,為了防範現今網銀都會增加幾道防禦措施,使用圖形驗證碼並要求使用者需要再輸入一次密碼,再加上OTP簡訊動態密碼,再次要求輸入驗證,ASP.NET MVC架構中已有提供Html.AntiForgeryToken方法可防禦,但前提是網站沒有XSS(Cross Site Scripting)弱點且Token不可以被看到,若發生XSS弱點系統產生隱藏欄位Token值仍會被取得造成防禦上失效。
對開發者來說使用Open Source可以減少開發時程以及使用現成寫好程式碼,但忽略了在使用前需思考這些Open Source本身是否已被CVE網站公告弱點,且未提供更新,甚至不在提供維護,如開發商還有繼續維護並定期更新修復弱點版本,那麼還可以考慮使用,天下沒白吃的午餐,最好使用前透過源碼檢測或OpenSource掃描工具再次檢驗確保安全。
未經驗證導向,網站系統常會使用Redirect或Forward到其他頁面或是其他網站,且可能透過參數控制進行導址動作,原設計某系統提醒客戶要定期更換密碼此Email連結URL為http://xyz.com/Account/logon.aspx?returnUrl=update.aspx,而攻擊者偽造一封信件給使用者一樣提醒客戶定期更換密碼,但returnUrl被修改連結為http://xyz.com/Account/logon.aspx?returnUrl=http://hacker.com/loguserinfo.aspx,一旦登入後即被轉到駭客網站中,藉此攻擊者可以蒐集到使用者敏感資訊,因此在開發及設計上盡量避免使用Redirect和Forward,並建立一個白名單驗證轉址URL都在允許範圍內。
撰寫一套系統是件不簡單事情,以國內不健康的軟體開發環境為例,大多數開發人員早就過勞,又因責任制、薪資少、一個人當三個人使用,系統能如期上線算是祖宗有保佑,至於資安上的議題是完全沒有時間以及精力加以思索,因此漏洞百出,直到透過工具檢測才發現,通常發現時機已接近完工上線階段,後續資安問題修正更是頭痛,輕者只需加入安全函式,重者幾乎打掉重練,像網銀系統動輒幾百萬行程式碼,很難想像最後修正漏洞所花的人力成本,且還要每行都完美不出錯,才不讓駭客有機會下手,如同大家認同只要是軟體就會出錯,所謂的零問題、零風險才能上線想法在現實上根本不存在,畢竟我們都是人,只是遲早發現問題、漏洞遲早被揭露,雖然已有「漏洞獎勵方案」,但實質上獎勵金額遠遠低於賣給黑市價格,因此無論企業、政府單位對於安全軟體開發還是要從本質上下手,盡量減少先天上的漏洞、藉由軟體安全生命開發週期,將安全納入於開發中,並透過工具檢測讓開發人員能盡早發現處理,避免上線前才發現造成時程上的壓力,另外透過教育訓練將資安觀念融入系統開發,相關國際資安訓練機構,如EC-Council、ISC²、SGS等,最後在透過工具檢測讓開發人員及早發現處理,降低應用程式本身弱點風險。
由於企業以及個人隨時隨地有可能遭受到駭客攻擊,因此筆者建議幾項自保措施:
最後引自史蒂芬.賈伯斯所述「不是對科技有信心,而是對人有信心」(Technology is nothing. What's important is that you have a faith in people, that they're basically good and smart, and if you give them tools, they'll do wonderful things with them.),雖然我們所處的數位世界並非想像中的安全,對於資安攻防上先天不公平更是越演越烈,而科技就如同兩面刃,可以往好的方面也可以往黑暗面,如同前頂尖駭客凱文‧米特尼特早已棄暗投明,在各企業擔任資安顧問,指導大眾如何自保以及防禦,而本文也以此角度做為出發點,宣導資安相關議題加以探討,期望對各位讀者有所收穫。
參考文獻