簡單介紹一下SQL語句:通俗來理解就是開發(fā)者盲目相信用戶,沒有嚴格檢查用戶輸入,導致用戶可以輸入惡意參數(shù)進入程序邏輯,最終拼接惡意參數(shù)改變原本的SQL語句邏輯,造成SQL注入漏洞。
本次審計的CMS是基于Web應用的B/S架構的團購網(wǎng)站建設解決方案的建站系統(tǒng),它可以讓用戶高效、快速、低成本的構建個性化、專業(yè)化、強大功能的團購網(wǎng)站,采用PHP和MYSQL數(shù)據(jù)庫開發(fā)技術,版本CV1.6。商業(yè)案例如下:
審計結果實戰(zhàn)測試:
首先在本地搭建一個網(wǎng)站,方便之后測試,一鍵安裝也沒啥說的,跳過。重點講講這個團購CMS的SQL操作。這個團購CMS將SQL操作全部寫到了include/library/DB.class.php文件:
然后分析這個文件,發(fā)現(xiàn)這里面的函數(shù)有些使用了:mysql_real_escape_string函數(shù)對參數(shù)進行過濾,整數(shù)參數(shù)就強制轉(zhuǎn)換int類型
關于mysql_real_escape_string函數(shù)的注入可以嘗試寬字節(jié)注入,當數(shù)據(jù)庫編碼采用GBK的時候可以嘗試bypass函數(shù)檢查,但是此處不適用。之后審計發(fā)現(xiàn)其中存在幾個未對參數(shù)進行過濾直接執(zhí)行SQL語句的函數(shù):GetDbRowById、GetQueryResult、GetField。
此處采用敏感函數(shù)回溯的方法進行審計,先全局搜索這些函數(shù),然后想辦法對達到觸發(fā)條件。
1、 全局搜索GetField函數(shù),發(fā)現(xiàn)沒有被引用的地方。
2、全局搜索GetQueryResult函數(shù),搜索結果比較多,如下:
先嘗試審計第一處:/ajax/manage.php,如下,如果存在,可以通過$id變量進行注入。
追蹤如何觸發(fā)函數(shù):第490行,當變量action滿足條件即可:
而繼續(xù)回溯,$action的來源$_GET:
同時也發(fā)現(xiàn)id變量被強制類型轉(zhuǎn)換了,哦豁,這下安逸了,這個點基本利用不了了。同時測試過程中此處還有一處調(diào)用了未過濾SQL函數(shù):
不過都用到了ID參數(shù)進行注入,所以不能利用,放棄。
之后選擇其他可能存在的地方繼續(xù)審計:/manage/user/index.php
但是這兩處同樣存在intval參數(shù)過濾。
再繼續(xù)搜索,發(fā)現(xiàn)/manage/vote/feedback.php
此處$question['id’]參數(shù)來源于前一個查詢結果,可以考慮二次注入,不過此處因為id參數(shù)為提交問卷時系統(tǒng)自動生成,所以無法利用了。
最后兩處調(diào)用這個函數(shù)的地方在DB.class.php中:其中一個屬于LimitQuery函數(shù)調(diào)用,因為存在過濾,所以利用比較困難:
另外一處便是GetDbRowById調(diào)用,此處不存在過濾,可能存在注入,這個審計便放到下一部分:
3、全局搜索GetDbRowById函數(shù):根據(jù)之前的審計,函數(shù)本身沒有對參數(shù)過濾,其中調(diào)用的GetQueryResult函數(shù)也沒有過濾,可能存在SQL注入。
可以發(fā)現(xiàn)GetDbRowById函數(shù)在include/library/Table.class.php文件存在調(diào)用:_Fetch函數(shù)和FetchForce函數(shù)
其中_Fetch函數(shù)在同類中的Fetch方法被調(diào)用:
因此需要全局搜索Fetch函數(shù)和FetchForce函數(shù):
首先來搜索FetchForce函數(shù),結果如下,還挺多的
首先要說的就是搜索的結果不一定全部存在注入,需要再次尋找其中疏于過濾的點進行驗證,下面舉幾個栗子:
文件:/ajax/chargecard.php
不需要登錄便可以直接訪問這個文件,當$action為query時可以調(diào)用函數(shù),且$secret不存在過濾,開啟debug調(diào)試跟蹤參數(shù)的流程:先輸入secret=123’
可以看到對secret參數(shù)沒有進行任何過濾便傳入FetchForce函數(shù):
將存在惡意字符的參數(shù)拼接SQL語句,造成SQL注入,因為此處存在對空格等字符的正則匹配,所以可以使用/**/代替空格。
因為此處不存在回顯,要使用盲注,使用時間盲注驗證,一個用時2秒,一個用時5秒
而且同文件下存在另外一處注入:
這個地方利用方法也差不多,就改一下action參數(shù)便可以。
再舉一個不存在注入的情況:/ajax/manage.php
雖然調(diào)用了FetchForce函數(shù),但是溯源之后發(fā)現(xiàn)對id變量進行了強制轉(zhuǎn)換,因此屬于不能利用的點。與此同時new.php也屬于同理情況:
同時如果繼續(xù)搜索審計就能發(fā)現(xiàn)其他存在注入的點:
其余的文件就不一一看了。接下來查看Fetch函數(shù):搜索結果如下
先來看文件:/ajax/system.php
不過這個地方應該是需要管理員登錄的,登錄之后傳參是這個亞子的:
可以采用和之前相同的時間盲注:
再看另外一處漏洞:/api/call.php,此處不需要任何登錄,可以在前臺直接訪問到文件,而且其中多個參數(shù)存在注入:
再之后很多便與上面的審計方法類似,還存在可以利用的點,也會存在許多無法利用的點,就不一一寫出來了。上面這個注入點還找到一個案例:
不過存在問題的便是這個CMS的密碼加了一個固定字符串當作鹽,在解MD5時會存在困難。
按照慣例,來小結幾句。關于SQL注入的防御,應該有很多方法了,首先就是不信任用戶輸入,嚴格過濾參數(shù),之后的話還可以使用預查詢方案,之后的話還可以使用軟硬件防火墻。不過這些理論上都會存在bypass的情況,不過我太菜,不會bypass。
另外就是關于參數(shù)過濾,如同上面,執(zhí)行參數(shù)過濾,但是依然找到了漏網(wǎng)之魚,所以過濾策略某種情況下也是不可靠的。
最后就是關于代碼審計了,代碼審計一時爽,一直審計一直爽,加油?。?!
聯(lián)系客服