《缺陷周話》第二期:SQL注入

代碼審計是使用靜態分析發現源代碼中安全缺陷的方法,能夠輔助開發或測試人員在軟件上線前較為全面地瞭解其安全問題,防患於未然,因此一直以來都是學術界和產業界研究的熱點,並且已經成為安全開發生命週期 SDL 和 DevSecOps 等保障體系的重要技術手段。

360代碼衛士團隊基於自主研發的國內首款源代碼安全檢測商用工具,以及十餘年漏洞技術研究的積累,推出“缺陷周話”系列欄目。每週針對 CWE、 OWASP 等標準中的一類缺陷,結合實例和工具使用進行詳細介紹,旨在為廣大開發和安全人員提供代碼審計的基礎性標準化教程。

上一期給大家瞭解了空解指針【傳送門】的應用,本期繼續帶來SQL注入的介紹。

一、SQL 注入

所謂 SQL 注入,就是通過將 SQL 命令插入應用程序的 http 請求中,並在服務器端被接收後用於參與數據庫操作,最終達到欺騙服務器執行惡意的 SQL 命令的效果。理論上來講,應用程序中只要是與數據庫有數據交互的地方,無論是增刪改查,如果數據完全受用戶控制,而應用程序又處理不當,那麼這些地方都是 可能存在 SQL 注入的。目前幾乎所有的開發語言如:JAVA、PHP、Python、ASP 等都可以使用SQL數據庫來存放數據,處理不當就可能導致SQL注入問題的發生。本篇文章以 JAVA 語言源代碼為例,分析 SQL 注入產生的原因以及修復方法。SQL 注入詳細請見 CWE-89: Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)(http://cwe.mitre.org/data/definitions/89.html)。

二、SQL 注入的危害

惡意攻擊者除了可以利用 SQL 注入漏洞獲取數據庫中的信息(例如,管理員後臺密碼、站點的用戶個人信息)之外,甚至在數據庫權限足夠的情況下可以向服務器中寫入一句話木馬,從而獲取 webshell 或進一步獲取服務器系統權限。

2017年1月至2018年9月,CVE 中共有793條漏洞信息與其相關。部分 CVE如下:

CVE-2018-13050 Zoho ManageEngineApplications Manager 13.x 中存在 SQL 注入漏洞,通過 / j_security_check POST 請求中的 j_username 參數可以注入sql語句。 CVE-2017-16542 Zoho ManageEngineApplications Manager 13 程序可以通過manageApplications.do?method=insert 請求中的 name 參數進行 SQL 注入。 CVE-2017-16849 Zoho ManageEngine Applications Manager 13允許通過 /MyPage.do?method=viewDashBoard 中的forpage 參數進行SQL注入。 CVE-2017-5570 在 eClinicalWorks Patient Portal 7.0 build 13 中發現MessageJson.jsp 中存在的盲注,但是隻能由經過身份驗證的用戶通過發送HTTP POST請求來利用。並且惡意攻擊者可以通過該漏洞使用諸如select_loadfile() 之類的方法將數據庫數據轉儲到惡意服務器。 三、示例代碼

3.1 缺陷代碼

本章節中使用示例代碼來源於Samate Juliet Test Suite for Java v1.3 (https://samate.nist.gov/SARD/testsuite.php),源文件名:CWE89_SQL_Injection__connect_tcp_execute_01.java。

《缺陷周話》第二期:SQL注入

《缺陷周話》第二期:SQL注入

在上述代碼可以看到數據在 54 行被汙染,在第 58 行中將汙染數據傳遞給data,並未經任何安全處理就在第 115 行中直接用於 SQL 拼接,且參與數據庫操作,從而導致 SQL 注入的產生。

使用 360 代碼衛士對上述示例代碼進行檢測,可以在文件第 115 行檢出“SQL注入”缺陷,顯示等級為高,同時,提供跟蹤路徑可以清晰分析缺陷產生的過程。如圖1、圖2所示:

《缺陷周話》第二期:SQL注入

圖1 SQL 注入檢出缺陷的 source 點

《缺陷周話》第二期:SQL注入


圖2 SQL 注入檢出缺陷的 sink 點

3.2 修復代碼

《缺陷周話》第二期:SQL注入

在上述修復代碼中的第 305 行,執行 SQL 時採用的預編譯,使用參數化的語句,用戶的輸入就被限制於一個參數當中。通過圖3可以看出,360代碼衛士對修復後的代碼並未檢出。

《缺陷周話》第二期:SQL注入

圖3 SQL注入修復示例

4、如何避免SQL注入

常見的修復方法:

1. 使用預編譯處理輸入參數:要防禦 SQL 注入,用戶的輸入就不能直接嵌套在 SQL 語句當中。使用參數化的語句,用戶的輸入就被限制於一個參數當中。如下所示:

《缺陷周話》第二期:SQL注入

2. 輸入驗證:檢查用戶輸入的合法性,以確保輸入的內容為正常的數據。數據檢查應當在客戶端和服務器端都執行,之所以要執行服務器端驗證,是因為 客戶端的校驗往往只是減輕服務器的壓力和提高對用戶的友好度,攻擊者完全有可能通過抓包修改參數或者是獲得網頁的源代碼後,修改驗證合法性的腳本(或者直 接刪除腳本),然後將非法內容通過修改後的表單提交給服務器等等手段繞過客戶端的校驗。因此,要保證驗證操作確實已經執行,唯一的辦法就是在服務器端也執 行驗證。但是這些方法很容易出現由於過濾不嚴導致惡意攻擊者可能繞過這些過濾的現象,需要慎重使用。

3. 錯誤消息處理:防範 SQL 注入,還要避免出現一些詳細的錯誤消息,惡意攻擊者往往會利用這些報錯信息來判斷後臺 SQL 的拼接形式,甚至是直接利用這些報錯注入將數據庫中的數據通過報錯信息顯示出來。

4.加密處理:將用戶登錄名稱、密碼等數據加密保存。加密用戶輸入的數據,然後再將它與數據庫中保存的數據比較,這相當於對用戶輸入的數據進行了“消毒”處理,用戶輸入的數據不再對數據庫有任何特殊的意義,從而也就防止了攻擊者注入 SQL 命令。


分享到:


相關文章: