一、介绍
拒绝服务攻击是大量机器访问web系统,导致资源耗尽不能提供服务。
正则表达式是一种用于匹配(编程语言中)字符串的模式。
正则表达式引起拒绝服务攻击,也叫ReDoS。
正则表达式由正则表达式运算器处理。在 ReDoS 攻击期间,攻击者通过提供输入字符串强制正则表达式运算器陷入循环。当它处于循环中时,正则表达式运算器可能会花费大量时间,并消耗大量资源。这会导致其他合法客户端无法使用资源,并可能导致 Web 服务器和应用程序无响应并最终崩溃。
另一种情况可能是设计不良的正则表达式模式,这可能导致输入验证失败,在正则表达式运算器解析时会消耗大量时间等。
有害正则表达式模式是攻击者可以利用的正则表达式。根据 Wikipedia,这些是有害正则表达式模式的特征。
正则表达式将重复(+,*)应用于复杂的子表达式。
对于重复的子表达式,存在一个匹配,同时该匹配也是另一个有效匹配的后缀。
二、缺陷实例
请在浏览器 F12 开发者工具的控制台执行以下正则表达式匹配语句,感受下浏览器的变化:
/(a+)+z/.test('aaaaab')
/(a+)+z/.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab')
对于第一个语句,浏览器很快给出匹配结果 false,但是对于第二个语句,浏览器允许半个小时都出不来结果,且观察 cpu 处于高占用率状态,同时浏览器当前 Tab 页无任何响应(只能强制关闭):
如此简单的正则匹配,JS引擎却陷入了“死循环”之中,原因下面会进行解释。
二、问题代码
三、检测正则表达式
ReDos攻击往往需要结合白盒审计才能有效发现存在缺陷的正则表达式。那么在已知源码的情况下,可以使用 Github regexploit验证。
地址:GitHub - doyensec/regexploit: Find regular expressions which are vulnerable to ReDoS (Regular Expression Denial of Service)
release包:Release Regexploit v1.0.0 · doyensec/regexploit · GitHub
安装regexploit:
C:\Python311\Scripts\pip.exe install regexploit-1.0.0-py3-none-any.whl
运行:
C:\Python311\Scripts\regexploit.exe
Welcome to Regexploit. Enter your regexes:
a+
No ReDoS found.
(00){1,}$
No ReDoS found.
^[a-zA-Z]+(([',.-][a-zA-Z ])?[a-zA-Z])$
No ReDoS found.
^(0-9a-zA-Z@(([0-9a-zA-Z])+([-\w][0-9a-zA-Z])*.)+[a-zA-Z]{2,9})$
Pattern: ^(0-9a-zA-Z@(([0-9a-zA-Z])+([-\w][0-9a-zA-Z])*.)+[a-zA-Z]{2,9})$
---
Redos(starriness=21, prefix_sequence=SEQ{ [0] [2d:-] [9] [a] [2d:-] [z] [A] [2d:-] [Z] [40:@] }, redos_sequence=SEQ{ SEQ{ [[a-z],[0-9],[A-Z]]{1+} SEQ{ [2d:-;WORD] [[a-z],[0-9],[A-Z]] }{0+} . }{1+} [[a-z],[A-Z]]{2,9} $None }, repeated_character=[[a-z],[A-Z]], killer=None)
Worst-case complexity: 21 ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ (exponential)
Repeated character: [[a-z],[A-Z]]
Example: '0-9a-zA-Z@' + 'a' * 3456
Redos(starriness=21, prefix_sequence=SEQ{ [0] [2d:-] [9] [a] [2d:-] [z] [A] [2d:-] [Z] [40:@] }, redos_sequence=SEQ{ [[a-z],[0-9],[A-Z]]{2+}{1+} [[a-z],[A-Z]]{2,9} $None }, repeated_character=[[a-z],[A-Z]], killer=None)
Worst-case complexity: 21 ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ (exponential)
Repeated character: [[a-z],[A-Z]]
Example: '0-9a-zA-Z@' + 'a' * 3456
输入你想要检测的正则表达式,即可判断是否存在 ReDos 攻击,并且给出 Payload。
四、ReDos攻击的防范手段