這些年我們發現越來越多的公司開始注重安全測試了,為什么?因為安全測試可以在某種程度上可以排查掉你項目的一些安全漏洞,這樣你的系統上線后才會相對安全,才有可能盡量避免來自外部的攻擊。每一年互聯網都會發生一些重大的安全事件,而且每一次帶來的后果也是很嚴重的,而這些教訓恰恰都說明了安全測試的重要性。
那什么是安全測試呢?百度百科上給出來的解釋是:安全測試是在IT軟件產品的生命周期中,特別是產品開發基本完成到發布階段,對產品進行檢驗以驗證產品符合安全需求定義和產品質量標准的過程 。按照小編的理解,簡單點來講,其實安全測試可以這么理解:安全測試其實就是測試你的系統是否有安全漏洞,普通測試以發現BUG為目標,安全測試以發現安全隱患為目標。
那么安全測試有哪些東西可以測呢?我們在對一個系統進行安全測試的時候其實是有很多應該考慮進去的,像表單攻擊,sql注入,XSS攻擊,CSRF攻擊,暴力破解等。
小編今天要講的是安全測試下的SQL注入,通過學習,了解什么是sql注入,同時小編我會結合項目中的幾種情況來為大家講解常見的sql注入場景以及如何去執行sql注入攻擊。首先我們來看一下什么是sql注入,解釋:sql注入就是通過構建一些特殊的表達式或這一些特殊的sql命令,通過表單提交到后台服務器,最終達到欺騙服務器執行惡意的SQL命令,或者達到一個繞過服務器校驗的一個效果。
第一種比較常見的注入場景是系統的登錄功能,當然現在很多大公司的項目在這一塊是做的很好,也做的非常安全的,很少會留下sql注入這樣的漏洞,而一些小的系統,小的項目或者自己寫着玩的系統可能會存在這樣的安全漏洞。這里我就寫了一個簡單的登錄注冊功能,來幫助大家了解什么是sql注入,大概邏輯是這樣的:通過在登錄頁面輸入用戶名和密碼來完成登錄,后台會拿到前台表單提交的數據去數據庫做校驗匹配,如果存在此用戶就讓登錄成功,如果匹配不到就提示“錯誤的用戶名或者密碼”。然后我們這里呢會通過構建一些特殊的數據或者表達式來實現sql注入。現在小編就先把這個登錄功能的前台頁面和后台的幾行關鍵代碼貼出來:
以下是前台登錄頁面:
以下是后台登錄關鍵代碼:
其實我們看到這個后台的核心代碼其實就是拿到前台用戶名和密碼去數據庫做了檢索,看是否存在,存在就放行,不存在就提示錯誤信息。然后接下來我們來測試一下登錄,首先我們拿數據庫表里已經注冊的用戶“001@qq.com/111111”來登錄:
前台登錄界面輸入用戶名“001@qq.com”,密碼“111111”,點擊登錄,然后我們發現成功登錄了,這個結果是正常的。
然后我們接着來試一下錯誤的用戶名或者密碼,這里我們直接拿一個上面用戶表不存在的用戶“007@qq.com/111111”來進行登錄,最后結果提示“用戶名或者密碼錯誤”,這個結果也是正常的。
正確的用戶名密碼能登錄成功,錯誤的用戶名密碼就登錄失敗,看上去沒有任何問題,那是不是就意味着這個登錄功能就沒有bug沒有漏洞了呢?現在下決定還為時尚早,前面我們做測試都是拿的正常的數據,不是特殊,極端的數據。后面我們將輸入一些特殊的數據來繼續完成測試。測試之前,我們來分析一下登錄的一行核心代碼,我們稍微有點編程基礎的同學都看得懂下面登錄邏輯里的數據庫查詢代碼:
這一行代碼其實就是拿到前端傳進來的用戶名和密碼來拼接得到一條sql,然后在后台執行這條拼接的sql去查詢用戶表是否存在這樣的用戶,看上去似乎沒啥問題,其實不然,我們看到這條sql里的條件字段的跟它的值拼接的時候用了一對單引號包起來了,這個也很好解釋,因為數據庫中字符串類型的條件字段后面帶值的時候需要帶一對單引號(這里需要一定的數據庫基礎,沒有這部分基礎的同學可以加我們的測試群,找相關管理員要數據庫基礎這一部分視頻來學習),而正是因為這樣的拼接寫法導致了sql注入漏洞的存在,因為我們可以通過在前端登錄頁面用戶名一欄輸入:’ or ‘1’=’1這樣一個特殊的表達式,密碼的話隨便填一個,比如還是填111111,那最后服務器后台拿到前台傳入的用戶名和密碼去做sql拼接的時候,得到的最終sql將會是這樣一條:select count(*) from nm_user where password=’111111’ and username=’’ or ‘1’=’1’;而這樣一條sql因為存在一個恆等的條件表達式:’1’=’1’,所以無論如何都可以從user表查到數據的(只要user表有數據),所以最后就通過了服務器后台的校驗,登錄成功了,如下圖:
但是,我們的數據庫其實是沒有這樣的用戶的。這里再次附上我們用戶表的數據:
而這樣的一個用戶名卻登錄成功了,這個就是sql注入,通過構建一些特殊的表達式或者特殊的sql然后通過表單提交到后台服務器,騙過后台服務器去執行這樣一條惡意的sql或者別有用心的sql來繞過服務器的校驗。
好的,簡單的舉例說明了一下什么是sql注入,我相信大家也對於這個概念有了一定的理解,這里其他的一些sql注入場景這里就不再另行舉例了,例子是變的,但是思想是不變的,大家把握住sql注入的概念和思想就可以了。大家可以寫個簡單的demo去驗證下,或者拿自己公司的項目去驗證下,不保證能復現這樣的問題,因為這樣的sql注入漏洞還是很好去避免的,直接使用ibatis,mybatis,hibernate數據庫等框架的相關API就能規避這樣的安全漏洞,因為這些框架里操作數據庫的API底層都是使用的PreparedStatement而不是Statement,前者相對於后者的一個好處是它提供了一個sql預編譯的機制和防注入的一個功能。
來源: https://mp.weixin.qq.com/s/p8Kv89G-L3LIn6pWjizqow