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

dongren1353
dongren1353 我投票把这个问题作为主题关闭,因为它是在security.stackexchange.com/questions/178276/...上交叉发布的。
2 年多之前 回复
duanbanfei2875
duanbanfei2875 感谢您分享更新。我也在测试。让我们看看谁先找到答案:)
2 年多之前 回复
doubo1883
doubo1883 我也尝试过函数声明,但这只适用于js。所以很遗憾,否则我已经发了回答。但是否定的结果也是结果:)
2 年多之前 回复
douluanji8752
douluanji8752 好的想法......你看到绕过代码的其他任何方式吗?
2 年多之前 回复
dongleiqiao4906
dongleiqiao4906 我没有写代码,我试图证明它的不安全,除非我得到代码执行,我不能说明我的观点
2 年多之前 回复
dro59505
dro59505 我编辑了我的评论(该死的自动提交输入..)
2 年多之前 回复
dourong6054
dourong6054 即使它被安全使用,如上所述,因为if(0){}这是保护,删除它,这将是一个不同的故事,人们喜欢跳上eval()。邪恶/eval行列(它在php.net上的廉价),同样的人看到一个SQL注入并喜欢扔掉bobbydroptable滑稽评论,当他们知道你不能使用多查询api丢弃一个表。我已经建立了许多项目,使用eval没有问题,甚至netflix使用“脚本引擎”,最终击中了各种各样的评估机制。
2 年多之前 回复
drmcm84800
drmcm84800 究竟!我尝试了很多方法来绕过它来执行任意用户输入。到目前为止没有......
2 年多之前 回复
doujing5435
doujing5435 由于它使用与php相同的AST解析器,任何对注释的欺骗都将失败。我已经检查了代码中所有可能的{-s,但无法发现任何错过的内容。参考:github.com/php/php-src/blob/...
2 年多之前 回复
dongzhi1822
dongzhi1822 没用是真的,但我不知道是否有人能以某种方式绕过它并执行任意PHP代码。我试图添加“//{”以使大括号失去平衡,因此它不会添加if(0)检查并直接调用eval,但get_tokens调用会使其失效。试图找到一种方法来证明其不安全
2 年多之前 回复
douwen0612
douwen0612 你似乎永远不会执行(0){}。但它再次无用,因为它不检查所有语法错误大声笑
2 年多之前 回复
dongshuo1856
dongshuo1856 从PHP.net网站评论中获取原始代码,看看是否可以打破它的监狱并直接用eval执行用户输入
2 年多之前 回复
dqd22496
dqd22496 代码的要点是验证但不执行PHP代码,但我想绕过它的安全性并直接用eval执行用户输入
2 年多之前 回复
douwen2072
douwen2072 该函数的重点是不验证其工作的PHP代码,但不执行它:/
2 年多之前 回复
duanfang2708
duanfang2708 不,我测试它,我总是得到大括号:0表示有效和无效的代码。试一试:eval_syntax(“if(){}”);显示有效,但显然不是。
2 年多之前 回复
doukui4786
doukui4786 你可能在最后忽略了eval()。
2 年多之前 回复
dqnrk44682
dqnrk44682 它也没有检查语法,它只检查断括号,所以它没用。
2 年多之前 回复
dongyi7513
dongyi7513 我知道eval是完全不安全的,但这里的诀窍是什么?有人如何绕过上面代码中的安全检查?
2 年多之前 回复
doubo7131
doubo7131 查看关于eval的回答:stackoverflow.com/a/951868/3541922
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问