douqiaoru2583 2018-01-24 00:46
浏览 36

PHP eval代码沙箱中断

I noticed a heavily downvoted comment in here: http://php.net/manual/en/function.php-check-syntax.php

function eval_syntax($code)
{
    $braces = 0;
    $inString = 0;

    // We need to know if braces are correctly balanced.
    // This is not trivial due to variable interpolation
    // which occurs in heredoc, backticked and double quoted strings
    foreach (token_get_all('<?php ' . $code) as $token)
    {
        if (is_array($token))
        {
            switch ($token[0])
            {
            case T_CURLY_OPEN:
            case T_DOLLAR_OPEN_CURLY_BRACES:
            case T_START_HEREDOC: ++$inString; break;
            case T_END_HEREDOC:   --$inString; break;
            }
        }
        else if ($inString & 1)
        {
            switch ($token)
            {
            case '`':
            case '"': --$inString; break;
            }
        }
        else
        {
            switch ($token)
            {
            case '`':
            case '"': ++$inString; break;

            case '{': ++$braces; break;
            case '}':
                if ($inString) --$inString;
                else
                {
                    --$braces;
                    if ($braces < 0) return false;
                }

                break;
            }
        }
    }

    // If $braces is not zero, then we are sure that $code is broken.
    // We run it anyway in order to catch the error message and line number.

    // Else, if $braces are correctly balanced, then we can safely put
    // $code in a dead code sandbox to prevent its execution.
    // Note that without this sandbox, a function or class declaration inside
    // $code could throw a "Cannot redeclare" fatal error.

    echo "Braces: ".$braces."
";
    $braces || $code = "if(0){{$code}
}";

    if (false === eval($code)) {}
}

eval_syntax("file_put_contents('/home/yourname/Desktop/done.txt', 'OVERWRITTEN');");

I tried to bypass the code to maliciously execute user-input, but I couldn't. I wonder why it got downvoted.

As you can see if curly brackets are not matching, it doesn't add the 'if(0){' . $code . '} and executes the user input with mismatching curly brackets which will throw exception and won't really run.

If curly brackets are a match, it calls the eval, but its inside a if {0} "sandbox". How can someone bypass this?

I know eval is insecure, but I want to know what's the trick here. How can you bypass security of if (0) and braces check in the code above?

You can try directly the code from php.net or my minified/edited version above. Point is proving that this code is not secure and user an execute arbitrary PHP Code

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 谁有desed数据集呀
    • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
    • ¥15 关于#hadoop#的问题
    • ¥15 (标签-Python|关键词-socket)
    • ¥15 keil里为什么main.c定义的函数在it.c调用不了
    • ¥50 切换TabTip键盘的输入法
    • ¥15 可否在不同线程中调用封装数据库操作的类
    • ¥15 微带串馈天线阵列每个阵元宽度计算
    • ¥15 keil的map文件中Image component sizes各项意思
    • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏