reDOS攻击

正则表达式回溯:

当涉及到正则表达式的回溯时,让我们来看一个具体的例子。

考虑以下正则表达式模式 a+b,其中 a+ 表示匹配一个或多个连续的字符 "a",b 表示匹配字符 "b"。

现在,假设有一个输入字符串为 "aaab",我们试图将这个字符串与模式进行匹配。以下是回溯的过程:

  1. 引擎开始尝试匹配 a+,它找到了第一个 "a"。

  2. 然后引擎尝试匹配更多的 "a",发现了两个额外的 "a"。

  3. 此时,引擎已经匹配了三个 "a",接下来它尝试匹配字符 "b"。

  4. 因为输入字符串中的下一个字符是 "b",引擎成功地匹配了 "b",整个匹配成功。

但是,如果我们考虑一个不匹配的场景,比如输入字符串为 "aaac"。在这种情况下,回溯过程如下:

  1. 引擎开始尝试匹配 a+,它找到了第一个 "a"。

  2. 然后引擎尝试匹配更多的 "a",发现了两个额外的 "a"。

  3. 此时,引擎已经匹配了三个 "a",接下来它尝试匹配字符 "b"。

  4. 由于输入字符串中的下一个字符是 "c",引擎无法匹配 "b"。

  5. 这意味着整个模式匹配失败。引擎开始回溯,尝试其他可能的匹配路径。

  6. 引擎回溯到第二个字符 "a",重新尝试匹配 a+

  7. 引擎再次找到了两个额外的 "a",然后尝试匹配字符 "b"。

  8. 由于输入字符串中的下一个字符仍然是 "c",引擎仍然无法匹配 "b"。

  9. 再次回溯,引擎继续尝试其他的匹配路径,但都失败了。

  10. 最终,整个模式匹配失败。

这个例子展示了当模式无法匹配输入时,正则表达式引擎会回溯到之前的位置,尝试其他可能的匹配路径。当处理复杂的正则表达式或大量数据时,回溯可能会导致性能下降

reDOS攻击简介:

Redos(正则表达式拒绝服务攻击)是一种针对使用正则表达式的应用程序的一种类型的拒绝服务攻击。

在正则表达式中,存在一些复杂的模式,称为“可回溯的”(Backtracking)。当使用这些模式来匹配字符串时,可能会导致回溯操作消耗大量的时间和计算资源。

攻击者可以构造特定的输入,使得正则表达式的回溯机制不断进行操作,耗尽大量的 CPU 时间和内存资源。这导致服务器无法处理其他正常的请求,造成拒绝服务。

计算(回溯)

根据NOSEC研究发表显示:计算机在处理正则表达式的时候可以说是非常愚蠢,虽然看上去它们有很强的计算能力。当你需要用x*y表达式对字符串xxxxxxxxxxxxxx进行匹配时,任何人都可以迅速告诉你无匹配结果,因为这个字符串不包含字符y。但是计算机的正则表达式引擎并不知道!它将执行以下操作

xxxxxxxxxxxxxx # 不匹配
xxxxxxxxxxxxxx # 回溯
xxxxxxxxxxxxx  # 不匹配
xxxxxxxxxxxxx  # 回溯
xxxxxxxxxxxx   # 不匹配
xxxxxxxxxxxx   # 回溯
xxxxxxxxxxx    # 不匹配
xxxxxxxxxxx    # 回溯

>>很多很多步骤 

xx             # 不匹配
x              # 回溯
x              # 不匹配
               # 无匹配结果

你不会以为结束了吧?这只是第一步!

现在,正则表达式引擎将从第二个x开始匹配,然后是第三个,然后是第四个,依此类推到第14个x。

最终总步骤数为256。

它总共需要256步才能得出无匹配结果这一结论。计算机在这方面真的很蠢。

同样,如果你使用非贪婪匹配,x*?y表达式会从一个字母开始匹配,直到尝试过所有的可能,这和贪婪匹配一样愚蠢。

题目演示:


/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-13 05:19:40

*/


error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = (String)$_POST['f'];

    if(preg_match('/.+?ctfshow/is', $f)){
        die('bye!');
    }
    if(stripos($f,'36Dctfshow') === FALSE){
        die('bye!!');
    }

    echo $flag;

}

这里POST的字符串如果包含了ctfshow那就直接die了,但是后面stripos是

查找 "php" 在字符串中第一次出现的位置:


?>

输出:9

后面必定得返回true才行,也就是说必须包含36Dctfshow,似乎进去了死局,但是别忘了我们是学习过reDOS攻击的,PHP 为了防止reDOS攻击,

在PHP的pcre扩展中, 提供了俩个设置项.

  1. 1. pcre.backtrack_limit //最大回溯数
  2. 2. pcre.recursion_limit //最大嵌套数

默认的backtarck_limit是100000(10万)

参考文献:深悉正则(pcre)最大回溯/递归限制 - 风雪之隅 (laruence.com)

这里我们就直接使得对面超过最大回溯,直接返回false就好了

脚本:

 接下来直接运行脚本post发过去就好了

主流预防reDOS攻击方法:

为了预防 Redos(正则表达式拒绝服务)攻击,可以采取以下措施:

  1. 避免使用可回溯的复杂正则表达式:尽量避免使用可回溯的模式,特别是包含量词的贪婪匹配(如使用 .* 或 .+)和嵌套组合的模式。优化正则表达式,使其更加精确和高效。

  2. 设置适当的时间限制:在处理正则表达式时,设置合适的时间限制,以防止一个匹配过程消耗过多的时间。可以使用 PHP 的 set_time_limit 函数来设置最大的执行时间。

  3. 对输入进行限制和过滤:对于接受用户输入的正则表达式,实施输入验证和过滤措施,限制输入的长度和字符类型,避免恶意构造的输入触发回溯操作。

  4. 限制匹配范围:根据应用需求,尽量缩小正则表达式的匹配范围。例如,指定具体的字符集和匹配模式,而不是使用更宽泛的通配符。

  5. 定期更新正则表达式引擎:保持正则表达式引擎的及时更新,以确保它们拥有最新的安全补丁和性能优化。

  6. 使用限制资源的匹配操作:在处理大量或复杂输入时,可以限制正则表达式引擎的处理资源,如匹配回溯深度、匹配重复次数、递归限制等。这可以通过配置正则表达式引擎或使用专门的 PCRE 库来实现。

  7. 审查和测试正则表达式:对使用的正则表达式进行审查和测试,特别关注复杂模式和可能导致回溯的部分。使用测试工具和输入集合来评估正则表达式的性能和安全性。

你可能感兴趣的:(android,ReDos攻击,web安全,正则表达式)