Regexploit:DOS-能够的正则表达式

2021-03-22 12:53:09

在思考拒绝服务(DOS)时,我们经常专注于分布式拒绝服务(DDOS),其中数百万僵尸机通过启动数据的海啸来重载服务。然而,通过滥用Web应用程序使用的算法,可以使用攻击者将服务器带到其膝盖,只需单个请求。需要发现在某些条件下具有可怕性能的算法,然后触发那些条件的算法。一般且经常易受攻击的区域是滥用正则表达式(正则表达式)。

正则表达式用于所有文本处理任务的方式。它们似乎可以运行正常,但如果正则表达式容易受到正则表达式拒绝服务(REDO),则可以工艺引起CPU运行的输入100%多年。

在本博客文章中,我们正在发布一个新工具来分析正则表达式并寻找Redos漏洞。我们的启发式已被证明是非常有效的,正如各地流行的NPM,Python和Ruby依赖项所发现的许多漏洞所示。

要进入主题,让我们回顾像Python,Perl,Ruby,C#和JavaScript工作的语言中的Regex匹配引擎的匹配方式。让我们想象一下,我们正在使用这种故意愚蠢的regex来提取版本号:

这将正确地处理类似于123.456.789的东西,但它是一个非常低效的正则表达式。匹配过程如何工作?

第一个。+捕获组贪婪地匹配字符串的末尾,因为点匹配每个角色。

$ 1 =" 123.456.789"那个匹配器然后查找一个字面点字符。可找到它,它试图从第一个字符删除一个字符。+

第二个捕获组与最终三位数2美元=" 789",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,望

嗯......似乎可能是捕获组1的匹配是不正确的,让我们尝试回溯。

好的,让我们尝试1美元=" 123&#34 ;,让我们将群体匹配到最后。

$ 2 =" 456.789"但现在没有DOT!这不能是正确的第2组......

正如您希望看到的,因此可以在Regex匹配过程中存在很多。这是由于正则表达式的模糊性质,其中输入可以以不同的方式匹配。如果正则表达式不是精心设计的,恶意输入可能导致更多的资源密集型回溯循环。

如果回溯需要极高的时间,它将导致拒绝服务,例如CloudFlare在2019年发生的事情。在NodeJS这样的运行时,将阻止事件循环,该循环停止所有计时器,等待,请求和响应直到正则表达式处理完成。

现在我们可以看一下重做例子。 UA-Parser软件包包含用于解密浏览器用户 - 代理标头的巨大正则表达式列表。 CVE-2020-5243中报告的一个正则表达式是:

如果我们在结束部门仔细观察,我们可以看到三个重叠重复组:

数字字符匹配\ d和[\);]。如果一串n个数字进入该部分,则会在\ d +,[\)] +和[\)之间将其拆分为1/2(n-1)n可能的方法。导致重做的关键是提供未成功匹配的输入,例如未结束我们的恶意输入,并使用关闭括号。正则表达式引擎将返回并尝试所有可能的方式匹配数字的匹配数字的希望)。

通过使用CPython Fork从CPython的Regex引擎发出冗长调试,通过从CPython的RegEx引擎发出匹配步骤的这种可视化。

今天,我们正在发布一个名为Regexploit的工具来从代码中提取正则表达式,扫描它们并查找重做。

已经存在了几个工具以查找具有指数最坏情况复杂性的正则表达式(表单的正则表达式(A +)+ B),但立方复杂性正则表达式(A + A + A + B)仍然可以损害。 Regexploit遍历正则表达式,并试图找到一个字符可以通过多个重复零件捕获单个字符的含糊之处。然后它正在寻找一种使正则表达式不匹配的方法,以便Regex引擎必须回溯。

Regexploit脚本允许您通过Stdin输入正则表达式。如果正则表达式正常好的话,它会说“找不到重做”。使用上面的正则表达式,它显示了漏洞:

最糟糕的复杂性:3‰(立方)重复字符:[[0-9]]示例:&#39 ;; 0 Build / Huaweia' +' 0' * 3456.

最终输出系列提供了一个创建用户代理标题的配方,该标题将使用旧版本的UA-Parser在站点上导致重做可能导致错误的网关错误。

要扫描您的源代码,有内心支持从Python,JavaScript,CyperScript,C#,JSON和Yaml中提取正则表达式。如果您能够从其他语言中提取正则表达式,则可以将其送入并分析。

一旦找到了一个脆弱的正则表达式,它仍然需要一些手动调查。如果不可信的输入不可能达到正则表达式,那么它可能不代表安全问题。在某些情况下,可能需要前缀或后缀以将有效载荷获取到正确的位置。

那么有什么样的重做问题?我们使用Regexploit来分析几千名NPM和PYPI库(从Libraries.io API抓住)来查明。

我们试图排除构建工具和测试框架,因为这些错误不太可能有任何安全影响。找到一个易受攻击的正则表达式时,我们需要弄清楚不受信任的输入如何达到它。

最有问题的区域是使用正则表达式来解析编程或标记语言。对于定期表达来解析一些语言。 Markdown,CSS,Matlab或SVG充满了危险。危险的语言具有语法,该语法被设计为由专门的Lexers和Parsers处理。尝试使用正则表达式执行任务导致过于复杂的模式,这是难以读取的凡人。

重复漏洞源是可选空格的处理。例如,让我们带上使用以下Regex的Python模块CairSvg:

$ regexploit-py .env / lib / python3.9 / site-packages / cairosvg / vvstnerable regnx在.env / lib / python3.9 / site-packages / cairosvg / colors.py#190pattern:rgba \([\ n \ r \ t] *(。+?)[\ n \ r \ t] * \)上下文:rgba = re.compile(r' rgba \([\ n \ r \ t] *(。+?) [\ n \ r \ t] * \)')--- Starriness:3⭐⭐⭐(立方)重复字符:[20,09,0a,0d]示例:' rgba(&# 39; +'' * 3456

开发人员想要找到像RGBA(100,200,10,0.5)的字符串,并在没有周围空间的情况下提取中间部分。不幸的是,。+中间也接受空间。如果字符串不以关闭括号结尾,则Regex将不匹配,我们可以获得O(n 3)回溯。

让我们来看看输入" rgba(" +"" * 19:

在CPython的Http.Cookiejar中发现了一个有趣的Redos错误,并使用这一华丽的Regex:

模式:^(\ d \ d?)#day(?:\ s + | [ - \ /])(\ w +)#月(?:\ s + | [ - \ /])(\ d +)#年(? :(?:\ S + | :)#时钟分隔符(\ d \ d?):( \ d \ d)#小时:min(?::(\ d \ d))?#可选秒)? #可选时钟\ s *([ - +]?\ d {2,4} |(?![apap] [mm] \ b)[a-za-z] +)? #timezone \ s *(?:\(\ w +))? #ASCII表示Parens的时区。 stock_http_date_re = re.compile( - - '' * 3456 +' 0'

它是在Processing Cookie到达日期时使用的GMT,但GMT 23:20:00 23:20:00 23:20:00的兼容性,但兼容一些已弃用的日期格式。正则表达式模式的最后5行包含由可选组分隔的三个\ s *组我们有一个立方重做。

仅仅是制作HTTP请求的受害者(' http://evil.server')等http请求可能是由窗体的set-cookie标题响应的远程服务器攻击:

最大65506个空格可以填充到Python中的HTTP标头行中,客户端将需要一周时间才能完成处理标题。

另一点注意到,基于Git历史,我们发现的麻烦正跳得大多仍然保持不变,因为他们首次进入CodeBase。虽然正常情况似乎在正常情况下没有问题,但它可能表明正常呈现太难以难以维护。如果上面的正则表达式没有评论来解释它应该匹配的内容,谁敢试图改变它?可能只有来自XKCD的人。

那么为什么我不打算在戈兰寻找重做? Go的Regex引擎RE2不会回溯。

它的设计(确定性有限自动机)选择即使正则表达本身也是不受信任的。保证是,无论Input.Thevers,虽然,Legex匹配会在线性时间发生。但是,虽然是一个折衷。虽然是一个折衷。像用例中,像re2这样的库可能不是最快的引擎。还有一些regex特征,如反向参考必须丢弃。在病理情况下,正则表达式不会成为您的网站所需的内容。对于许多语言来说是Re2库,因此您可以使用它以优先于Python的RE模块。

对于空白模糊的问题,通常可以首先使用一个简单的正则表达式,然后从结果的两侧修剪/剥离空格。

在Ruby中,标准库包含StringScanner,它有助于“词汇扫描操作”。虽然HTTP-cookie Gem具有比Mega-Regex更多的代码行,但它会在解析Set-cookie标头时避免重做。一旦匹配的每个部分都匹配,它拒绝回溯。在某些正则表达式味道中,您可以使用“占有量词”将部分标记为非回溯并实现类似的效果。

CVE-2021-27291:Pygments For Adl,Cadl,锡兰,Evoque,因子,徽标,Matlab,octave,Odin,Scilab&清漆VCL(语法突出显示)

加上少数几个Pypi,NPM,Ruby和Nuget套餐中的更多未发布错误。 我们将在https://github.com/doyensec/regexploit上更新此列表