先给源代码
<?php highlight_file(__FILE__); #### easy game $upload = 'upload/'.md5("2021".$_SERVER['REMOTE_ADDR']); @mkdir($upload); file_put_contents($upload.'/index.php', ''); var_dump($upload); if (isset($_POST['file']) && isset($_POST['file'])){ if(preg_match('#.+\.ph(p[3457]?|t|tml)$|/#is',$_POST['file'])){ die('file error'); } if(preg_match('#\w{2,}|[678]|<\?|/#',$_POST['content'])){ die('content error'); } file_put_contents($upload.'/'.$_POST['file'], $_POST['content']); } if (isset($_GET['reset'])){ @rmdir($upload); }
这道题思路很简单,就是一个文件上传。文件名和内容都有过滤。内容的过滤非常不给面子,\w等同于[A-Za-z_0-9],也就是说,只要连续两个字符/数字/下划线出现,那就直接过滤掉。
不过绕过很简单,file_put_contents函数支持数组,然后prag_match对于数组参数直接返回false,就可以绕过过滤。
预期解是写.htaccess,因为php后缀的基本都被过滤了,payload:
file=.htaccess&content[]=SetHandler application/x-httpd-php
随便上传一个文件就可以了
关键是这道题还有另外一个非预期。在新版的Apache中,配置文件变成了这样:
phar文件默认用php解析器解析
在旧版的配置文件中,是这样的:
<FilesMatch ".+\.ph(p[3457]?|t|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
实测
Ubuntu22.04,php8.1默认解析phar
apache2.4.41,php7.4默认解析phar
apache2.4.29,php7.2默认解析phar
apache2.4.38,php7.0默认不解析phar
应该与php版本有关
[总结]
以后文件上传的题目可以尝试phar文件上传
文章评论