这个文章是我看完离别歌大佬的博客文章写的 毕竟不写下来巩固一下不是好的学习

这是博客的文章 https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html

主要的思路是利用了php的pcre的回溯机制 达到pcre的正则匹配上限次数,从而返回false 让php以为正则不匹配

首先我们先看php的回溯上限

可以看到是1000000次数 如果你超过这个次数就会返回false 从而绕过正则

<?php

/*
var_dump(ini_get('pcre.backtrack_limit'));
*/

$put=$_REQUEST['input'];
if(preg_match('/<\?.*[(`;?>].*/is',$put)){
	die('Hacker');
}
else{
	echo "SUCCESS";
}

这个是拿来测试的php代码 其中可以看到是对一般的php代码进行正则匹配 

我们一般的传一个phpinfo 会发现是匹配正则的 如果我们传另外一个PAYLOAD导致回溯超过上限呢呢

可以发现是成功的绕过正则了的 因为他的匹配是这样子的

首先匹配一个 <?     一次 匹配

然后.*匹配完全部  但是你的.*后面还有正则没有匹配 所以回溯 然后匹配最后一个a 第二次匹配 发现不符合 

 [(`;?>]

再匹配倒数第二个a 第三次匹配·····一直到第x个的时候 匹配已经超过1000000次了 然后就返回false

然后php就以为没有匹配正则 就绕过了 

还有许多这样子的waf




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

if(preg_match('/UNION.+?SELECT/is', $input)) {
    die('SQL Injection');
}
if(preg_match('/.*[(`;?>].*/is', $input)) {
    die('hackler');
}

修复的话老样子 用3个=就可以了