Sqli-Labs:Less 32 - Less 33

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)這個問題,默認(rè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 查詢中仍然一個普通的字符串,不能進(jìn)行注入。

而網(wǎng)站在過濾'的時候,通常的思路就是將'轉(zhuǎn)換為\',因此我們在此想辦法將'前面添加的\去掉,一般有兩種思路:

  1. %bb連帶\
    如果程序的默認(rèn)字符集是GBK等寬字節(jié)字符集,就有可能產(chǎn)生寬字節(jié)注入,繞過上述過濾。
    若在 PHP 中使用mysql_query("set names gbk")將默認(rèn)字符集設(shè)為GBK,而使用addslashes()轉(zhuǎn)義用戶輸入,這時如果用戶輸入%bb%27,則addslashes()會在%27前面加上一個%5c字符,即轉(zhuǎn)義字符\
    而 MySQL 在使用GBK編碼時,會認(rèn)為兩個字符為一個漢字,%bb%5c是一個寬字符(前一個 ASCII 碼大于 128 才能到漢字的范圍),也就是,也就是說%bb%5c%27=籠',這樣單引號就未被轉(zhuǎn)義能閉合語句,從而產(chǎn)生 SQL 注入。%bb并不是唯一一個可以產(chǎn)生寬字節(jié)注入的字符,理論上%81-%FE均可。

  2. 過濾\'中的\
    構(gòu)造%bb%5c%5c%27,addslashes()會在兩個%5c%27前都加上\%5c,變?yōu)?code>%bb %5c%5c %5c%5c %5c%27,但寬字符集認(rèn)為%bb%5c是一個字符即,則變?yōu)?code>%bb%5c %5c%5c %5c%5c %27即籠\\\\',四個\正好轉(zhuǎn)義為兩個\,即'未被轉(zhuǎn)義。這也是 bypass 的一種方法。

一個字符集轉(zhuǎn)碼網(wǎng)站

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é)注入

11'、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ù)庫查詢語句準(zhǔn)備字符串。

注意:默認(rèn)地,PHP對所有的GET、POST和COOKIE數(shù)據(jù)自動運行addslashes()。所以不應(yīng)對已轉(zhuǎn)義過的字符串使用addslashes(),因為這樣會導(dǎo)致雙層轉(zhuǎn)義。遇到這種情況時可以使用函數(shù)get_magic_quotes_gpc()進(jìn)行檢測。

stripslashes(string)函數(shù)刪除由addslashes()函數(shù)添加的反斜杠。

判斷和注入過程同 Less 32 完全相同。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容