联合SQL注入

本文关键字:注入 SQL 联合 | 更新日期: 2023-09-27 17:52:16

我试图用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)。

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

联合SQL注入

如果您将' UNION SELECT * FROM Products传递到password参数,那么您的查询看起来像这样(假设您将foo或任何其他有效或无效的用户名放入username):

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

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

如果你把这个值传递给username,你会得到这样的结果:

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

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

' OR 1=1;--

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