关于file_put_content()

file_put_contents:用于将数据写入文件。

file_put_contents(
    string $filename,
    mixed $data,
    int $flags = 0,
    ?resource $context = null
): int|false

tricks——文件解析漏洞

file_put_contents的参数中,filename是要被写入数据的文件名,data是要写入的数据。

file_put_contents函数存在一个文件解析漏洞:

但传入的filenamea.php/.时,file_put_contents会认为要在将内容写入a.php的同时,还要在a.php 所在的目录下创建一个名为.的文件。

在以下这个题目中,使用这一tricks就可绕过:

<?php

function blacklist($file)
{
    $deny_ext = array("php", "php5", "php4", "php3", "php2", "php1", "html", "htm", "phtml", "pht", "pHp", "pHp5", "pHp4", "pHp3", "pHp2", "pHp1", "Html", "Htm", "pHtml", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "jSp", "jSpx", "jSpa", "jSw", "jSv", "jSpf", "jHtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "aSp", "aSpx", "aSa", "aSax", "aScx", "aShx", "aSmx", "cEr", "sWf", "swf", "ini");
    $ext = pathinfo($file, PATHINFO_EXTENSION);
    foreach ($deny_ext as $value) {
        if (stristr($ext, $value)) {
            return false;
        }
    }
    return true;
}

if (isset($_FILES['file'])) {
    $filename = urldecode($_FILES['file']['name']);
    $filecontent = file_get_contents($_FILES['file']['tmp_name']);
    if (blacklist($filename)) {
        file_put_contents($filename, $filecontent);
        echo "Success!!!";
    } else {
        echo "Hacker!!!";
    }
} else {
    highlight_file(__FILE__);
}