1. 程式人生 > >Sql 註入詳解:寬字節註入+二次註入

Sql 註入詳解:寬字節註入+二次註入

.com 主動 一個 from 攻擊 過濾 分享圖片 size 就是

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 的仿真效果。

寬字節註入測試示例:

技術分享圖片

Gbk編碼格式輸入結果:

技術分享圖片

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

(2) 二次urldecode 註入

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

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

二次註入測試代碼:

技術分享圖片

執行結果:

技術分享圖片

原理:由於我們提交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對數據庫或者文件中獲取的數據進行過濾。

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

Sql 註入詳解:寬字節註入+二次註入