Less 32
JSP
可能是閑著沒事多做了一關(guān)秉沼,名字就是Fun with JSP蛮浑,可能確實是用來娛樂的迎献。
單引號小括號字符型达舒,無過濾值朋。
唯一的樂趣是有一個index.jsp1
的備份文件,可以看到源碼巩搏,這也是 Web 題的一種套路昨登,一般用在 PHP 代碼審計和 SQL 注入的混合關(guān)。
PHP
基于錯誤_GET_單引號_字符型_轉(zhuǎn)義引號反斜杠_寬字節(jié)注入
0x01. 寬字節(jié)注入
在舊版本的 MySQL 安裝時贯底,會有編碼問題導(dǎo)致中文亂碼丰辣,需要手動設(shè)置編碼為 UTF-8。而安裝 MySQL 5.7 時并沒有出現(xiàn)這個問題禽捆,默認編碼已經(jīng)是 UTF-8笙什。
SHOW VARIABLES LIKE 'character%';
PHP 自帶一些轉(zhuǎn)義特殊字符的函數(shù),如addslashes()
睦擂,mysql_real_escape_string()
得湘,mysql_escape_string()
等,這些函數(shù)可用來防止 SQL 注入顿仇。
如id=1'or'1'='1
淘正,單引號本用來閉合語句摆马,這些函數(shù)會自動轉(zhuǎn)義這些閉合的單引號,在這些單引號前面加上轉(zhuǎn)義符\
鸿吆,變?yōu)?code>1\'or\'1\'=\'1囤采,如此在 SQL 查詢中仍然一個普通的字符串,不能進行注入惩淳。
而網(wǎng)站在過濾'
的時候蕉毯,通常的思路就是將'
轉(zhuǎn)換為\'
,因此我們在此想辦法將'
前面添加的\
去掉,一般有兩種思路:
%bb
連帶\
如果程序的默認字符集是GBK
等寬字節(jié)字符集思犁,就有可能產(chǎn)生寬字節(jié)注入代虾,繞過上述過濾。
若在 PHP 中使用mysql_query("set names gbk")
將默認字符集設(shè)為GBK
激蹲,而使用addslashes()
轉(zhuǎn)義用戶輸入棉磨,這時如果用戶輸入%bb%27
,則addslashes()
會在%27
前面加上一個%5c
字符学辱,即轉(zhuǎn)義字符\
乘瓤。
而 MySQL 在使用GBK
編碼時,會認為兩個字符為一個漢字策泣,%bb%5c
是一個寬字符(前一個 ASCII 碼大于 128 才能到漢字的范圍)衙傀,也就是籠
,也就是說%bb%5c%27
=籠'
萨咕,這樣單引號就未被轉(zhuǎn)義能閉合語句统抬,從而產(chǎn)生 SQL 注入。%bb
并不是唯一一個可以產(chǎn)生寬字節(jié)注入的字符任洞,理論上%81
-%FE
均可蓄喇。過濾
\'
中的\
構(gòu)造%bb%5c%5c%27
发侵,addslashes()
會在兩個%5c
和%27
前都加上\
即%5c
交掏,變?yōu)?code>%bb %5c%5c %5c%5c %5c%27,但寬字符集認為%bb%5c
是一個字符即籠
刃鳄,則變?yōu)?code>%bb%5c %5c%5c %5c%5c %27即籠\\\\'
盅弛,四個\
正好轉(zhuǎn)義為兩個\
,即'
未被轉(zhuǎn)義叔锐。這也是 bypass 的一種方法挪鹏。
0x02. 注入過程
知道這關(guān)是寬字節(jié)注入,先以上帝視角看看源碼:
mysql_query("SET NAMES gbk");
$id = check_addslashes($_GET['id']);
function check_addslashes($string)
{
$string = preg_replace('/'.preg_quote('\\').'/',"\\\\\\",$string); //escape any backslash
$string = preg_replace('/\'/i','\\\'',$string); //escape single quote with a backslash
$string = preg_replace('/\"/',"\\\"",$string); //escape double quote with a backslash
return $string;
}
可以看到這個函數(shù)是個過濾\
愉烙、'
讨盒、"
的函數(shù),分別在前面加上\
步责。
步驟1:確定寬字節(jié)注入
1
返顺、1'
禀苦、1"
都能正常回顯遂鹊,可以猜測輸入的引號被過濾振乏,從頁面給的 hint 也證實了這一點。
猜測是引號是被轉(zhuǎn)義而并非被純粹過濾秉扑,嘗試寬字節(jié)注入:
http://localhost:8088/sqlilabs/Less-32/?id=1%bb%27
有錯誤回顯慧邮,從其中可以看到被單引號閉合。
若無錯誤回顯舟陆,可注釋后面的查詢語句:
http://localhost:8088/sqlilabs/Less-32/?id=1%bb%27--+
用上述第二種方法同樣可以做到:
http://localhost:8088/sqlilabs/Less-32/?id=1%bb%5c%5c%27--+
已經(jīng)確定了單引號閉合且寬字節(jié)注入可以繞過误澳,剩下的就是正常的注入,無其他過濾條件秦躯。
因未過濾注釋脓匿,所以只有開頭的單引號需要寬字節(jié)注入。
0x03. 吐槽
總覺得越到后面越簡單了宦赠,可能是沒把過濾條件都結(jié)合起來陪毡,后來還得總結(jié)一下過濾條件和注入方式。
Less 33
基于錯誤_GET_單引號_字符型_addslashes()_寬字節(jié)注入
Less 32 是自定義的過濾器勾扭,本關(guān)直接使用了 PHP 的addslashes()
函數(shù)毡琉,在 Less 17 中介紹過:
addslashes()與stripslashes()函數(shù)
addslashes(string)
函數(shù)返回在預(yù)定義字符之前添加反斜杠\
的字符串:
- 單引號
'
- 雙引號
"
- 反斜杠
\
- 空字符
NULL
該函數(shù)可用于為存儲在數(shù)據(jù)庫中的字符串以及數(shù)據(jù)庫查詢語句準備字符串。
注意:默認地妙色,PHP對所有的GET桅滋、POST和COOKIE數(shù)據(jù)自動運行
addslashes()
。所以不應(yīng)對已轉(zhuǎn)義過的字符串使用addslashes()
身辨,因為這樣會導(dǎo)致雙層轉(zhuǎn)義丐谋。遇到這種情況時可以使用函數(shù)get_magic_quotes_gpc()
進行檢測。
stripslashes(string)
函數(shù)刪除由addslashes()
函數(shù)添加的反斜杠煌珊。
判斷和注入過程同 Less 32 完全相同号俐。