所謂SQL注入,就是通過把SQL命令插入到Web表單提交或輸入域名或頁(yè)面請(qǐng)求的查詢字符串,最終達(dá)到欺騙服務(wù)器執(zhí)行惡意的SQL命令臭胜。
一般SQLI出現(xiàn)在登陸頁(yè)面,獲取HTTP頭(user-agent,client-ip等)癞尚,訂單處理等處耸三。
- 普通注入:
如下代碼,
<?php
$uname = $_GET['name'] ;
$sql = "SELECT * FROM user where name=$uname";
$conn=mysql_connect('localhost','root','root');
mysql_select_db("userinfo",$conn);
$result=mysql_query($sql,$conn);
print_r('now sql is:'.$sql.'<br/>result is:');
print_r(mysql_fetch_row($result));
?>
uname變量沒有經(jīng)過處理浇揩,便拼接到數(shù)據(jù)庫(kù)指令之中仪壮,造成了sql注入風(fēng)險(xiǎn)。
所以我們?cè)趯徲?jì)的時(shí)候應(yīng)該關(guān)注一些重點(diǎn)關(guān)鍵字胳徽,就可以幫助我們高效的發(fā)掘漏洞积锅。
關(guān)鍵字 |
---|
select from |
mysql_connect |
mysql_query |
mysql_fetch_row |
... |
- 編碼注入:
寬字節(jié)注入
如下代碼:
<?php
$conn=mysql_connect('localhost','root','root');
mysql_select_db("userinfo",$conn);
mysql_query("SET NAMES 'GBK'");
$uid=addslashes($_GET['id']);
$sql="SELECT * FROM user where name='$uid'";
$result=mysql_query($sql,$conn);
print_r('now sql is:' .$sql. '<br/>result is:');
print_r(mysql_fetch_row($result));
mysql_close();
?>
這里加入了addslashes函數(shù),對(duì)部分字符進(jìn)行了轉(zhuǎn)義养盗,比如:
這里主要是存在一個(gè)問題是缚陷,編碼設(shè)置成了GBK,這里會(huì)導(dǎo)致成編碼注入往核,也就是寬字節(jié)注入蹬跃,GB2312、GBK、GB18030蝶缀、BIG5丹喻、Shift_JIS等這些都是常說的寬字節(jié),實(shí)際上只有兩字節(jié)翁都。寬字節(jié)帶來的安全問題主要是吃ASCII字符(一字節(jié))的現(xiàn)象碍论,這里addslashes會(huì)將引號(hào)后面加入反斜杠(\),會(huì)造成我們無法利用柄慰,GBK的編碼范圍是0x8140~0xFEFE(不包括xx7F)鳍悠,在遇到%df(ascii(223)) >ascii(128)時(shí)自動(dòng)拼接%5c,因此吃掉‘\’坐搔,而%27藏研、%20小于ascii(128)的字符就保留了,而反斜杠的編碼是%5c概行,而%df%5c是漢字“運(yùn)”蠢挡,所以我們?cè)趩我?hào)前加上%df即可將后面的單引號(hào)吞掉,造成引號(hào)成功逃脫轉(zhuǎn)義:
GBK編碼第一字節(jié)(高字節(jié))的范圍是0x81~0xFE,第二字節(jié)(低字節(jié))的范圍是0x40~0x7E與0x80~0xFE凳忙,這樣的十六進(jìn)制表示业踏。而\符號(hào)的十六進(jìn)制表示為0x5C,正好在GBK的低字節(jié)中涧卵,如果之前有一個(gè)高字節(jié)勤家,那么正好會(huì)被組成一個(gè)合法字符,GB2312是被GBK兼容的,它的高位范圍是0xA1~0xF7柳恐,低位范圍是0xA1~0xFE(0x5C不在該范圍內(nèi))伐脖,因此不能使用編碼吃掉%5c,其它的寬字符集也是一樣的分析過程乐设,要吃掉%5c讼庇,只需要低位中包含正常的0x5c就行了。
這里一定要注意sql注入和xss不同伤提,在xss中,把上面的PHP代碼的GBK改為GB2312认烁,在瀏覽器中處理行為同GBK肿男,也許是由于GBK兼容GB2312,瀏覽器都做了同樣的兼容:把GB2312統(tǒng)一按GBK行為處理
結(jié)果如下:
關(guān)鍵字 |
---|
SET NAMES |
character_set_client=gbk |
mysql_set_charset('gbk') |
二次urldecode注入
字符進(jìn)行轉(zhuǎn)換就會(huì)有可能產(chǎn)生漏洞却嗡,現(xiàn)在大多數(shù)web程序都會(huì)進(jìn)行參數(shù)過濾舶沛,一般會(huì)選擇addslashes() 等函數(shù)或者開啟GPC來對(duì)特殊符號(hào)進(jìn)行轉(zhuǎn)義,如果某處使用了urldecode或者rawurldecode函數(shù)會(huì)導(dǎo)致二次解碼生成單引號(hào)而引起注入窗价。
測(cè)試代碼:
<?php
$a=addslashes($_GET['p']);
$b=urldecode($a);
echo 'a='.$a;
echo "<br/>";
echo 'b='.$b;
?>
這里我們有兩個(gè)變量如庭,a變量是使用addslashes函數(shù)對(duì)get得到的p進(jìn)行轉(zhuǎn)義,b變量是對(duì)a進(jìn)行urldecode的結(jié)果撼港,由于使用了addslashes坪它,所以我們的單引號(hào)后面加上了反斜杠:
但是由于urldecode函數(shù)的存在骤竹,我們可以構(gòu)造如下利用過程:
?p=1%2527
由于瀏覽器自動(dòng)進(jìn)行了一次url解碼,所以%25被解碼為%往毡,而又因?yàn)閡rldecode函數(shù)的作用蒙揣,%27被解碼為單引號(hào)('):
關(guān)鍵字 |
---|
urldecode |
rawurldecode |
Base64編碼注入
類似于URL編碼注入,還有Base64編碼注入开瞭,經(jīng)過前端Base64轉(zhuǎn)換后懒震,參數(shù)被Base64加密,防御模塊無法通過關(guān)鍵詞分析出此參數(shù)的惡意字符嗤详。審計(jì)過程中遇到Base64_decode函數(shù)个扰,之后沒有做任何過濾,直接拼接到SQL語(yǔ)句中葱色,就可能導(dǎo)致SQL注入漏洞递宅。
參考文章: