0

我正在尝试使用UNION查询演示 SQL 注入,但我没有得到结果。

这是 C# 代码,数据库是 SQL Server 2008 R2:

        SqlConnection conn = new SqlConnection(cString);
        conn.Open();

        string sql = "select * from Users where UserName='" + userName 
                   + "' and Password='" + password + "'";
        SqlCommand cmd = conn.CreateCommand();
        cmd.CommandText = sql;

        SqlDataReader reader = cmd.ExecuteReader();

        StringBuilder sb = new StringBuilder(1024);

        while (reader.Read())
        {
            for (int i = 0; i < reader.FieldCount; i++)
            {
                sb.Append(" " + reader.GetName(i));
                sb.Append(": ");
                sb.Append(reader[i]);
            }
            sb.Append("<br />");
        }
        dataLabel.Text = sb.ToString();

我有一个用户名和密码文本框,输入被传递给这个方法。
我尝试了以下但没有结果:

'UNION SELECT * FROM products --

Users表和表具有相同的Products列类型 ( int, nvarchar, nvarchar)。

有人可以帮忙吗?我错过了什么?

4

2 回答 2

2

如果您要传入' UNION SELECT * FROM Products参数password,那么您的查询将如下所示(假设您将foo或任何其他有效或无效的用户名放入username):

SELECT * from Users 
  where UserName='foo' and Password='' 
UNION 
SELECT * FROM Products --'

除非您有一行Users与 where 子句匹配(即使您使用有效的用户名,恶意用户可能只能猜到,但仍然有一个肯定不匹配的空白密码),您为什么期望任何从表中返回的行Users

如果您将此值传递给用户名,您最终会得到:

SELECT * from Users 
  where UserName='' 
UNION 
SELECT * FROM Products -- and Password='foo'

同样,除非您的用户名带有空白用户名,否则您为什么会期望任何行?

无论如何,那里有很多很棒的材料来描述 SQL 注入。为什么要重新发明轮子?为什么不只强制执行参数化查询,并让他们阅读现有材料以了解原因的详细信息?这里只是一些很好的资源:

http://en.wikipedia.org/wiki/SQL_injection

http://www.unixwiz.net/techtips/sql-injection.html

http://msdn.microsoft.com/en-us/library/ms161953(v=sql.105).aspx

http://weblogs.sqlteam.com/mladenp/archive/2011/02/16/sql-server-sql-injection-from-start-to-end.aspx

于 2013-01-13T02:04:39.587 回答
2

我同意 Aaron 的观点:利用现有资源而不是重新发明轮子。但是,我也明白,展示您自己的应用程序的脆弱性可能非常强大。因此,要使您的查询工作,您需要将以下内容传递给用户名和密码:

' OR 1=1;--

这与查询中密码和用户名的顺序无关。它将返回所有用户的记录。您不需要在其中添加产品表。

于 2013-01-13T02:29:08.587 回答