SQL注入单引号漏洞

5

你好,我正在对我正在开发的网站进行安全测试。某些开发人员试图通过将每个单引号替换为双引号来避免SQL注入攻击。这是C#代码:

string sql = 
  @"SELECT *
      FROM users
     WHERE us_username = '$us'
       AND us_password = '$pw'";    

sql.Replace("$pw", txtPassword.Text.Replace("'","''"));

有没有办法进行SQL注入攻击?我尝试过Unicode技巧,但没有成功。数据库运行在SQL Server 2008R2上。


9
可能是的,但与其试图弄清楚如何解决,你不如用湿面条抽打程序员并重写他们的代码,使用已经注入防护的正确方法。选择100%解决方案而非99.9%的“或许”。 - Marc B
是的,你可能是对的,但我没有时间修复它,除非我可以破解它并证明它的弱点。 - Dibran
1
“不允许使用单引号,这个SQL注入点还能利用吗?” - sstan
正如先前所述,答案可能是肯定的。如果你正在寻找某个人提供证明,你可能需要指定你正在使用哪个数据库,因为攻击方式将根据数据库而异。 - sstan
我认为这是在这种情况下你能找到的最接近答案的链接:https://dev59.com/cWfWa4cB1Zd3GeqPmPlr - sstan
显示剩余2条评论
3个回答

7

你应该使用参数化命令。使用 string.Replace 只是一个糟糕的想法。

var command = conn.CreateCommand();
command.CommandText = @"SELECT *
        FROM users
        WHERE us_username = @user
        AND us_password = @password";
cmd.Parameters.Add("@user", txtUser.Text);
cmd.Parameters.Add("@password", txtPassword.Text);

这可能是您设置的潜在候选者:
As an example, note the following trivial Stored Procedure:
create procedure GetData ( @param varchar(20) ) as
begin
declare @s varchar(200)
select @s = 'select * from dataTable where name = ''' + @param + ''''
exec (@s)
end

This SP may be called from a Web page, which executes validation code before passing the input to the SP. At a minimum, this validation code either verifies that the input does not contain a quote, or sanitizes it to double any existing quote. For instance, the validation code may be using string.Contains(), string.Replace(), Regular expressions, etc. It is also possible that this Web page is behind a finely-tuned Web Application Firewall that validates all input and verifies that no quotes are included. A malicious user or attacker can submit malicious code containing a modifier letter apostrophe (U+02BC, URL encoded to %CA%BC). This will easily pass applicative validation code and WAF filters, since these search for an actual quote (U+0027) which does not exist in the input at this time. Obviously, IDS/IPS systems would also not detect anything amiss. The validation mechanisms may even search for various encodings of a quote, such as URL Encoding, UTF-8 encoding, Hex encoding, double encoding, and more – however, U+02BC is none of these, and is in fact a completely different character value.


And this is where the interesting (or scary) part starts – the Unicode homoglyph translation is not limited to base alphabet characters... Specifically, the Unicode character U+02BC (modifier letter apostrophe) can be translated by the database server to a simple quote – ' (U+0027). There are, of course, many other similar examples.

来源:http://web.archive.org/web/20130401091931/http://www.comsecglobal.com/FrameWork/Upload/SQL_Smuggling.pdf


2
这不是OP所问的。虽然是个好建议,但并不是问题的关键。 - Marc B
1
确实我需要漏洞利用,而不是修复程序。无论如何感谢您。 - Dibran
1
感谢更新,我尝试在文本框中输入以下内容,但它没有起作用:\u0027或\u00271\u0027=\u00271。在C#中,该字符串看起来像这样:password = '"\u0027 or \u00271\u0027=\u00271"'。 - Dibran

3
那个特定查询的代码对SQL注入是安全的,但仅当与某些数据库一起使用时才安全。每个系统都有自己需要转义的字符集,因此如果您将其与例如MySQL一起使用,则不安全。其他查询可能安全。
尽管如此,应该替换该代码,因为它已经损坏了。由于您需要修复代码,因此还应更改为使用参数化查询,这是更强大和可移植的解决方案。
那么,让我们看看出了什么问题。由于代码一次替换一个参数,它们可能会互相干扰。例如,如果我输入用户名has$$$pwnd和密码1234(是的,密码太弱了),那么您最终得到的查询将如下所示:
SELECT *
  FROM users
WHERE us_username = 'has$$1234nd'
  AND us_password = '1234'

如果某些值包含用于替换其后的参数所使用的代码,则这些值会变得不完整。
如果代码中存在不同类型的参数且未正确验证值,则甚至可以将其用于在代码中的其他查询中进行SQL注入。由于来自一个参数的值可能最终出现在另一个参数中,因此字符串值可能最终出现在没有单引号的数值参数中,因此无需偷偷加入单引号以跳出字符串文字并将有害代码放入查询中。

感谢指出替换错误和数字参数。非常感谢您的努力! - Dibran

-1

防止 SQL 注入的最佳方法是添加参数。

   SqlCommand sql = new SqlCommand (@"SELECT *
            FROM users
            WHERE us_username = @user
            AND us_password = @password")

sql.Parameters.Add("@users", SqlDbType.Varchar2, 5).Value = "users"; 
sql.Parameters.Add("@user", SqlDbType.Varchar2, 6).Value = "your_value";
sql.Parameters.Add("@password", SqlDbType.Varchar2, 8).Value = "your_value";

正如您所看到的,您可以采取相当多的措施来确保执行的是您想要执行的值。

开发人员编写的代码仅会在事后更改 SQL 语句,如果他们正在记录此 SQL 语句,则这很好。但是,您现在拥有的内容将无法防止 SQL 注入攻击。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接