ReDos与preg_match某些场景下的绕过

渗透技巧 2年前 (2022) admin
1,086 0 0

ReDos与preg_match某些场景下的绕过

前几天帮A同学看了一段PHP代码,发现了其中一个可被绕过的点,问题点代码大概是:
ReDos与preg_match某些场景下的绕过
这段代码似曾相识,它的作用主要是通过正则表达式(”<?”之后不能再有`;?>这几个字符中的任意一个)来判断我们传入的数据是否包含php代码。

直接来看一下我们的绕过方式,我们传入的数据为一串超长字符串(在php代码之后拼接了一百万个a字符):

ReDos与preg_match某些场景下的绕过

让我们看看匹配的效果,发现is_php函数并没有按照作者预想中的情况返回1,而是返回了false,导致走到了else语句,达成绕过效果:

ReDos与preg_match某些场景下的绕过

为什么这样的字符串会导致preg_match返回false呢?我们一步一步探索一下。

回溯和Redos

首先我们需要知道作者会这样写判断语句的原因,因为他觉得preg_match的执行结果只有1和0两种结果,但实际上,正如我们所见,preg_match还可能会返回false:

ReDos与preg_match某些场景下的绕过

在分析正则匹配的流程之前,我们需要先了解一下正则引擎。

正则引擎

传统正则表达式引擎分为两类,分别是 NFA(非确定性有限状态自动机)和 DFA(确定性有限状态自动机)。

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

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

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

回溯过程

结合上面的正则表达式,我们来看下回溯的过程:

ReDos与preg_match某些场景下的绕过

  • 因为第一个.*可以匹配任何字符,所以在第四步的时候,匹配到了字符串的末尾,准备开始进行子表达式[(`;?>]的匹配:

    ReDos与preg_match某些场景下的绕过
  • 这里子表达式显示在第一个.*后面还有一个字符[(`;?>],所以NFA开始进行回溯,回溯了8次之后匹配到了分号,然后继续向后匹配

    ReDos与preg_match某些场景下的绕过

ReDos

那么回溯会导致什么问题呢?如果回溯次数过多,计算次数也会急剧增多,严重可导致ReDos(正则表达式拒绝服务攻击)。

  • 2019年七月,Cloudflare 曾经全球中断服务,原因是为了改进内联JavaScript屏蔽,部署了一条正则表达式组成的WAF防御规则,耗尽了CPU资源,导致全球大量网站访问出现了502。

    ReDos与preg_match某些场景下的绕过

举个栗子,我们在python中使用这个正则做一个测试:

ReDos与preg_match某些场景下的绕过

可以看到程序执行的时间随着a的个数增多,呈现出一个指数爆炸的增长趋势:

ReDos与preg_match某些场景下的绕过

pcre.backtrack_limit

因此PHP为了防止回溯次数过多,限制了回溯的次数上限,这个次数对应着php_ini中的pcre.backtrack_limit:

ReDos与preg_match某些场景下的绕过

可见,当前环境回溯次数上限默认是100万。而超过100万次之后,preg_match就会执行错误返回false,这也就是为什么上面的超长字符串可以绕过is_php函数的原因。

修复

明白了为什么被绕过之后,修复这个问题也会变得很简单。其实,PHP官方文档对preg_match的警告中已经给了答案:

ReDos与preg_match某些场景下的绕过

建议我们使用===全等号来判断preg_match函数的返回值:

ReDos与preg_match某些场景下的绕过


参考链接

  • https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html?page=1#reply-list

  • https://www.php.net/manual/en/function.preg-match






About us

ReDos与preg_match某些场景下的绕过

陌陌安全
致力于以务实的工作保障陌陌旗下所有产品及亿万用户的信息安全
以开放的心态拥抱信息安全机构、团队与个人之间的共赢协作
以自由的氛围和丰富的资源支撑优秀同学的个人发展与职业成长


/   往 期 分 享   /

ReDos与preg_match某些场景下的绕过
App合规实践3000问之二
ReDos与preg_match某些场景下的绕过
陌陌合规审计平台Bombus开源2.0


ReDos与preg_match某些场景下的绕过
「陌陌安全」
扫上方二维码码关注我们,惊喜不断哦

M   O   M   O   S   E   C   U   R   I   T   Y



原文始发于微信公众号(陌陌安全):ReDos与preg_match某些场景下的绕过

版权声明:admin 发表于 2022年4月11日 下午4:00。
转载请注明:ReDos与preg_match某些场景下的绕过 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...