Preg_Match绕过:回溯,换行与数组

作者: const27 分类: All,PHP自身缺陷或特性 发布时间: 2020-06-12 06:52

换行绕过

在preg_match没启动 /s模式(单行匹配模式)时,正则表达式 . 是无法匹配换行符(%0a,\n)的,且$会自动忽略末尾的换行符
所以可以进行一些绕过,故可以进行一些绕过.


数组绕过

这个很简单,向preg_match函数传入数组,将直接返回false

回溯绕过

首先我们要了解正则表达匹配的引擎,常见的有DFA和NFA
DFA: 从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
NFA: 从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯。
回溯的方式有很多情况,这里介绍两种
字符串被匹配完但正则表达式还未读取完的情况(字符串前移)

离别歌:”

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

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

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

非贪婪模式的回溯(表达式前移)

那么这个回溯关preg_match什么事?,在PHP中,是规定了回溯次数上线的( 正则表达式的拒绝服务攻击(reDOS) ) ,只要回溯次数到达了一定上限( pcre.backtrack_limit ) ,就会返回false,这个 pcre.backtrack_limit 的上限一般是一百万

image.png

故我们只需要发送大量要被回溯的字符过去,就可以突破回溯上限,绕过preg_match

参考: https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

Leave a Reply

Your email address will not be published. Required fields are marked *

标签云