此代码是否可以任何方式进行曝光?
<?
$arg=$_REQUEST['arg'];
preg_replace("/([0-9]+)(.+)/e",'list($var,$var2)=array("$1","$2")',$arg);
echo "$var - $var2";
?>
是否可以使用特殊字符或其他方法来注入代码?
我在某些项目中使用类似的代码,我只是想确保它是安全的。
答案 0 :(得分:3)
/e
修饰符非常难以安全,并且将在未来的PHP版本中删除。原因是它首先执行替换然后评估代码(就像使用eval()
)。
因此可以设置输入,使替换代码运行任意PHP函数或公开私有变量。
某些转义会自动执行,但保护不足,如this example which executes an arbitrary function using your code和examples in the PHP manual所示:
function dangerous()
{
echo 'Dangerous code executed';
}
$arg = '42{${dangerous()}}';
preg_replace("/([0-9]+)(.+)/e",'list($var, $var2) = array("$1", "$2")', $arg);
var_dump($var, $var2);
相反,preg_replace_callback()
将替换值作为参数发送给回调函数,因此初始字符串的内容无法直接作为代码进行评估。
请注意,在您的示例中,执行的代码只是分配变量,所以不需要任何类型的回调,只能用preg_match()
捕获匹配项:
preg_match("/([0-9]+)(.+)/", $arg, $matches);
$var = $matches[1];
$var2 = $matches[2];
答案 1 :(得分:2)
使用
(.+)
/ e 参数始终可以被利用,因为它允许任何语言构造。
示例漏洞利用代码:
$test = new test();
$test->setSuperSecret();
$test->exploitableExpression();
class test
{
private $mySuperSecretVariable;
public function exploitableExpression()
{
$arg= '1234$this->mySuperSecretVariable';
preg_replace("/([0-9]+)(.+)/e",'list($var,$var2)=array("$1","$2")',$arg);
var_dump($var,$var2);
}
public function setSuperSecret()
{
$this->mySuperSecretVariable = 'SECRET!';
}
}