最近在漏洞平台看到ucms后台漏洞,便寻找了一下发现有开源源码,分析一下
首先漏洞发生在后台,也就是需要先登录后台可利用,有点鸡肋,但还是要学习一下
后台管理中心->文件管理->任意选一个编辑->保存->抓包
然后访问该文件名
uncms/index.php 44行
<?php if(isset($_GET['do'])) { $thisdo=explode('_',$_GET['do']); } ?> <?php require('top.php');?> <?php if(isset($_GET['do'])) { if(!isset($thisdo[1])) { $thisdo[1]='index'; } check_admin_file($thisdo[0],$thisdo[1]); require($thisdo[0].'/'.$thisdo[1].'.php'); }else { if(power('s',0,$power)){ echo("<meta http-equiv=refresh content='0; url=?do=str'>"); exit(); }
也就是说获取get的do值为文件名,跟踪一下漏洞指的sadmin/fileedit.php文件
sadmin/fileedit.php
<?php if (!defined('admin')) {exit();} if(power('alevel')!=3) {die('error');} if(!AdminFileedit) { adminmsg('','文件管理功能已关闭',0); } if(isset($_GET['dir'])) { if(empty($_GET['dir'])) { $_GET['dir']='/'; } $getdir=$_GET['dir']; if($_GET['dir']=='/') { $dir=$_GET['dir']; }else { $dir=$_GET['dir']; } $alldir=$_SERVER['DOCUMENT_ROOT'].$_GET['dir'].'/'; if(stripos($_GET['dir'],'..')===false) {}else {die('error dir');} }else { die('no dir'); } if(isset($_GET['file'])) { $filename=$_GET['file']; if(stripos($_GET['file'],'..')===false) {}else {die('error filename');} if(!isedit($_GET['file'])) { die('error'); } }else { die('no file'); } if(isset($_POST['co'])) { checktoken(); $content=$_POST['co']; $fp = @fopen($alldir.$filename,"w"); if(!@fwrite($fp,$content) && strlen($content)<>0){ adminmsg('','写入失败,请修改文件权限',1); exit; } fclose($fp); $refererurl='?do=sadmin_fileedit&dir='.$_GET['dir'].'&file='.$_GET['file'].'&pos='.$_POST['pos']; adminmsg($refererurl,'保存成功',1,'编辑页'); exit(); } if(!is_file($alldir.$filename)) { $content=''; }else { $content=htmlspecialchars(file_get_contents($alldir.$filename)); } function isedit($filename) { $array=array('php','css','js','htm','html','txt'); foreach($array as $val) { if(pathinfo($filename, PATHINFO_EXTENSION)==$val) { Return true; } } Return false; } ?>
可以看到该文件对传进来的路径与内容没有进行任何过滤与验证,引发了漏洞
$fp = @fopen($alldir.$filename,"w");
在请求co参数的时候,这一行,w指当文件不存在的时候会自动创建,由此触发了文件写入漏洞