1

我正在尝试 SQLi 攻击。

尽管出现警告,编译器仍执行以下查询:

select * from users where username='A' or 'B' and password='C';

因为查询执行,所以攻击成功。为什么这个查询有效,它在做什么?我可以假设值“B”在布尔意义上被视为“真”吗?逻辑运算符如何相互配合?数学有没有像 BODMAS 这样的特定顺序?请注意,“B”是独立的,而不是布尔条件。

上述格式的查询在 mysql 数据库中工作正常,并返回与查询相同的结果:

select * from users where username='A';

不返回任何语法错误。

mysql> select * from authentication where user='A' or 'B' and password='C';
+------+----------+
| user | password |
+------+----------+
| A    | B        |
+------+----------+
1 row in set, 1 warning (0.00 sec)

警告如下:

mysql> show warnings;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: 'B' |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
4

4 回答 4

3

如果 'B' 不是布尔值,那么您需要指定要比较的对象,在这种情况下可能是username.

就像是;

select * from users where username='A' or username='B' and password='C'

这将评估username='B' AND password='C'然后OR username='A'

您也可以参考这篇StackOverflow帖子。

您可以在此处找到 SQL 运算符排序。

于 2013-10-16T14:02:50.847 回答
3

更新

根据您更新的问题和评论,您似乎知道语法中的错误,并想具体了解MySQL如何处理此查询。

看起来 MySQL 首先将字符串转换为整数值(产生警告)。

MySQL 将任何非零数视为TRUE,因此“B”在转换为整数后将评估为TRUE


首先,我认为您的查询在我知道的任何 DBMS 中都无效。既然你说 'B' 不是布尔条件,那么我不得不认为你的意思是:

select * from users where username IN ( 'A', 'B' ) and password='C';

当然,这会使您关于BODMAS的问题无效。因此,为了回答您的核心问题,我将您的 SQL 更改为:

select * from users where username='A' or username='B' and password='C';

这将取决于 DBMS 以及它如何选择解析 SQL。一般来说,AND应该优先于OR,但显然软件开发人员可以随意实现 SQL,所以我相信如果你足够努力的话,你可以找到反例(也许是一个按顺序处理布尔运算符的 DBMS,例如例子)。

SQL Server将处理AND之前的OR

http://technet.microsoft.com/en-us/library/ms190276.aspx

username='A' or ( username='B' and password='C' )

MySQL也会处理AND之前的OR

http://dev.mysql.com/doc/refman/5.0/en/operator-precedence.html

username='A' or ( username='B' and password='C' )

Sybase会处理AND之前的OR

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.ase_15.0.sqlug/html/sqlug/sqlug102.htm

username='A' or ( username='B' and password='C' )

DB2和其他人一样,将AND在之前处理OR

http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=%2Fcom.ibm.db2z9.doc.sqlref%2Fsrc%2Ftpc%2Fdb2z_precedenceofoperations.htm

username='A' or ( username='B' and password='C' )

即使是MS Access,我所知道的最不符合标准的 SQL 实现之一,也保留AND了 -before-OR优先级:

http://office.microsoft.com/en-us/access-help/HV080756432.aspx

username='A' or ( username='B' and password='C' )
于 2013-10-16T14:04:28.137 回答
2

当您编写这样的查询时,查询分析器会抛出语法错误。

SQL 不允许以“OR”分隔的值列表的语法构造,mu 必须“ORize”所有条件:

select * from users where (username='A' or user_name='B') and password='C';

这里需要括号,因为 AND 运算符优先于 OR 运算符,因此没有括号的查询被解释为username='A' or (user_name='B' and password='C')

一个额外的建议:不要将密码存储在数据库中。数据库不应处理纯文本密码,用户凭据验证应在应用程序级别而不是数据库级别进行管理。存储加密的密码哈希,从应用程序级别检索它们并在那里验证。此外,如果在 Web 环境中工作,强烈建议在客户端(浏览器)层加密密码或使用 SSL。

于 2013-10-16T14:01:57.510 回答
2

这篇文章有一个不错的表格,显示了 T-SQL 的操作顺序

假设您修复了查询中的小语法错误,您将返回以下任何内容:

  • 用户名“B”,密码“C”
  • 有一个用户名“A”

我相信你的语法应该是这样的

 select * from users where username='A' or username = 'B' and password='C';
于 2013-10-16T14:01:58.217 回答