1. 程式人生 > >Sql 注入詳解:寬位元組注入+二次注入

Sql 注入詳解:寬位元組注入+二次注入

sql注入漏洞

原理:由於開發者在編寫操作資料庫程式碼時,直接將外部可控引數拼接到sql 語句中,沒有經過任何過濾就直接放入到資料庫引擎中執行了。

攻擊方式:

(1) 許可權較大時,直接寫入webshell 或者直接執行系統命令

(2) 許可權較小時,通過注入獲得管理員密碼資訊,或者修改資料庫內容進行釣魚等

常出現的地方:

登入頁面、獲取HTTP頭(user-agent、client-ip等)、訂單處理等,HTTP頭裡面client-ip 和 x-forward-for 常出現漏洞,在涉及購物車的地方,常發生二次注入;

1、 普通注入

指未做任何處理的,直接通過注入union 查詢就可以注入的漏洞。在普通注入測試時,通過查詢關鍵字定向挖掘,資料庫操作:select from 、mysql_connect 、mysql_query 、mysql_fetch_row 等,資料庫查詢方式:update、insert、delete等

2、 編碼注入

程式在進行一些操作之前,經常會進行一些編碼處理,而做編碼的函式也是存在問題的,通過輸入轉碼函式不相容的特殊字元,可以導致輸出的字元變成有害的資料。常見的編碼注入有mysql 寬位元組以及urldecode/rawurldecode 函式導致的。

(1) 寬位元組注入

在進行php 連線mysql 時,當設定”ser character_set_client=gbk” 時會導致一個編碼轉換的注入問題,也就是熟悉的寬位元組注入,當存在寬位元組注入時,%df%27 可把程式中過濾的\ (%5c)吃掉。例如:/1.php?id=1存在寬位元組注入時,則: /1.php?id=-1’and 1=1%23 單引號會被轉義成 \’但是提交:/1.php?id=-1%df’and 1=1%23 時,%df和\ 反斜槓(%5c) 組合 %df%5c 編碼後是一個漢字,這時候單引號依然存在,則會閉合成功,形成注入漏洞。

形成原因:由於設定Mysql 伺服器客戶端資料編碼是GBK ,set character_set_client=gbk執行語句時進行GBK 轉碼時形成攻擊,通常都設定方法是: SET NAMES ‘gbk’,等同於:

SET

character_set_connection=’gbk’,

character_set_results=’gbk’,

character_set_client=’gbk’

此編碼設計也存在漏洞,建議使用官方給的mysql_set_charset方式來設定編碼,在呼叫SET NAMES 之後還記錄了當前的編碼,留著給後邊mysql_real_escape_string處理字元時使用,後邊合理的使用mysql_real_escape_string還是可以防禦此漏洞的。

防禦方法:

①在執行查詢之前先執行SET NAMES ‘gbk’,character_set_client=binary 設定character_set_client 為 binary

② 使用mysql_set_charset(‘gbk’) 設定編碼,然後使用mysql_real_escape_string() 函式被引數過濾

③使用pdo方式,在Php 5.3.6及以下版本中需要設定setAttribute(PDO:ATTR_EMULATE_PREPARES,false); 來禁用preparcd statements 的模擬效果。

寬位元組注入測試示例:

https://images2018.cnblogs.com/blog/1391871/201807/1391871-20180728235702578-1595948633.png

Gbk編碼格式輸入結果:

https://images2018.cnblogs.com/blog/1391871/201807/1391871-20180728235718003-1448078680.png

寬位元組注入成功,%df\’被過濾後成為%dr\’,經過編碼後成為%df%5c,即就是漢字“運”。因此,可以繞過,形成注入。

(2) 二次urldecode 注入

現在通常Web應用程式大多都會進行引數過濾,來防止注入。如果某處使用了urldecode或者 rawurldecode 函式,則會導致二次解碼生成單引號二引發注入,即二次注入。

Web應用程式通常使用addslashes() 、mysql_real_escape_string()、mysql_escape_string()函式或者開啟GPC來防止注入,也就是給單引號(‘’)、雙引號(“”)、反斜槓(\)和NULL加上反斜槓轉義。

二次注入測試程式碼:

https://images2018.cnblogs.com/blog/1391871/201807/1391871-20180728235736902-1861427825.png

執行結果:

https://images2018.cnblogs.com/blog/1391871/201807/1391871-20180728235746244-1218020835.png

原理:由於我們提交id引數到webserver時,webserver會自動解碼一次,假設目標程式開啟了GPC,我們提交引數id=1%2527 ,經過第一次解碼後,%25解碼結果為%,則引數為id=1%27,第二次程式使用了urldecode 或者 rawurldecode 函式來解碼id引數,則解碼後結果為id=1’ ,這時單引號成功出現引發注入。

3、 sql注入漏洞防範

這裡提供三種防禦方法:預編譯方式、過濾函式和類、魔術引號。

(1)、預編譯方式:在.NET語言中使用SqlParameter進行預編譯方式處理資料庫查詢,在java中語言使用prepareStatement進行預編譯處理資料庫查詢,在PHP中使用pdo 的prepare 進行預編譯處理資料庫查詢;

(2)、過濾函式和類:兩種共使用場景。一種是程式入口統一過濾,像框架程式這種方式比較多,另一種是在程式進行SQL語句執行之前使用。PHP常使用的函式有addslashes()、mysql_escape_string()、msyql_real_string()、intval()函式等;

(3)、魔術引號:通常資料汙染的方式有兩種:一種是應用被動接收引數,類似於GET、POST等;另一種是主動獲取引數,類似與讀取遠端桌面頁面或者檔案內容等。在PHP中魔術引號配置方法,magic_quotes_gpc負責對GET、POST、COOKIE的值進行過濾,magic_quotes_runtime對資料庫或者檔案中獲取的資料進行過濾。

注:本文屬於作者自己原創,轉載請註明出處,若有錯誤之處,還請指出,謝謝!