字符集SQL注入
2015-12-16 17:08
316 查看
SQL注入
以前只是知道部分字符集转化时会导致注入,并未找到实际例子,现在看到了记录一下。
BIG5, CP932, GB2312, GBK and SJIS are blacklisted as they
may introduce a SQL injection vulnerability!
代码(php语言)
原理
Selecting a Character Set
For this attack to work, we need the encoding that the server's expecting on the connection both to encode
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 function
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
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
The Query
This part is just a formality, but here's the rendered query:
防范
If you:
OR
You're 100% safe.
原文
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
以前只是知道部分字符集转化时会导致注入,并未找到实际例子,现在看到了记录一下。
BIG5, CP932, GB2312, GBK and SJIS are blacklisted as they
may introduce a SQL injection vulnerability!
代码(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");
原理
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 function
mysql_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
防范
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.
原文
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
相关文章推荐
- Mysql 权限
- mysql设置远程连接
- RHCS + Mysql安装配置
- oracle内置函数 NVL (expr1, expr2),NVL2 (expr1, expr2, expr3)
- SQL中JOIN 的用法
- MySQL中使用表别名与字段别名的基本教程
- mysql远程连接出错
- Mybatis 使用Mapper接口的Sql动态代码方式进行CURD和分页查询
- sql基本语法与问题
- MySQL列转行
- Oracle 树操作(select…start with…connect by…prior)
- .NET 连接SQL Server2012遇到的连接出错问题解析
- .NET 连接SQL Server2012遇到的连接出错问题解析
- 性能调优之mysql通过status性能优化 3
- 性能调优之mysql通过status性能优化 2
- 性能调优之mysql通过status性能优化 1
- mysql 一些用法 总结
- sql语句添加删除外键
- 用VB连接MySQL数据库模块(详解)
- oracle中提高order by的性能