从万能密码看SQL的逻辑运算符

0x00 背景介绍

万能密码大伙都知道,类似于 admin' or '1'='1,至于为什么,我突然间糊涂了,糊涂的地方在于or和and两个逻辑运算符的优先级。
  下面来看一个例子,后台数据库语句很普通,如下:select * from user where username='$name' and passwd='$password';将username写成admin' or '1'='1,passwd随意写成123,那么上面那条语句就变成了:select * from user where username='admin' or '1'='1' and passwd='123'
  因为逻辑运算符的优先级:NOT>AND>OR,所以上面语句的执行过程如下: select * from user where username='admin' or 【 '1'='1' and passwd='123'】,方括号中间的内容一般都是假的,因为passwd是随意写的,一般都不对,所以也无外乎写成'1'='1'还是'1'='2',所以or后面的逻辑是【假】,但是username='admin'是【真】,所以这条语句就相当于:select * from user where username='admin'
  当然,如果passwd字段如果正确了,则会返回至少两条数据。【大前提】username中有admin。

0x01 AND OR 实验

mysql> select * from pet;
+-------+------+
| name  | seq  |
+-------+------+
| danny |    1 |
| bell  |    2 |
| sunny |    3 |
+-------+------+
3 rows in set (0.00 sec)

mysql> select * from pet where name = 'danny' and seq='1';
+-------+------+
| name  | seq  |
+-------+------+
| danny |    1 |
+-------+------+
1 row in set (0.00 sec)

mysql> select * from pet where name = 'danny' or seq='2';  
+-------+------+
| name  | seq  |
+-------+------+
| danny |    1 |
| bell  |    2 |
+-------+------+
2 rows in set (0.00 sec)

mysql> select * from pet where name = 'danny' or '1'='1' and seq='1';
+-------+------+
| name  | seq  |
+-------+------+
| danny |    1 |
+-------+------+
1 row in set (0.00 sec)

mysql> select * from pet where name = 'danny' or '1'='1' and seq='2'; //注意看此处
+-------+------+
| name  | seq  |
+-------+------+
| danny |    1 |
| bell  |    2 |
+-------+------+
2 rows in set (0.00 sec)

mysql> select * from pet where name ='danny' or '1'='2' and seq='2';  //注意看此处
+-------+------+
| name  | seq  |
+-------+------+
| danny |    1 |
+-------+------+
1 row in set (0.19 sec)

0x02 NOT实验

mysql> select * from pet where not name ='danny' or '1'='1' and seq='1'; //关于NOT,NOT虽然优先级最高,但是他的作用域只到OR,如果NOT的作用域是整个where的话,那结果应该是bell和sunny
+-------+------+
| name  | seq  |
+-------+------+
| danny |    1 |
| bell  |    2 |
| sunny |    3 |
+-------+------+
3 rows in set (0.00 sec)

mysql> select * from pet where not name ='danny' and seq='1'; //作用域只到AND,总结一下就是NOT只到最近的一个逻辑运算符。
Empty set (0.00 sec)

mysql> select * from pet where not name ='danny' and seq='2';
+------+------+
| name | seq  |
+------+------+
| bell |    2 |
+------+------+
1 row in set (0.00 sec)

mysql> select * from pet where not (name ='danny' and seq='2');
+-------+------+
| name  | seq  |
+-------+------+
| danny |    1 |
| bell  |    2 |
| sunny |    3 |
+-------+------+
3 rows in set (0.00 sec)

mysql> select * from pet where not name ='danny' and seq='2' or seq='3'; //最后一个例子再次佐证
+-------+------+
| name  | seq  |
+-------+------+
| bell  |    2 |
| sunny |    3 |
+-------+------+
2 rows in set (0.00 sec)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容