0x00概述
寬字節(jié)注入主要源于程序員設(shè)置數(shù)據(jù)庫編碼與php編碼設(shè)置為不同的兩種編碼埋市,那么就可能產(chǎn)生寬字節(jié)注入
例如:PHP編碼為UTF-8而Mysql的編碼設(shè)置為set? names 'gbk'或是set character_set_client=gbk,這樣配置會引發(fā)編碼轉(zhuǎn)換從而導(dǎo)致的注入漏洞(一個(gè)gbk編碼漢字,占用2個(gè)字節(jié),一個(gè)utf-8編碼的漢字,占用3個(gè)字節(jié))
注意:set name 'x'與以下三個(gè)語句等價(jià):
mysql->set charater_set_client=x;
mysql->set charater_set_results=x;
mysql->set charater_set_connection=x;
也就是說當(dāng)你設(shè)置了set? names 'x'時(shí)就同時(shí)執(zhí)行了上面3條語句
寬字節(jié)注入就是PHP發(fā)送請求到Mysql時(shí)使用了語句set? names 'gbk'或是set character_set_client=gbk進(jìn)行了一次編碼,但是又由于一些不經(jīng)意的字符集轉(zhuǎn)換導(dǎo)致了寬字節(jié)注入
0x01寬字節(jié)注入原理
1、在我們正常使用addslashes函數(shù)或是開啟PHP的GPC(如果magic_quotes_gpc=on,php解析器就會自動(dòng)為post拟枚、get、cookie過來的數(shù)據(jù)增加轉(zhuǎn)義字符"\"众弓,以確保這些數(shù)據(jù)不會引起程序恩溅,特別時(shí)數(shù)據(jù)庫語句因?yàn)樘厥庾址ㄕJ(rèn)為是PHP的字符)引起的污染,插入后在數(shù)據(jù)庫里顯示的是轉(zhuǎn)義前的原始數(shù)據(jù)谓娃,所以取出來不用轉(zhuǎn)義)時(shí)過濾get脚乡、post、cookie滨达、requst提交的參數(shù)時(shí)奶稠,我們使用的預(yù)定義字符會被轉(zhuǎn)義成添加反斜杠的字符串
0x02實(shí)例
在php中使用$pdo->query('set names gbk');指定三個(gè)字符集(客戶端、連接層捡遍、結(jié)果集)都是gbk編碼锌订。而php的編碼為utf-8編碼時(shí)造成寬字節(jié)注入
加了單引號沒有報(bào)錯(cuò)画株,可以看出我們輸入的? '? 已經(jīng)給addslashes函數(shù)過濾掉了
那么如何逃過addslashes的限制呢辆飘?
addslashes函數(shù)產(chǎn)生的效果就是,讓(')變成(\')谓传,讓單雙引號變得不再是“單雙引號”蜈项,只是一撇而已。一般的繞過方法是续挟,想辦法處理掉(\')前面的(\):
1紧卒、給(\)前面再加上一個(gè)(\),變成(\\')诗祸,這樣(\)被轉(zhuǎn)義了跑芳,(’)逃出了限制
2、想辦法把(\)去掉
eg.mysal在使用gbk編碼的時(shí)候直颅,會認(rèn)為兩個(gè)字符是一個(gè)漢字(前一個(gè)ASCII碼要大于128博个,才到漢字的范圍),所以%df和后面的\也就是變成了一個(gè)漢字际乘,'就逃逸了出來。
sql語句出錯(cuò)漂佩,說明可以注入脖含。
不會報(bào)錯(cuò)罪塔,因?yàn)?df%df是一個(gè)漢字,%5c%27不是漢字养葵,仍是\'
然后我們就可以構(gòu)造一個(gè)exp獲得管理員賬號密碼
http://localhost/index.php?id=-1%df%27union%20select%201,2,concat(name,0x23,pass)%20from%20admin%23