我正在尝试使用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
)。
有人可以帮忙吗?我错过了什么?
答案 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
答案 1 :(得分:2)
我同意Aaron:使用那里的资源而不是重新发明轮子。但是我也明白,显示你自己的应用程序是多么容易受到威胁。因此,为了使您的查询有效,您需要将以下内容传递给UserName和Password:
' OR 1=1;--
这与查询中的Password和UserName的顺序无关。它将返回所有用户的记录。你不必在那里添加产品表。