知識點: MySQL表達式的計算順序、MySQL隱式轉化html
0x00:題目描述mysql
題目地址 http://www.shiyanbar.com/ctf/1942sql
0x01:試探post
對我這種小白來講,固然是[右鍵->查看源代碼]。測試
- - 沒有效果spa
輸入字符進行測試:.net
先輸個'試試htm
有回顯。blog
接着試試看過濾了啥ci
提交 1'2union3select4UNION5SeLect6oOrr7and8-- -9#10=11/
返回:
username:1'234567and8 -910=11
由此看來union select or -- # /都被過濾了
能用的有 ' =
因而思路就有了:
在username 和password處分別提交 '=',結果會是什麼樣子呢?
0x02:分析
假設他的查詢語句是這樣的:
select * from flag where username=’$_POST[‘username’]’ and password=’ $_POST[‘password’]’;
那麼該查詢語在接收到post的數據後變爲:
select * from flag where username=’’=’’ and password=’‘=’’;
知識點1:MySQL表達式的計算順序
遇到這種鏈式比較,mysql是從左到右依次計算的。
username=''返回FALSE(FALSE常量即爲0)
FALSE='' 即0=''
mysql> select FALSE='';
+----------+
| FALSE='' |
+----------+
| 1 |
+----------+
返回TRUE,這又是爲何呢
知識點2:MySQL隱式轉化
- 若是兩個參數比較,有至少一個NULL,結果就是NULL,除了是用NULL<=>NULL 會返回1。不作類型轉換
- 兩個參數都是字符串,按照字符串比較。不作類型轉換
- 兩個參數都是整數,按照整數比較。不作類型轉換
- 若是不與數字進行比較,則將十六進制值視爲二進制字符串。
- 有一個參數是 TIMESTAMP 或 DATETIME,而且另一個參數是常量,常量會被轉換爲時間戳
- 有一個參數是 decimal 類型,若是另一個參數是 decimal 或者整數,會將整數轉換爲 decimal 後進行比較,若是另一個參數是浮點數,則會把 decimal 轉換爲浮點數進行比較
- 全部其餘狀況下,兩個參數都會被轉換爲浮點數再進行比較
也就是說:
數字和字符串比較時,字符串將被轉換爲浮點數,即0。以數字開頭的字符串將會從最後一個數字後截斷。
例:’’=>0 ‘a’=>0 ‘11a’=>11
因此查詢語句最後結果爲
select * from flag where 1 and 1;
即拿到了flag。
延伸:
select * from test where groupname=0; (groupname爲varchar類型)
可是查詢語句中參數常常會被’’括起來。能夠用運算符將字符串轉換爲數字類型。
例如使用+:
select * from test where groupname=’’+’’;
+的優先級高於=,’’+’’被轉換爲0+0結果爲0,再計算groupname=0
還有其餘的方法好比-,*,/(‘’/1),%(‘’%1),位操做運算,比較運算符。詳情請參考[3]。
reference:
[1] helingfeng MySQL運算符的優先級 http://www.javashuo.com/article/p-ypqtlqyl-eb.html
[2] Rollen Holt MySQL隱式轉化整理 http://www.cnblogs.com/rollenholt/p/5442825.html
[3] Leej MySQL False注入及技巧總結 https://www.anquanke.com/post/id/86021
[4] 紫楓葉520 http://blog.csdn.net/zifengye520/article/details/48689175?locationNum=10