Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

TL;DR: Basically, if a target website is protected by a WAF using the OWASP Core Rule Set or Comodo Rule Set or Atomicorp Rule Set, you can send the string ORA-1234 or OracleDrive or ASL-CONFIG-FILE in a comment, product review, registration form, e-commerce order details, etc… to prevent the website from showing its content to any users like a Denial of Service with a minimal effort. This happens because the overly inclusive response rules of the WAF try to prevent SQL error leakage or web shells.
TL;医生:基本上,如果目标网站由WAF使用OWASP核心规则集或Comodo规则集或Atomicorp规则集保护,您可以在评论,产品评论,注册表单,电子商务订单详细信息等中发送字符串 ORA-1234 或 OracleDrive 或 ASL-CONFIG-FILE 。防止网站向任何用户显示其内容,如以最小的努力拒绝服务。这是因为WAF过度包容的响应规则试图防止SQL错误泄漏或Web shell。

By checking all target websites on the most popular bug bounty platforms, I’ve earned 1,200$ of bounty for a single company having this RFDoS problem on their portal.
通过检查最流行的错误赏金平台上的所有目标网站,我已经赢得了1,200 $的赏金为一个单一的公司有这个RFDoS问题在他们的门户网站。

Why showing debug errors isn’t good for security?

One of the information-gathering technique used by attackers is based on the extraction of valuable insights from error or debug messages inadvertently exposed by target web applications. Imagine a scenario where a database throw an error, or a server-side script like PHP or ASP accidentally reveals a full path or a snippet of its inner workings. These unintentional leaks, often overlooked, can provide valuable information for an attacker, collecting information for more significant vulnerabilities to be exploited.

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule
Example of a PHP error

Also, showing SQL error messages in a web application can be a security problem if the website inadvertently expose sensitive information about the underlying database. When these error messages are displayed, they often include specific details such as the type and name of the database, table names, and portions of the SQL query that triggered the error.

As you might know, by understanding the database schema, an attacker can craft more effective SQL injection attacks, which can lead to unauthorized data access, data loss, or even complete system compromise.

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

For that reason, many Web Application Firewalls implement rules and response validation methods to prevent the leakage of sensitive information, such as SQL errors or errors related to scripting languages. The same happens, for example, to prevent Web Shell response body.
出于这个原因,许多Web应用程序防火墙实现了规则和响应验证方法,以防止敏感信息的泄漏,例如SQL错误或与脚本语言相关的错误。例如,防止Web Shell响应体也会发生同样的情况。

This prevention often occurs by blocking the response body before it reaches the user, typically returning a 403 Forbidden status instead of the page containing the leakage. More modern WAFs often replace the leaked information with a series of asterisk characters ****. This method is commonly used to prevent leaks of credit card numbers or US Social Security numbers.
这种预防通常通过在响应体到达用户之前阻止它来实现,通常返回403 Forbidden状态而不是包含泄漏的页面。更现代的WAF经常用一系列星号字符 **** 替换泄露的信息。这种方法通常用于防止信用卡号码或美国社会安全号码泄露。

However, both prevention methods (blocking the response or replacing the leaked content) are often completely ineffective. An attacker can usually bypass these preventions by sending a Range HTTP Request, which requests only portions of the response that do not trigger the WAF. We’ll explore in more detail how this is done later in this post.

Preventing leakages with a WAF is good, right?

Once I read a statement attributed to Ivan Ristić that went something like, “When you create a new WAF Rule, you are also creating many ways to bypass it.” Similarly, we can say that every time you create a response body WAF rule, you’re also exposing websites or applications to RFDoS.
有一次,我读到了Ivan Ristić的一句话,大意是:“当你创建一个新的WAF规则时,你也在创建许多绕过它的方法。同样,我们可以说,每次您创建响应主体WAF规则时,您也会将网站或应用程序暴露给RFDoS。

Let’s say you are trying to prevent the leakage of credit card numbers on your e-commerce site. To do this, you create a WAF rule that checks for four groups of digits separated by a - in the response body, using a regex like [0-9]+\-[0-9]+\-[0-9]+\-[0-9]+.
假设您正试图防止电子商务网站上的信用卡号码泄露。要做到这一点,您可以创建一个WAF规则,使用像 [0-9]+\-[0-9]+\-[0-9]+\-[0-9]+ 这样的正则表达式,检查响应正文中由 - 分隔的四组数字。

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule
An example of Regular Expression matching CC numbers

While this might seem like a sensible approach, it is actually quite risky because it’s very easy for someone to exploit this rule to shut down parts of the website where user input is displayed. For example, if a user posts a comment or a review on a product with the string 4111-1111-1111-1111, the WAF will block the page response for everyone. Imagine if a user sends this type of comment or review to ALL products on the e-commerce site… it could trigger a sort of Denial of Service, preventing everyone from viewing any products on the protected e-commerce site.
虽然这似乎是一种明智的方法,但实际上是相当危险的,因为有人很容易利用此规则关闭显示用户输入的网站部分。例如,如果用户发布了一个带有字符串 4111-1111-1111-1111 的评论或评论,WAF将阻止所有人的页面响应。想象一下,如果一个用户发送这种类型的评论或审查的所有产品的电子商务网站.它可能会触发一种拒绝服务,阻止每个人查看受保护的电子商务网站上的任何产品。

That’s why I’ve started referring to this scenario as “Response Filter Denial of Service” or RFDoS.

Additionally, apart from RFDoS, an attacker could always obtain data leakage from the target website using a Range Request. We’ll explore why and how in the section titled “Prevent leakage in HTTP response body is often useless because of Byte Range HTTP request“.

To get the website up and running again after a Response Filter Denial of Service attack, the website owner has several options. These options include removing the rules that triggered the block, creating new exclusion rules to bypass these triggers, or disabling the response body access feature in the WAF. Each of these solutions requires a good understanding of how the WAF and its rules work, which can be challenging for someone without technical expertise in this area.

Sometimes, less experienced users may not understand what is happening with the WAF and could decide to disable it, leaving the website without any protection or monitoring.

For example, a user who simply activated ModSecurity v2 and the Core Rule Set via their hosting control panel like Plesk might find it difficult to diagnose and resolve the issue. The time required to identify and fix the problem could result in significant downtime. This downtime is particularly critical for e-commerce sites, where prolonged unavailability can directly translate into financial losses due to missed sales opportunities.
例如,用户通过Plesk等主机控制面板简单地激活ModSecurity v2和核心规则集,可能会发现很难诊断和解决问题。识别和修复问题所需的时间可能会导致严重的停机时间。这种停机时间对于电子商务网站来说尤其重要,因为长时间的不可用可能会因错过销售机会而直接导致财务损失。

ModSecurity and community Rule Set

ModSecurity is an open-source Web Application Firewall that provides a variety of security features for web applications. It operates as a module in the web server environment, where it can perform real-time HTTP traffic monitoring, logging, and access control. ModSecurity supports flexible rule configuration, that can inspect both HTTP request and HTTP response.

ModSecurity it’s just the engine, and it requires rules to protect a web application. There’re more than one free rule set, but the most well-known and widely used is the OWASP Core Rule Set (CRS) that is used by Google Cloud Armor, Azure Application Gateway, CloudFlare, and many other vendors (no… AWS WAF has a “Core Rule Set” managed rule, but it is not the OWASP Core Rule Set).
ModSecurity只是引擎,它需要规则来保护Web应用程序。有不止一个免费的规则集,但最知名和最广泛使用的是OWASP核心规则集(CRS),它被Google Cloud Armor,Azure Application Gateway,CloudFlare和许多其他供应商(不… AWS WAF有一个“核心规则集”管理规则,但它不是OWASP核心规则集)。

However, there are also other rule sets available, created and distributed by different security organizations or companies, each with their unique features and focus. For instance, Comodo and Atomicorp are two such providers. Comodo offers its own set of ModSecurity rules focusing on a broad range of web security threats, while Atomicorp develops rules that are often integrated into their broader security products and services. These company-specific rule sets can provide alternative or supplementary protection strategies to the OWASP CRS, giving users more options depending on their specific security needs and the nature of the threats they are most concerned about.
但是,还有其他规则集可用,由不同的安全组织或公司创建和分发,每个都有其独特的功能和重点。例如,Comodo和Atomicorp就是两个这样的供应商。Comodo提供了自己的一套ModSecurity规则,专注于广泛的Web安全威胁,而Atomicorp开发的规则通常集成到其更广泛的安全产品和服务中。这些特定于公司的规则集可以为OWASP CRS提供替代或补充保护策略,根据用户的特定安全需求和他们最关心的威胁的性质为用户提供更多选择。

And what you’ve just read is ChatGPT’s take on rule set alternatives to the OWASP Core Rule Set. The truth that few are willing to say publicly is that there are no good alternatives to the OWASP Core Rule Set. Other rule sets are often a jumble of poorly crafted rules that target very specific payloads and are easily bypassed. Most of the time, they end up being a waste of CPU resources.

The OWASP Core Rule Set

The OWASP Core Rule Set is a set of generic attack detection rules for use with ModSecurity or compatible WAFs. CRS aims to protect web applications from a wide range of attacks, including the OWASP Top Ten vulnerabilities, with minimal false positives. The CRS is designed as a plug-and-play solution, providing a basic security layer for any web application out of the box.

Like many other WAF rule sets, the OWASP Core Rule Set includes some rules that inspect the response body, which you can find here.

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

All those rule sets pose problems in terms of RFDoS, but the most problematic one is the RESPONSE-951-DATA-LEAKAGES-SQL.conf configuration file/rule set.
所有这些规则集都会在RFDoS方面造成问题,但最有问题的是 RESPONSE-951-DATA-LEAKAGES-SQL.conf 配置文件/规则集。

The main issue with detecting SQL errors in the HTTP response body is that you cannot avoid using a list of regexes that match simple strings without special characters. This is due to how some SQL errors are output by the engine.

Consider blocking all HTTP response bodies containing the string “You have an error in your SQL syntax“. While this might seem like a good practice, it’s actually a risky approach that can not only cause false positives but also gives any attacker the ability to shut down any page that stores user input and displays it on the website. The fact that the statement “You have an error in your SQL syntax” contains no special characters makes it nearly impossible to validate or sanitize before storing it.
考虑阻止所有包含字符串“You have an error in your SQL syntax”的HTTP响应正文。虽然这似乎是一个很好的做法,但实际上这是一种危险的方法,不仅会导致误报,而且会让任何攻击者能够关闭任何存储用户输入并在网站上显示的页面。事实上,语句“You have an error in your SQL syntax”不包含任何特殊字符,这使得在存储它之前几乎不可能进行验证或清理。

Another example is a SQL error leakage rule that uses a regular expression to match ORA- followed by four digits, such as:
另一个例子是SQL错误泄漏规则,它使用正则表达式匹配 ORA- 后跟四位数字,例如:

ORA-1234 ORA—1234

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

As you can see, this rule runs at phase 4, which includes the response body, and blocks the response if the regex matches the RESPONSE_BODY variable.
如您所见,此规则在第4阶段运行,其中包括响应主体,如果正则表达式匹配 RESPONSE_BODY 变量,则会阻止响应。

Another really simple string is dynamic sql error
另一个非常简单的字符串是 dynamic sql error

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

Imagine how easy could be to trigger those rules, just by sending ORA-1234 inside a comment, or used as username or e-mail address.
想象一下,触发这些规则是多么容易,只需在评论中发送 ORA-1234 ,或用作用户名或电子邮件地址。

Update 14th May 2024 更新2024年5月14日

While I was completing this article, the OWASP Core Rule Set team committed a change to the rule I used to demonstrate RFDoS. They modified the regex that matched ORA-1234 to something like ORA-12345:. However, this change doesn’t impact the RFDoS issue, and you’ll still find the old regex in all of the OWASP Core Rule Sets deployed in production environments.
在我完成本文的过程中,OWASP核心规则集团队对我用来演示RFDoS的规则进行了更改。他们将匹配 ORA-1234 的正则表达式修改为类似于 ORA-12345: 的内容。但是,这个更改不会影响RFDoS问题,您仍然可以在生产环境中部署的所有OWASP核心规则集中找到旧的正则表达式。

Comodo Free Rules 科摩多自由规则

The “Comodo Free ModSecurity Rules” project, on this topic is even worse. It provides a set of free (but not open-source) rules for ModSecurity. These rules are maintained and updated by Comodo, after days trying to download the latest version (the website was always down) I finally managed to get my copy of cwaf_rules-1.241.
“Comodo Free ModSecurity Rules”项目在这个问题上更糟糕。它为ModSecurity提供了一套免费(但不是开源)的规则。这些规则由Comodo维护和更新,经过几天尝试下载最新版本(网站总是关闭),我终于设法获得了我的 cwaf_rules-1.241 副本。

Comodo distributes a series of OutgoingFilter rule sets that also include prevention of SQL error leakages.

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule
from Comodo

As you can imagine, inside the 17_Outgoing_FilterSQL.conf file we can found our magic string ORA-1234:
正如你所想象的,在 17_Outgoing_FilterSQL.conf 文件中,我们可以找到我们的魔术字符串ORA-1234:

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

But also other really simple string like Dynamic SQL Error or JET Database Engine or Access Database Engine
还有其他非常简单的字符串,比如 Dynamic SQL Error 或 JET Database Engine 或 Access Database Engine

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule
Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

Atomicorp Free ModSecurity Rules

Atomicorp offers a free-to-use set of ModSecurity rules that you can download by registering on their portal. One of these rules aims to prevent the leakage of the rules or configurations themselves by blocking any response body that includes the string:

---ASL-CONFIG-FILE---. So, in an attempt to prevent a self-configuration leakage, they inadvertently allow anyone to shut down a website by reflecting user input made up solely of A-Z characters and -.
---ASL-CONFIG-FILE--- 。因此,为了防止自我配置泄漏,他们无意中允许任何人通过反映仅由A—Z字符和 - 组成的用户输入来关闭网站。

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule
From the latest Atomicorp modsec-202405080003.tar.bz2
来自最新的Atomicorp modsec—202405080003.tar.bz2

Why response WAF rules are dangerous?

If you can store user input on a target website (protected by a WAF), such as a comment or a product review, you can easily shut down the page where the user input is displayed by simply sending something like:

ORA-1234 ORA—1234

Imagine an e-commerce protected by WAF. To generate a Denial of Service attack on it, an attacker could simply submit a product review containing a message like, “Really useful product, I tried it with ORA-1234, and it works really well” effectively preventing any user from accessing the page where the review is published. The same applies to the “User Account Details” page: by registering an account with an email address like [email protected], it would stop any administrator from viewing the user list or editing the account details.
想象一个受WAF保护的电子商务。要对其进行拒绝服务攻击,攻击者只需提交一个包含以下消息的产品评论:“非常有用的产品,我用ORA-1234试用过,效果非常好”,从而有效地阻止任何用户访问发布评论的页面。这同样适用于“用户帐户详细信息”页面:通过使用 [email protected] 这样的电子邮件地址注册帐户,它将阻止任何管理员查看用户列表或编辑帐户详细信息。

The magic string ORA-1234

ORA-1234 isn’t the only string that triggers this issue. Here’s a list of very simple strings (without any special characters) that anyone can use to generate a Response Filter Denial of Service on a website that meets the conditions we mentioned earlier.
ORA-1234 不是触发此问题的唯一字符串。下面是一个非常简单的字符串列表(没有任何特殊字符),任何人都可以使用它在满足我们前面提到的条件的网站上生成响应过滤器拒绝服务。

Each one of the following strings will be blocked by one or more Response Body rule enabled on ModSecurity v2 + OWASP Core Rule Set:
以下每个字符串将被ModSecurity v2 + OWASP核心规则集上启用的一个或多个响应主体规则阻止:

ET Database Engine
Access Database Engine
Oracle error
CLI DriverDB2
DB2 SQL error
Dynamic SQL Error
An illegal character has been found in the statement
Unexpected end of command in statement
SQL errorPOS1
Unclosed quotation mark after the character string
Microsoft OLE DB Provider for ODBC Drivers
Microsoft OLE DB Provider for SQL Server
Incorrect syntax near
Sintaxis incorrecta cerca de
Syntax error in string in query expression
Procedure or function foo expects parameter
Unclosed quotation mark before the character string
Syntax error foo in query expression
the used select statements have different number of columns
DriverSQL Server
SQL ServerDriverS
QL Server12345678
supplied argument is not a valid MySQL
on MySQL result index
You have an error in your SQL syntax near
MySQL server version for the right syntax to use
SQL syntaxMySQL
valid MySQL result
valid PostgreSQL result
Supplied argument is not a valid PostgreSQL foo resource
Unable to connect to PostgreSQL server
SybaseServer message
An Error Has Occurred

The Core Problem 的核心问题

The main issue here is that all these strings can pass through any type of input validation or sanitization module. The lack of special characters, HTML tags, and terms included in bad-word dictionaries (like eval or exec) makes them the perfect choice for any attacker who wants to prevent a website from being displayed to users.
这里的主要问题是,所有这些字符串都可以通过任何类型的输入验证或清理模块。由于没有特殊字符、HTML标签和坏词词典中包含的术语(如 eval 或 exec ),这使得它们成为任何想要阻止网站向用户显示的攻击者的完美选择。

RFDoS demo on a vanilla WordPress website

Prevent leakage in HTTP response body is often useless because of Byte Range HTTP request

Let’s say I’m triggering a visible error-based SQL Injection on a target protected by a WAF. This WAF blocks all response bodies containing a SQL error. To bypass this and see the SQL error, I can send an Byte Range HTTP request. By requesting only a portion of the response body, it’s quite easy to avoid triggering the WAF rule that is designed to prevent data leakage.
假设我在一个受WAF保护的目标上触发一个可见的基于错误的SQL注入。此WAF阻止所有包含SQL错误的响应主体。要绕过这个并查看SQL错误,我可以发送一个Byte Range HTTP请求。通过只请求响应体的一部分,很容易避免触发WAF规则,该规则旨在防止数据泄漏。

The Range request header in the HTTP protocol is a feature that allows clients to request a specific part of a resource, rather than downloading the entire file or content at once. This header indicates which part of the resource the client wants to receive, specified as one or more data ranges. For example, a client can request the first 500 bytes of a file or a specific segment in the middle of a large video or document.
HTTP协议中的 Range 请求头是一个允许客户端请求资源的特定部分的功能,而不是一次下载整个文件或内容。此标头指示客户端希望接收资源的哪一部分,指定为一个或多个数据范围。例如,客户端可以请求文件的前500个字节或大型视频或文档中间的特定片段。

The syntax for a Range request is typically like this: Range: bytes=0-499, which requests the first 500 bytes of the resource.
Range 请求的语法通常是这样的: Range: bytes=0-499 ,它请求资源的前500个字节。

Let test it. 让我们测试一下。

In the following test, I’m attempting to exploit a SQL Injection using the query string parameter ‘a’, but an error occurs and the WAF blocks the response body to prevent the error from being leaked:

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

Typically, MySQL errors display a message like: “You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘foo bar’ at line xyz“.
通常,MySQL错误会显示这样的消息:“您的SQL语法中有一个错误;请检查与您的MySQL服务器版本对应的手册,以获得正确的语法,以便在xyz行的’foo bar’附近使用”。

Knowing that the WAF rule likely matches the initial part of this message, You have an error in your SQL syntax, I can avoid triggering the WAF by “cutting off” the beginning of the response. I do this by sending a byte range HTTP request from 90 to 140. For example:
知道WAF规则可能匹配此消息的初始部分 You have an error in your SQL syntax ,我可以通过”切断”响应的开头来避免触发WAF。我通过发送一个字节范围从90到140的HTTP请求来做到这一点。举例来说:

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

So, as you can see, bypassing any response body filter becomes quite easy using the Range request header. This applies not only to SQL error leakage but also to rules designed to prevent web shell or backdoor responses in the response body.
因此,正如您所看到的,使用Range请求头绕过任何响应体过滤器变得非常容易。这不仅适用于SQL错误泄漏,也适用于旨在防止响应主体中的Web Shell或后门响应的规则。

⚠️ Requesting a byte range HTTP request is not always possible, as it depends on the webserver’s decision to accept it or not. For example, if a SQL Injection payload leads the application to an error resulting in a 500 internal server error, the webserver might choose not to accept the byte range request and instead send the entire error page to the user.

The OWASP Core Rule Set includes a set of rules aimed at preventing “Web Shells” or, in other words, backdoors. These rules attempt to match the HTML body of the most common online backdoors by, for example, triggering on the title tag of the page.
OWASP核心规则集包括一组旨在防止“Web Shell”(换句话说,后门)的规则。这些规则试图匹配最常见的在线后门的HTML主体,例如,在页面的标题标签上触发。

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

One of the most common objections I’ve encountered when explaining the RFDoS problem goes something like this: “Okay, RFDoS could be a problem, but preventing backdoors or PHP shells from being sent to an attacker is more important and worth the risk of RFDoS.
在解释RFDoS问题时,我遇到的最常见的反对意见之一是这样的:“好吧,RFDoS可能是一个问题,但防止后门或PHP shell发送给攻击者更重要,值得冒RFDoS的风险。“

Initially, this seemed like a valid point. However, I then remembered the Byte Range request, and I realized that attackers are often in a position to circumvent the response filter by requesting portions of the response body. I say often because this really depends on the configuration of the webserver and the server side modules. Let’s do a test.
起初,这似乎是一个有效的观点。然而,我随后想起了Byte Range请求,并意识到攻击者通常能够通过请求响应正文的一部分来绕过响应过滤器。我经常这么说,因为这实际上取决于Web服务器和服务器端模块的配置。我们做个测试吧。

I’m going to simulate a web shell, with a title tag that matches one of the Web Shells rules, and include a leak of the WordPress config file (which often contains the username and password for the MySQL database) that will trigger the PHP code leakage rule.
我将模拟一个Web Shell,使用与Web Shell规则之一匹配的标题标签,并包含将触发PHP代码泄漏规则的WordPress配置文件(通常包含MySQL数据库的用户名和密码)的泄漏。

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

If I attempt to access the content of the web shell, the WAF will block my request because of one of the rules mentioned above.
如果我试图访问Web shell的内容,WAF将阻止我的请求,因为上面提到的规则之一。

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

ModSecurity logs: ModSecurity日志:

ModSecurity: Warning. Match of "rx ..." against "RESPONSE_BODY" required. [file "/etc/modsecurity.d/owasp-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf"] [line "102"] [id "953120"] [msg "PHP source code leakage"] [severity "ERROR"] ...

ModSecurity: Warning. Matched phrase "<title>=[ 1n73ct10n privat shell ]=</title>" at RESPONSE_BODY. [file "/etc/modsecurity.d/owasp-crs/rules/RESPONSE-955-WEB-SHELLS.conf"] [line "41"] [id "955100"] [msg "Web shell detected"] ...

To bypass the response filter, I can omit the first part of the response that contains the title tag by skipping the first 60 bytes:

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

But when I try to extend the response to include the wp-config file content, the WAF block me again due to PHP leakage rule:

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

Fortunately, I can use a Multipart Range to request multiple portions of the same response body, which will be served to me as a multipart response. For example:

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

As you can see, I was able to bypass two OWASP Core Rule Set response body rules simply because the HTTP protocol allows me to do so.

With this demonstration, I’m not suggesting that preventing web shells is a bad thing. In many cases, it can help website administrators or hosting providers quickly identify compromised websites, alert the owners, or even remove the shells promptly.
通过这个演示,我并不是说防止Web Shell是一件坏事。在许多情况下,它可以帮助网站管理员或托管服务提供商快速识别受损网站,提醒所有者,甚至及时删除外壳。

The point is that developers and maintainers need to consider RFDoS before implementing a new response body rule, and users should have the option to enable these rules rather than having them activated by default.

Why only ModSecurity v2.x branch is affected by this problem, and not the v3.x branch?
为什么只有ModSecurity v2.x分支受此问题影响,而不是v3.x分支?

ModSecurity v2 is primarily available on Apache (as of this writing). The v3.x branch can only run as an external library on Nginx and other webservers, except for Apache.
ModSecurity v2主要在Apache上可用(截至撰写本文时)。v3.x分支只能作为外部库在Nginx和其他Web服务器上运行,Apache除外。

As you might be aware, all ModSecurity rules must operate in a specific phase. Phase 1 is for the request string and request headers, Phase 2 includes the request body, Phase 3 adds the response headers, and Phase 4 includes the response body.

Nginx, like many other modern webservers, tries to send the HTTP response to the user as quickly as possible. This means that sending the response takes priority over ModSecurity rule inspection. That’s why you can’t inspect the response body on Nginx + ModSecurity v3.x; Nginx sends the response body before ModSecurity has a chance to inspect it at Phase 4.
Nginx,像许多其他现代Web服务器一样,试图尽可能快地向用户发送HTTP响应。这意味着发送响应的优先级高于ModSecurity规则检查。这就是为什么你不能在Nginx + ModSecurity v3.x上检查响应体的原因;Nginx在ModSecurity有机会在第4阶段检查它之前发送响应体。

Why OWASP Core Rule Set doesn’t fixed it yet?

Before I continue, I want to mention that we at SicuraNext are all big fans of the OWASP Core Rule Set project. I privately reported this issue months ago, hoping to convince the team to (at least) remove all those strings that don’t include special characters from the list of denied strings in the response body, or (a better solution for me) move all RESPONSE rules to a plugin, meaning that no response rule are executed by default.
在我继续之前,我想提一下,我们SicuraNext都是OWASP核心规则集项目的忠实粉丝。我在几个月前私下报告了这个问题,希望说服团队(至少)从响应主体的拒绝字符串列表中删除所有不包含特殊字符的字符串,或者(对我来说更好的解决方案)将所有 RESPONSE 规则移动到插件中,这意味着默认情况下没有响应规则被执行。

My concern was about releasing the major version 4.0 of the Core Rule Set with all these RFDoS issues enabled by default. This, along with other issues related to the ModSecurity engine that should be addressed by the rule set itself to prevent bypasses not only in ModSecurity but also in compatible WAFs and all possible future implementations, forms part of a bigger picture (but it’s another story).

Unfortunately, my request to fix wasn’t really considered for the following sentences, with which I strongly disagree:

  • ModSecurity does not enable access to the response body by default.
  • Users can choose to not include rules for the response body.
  • The problem has not yet been reported by any other users.
  • The technique requires too many preconditions.
  • Blocking web shell worth the risk of RFDoS.
    阻止Web Shell值得冒RFDoS的风险。

Let’s examine why, in my opinion, these assumptions are incorrect.

ModSecurity doesn’t access to the response body by default

Yes, it does on v3.x and it does on v2.x and based on my experience, users typically opt to use the default configuration.

Users can choose to not include rules for the response body

In my personal experience with WAFs, users seldom try to understand what a rule actually inspects. Typically, users simply run the rule set without even reading the rule descriptions.

Moreover, let’s put ourselves in the shoes of a WAF end user: Our primary concern is to protect our website, and when a team of security experts (maintaining one of the most used WAF rule sets) recommends preventing SQL error leakages by enabling by default all response rules, what would you do? So, I believe that most users are not able to discern when and where to enable a rule set, and understandably, they tend to trust the vendor (or the community).

Even in the Core Rule Set Documentation, there is no mention that users should first review the rules to decide whether or not to include the response rule set. The documentation simply instructs users to use Include rules/*.conf, which implies including all rules.
即使在核心规则集文档中,也没有提到用户应该首先查看规则以决定是否包含响应规则集。文档只是指导用户使用 Include rules/*.conf ,这意味着包括所有规则。

In this post we’ll see how prevalent this RFDoS is across many websites, and one of the main reasons is Plesk. Many of the targets I checked in order to trigger this problem, send a Plesk error page along with a 403 Forbidden response. As detailed in this documentation, it’s very easy for a Plesk user to enable ModSecurity and the OWASP Core Rule Set (which they refer to simply as OWASP Rule… shame on you, Plesk), but it’s nearly impossible for a user to choose whether or not to enable the Core Rule Set response rules.

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule
Plesk 403 Response HTML 403响应HTML

The problem has not yet been reported by any other users, and if it were a real issue, we would have received numerous reports by now

It’s true that leakage prevention rules have been part of the OWASP Core Rule Set for many years, and there haven’t been any security issues reported related to them. However, we did earn a bounty thanks to this problem, so I am really convinced that these rules represent a real issue that nobody has thoroughly investigated yet.

Moreover, there are numerous cases where a vulnerability was discovered years after being included in software.

The technique requires too many preconditions

When we talk about e-commerce, there are many places where user input is stored and reflected in the response body. As I mentioned before, nearly all e-commerce platforms, like WooCommerce and similar, allow users to leave reviews and comments on products. This alone is enough to be concerned about this issue. Moreover, nowadays, I believe there are no websites that don’t handle user input at all, and very few do not store it and include it in the response body.

Blocking web shell worth the risk of RFDoS
阻止Web Shell值得冒RFDoS的风险

As I mentioned earlier, an attacker is often in a position to bypass a WAF response filter by leveraging the Range request header, allowing them to request just a portion of the response that doesn’t match any WAF rules.

In my opinion, protecting users from a backdoor should not expose them to another type of attack that could be much easier to execute and that anyone could perform, regardless of their skill level.

How many websites are affected by this RFDoS?

As I mentioned earlier, software like Plesk and cPanel allows users to easily enable ModSecurity and rule sets such as the OWASP Core Rule Set, Comodo, or Atomicorp Rules. In both cPanel and Plesk, disabling response body inspection isn’t something a non-expert user can easily do or would typically consider doing. Therefore, many users opt to enable the default configuration, which includes response body inspection and SQL Error leakage prevention rules.

Due to the widespread use of Plesk and cPanel, this type of RFDoS can easily be triggered on many websites across the internet.

It’s hard to determine the exact extent of this issue across the internet. As part of our side project, PWNPress, we’ve been collecting data on all WordPress websites worldwide by parsing the Common Crawl dataset. Through this, we have identified 15 million WordPress sites. Using this information, I ran a custom Nuclei template to verify the presence of a RFDoS condition against a subset of those 15 million websites, by using the WordPress search engine function.
很难确定这个问题在互联网上的确切程度。作为我们的副项目PWNPress的一部分,我们一直在通过解析Common Crawl数据集来收集全球所有WordPress网站的数据。通过这个,我们已经识别了1500万个WordPress网站。利用这些信息,我运行了一个自定义的Nuclei模板,通过使用WordPress搜索引擎功能,针对这1500万个网站中的一个子集验证RFDoS条件的存在。

As you might know, WordPress reflects the user input from the s parameter in the query string back to the response body, as seen in URLs like /?s=foobar.
正如你可能知道的,WordPress将用户输入从查询字符串中的 s 参数反射回响应正文,如在URL中看到的 /?s=foobar 。

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

So, basically for each target I’m going to run 2 HTTP request:

  1. /?s=ORA-1 expecting a 200 OK
    /?s=ORA-1 期待200 OK
  2. /?s=ORA-1234 expecting a 403 Forbidden
    /?s=ORA-1234 期待一个403禁止

If both return the expected status code, so RFDoS is possible. By doing this, I was able to identify a lot of WordPress websites affected by RFDoS.

So, what I’ve done is selected just the first 200K WordPress sites with some European ccTLDs (specifically IT, DE, FR, ES, CH). I’m not planning to test all 15 million WordPress sites available to me because that would require a huge amount of time. My goal is more to understand how frequent this problem is.
所以,我所做的只是选择了前200K WordPress网站与一些欧洲国家代码顶级域(特别是IT,DE,FR,ES,CH)。我不打算测试所有1500万个WordPress网站,因为这将需要大量的时间。我的目标是更多地了解这个问题有多频繁。

.it 200.000 3076 1.54
.es 200.000 2516 1.26
.fr 200.000 1032 0.52
.de 200.000 835 0.42
.ch 124.658 481 0.39

Please keep in mind that all these numbers refer only to WordPress websites, and the subset of tested targets was selected in alphabetical order: the first 200,000 results from 0 to z.

Top 10 Providers with RFDoS Found for Each Analyzed ccTLD (WordPress websites)

Aruba S.p.A. 阿鲁巴公司 1224
Server Plan S.r.l. 服务器计划S.r.l. 314
Cloudflare, Inc. Cloudflare公司 216
SEEWEB s.r.l. 158
Hetzner Online GmbH 141, Inc. 94
Consortium GARR GARR联盟 78

DinaHosting S.L. 667
Cloudflare, Inc. Cloudflare公司 157
Soluciones web on line s.l. 135
Hetzner Online GmbH 67
Abansys & Hostytec, S.L.
Abansys & Hostytec,S.L.
45, Inc.,公司名称 41

Cloudflare, Inc. Cloudflare公司 63
Contabo GmbH 41
Renater 32
Internet Vikings International AB
Cogent Communications 21, Inc.,Inc. 12
Ikoula Net SAS 10

Host Europe GmbH 104
Hetzner Online GmbH 91
dogado GmbH 多加多有限公司 77
Strato AG 49
netcup GmbH 30
Cloudflare, Inc. Cloudflare公司 29
Internet Vikings International AB
Nawork Internet Informationssysteme GmbH 26
Michael Sebastian Schinzel trading as IP-Projects GmbH & Co. KG
Michael塞巴斯蒂安Schinzel作为IP—Projects GmbH & Co. KG进行贸易

Hetzner Online GmbH 157
Cloudflare, Inc. Cloudflare公司 35
Internet Vikings International AB
Nexanet AG 20
Infomaniak Network SA 17
hosttech GmbH 11, Inc. 10
Liberty Global B.V. 10

Obviously, if any of the mentioned providers want to know where we found RFDoS issues with their customers, they can contact us, and we are willing to share this information with them.

Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

The Credit Card Number Problem

Many years ago, Trustwave published some advice on how to prevent credit card number leakages using ModSecurity WAF.
许多年前,Trustwave发布了一些关于如何使用ModSecurity WAF防止信用卡号码泄露的建议。

# Visa
SecRule RESPONSE_BODY|RESPONSE_HEADERS:Location "@verifyCC (?:^|[^\d])(?<!google_ad_client = \"pub-)(4\d{3}\-?\d{4}\-?\d{2}\-?\d{2}\-?\d(?:\d{3})??)(?:[^\d]|$)" \
logdata:'Start of CC #: %{tx.ccdata_begin}***...',\
msg:'Visa Credit Card Number sent from site to user',\

This SecRule is a ModSecurity rule designed to identify and block the transmission of Visa credit card numbers either within the response body or in the headers of a web response. Let’s break down the components of this rule to understand its function:

  • SecRule RESPONSE_BODY|RESPONSE_HEADERS:Location: This specifies the targets for the rule, which are the response body and the Location header in HTTP responses. The rule will check these areas for patterns that match a Visa credit card number.
    SecRule响应_正文|RESPONSE_HEADERS:Location:指定规则的目标,即HTTP响应中的响应体和 Location 头。该规则将检查这些区域中与Visa信用卡号匹配的模式。
  • @verifyCC ..regex..: This is the regular expression used for detection. It uses @verifyCC to apply a credit card verification algorithm, ensuring the numbers match a typical Visa card format:
    @ verifyCC.. regex..:这是用于检测的正则表达式。它使用 @verifyCC 来应用信用卡验证算法,确保数字与典型的Visa卡格式相匹配:

    • Visa cards begin with a 4.
    • The format is typically 4 sets of 4 digits, which can optionally be separated by hyphens.
    • The regex ensures that the numbers are not part of a larger sequence of digits and aren’t improperly extracted from substrings like text or scripts.
  • ctl:auditLogParts=-E: This control directive modifies which parts of the transaction are included in the audit log. In this case, -E means to exclude the response body from the audit logs to protect sensitive data. 重试  错误原因
  • block: This action directive tells ModSecurity to block the response if the rule condition is met, preventing the data from reaching the user. 重试  错误原因

This rule seems crucial for compliance with data security standards like PCI DSS, which require the protection of credit card information to prevent data breaches and fraud. However, it also exposes the protected website to RFDoS, when the website allows users to store and reflect any user input. 重试  错误原因

Indeed, this approach is widely used where companies must comply with PCI DSS. Many vendors opt for an alternative to blocking the response body. They replace the suspicious leakage string with a series of * without actually blocking the response. While this method is less problematic in terms of RFDoS, it becomes completely ineffective when an attacker can send a Byte Range HTTP request, as we’ve seen before.
事实上,这种方法被广泛用于公司必须遵守PCI DSS的情况。许多供应商选择了一种替代方法来阻止响应主体。他们用一系列的 * 替换可疑的泄漏字符串,而实际上没有阻止响应。虽然这种方法在RFDoS方面问题较少,但当攻击者可以发送字节范围HTTP请求时,它变得完全无效,正如我们之前看到的那样。

Conclusion 结论

The Response Filter Denial of Service problem represents a significant security challenge that arises when well-intentioned security measures inadvertently create new vulnerabilities. Specifically, RFDoS occurs when Web Application Firewalls or similar security tools are configured to inspect and filter HTTP response bodies to prevent sensitive data leakage, such as application errors or credit card numbers. While these filters aim to protect against data exposure and comply with regulations like PCI DSS, they also allow attackers to exploit these mechanisms to induce service disruptions.
响应过滤器拒绝服务问题是一个重大的安全挑战,当善意的安全措施无意中创建新的漏洞时就会出现。具体来说,当Web应用程序防火墙或类似的安全工具被配置为检查和过滤HTTP响应主体以防止敏感数据泄漏(如应用程序错误或信用卡号)时,就会发生RFDoS。虽然这些过滤器旨在防止数据泄露并遵守PCI DSS等法规,但它们也允许攻击者利用这些机制来引发服务中断。

Attackers can trigger RFDoS by injecting content that matches the filters set to block or alter responses, leading to legitimate requests being blocked or altered (effectively denying access to the service for regular users). Furthermore, the ability of attackers to use features like the HTTP Range request complicates the issue, as it allows them to bypass filters that inspect entire response bodies by requesting only portions of the data.
攻击者可以通过注入与过滤器匹配的内容来触发RFDoS,从而阻止或更改响应,导致合法请求被阻止或更改(有效地拒绝普通用户访问服务)。此外,攻击者使用HTTP Range请求等功能的能力使问题复杂化,因为它允许他们通过仅请求部分数据来绕过检查整个响应主体的过滤器。

The main takeaway is that while response body filtering is critical for protecting sensitive data from being exposed, it requires a balanced approach to ensure it does not compromise the availability of web services. Security teams must continually evaluate the effectiveness of their protective measures against emerging threat vectors and consider adopting more dynamic and context-aware filtering techniques. Additionally, educating users on the potential risks and configurations of WAF settings can help mitigate some aspects of RFDoS vulnerabilities.

原文始发于Andrea Menin:Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule

版权声明:admin 发表于 2024年5月15日 上午10:49。
转载请注明:Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule | CTF导航