PHP多字节编码漏洞原理与实现
可能很多人不知道多字节编码漏洞的本质和做法,我们可以用php实现,这篇文章主要介绍了PHP多字节编码漏洞小结,需要的朋友可以参考下!
漏洞本质:
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,这样一来,多字节编码问题就不存在了吗?不见得
当使用mb_convert_encoding、iconv对字符集进行错误的转换时候,漏洞再次的出现了(GPC=ON时问题同样存在)
例如:
$username = iconv('gbk','utf-8',$username);
或
$username = mb_convert_encoding($username,'utf-8','gbk');
来看下T00ls上看到的ECSHOP 2.6.x/2.7.x GBK版本的漏洞吧
漏洞文件在api/checkorder.php line 28
复制代码代码如下:
$sql = "SELECT COUNT(*) ".
" FROM " . $ecs->table('admin_user') .
" WHERE user_name = '" . trim($_REQUEST['username']). "' AND password = '" . md5(trim($_REQUEST['password'])) . "'";
我们来看下$_REQUEST['username'] 的获取过程
复制代码代码如下:
$_REQUEST['username'] = json_str_iconv($_REQUEST['username']);
json_str_iconv()这个函数在includes/lib_base.php中定义,其功能是将非UTF-8编码的字符串进行转换,然后return ecs_iconv('utf-8', EC_CHARSET, $str);
ecs_inonv这个函数也在 includes/lib_base.php中定义,看下函数吧:
function ecs_iconv($source_lang, $target_lang, $source_string = '')
{
static $chs = NULL;
/* 如果字符串为空或者字符串不需要转换,直接返回 */
if ($source_lang == $target_lang || $source_string == '' || preg_match("/[\x80-\xFF]+/", $source_string) == 0)
{
return $source_string;
}
if ($chs === NULL)
{ require_once(ROOT_PATH . 'includes/cls_iconv.php');
$chs = new Chinese(ROOT_PATH);
}
return $chs->Convert($source_lang, $target_lang, $source_string);
}
先是引入了includes/cls_iconv.php这个文件,然后实例化了Chinese这个类,在调用类的Convert的方法见line 127
$string = $this->_convert_iconv_mbstring($this->SourceText, $this->config['target_lang'], $this->config['source_lang']);
又调用了另外一个函数_conver_iconv_mbstring见line 278
//这里错误的吧字符集从gbk转为了utf8,所以漏洞产生了
$return_string = @mb_convert_encoding($string, $target_lang, $source_lang);
补充:校园网安全维护技巧
校园网络分为内网和外网,就是说他们可以上学校的内网也可以同时上互联网,大学的学生平时要玩游戏购物,学校本身有自己的服务器需要维护;
在大环境下,首先在校园网之间及其互联网接入处,需要设置防火墙设备,防止外部攻击,并且要经常更新抵御外来攻击;
由于要保护校园网所有用户的安全,我们要安全加固,除了防火墙还要增加如ips,ids等防病毒入侵检测设备对外部数据进行分析检测,确保校园网的安全;
外面做好防护措施,内部同样要做好防护措施,因为有的学生电脑可能带回家或者在外面感染,所以内部核心交换机上要设置vlan隔离,旁挂安全设备对端口进行检测防护;
内网可能有ddos攻击或者arp病毒等传播,所以我们要对服务器或者电脑安装杀毒软件,特别是学校服务器系统等,安全正版安全软件,保护重要电脑的安全;
对服务器本身我们要安全server版系统,经常修复漏洞及更新安全软件,普通电脑一般都是拨号上网,如果有异常上层设备监测一般不影响其他电脑。做好安全防范措施,未雨绸缪。
相关阅读:提高服务器安全性的技巧
1.经常更改系统管理员密码。---->且密码最好是大小写都有
2.定期更新系统补丁。---->开启自动更新,并设定到晚上重启。
3.检查系统是否多出超级管理员,检查是否有帐号被克隆在“开始”>运行中输入“cmd”>在输入 net localgroup administrators
4.在“开始”>运行中输入“msconfig”检查随机启动的程序和服务,关掉不必要的随机启动程序和服务。
5.服务器上的所有程序尽量安装程序的最新稳定版。
6.检查SERVU是否被创建有执行权限的用户或者对C盘有读写权限的用户,并且给SERVU设置一个登录密码。如果需要请给serv_u设置独立启动账户。
7.不要随意安装任何的第三方软件。例如XX优化软件,XX插件之类的,更不要在服务器上注册未知的组件。
8.不要随意在服务器上使用IE访问任何网站,杜绝隐患那是必须的。
9. 检查系统日志的“安全性”条目,在右侧查看近期“审核成功”的登录
10.不要在服务器上双击运行任何程序,不然怎么中了木马都不知道。
11.不要在服务器上用IE打开用户的硬盘中的网页,这是危险的行为。
12.不要在服务器上浏览图片,以前windows就出过GDI 的安全漏洞。
13.及时的更新病毒库,查杀病毒。
14.定时的查看系统各个盘符的磁盘权限,是否为设定的安全权限。
15.确保你自己的电脑安全,如果自己的电脑不安全,服务器也可能不太安全。
编码漏洞相关文章: