记一次文件上传之过滤php绕过

今天在群里看到群友发的一道题 想试试 解了一个多小时 过程挺有趣 就记录一下了 学到新的绕过姿势 看题; 一道文件上传+文件包含的题目 bp上传如下 经过测试文件名含有ph过滤 文件内容含有php过滤 上传后发现注释   访问后尝试进行文件包含,如下 显然 这是文件包含没错 试着读取flag 被过滤了 目前思路是通过上传jpg或者txt 然后内容写入php代码 即使文件不是以php后缀结尾,仍可以利用include特性执行代码 因此,我们需要绕过对内容的过滤 在此之前,我们可以用php:filter伪协议读取文件源码 base64解码后代码如下:

<div class="light"><span class="glow">
            <form enctype="multipart/form-data" method="post" onsubmit="return checkFile()">
                嘿伙计,传个火?!
                <input class="input_file" type="file" name="upload_file"/>
                <input class="button" type="submit" name="submit" value="upload"/>
            </form>
      </span><span class="flare"></span><div>
      <!--read.php?filename=  -->
<?php
    error_reporting(0);
    //设置上传目录
    define("UPLOAD_PATH", "./uplo4d");
    $msg = "Upload Success!";
    if (isset($_POST['submit'])) {
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $file_name = $_FILES['upload_file']['name'];
        $ext = pathinfo($file_name,PATHINFO_EXTENSION);
      if(preg_match("/ph/i", strtolower($ext))){
        die("这可不能上传啊!");
    }
       
            $content = file_get_contents($temp_file);
            if(preg_match("/php/i", $content)){
                die("诶,被我发现了吧");
            }


        $new_file_name = md5($file_name).".".$ext;
        $img_path = UPLOAD_PATH . '/' . $new_file_name;




        if (move_uploaded_file($temp_file, $img_path)){
            $is_upload = true;
        } else {
            $msg = 'Upload Failed!';
        }
        echo '<div style="color:#F00">'.$msg." Look here~ ".$img_path."</div>";
    }
?>

文件名含有ph过滤 文件内容含有php过滤 read代码如下:

<?php
error_reporting(0);
$a=$_GET["filename"];
if(preg_match('/flag/i',$a)){
  exit("nononono");
}
include($a);


?>

因为php被过滤了 所以我们无法构造 注意这里不要用GET传参 因为是图片所以传不上去 cat flag flag在环境变量里    因此flag在phpinfo里或者用printenv看环境变量   0xGame{upl0ad_f1le_causes_danger!!!}   解法2: 上传一个的图片或文本,然后访问, 要注意的是 如果要用查看的话,因为包含php会被过滤 因此要用base64解密   payload: End