
寻找易受正则表达式拒绝服务(ReDoS)攻击的正则表达式。
更多信息请参见 Doyensec 博客
许多默认的正则表达式解析器具有无界的最坏情况复杂度。当输入字符串匹配时,正则表达式匹配可能很快。然而,某些不匹配的输入字符串会使正则表达式匹配器陷入疯狂的回溯循环,并花费大量时间处理。这可能导致拒绝服务,因为CPU将被卡住尝试匹配正则表达式。
该工具旨在:
这反映了正则表达式匹配器回溯过程的复杂度与输入字符串长度的关系。
三次复杂度意味着,如果字符串中易受攻击部分的长度加倍,执行时间约为原来的8倍(2^3)。
对于带有星号的指数级ReDoS,例如 (a*)*$,会使用修正因子,复杂度将大于10。
对于可利用性,通常需要三次或更高的复杂度,除非允许输入非常长的字符串。
运行 regexploit 并在命令行中输入正则表达式 v\w*_\w*_\w*$。
$ regexploit
v\w*_\w*_\w*$
Pattern: v\w*_\w*_\w*$
---
最坏情况复杂度: 3 ⭐⭐⭐ (三次)
重复字符: [5f:_]
导致回溯的最终字符: [^WORD]
示例: 'v' + '_' * 3456 + '!'
部分 \w*_\w*_\w* 包含三个重叠的重复组(\w匹配字母、数字和下划线)。如行 重复字符: [5f:_] 所示,一长串 _(0x5f)会以多种方式匹配该部分。最坏情况复杂度为3,因为有3个无限重复组。给出的ReDoS示例包含必需的前缀 v、一长串 _ 以及一个 !(非单词字符)以触发回溯。并非所有ReDoS都需要末尾特定字符,但在本例中,一长串 _ 会成功匹配正则表达式而不会回溯。行 导致回溯的最终字符: [^WORD] 表明,末尾需要一个不匹配的字符(非单词字符)来阻止匹配并导致ReDoS。
再举一个例子,安装一个易受ReDoS攻击的模块版本,例如 pip install ua-parser==0.9.0。
要扫描已安装的 Python 模块,请运行 regexploit-python-env。
Importing ua_parser.user_agent_parser
Vulnerable regex in /somewhere/.env/lib/python3.9/site-packages/ua_parser/user_agent_parser.py #183
Pattern: \bSmartWatch *\( *([^;]+) *; *([^;]+) *;
Context: self.user_agent_re = re.compile(self.pattern)
---
最坏情况复杂度: 3 ⭐⭐⭐
重复字符: [20]
示例: 'SmartWatch(' + ' ' * 3456
最坏情况复杂度: 3 ⭐⭐⭐
重复字符: [20]
示例: 'SmartWatch(0;' + ' ' * 3456
Vulnerable regex in /somewhere/.env/lib/python3.9/site-packages/ua_parser/user_agent_parser.py #183
Pattern: ; *([^;/]+) Build[/ ]Huawei(MT1-U06|[A-Z]+\d+[^\);]+)[^\);]*\)
Context: self.user_agent_re = re.compile(self.pattern)
---
最坏情况复杂度: 3 ⭐⭐⭐
重复字符: [[0-9]]
示例: ';0 Build/HuaweiA' + '0' * 3456
...
对于每个易受攻击的正则表达式,它会打印一个或多个触发ReDoS的恶意字符串。将用户代理设置为 ;0 Build/HuaweiA000000000000000... 并浏览使用旧版本ua-parser的网站,可能会导致服务器花费大量时间处理你的请求,很可能以状态502结束。
需要Python 3.8+。要从JavaScript/TypeScript代码中提取正则表达式,还需要NodeJS 12+。
可选创建一个虚拟环境
python3 -m venv .env
source .env/bin/activate
现在用pip安装
pip install regexploit
通过stdin(每行一个)输入正则表达式到 regexploit。
regexploit
或者通过文件
cat myregexes.txt | regexploit
内置支持从Python、JavaScript、TypeScript、C#、YAML和JSON中解析正则表达式。
通过AST解析Python代码(无需执行)以查找正则表达式。然后分析这些正则表达式是否存在ReDoS。
regexploit-py my-project/
regexploit-py "my-project/**/*.py" --glob
将使用 regexploit/bin/javascript 中捆绑的NodeJS包,该包通过eslint将你的JavaScript解析为AST,并打印出所有正则表达式。
这些正则表达式被输入到Python的ReDoS查找器中。
regexploit-js my-module/my-file.js another/file.js some/folder/
regexploit-js "my-project/node_modules/**/*.js" --glob
注意:javascript和python的正则表达式解析存在差异,因此可能会有一些错误。我不想编写JS正则AST!
搜索当前路径/环境中所有已安装的Python模块中的正则表达式。这意味着你可以 pip install 任何你感兴趣的模块,然后它们将被分析。包括Cpython代码。
regexploit-python-env
注意:这不会将Python代码解析为AST,只会找到在模块导入时自动编译的正则表达式。模块会被实际导入,因此模块中的代码将被执行。这对于查找在加载时由较小子字符串构建的正则表达式很有用,例如 Pillow中的CVE-2021-25292
YAML支持需要pyyaml,可以通过 pip install regexploit[yaml] 安装。
regexploit-json *.json
regexploit-yaml *.yaml
regexploit-csharp something.cs
该工具由Doyensec LLC的Ben Caller在研究时间创建。