关于 SQL 注入示例的一些疑问,究竟是如何工作的?

信息安全 渗透测试 sql注入 注射 owasp
2021-08-27 21:48:46

我是一名开始研究应用程序安全的软件开发人员,我对 SQL 注入有以下疑问。

我正在关注视频课程,有以下两个示例:

  1. 我有一个不安全的 SQL 查询,如下所示:

    txtSql = "SELECT * FROM Users WHERE UserId = " + txtUserId
    

    如果传递的值txtUserId类似于99 OR 1 = 1,我将获得这样的查询

    SELECT * FROM Users WHERE UserId = 99 OR 1 = 1
    

    这将返回表中包含的整个记录​​列表,Users因为1 = 1它始终为真,并且OR连接将返回真,所以就像这个查询:

    SELECT * FROM Users WHERE TRUE
    

    将整个记录列表返回给我。这个推理正确吗?

  2. 然后我有第二个更复杂的例子:

    有一个用户登录表单(用户名和密码)。这种形式的背后有这个不安全的查询实现:

    sql = 'SELECT * FROM USERS WHERE Name = "' + uName + '" AND Pass = "' + uPass + '"'
    

    如果用户在登录表单中插入以下数据:

    uName = " OR ""="
    uPass = " OR ""="
    

    结果查询将是:

    SELECT * FROM Users WHERE Name = "" OR ""="" AND Pass = "" OR ""=""
    

    所以它正在选择记录

    • Name字段为空 ("") 或等于"="(并且此条件应始终为 false,因为拥有空用户名或像“=”这样的用户名是很奇怪的)。

    • Pass字段为空 ("") 或等于"="(并且此条件应始终为 false,因为使用空密码或类似“=”的密码是很奇怪的)。

    所以我们有一个像这样的条件:

    WHERE FALSE AND FALSE
    

    这是我的疑问: FALSE AND FALSE = FALSE

为什么它说这个查询返回了用户表的整个记录​​列表?

如果我理解正确的逻辑,第二个查询应该翻译成这样的:

SELECT * FROM Users WHERE FALSE AND FALSE

我的推理有什么问题?我错过了什么?

1个回答

您误读了注入,特别是这部分:

""=""

这不是检查是否Name是等号,而是检查空字符串是否等于空字符串。它实际上是一样的东西1=1(他们也可以1=1在这里使用),因此相当于TRUE. 所以这个条款:

Name = "" OR ""=""

是一样Name="" OR 1=1Name="" OR TRUE

很容易误读类似的内容。我相信这就是你所需要的,因为否则你会清楚地理解这些概念!只是作为一个书呆子,查询基本上归结为:

WHERE Name="" OR TRUE AND Pass="" OR TRUE

接下来发生的事情可能取决于确切的优先顺序,但它可能会很好。您可以使用的另一个技巧是用反斜杠Pass从查询中删除所有结束用户名(尽管这可能不适用于所有 SQL 风格)。想象一下注入User=\Pass= OR 1=1 --(以评论结束)。你最终会得到这个查询:

SELECT * FROM USERS WHERE Name="\" AND Pass = " OR 1=1 --"

由于反斜杠,它将搜索 a Nameof " AND Pass =(不匹配任何内容),但随后OR 1=1将使其匹配所有内容。结束注释去掉了最后一个双引号,否则会导致语法错误。Pass这种形式通过有效地对列进行搜索并因此放弃所有AND/OR子句,使您可以更好地控制查询。例如,您可以通过将Pass条件更改为OR ID=10(假设有一ID列)来搜索实际 ID。