SQL注入漏洞
SQL注入經常出現在登陸頁面、和獲取HTTP頭(user-agent/client-ip等)、訂單處理等地方,因為這幾個地方是業務相對復雜的,登陸頁面的注入現在來說大多數是發生在HTTP頭里面的client-ip和x-forward-for。
1.普通注入
普通注入是指最容易利用的SQL注入漏洞,比如直接通過注入union查詢就可以查詢數據庫,一般的SQL注入工具也能夠非常好地利用。普通注入有int型和string型
測試環境搭建:
數據庫名為test 數據庫表名userinfo 以下時數據庫數據
測試出SQL注入漏洞
從上面我們可以看出我們使用union查詢到當前的用戶
從上面的測試代碼中可以發現,數據庫操作存在一些關鍵字,比如 select from、mysql_connect、mysql_query、mysql_fetch_row等,數據庫的查詢方式還有update、insert、delete 我們在做白盒審計時,只需要查找這些關鍵字,即可定向挖掘SQL注入漏洞
2編碼注入
程序在進行一些操作之前經常會進行一些編碼處理,而做編碼處理地函數也是存在問題地,通過輸入轉碼函數不兼容地特殊字符,可以導致輸出地字符變成有害地數據,在SQL注入里,最常見地編碼注入是Mysql寬字節以及urldecode/rawurldecode函數導致的
2.1寬字節注入
在使用PHP連接mysql的時候,當設置set character_set_client=gbk 時會導致一個編碼轉換的注入問題,也就是我們所熟悉的寬字節注入。當存在寬字節注入漏洞時,注入參數里帶入%df%27,即可把成程序中過濾的\(%5c)吃掉。
舉個例子
我們可以看一個例子當我id=1加上‘號提交的時候 它將’號前面加了\很明顯這樣時注入不成功的。
但是我們如果提交/index.php?id=1%df’ and 1=1%23 由於單引號會被自動轉義成\‘ ,前面的%df和轉義反斜杠(%5c)組合成了%df%5c,就是一個字,這時候單引號依然存在於是就成功閉合了前面的單引號
出現這個漏洞的原因時PHP連接mysql的時候執行了如下設置
Set character_set_client=gbk
告訴mysql服務器客戶端來源數據編碼時GBK,然后mysql服務器對查詢語句進行GBK轉碼導致反斜杠\被%df吃掉,而一般都不是直接設置character_set_client=gbk
告訴mysql服務器客戶端來源數據編碼時GBK,然后Mysql服務器對查詢語句進行GBK轉碼導致反斜杠\被%df吃吃掉,而一般都不是直接設置character_set_client=gbk,通常設置方法時SET NAMES ‘gbk’,但其實SET NAMES ‘gbk‘不過是比character_set_client=gbk多干了兩件事而已,SET NAMES ’gbk‘等同於如下代碼:
SET
Character_set_connection=’gbk’,
Character_set_results=’gbk’,
Character_set_client=gbk
這同樣也是存在漏洞的,另外官方建議使用mysql_set_charset方式設置編碼,不幸的時它也知識調用了SET NAMES,所以效果也是一樣的。不過mysql_set_charset調用SET NAMES之后還記錄了當前的編碼,留着給后面mysql_real_escape_string處理字符串的時候使用,所以在后面只要合理地使用mysql_real_escape_string還是可以解決這個漏洞的,關於這個漏洞的解決方法:
(1) 在執行查詢之前先執行SET NAMES ‘gbk‘,character_set_client=binary設置character_set_client為binary。
(2) 使用mysql_set_chharset(‘gbk‘)設置編碼,然后使用mysql_real_escape_string()函數被參數過濾。
(3) 使用PDO方式,在PHP5.3.6及以下版本需要設置setAttribute(PDO::ATTR_EMULATE_PREPATES,FALSE);來禁用prepared statements的仿真效果
寬字節注入挖掘關鍵字:
SET NAMES
Character_set_client=gbk
Mysql_set_charset(‘gbk‘)
環境搭建
數據庫沿用普通注入里面的數據庫
測試出SQL注入漏洞
mysql的特性,因為gbk是多字節編碼,兩個字節代表一個漢字,所以%df和后面的\也就是%5c變成了一個漢字“運”,而’逃逸了出來。
寬字節挖掘關鍵字
SET NAMES
Character_set_clent=gbk
Mysql_set_charset(‘gbk’)
Mysql_set_charset(‘gbk‘)
2.2二次urldecode注入
只要字符被進行轉換就有可能產生漏洞,現在web程序大多都會進行參數過濾,通常使用addslashes()、mysql_real_escape_string()、mysql_escape_string()函數或開啟GPC的方式進行防止注入,也就是給單引號、雙引號、反斜杠和NULL加上反斜杠轉義。如果某處試用了urldecode或者rawurldecode函數,則會導致二次解碼生成單引號而引發注入。原理是我們提交參數到webserver時,webserver會自動解碼一次
測試環境搭建:
我們可以看url部分%25經過第一次轉碼后的結果時%所以拼接后面的成為%27 而%27再經過urldecode經過第二次轉碼成為單引號成功引發注入
二次urldecode挖掘關鍵字
Urldecode
Rawurldecode
3.漏洞防范
在PHP中可以利用魔術引號來解決,不過魔術引號在PHP5.4后被取消,並且gpc在遇到int型注入時也會顯得不那么給力了,所以通常用的多的還是過濾函數和類,像discuz、dedecms、phpcms等程序里面都使用過濾類,不過如果單純的過濾函數寫的不夠嚴謹,也會出現繞過的情況,像這三套程序都存在繞過問題。當然最好的解決方案還是利用預編譯的方式。
1. gpc/rutime 魔術引號
通常數據污染有兩種方式,一種格式應用被動接受參數,類似於GET、POST等;還有一種是主動紅紅火火去參數,類似於讀取遠程頁面或者文件內容等。所以放置SQL注入的方法就是要守住這兩條路。Magic_quotes_gpc負責對GET、POST、COOKIE的值進行過濾,magiic_quotes_runtime對從數據庫或者文件中獲取的數據進行過濾 開啟這兩個選項之后能防住部分SQL注入 在int型注入上是沒有多大作用的。
2.過濾類函數和類
(1)addslashes函數
Addslashhes函數過濾的值范圍和GPC時一樣的,即單引號(‘)、雙引號(“)、反斜杠(\)及空字符NULL,它只是一個簡單的檢查參數的函數,大多數程序使用它實在程序的入口。
(2)mysql_[real_]escape_string函數
Mysql_escape_string和mysql_real_e3.scape_string函數都是對字符串進行過濾,在PHP4.0.3以上版本才有。
(3)intval等字符轉換
以上里昂中過濾方式,在int類型注入時效果並不好,比如可以通過報錯或者盲注方式繞過,這時候intval等函數就起作用了,intval的作用是將變量轉換成int類型,這里距離intval是要表達的一種方式,一種利用參數類型白名單的方式來防止漏洞,對應的還有好很多如floatval等
2. PDO prepare預編譯
待更新…….