PHP代碼審計入門(SQL注入漏洞挖掘基礎)


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預編譯

待更新…….

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM