php双字节编码漏洞,PHP多字节编码漏洞小结

本文探讨了PHP中php_escape_shell_cmd函数在处理宽字节字符集如GBK时的安全漏洞,导致的SQL注入问题。通过示例代码展示了如何利用此漏洞,并解释了设置客户端字符集为二进制以防止此类注入的方法。尽管如此,文章指出这并不完全解决问题,暗示仍有潜在风险。
摘要由CSDN通过智能技术生成

如果小结中有理解错误的地方,麻烦大家提出。漏洞本质: php 使用 php_escape_shell_cmd这个函数来转义命令行字符串时是作为单字节处理的而当操作系统设置了GBK、EUC-KR、SJIS等宽字节字符集时候,将 ...

如果小结中有理解错误的地方,麻烦大家提出。

漏洞本质:

php 使用 php_escape_shell_cmd这个函数来转义命令行字符串时是作为单字节处理的

而当操作系统设置了GBK、EUC-KR、SJIS等宽字节字符集时候,将这些命令行字符串传递给MySQL处理时是作为多字节处理的

先看个简单的例子

复制代码代码如下:

header('Content-type: text/html; charset=gbk');

//连接MySQL

$conn = mysql_connect("localhost", "root", "");

//选择数据库

mysql_select_db("test", $conn);

//设置字符集编码

mysql_query("SET CHARACTER SET 'gbk'", $conn);

//创建DEMO表如果不存在

mysql_query("CREATE TABLE IF NOT EXISTS `demo` (

`uid` int(10) NOT NULL AUTO_INCREMENT,

`username` varchar(32) NOT NULL,

`password` varchar(32) NOT NULL,

PRIMARY KEY (`uid`)

) ENGINE=MyISAM DEFAULT CHARSET=gbk AUTO_INCREMENT=1;", $conn);

//插入个测试数据

mysql_query("REPLACE INTO `demo` VALUES('','admin','admin888') ",$conn);

//获取用户输入

$username = isset($_REQUEST['username']) ? $_REQUEST['username'] : '';

//执行查询并且DEBUG

$sql = "SELECT * FROM demo WHERE username = '{$username}' LIMIT 1";

echo "sql: ".$sql."

";

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

$row = mysql_fetch_array($res);

echo "result:
";

var_dump($row);

?>

当GPC=OFF时:

username未经任何过滤,这是个典型的字符型SQL注入

测试地址:

http://localhost/gbk.php?username=' or 1%23

http://localhost/gbk.php?username=' or 0%23

当然很多情况下GPC=OFF时候都会使用一些函数来过滤用户的输入

复制代码代码如下:

// 对用户传入的变量进行转义操作

if (!get_magic_quotes_gpc())

{

$username = addslashes($username);

}

看上去貌似没问题了,但是由于多字节编码问题,同样还是可以注入的

测试地址:http://localhost/gbk.php?username=%df%27

使用mysql_real_escape_string函数对用户输入进行转义存在同样的问题

目前的很多开源的系统都是通过设置客户端的字符集为二进制来防止多字节编码问题的。

//使用上面这句来替换DEMO中的 mysql_query("SET CHARACTER SET 'gbk'", $conn);

mysql_query("SET character_set_connection=gbk, character_set_results=gbk, character_set_client=binary", $conn);

再次测试:http://localhost/gbk.php?username=%df%27

OK,这样一来,多字节编码问题就不存在了吗?不见得

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值