知识点: MySQL表达式的计算顺序、MySQL隐式转化
0x00:题目描述
题目地址 http://www.shiyanbar.com/ctf/1942
0x01:试探
对我这种小白来说,当然是[右键->查看源代码]。
- - 没有效果
输入字符进行测试:
先输个'试试
有回显。
接着试试看过滤了啥
提交 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运算符的优先级 https://www.cnblogs.com/helingfeng/p/6486854.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