php preg_match pcre回溯繞過


原理
需要知識:正則NFA回溯原理,php的pcre.backtrack_limit設置。

正則NFA回溯原理
正則表達式是一個可以被"有限狀態自動機"接受的語言類。
"有限狀態自動機",擁有有限數量的狀態,每個狀態可以遷移到零個或多個狀態,輸入字串決定執行哪個狀態的遷移。
常見的正則引擎被分為DFA(確定性有限狀態自動機)與NFA(非確定性有限狀態自動機)他們匹配輸入的過程是:
DFA:從起始狀態開始,一個字符一個字符讀取輸入串,根據正則一步步確定至下一個轉移狀態,直到匹配不上或走完整個輸入。
NFA:從起始狀態開始,一個字符一個字符讀取輸入串,並與正則表達式進行匹配,如果匹配不上,則進行其他狀態。
狀態:輸入串被匹配的形式。
從上面過程可知,由於NFA存在回溯,所以性能會劣於DFA,但他支持更多功能,大多數語言都是以NFA作為正則引擎。

Demo
NFA的匹配模式:
正則:<\?.*[(`;?>].*         輸入串:<?php phpinfo();//aaaaa

匹配位置 模式 回溯
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 0
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 0
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 0
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 1
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 1
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 1
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 1
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 1
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 1
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 1
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 1
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 0
<?php phpinfo();//aaaaa <\?.*[(`;?>].* 0


通過表格可知,一共進行了八次回溯

什么是pcre.backtrack_limit()設置

對正則NFD回溯次數進行限制,能夠預防pcre ddos,默認值為1,000,000,如果超過限制,preg_match()
將會返回false,而如果preg_match匹配成功返回為1,匹配不成功返回為0。

安全問題出現原因

php的正則引擎是NFA,當preg_match()函數內正則的回溯次數超過pcre.backtrack_limit時,將會返回false。
漏洞出現的語法:
<?php
function is_php($data){
  return preg_match('/<\?.*[(`;?>].*/is', $data);
}
if(!is_php($input)) {
    //code
}
?>

修復方案
if( is_php($input) === 0 )
// preg_match匹配成功返回int(1),失敗返回int(0) 而不是false

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM