PHP利用PCRE回溯次数限制绕过waf
学习文章:https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html
前置知识:正则表达式
常见的正则分为DFA(确定性有限状态自动机)和NFA(非确定性有限状态自动关机)
- DFA:从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
- NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态
NFA执行过程存在回溯,性能劣于DFA,但它支持更多功能,大多数程序语言都是用了NFA作为正则引擎,其中也包括PHP使用的PCRE库
回溯过程解析
示例代码
1 | |
这题中的正则是<?.*[(`;?>].*
- <?:匹配<?
- .*:匹配任意长度的任意字符
- [(`;?>]:字符类,表示匹配其中的任何一个字符
- 修饰符i:不区分大小写
- 修饰符s:让.匹配换行符
假设输入的是<?php phpinfo();//aaaaa,那么实际执行的流程是这样的

见第4步,第一关.*可以匹配任意字符,所以最终能够匹配到输入串的结尾,就是//aaaaa,但这里是不对的,因为第一关.*后面还应该有[(`;?>]字符去匹配
所以这里NFA就开始回溯,先匹配到输入串结尾的前一位,即少匹配一个a,如第5步显示,但仍然匹配不上正则,所以还要继续少匹配一个a,依次类推,直到只匹配到<?php