字符集SQL注入

本文详细介绍了如何通过特定字符集设置绕过PHP中的mysql_real_escape_string函数进行SQL注入攻击的方法,并给出了具体的PHP代码示例。此外,还提供了有效的防范措施。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SQL注入

  1. 以前只是知道部分字符集转化时会导致注入,并未找到实际例子,现在看到了记录一下。

    BIG5, CP932, GB2312, GBK and SJIS are blacklisted as they may introduce a SQL injection vulnerability!

  2. 代码(php语言)

    mysql_query('SET NAMES gbk');
    $var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
    mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");
  3. 原理

    • Selecting a Character Set

      mysql_query('SET NAMES gbk');

      For this attack to work, we need the encoding that the server's expecting on the connection both to encode' as in ASCII i.e. 0x27 and to have some character whose final byte is an ASCII \ i.e. 0x5c. As it turns out, there are 5 such encodings supported in MySQL 5.6 by default: big5, cp932, gb2312, gbk and sjis. We'll select gbk here.

      Now, it's very important to note the use of SET NAMES here. This sets the character set ON THE SERVER. If we used the call to the C API functionmysql_set_charset(), we'd be fine (on MySQL releases since 2006). But more on why in a minute...

    • The Payload

      The payload we're going to use for this injection starts with the byte sequence 0xbf27. In gbk, that's an invalid multibyte character; in latin1, it's the string ¿'. Note that in latin1 and gbk, 0x27 on its own is a literal ' character.

      We have chosen this payload because, if we called addslashes() on it, we'd insert an ASCII \ i.e. 0x5c, before the ' character. So we'd wind up with 0xbf5c27, which in gbk is a two character sequence: 0xbf5c followed by 0x27. Or in other words, a valid character followed by an unescaped '. But we're not using addslashes(). So on to the next step...

    • mysqlrealescape_string()

      The C API call to mysql_real_escape_string() differs from addslashes() in that it knows the connection character set. So it can perform the escaping properly for the character set that the server is expecting. However, up to this point, the client thinks that we're still using latin1 for the connection, because we never told it otherwise. We did tell the server we're using gbk, but the client still thinks it's latin1.问题就出在latin1转成gbk过程中。

      Therefore the call to mysql_real_escape_string() inserts the backslash, and we have a free hanging ' character in our "escaped" content! In fact, if we were to look at $var in the gbk character set, we'd see:

      縗' OR 1=1 /*
    • The Query

      This part is just a formality, but here's the rendered query:

      SELECT * FROM test WHERE name = '縗' OR 1=1 /*' LIMIT 1
  4. 防范

    If you:

    Use Modern Versions of MySQL (late 5.1, all 5.5, 5.6, etc) AND mysql_set_charset() / $mysqli->set_charset() / PDO's DSN charset parameter (in PHP ≥ 5.3.6)
    

    OR

    Don't use a vulnerable character set for connection encoding (you only use utf8 / latin1 / ascii / etc)
    

    You're 100% safe.

  5. 原文

http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string/12118602#12118602

http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

### 判断字符型SQL注入的方法 对于字符型SQL注入漏洞的检测,通常采用特定的测试字符串来验证数据库查询语句的行为。具体来说,在URL参数或其他输入字段中加入特殊条件并观察应用程序响应的变化。 假设有一个存在潜在风险的查询: ```sql SELECT * FROM article WHERE id='$id' ``` 为了确认是否存在字符型SQL注入的可能性,可以尝试构造如下两种情况下的请求,并对比服务器返回的结果差异[^4]。 #### 测试场景一:真命题条件下 向目标应用发送带有附加逻辑表达式的HTTP GET/POST请求,使整个WHERE子句始终成立。例如: `http://example.com/article?id='33' AND '1'='1` 这相当于执行了下面这条SQL命令: ```sql SELECT * FROM article WHERE id='33' AND '1'='1'; ``` 正常情况下,此操作应该不会影响原有记录集的选择范围,即预期结果应与访问ID为33的文章相同。 #### 测试场景二:假命题条件下 同样地,构建另一个版本的请求使得WHERE部分最终求值为FALSE: `http://example.com/article?id='33' AND '1'='2` 对应的SQL语句变为: ```sql SELECT * FROM article WHERE id='33' AND '1'='2'; ``` 理想状态下,上述修改后的查询应当无法匹配任何数据行,从而导致空白页或报错信息显示给用户。 通过对这两种不同情形下网页表现形式的比较分析——特别是注意查看是否有异常提示、页面布局变动或是内容缺失等问题——便能有效推断出该处是否隐藏着字符型SQL注入的风险点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值