联合SQL注入

时间:2013-01-13 01:08:37

标签: c# sql-server sql-injection

我正在尝试使用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)。

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

我同意Aaron:使用那里的资源而不是重新发明轮子。但是我也明白,显示你自己的应用程序是多么容易受到威胁。因此,为了使您的查询有效,您需要将以下内容传递给UserName和Password:

' OR 1=1;--

这与查询中的Password和UserName的顺序无关。它将返回所有用户的记录。你不必在那里添加产品表。