千家信息网

PCRE回溯次数绕过安全限制的正则实例分析

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,这篇"PCRE回溯次数绕过安全限制的正则实例分析"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来
千家信息网最后更新 2025年01月20日PCRE回溯次数绕过安全限制的正则实例分析

这篇"PCRE回溯次数绕过安全限制的正则实例分析"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"PCRE回溯次数绕过安全限制的正则实例分析"文章吧。

这次Code-Breaking Puzzles中我出了一道看似很简单的题目,将其代码简化如下:

].*/is', $data);  }if(!is_php($input)) {    // fwrite($f, $input); ...}

大意是判断一下用户输入的内容有没有PHP代码,如果没有,则写入文件。这种时候,如何绕过is_php()函数来写入webshell呢?

这道题看似简单,深究其原理,还是值得写一篇文章的。

正则表达式是什么

正则表达式是一个可以被"有限状态自动机"接受的语言类。

"有限状态自动机”,其拥有有限数量的状态,每个状态可以迁移到零个或多个状态,输入字串决定执行哪个状态的迁移。

而常见的正则引擎,又被细分为DFA(确定性有限状态自动机)与NFA(非确定性有限状态自动机)。他们匹配输入的过程分别是:

  • DFA: 从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入

  • NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态

由于NFA的执行过程存在回溯,所以其性能会劣于DFA,但它支持更多功能。大多数程序语言都使用了NFA作为正则引擎,其中也包括PHP使用的PCRE库。

回溯的过程是怎样的

所以,我们题目中的正则<\?.*[(`;?>].*,假设匹配的输入是

见上图,可见第4步的时候,因为第一个.*可以匹配任何字符,所以最终匹配到了输入串的结尾,也就是//aaaaa。但此时显然是不对的,因为正则显示.*后面还应该有一个字符[(`;?>]

所以NFA就开始回溯,先吐出一个a,输入变成第5步显示的//aaaa,但仍然匹配不上正则,继续吐出a,变成//aaa,仍然匹配不上……

最终直到吐出;,输入变成第12步显示的,此时,.*匹配的是php phpinfo(),而后面的;则匹配上[(`;?>],这个结果满足正则表达式的要求,于是不再回溯。13步开始向后匹配;,14步匹配.*,第二个.*匹配到了字符串末尾,最后结束匹配。

在调试正则表达式的时候,我们可以查看当前回溯的次数:

这里回溯了8次。

PHP的pcre.backtrack_limit限制利用

PHP为了防止正则表达式的拒绝服务攻击(reDOS),给pcre设定了一个回溯次数上限pcre.backtrack_limit。我们可以通过var_dump(ini_get('pcre.backtrack_limit'));的方式查看当前环境下的上限:

这里有个有趣的事情,就是PHP文档中,中英文版本的数值是不一样的:

我们应该以英文版为参考。

可见,回溯次数上限默认是100万。那么,假设我们的回溯次数超过了100万,会出现什么现象呢?比如:

可见,preg_match返回的非1和0,而是false。

preg_match函数返回false表示此次执行失败了,我们可以调用var_dump(preg_last_error() === PREG_BACKTRACK_LIMIT_ERROR);发现失败的原因的确是回溯次数超出了限制:

所以,这道题的答案就呼之欲出了。我们通过发送超长字符串的方式,使正则执行失败,最后绕过目标对PHP语言的限制。

对应的POC如下:

import requestsfrom io import BytesIOfiles = {  'file': BytesIO(b'aaa

PCRE另一种错误的用法

延伸一下,很多基于PHP的WAF,如:

if(preg_match('/SELECT.+FROM.+/is', $input)) {    die('SQL Injection');}

均存在上述问题,通过大量回溯可以进行绕过。

另外,我遇到更常见的一种WAF是:

if(preg_match('/UNION.+?SELECT/is', $input)) {    die('SQL Injection');}

这里涉及到了正则表达式的"非贪婪模式"。在NFA中,如果我输入UNION/*aaaaa*/SELECT,这个正则表达式执行流程如下:

  • .+?匹配到/

  • 因为非贪婪模式,所以.+?停止匹配,而由S匹配*

  • S匹配*失败,回溯,再由.+?匹配*

  • 因为非贪婪模式,所以.+?停止匹配,而由S匹配a

  • S匹配a失败,回溯,再由.+?匹配a

  • ...

回溯次数随着a的数量增加而增加。所以,我们仍然可以通过发送大量a,来使回溯次数超出pcre.backtrack_limit限制,进而绕过WAF:

修复方法

那么,如何修复这个问题呢?

其实如果我们仔细观察PHP文档,是可以看到preg_match函数下面的警告的:

如果用preg_match对字符串进行匹配,一定要使用===全等号来判断返回值,如:

function is_php($data){      return preg_match('/<\?.*[(`;?>].*/is', $data);  }if(is_php($input) === 0) {    // fwrite($f, $input); ...}

这样,即使正则执行失败返回false,也不会进入if语句。

以上就是关于"PCRE回溯次数绕过安全限制的正则实例分析"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

正则 状态 输入 次数 字符 表达式 限制 内容 有限 自动机 安全 实例 实例分析 分析 贪婪 上限 函数 字符串 时候 模式 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 三国杀服务器登录错误是什么原因 用plsql远程数据库 数据库建e 福建工程学院计算机网络技术 长安的DNS服务器 怎么检查邮箱的邮件服务器 数据库import重复导入 网络安全的三个特性 使用国家法律法规数据库 吴中区推广网络技术哪家好 网络安全法正式实行时间为 chns数据库是什么数据库 access 数据库题 ftp服务器管理2019 创建班级数据库代码 双生幻想不同服务器加好友吗 数据库可以设置列值为null吗 天翼云盘服务器连接失败手机版 电脑上怎么上服务器未响应 远程管理控制服务器 下载 奉贤区软件开发系统 吕梁网络安全演练 gkfmt4代理服务器安装不上 怎么检查邮箱的邮件服务器 金融业网络安全风险防范措施 建立健全网络安全管控制度 计算机网络技术主要是由 东营ios软件开发公司有哪些 天翼云盘服务器连接失败手机版 计算机专业网络安全专业
0