CVE-2023-44487 是利用 HTTP2 协议本身的漏洞。在 HTTP2 中,数据请求通过发送 HEADERS 帧发起。服务器收到该帧后,会开始处理你的请求,随后发送 DATA 帧直到所有数据传输完毕。HTTP2 还定义了 RST_STREAM 帧,可用于在任何时刻关闭一个流。为防止攻击,服务器通常限制并发打开的最大流数量(默认为 100)。如果客户端实际等待所有资源消耗完毕,这个限制很少被触发。该攻击之所以奏效,原因很简单:客户端可以在 任何 时刻发送 RST_STREAM 帧。RST_STREAM 帧会关闭一个流,而关闭的流不计入并发流。这意味着客户端可以快速发送请求,而永远不会触及这个限制——只需在发送请求后立即关闭连接即可。在某些情况下,被攻击的服务器仍会开始加载数据,从而产生过载。
此工具旨在检查服务器对该攻击的脆弱性。它建立一个或多个并发 HTTP2 连接,随后发送指定数量的 HEADER 帧,紧接着发送 RST_STREAM 帧。
它还提供了许多其他配置选项,例如 HEADERS 和 RST_STREAM 帧之间的延迟、要打开的流数量、每个流要发送的帧数等等。攻击完成后,它会输出一个摘要,包含接收到的帧数量、错误数量以及接收到的 GOAWAY 帧数量。这可以帮助你判断你的服务是否容易受到 CVE-2023-44487 的攻击。
目前,此工具仅以源代码形式分发,意味着需要安装 Go。可以通过运行 go run main.go <options> 来执行该工具。
还有一个 Python 脚本,可用于绘制写入 monitor.log 文件的延迟信息。
此外,我创建了一个新的 Python 工具集,用于更精确和广泛的测量。
位于 tooling 文件夹中的 runner.py 文件将读取你在 config.py 中定义的值(详见 config-sample.py),并为所有定义的 Docker 容器运行所有测试。
然后,它会为所有在 paths 数组中定义的路径运行最成功的测试(中位数 + 平均延迟最高的)。它会为每个运行的测试输出图表和日志文件。
该工具集仍在开发中。我创建它仅仅是因为我懒得手动运行所有这些测试来为我们的研究论文提供数据。
欢迎提交 PR 来清理它,或使其真正适用于除了我们的用例之外的场景。
目前,实现了以下 CLI 选项:
该工具会输出大量调试信息以及一个摘要。 调试信息包含连接建立方式、当前进度以及当前发送帧类型的信息。
摘要看起来类似这样(取决于你的配置):
####################SUMMARY####################
Packet types received:
PING: 2
HEADERS: 12
SETTINGS: 0
DATA: 11
GOAWAY: 3
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Attack ending reasons (per receiving thread):
GoAway events: 3
Timeout events: 0
Error events: 0
Summary for connection 2
PING: 1
HEADERS: 9
SETTINGS: 0
DATA: 6
GOAWAY: 1
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Reason for stopping to listen for more packets: GoAway - the server responded as expected.
Summary for connection 1
PING: 1
HEADERS: 3
SETTINGS: 0
DATA: 5
GOAWAY: 1
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Reason for stopping to listen for more packets: GoAway - the server responded as expected.
Summary for connection 0
PING: 0
HEADERS: 0
SETTINGS: 0
DATA: 0
GOAWAY: 1
RSTSTREAM: 0
WINDOWUPDATE: 0
UNKNOWN: 0
Reason for stopping to listen for more packets: GoAway - the server responded as expected.
如果你认为还有其他需要收集的统计数据,请随时联系我或创建一个 Issue!
此工具仅供研究目的使用。请勿用于攻击你不拥有或管理的服务器。 我对所提供的统计数据的准确性,以及攻击对服务器和服务造成的后果不承担任何责任。
| 标志 | 默认值 | 含义 |
|---|
| frames | 1 | 在任意流上发送的 HEADERS 和 RST_STREAM 帧数量 |
| connections | 1 | 用于运行攻击的 TLS 连接数(并发) |
| consecutiveSends | 1 | 在发送 RST_STREAM 帧之前发送的 HEADERS 帧数量(每个流) |
| connectAttempts | 1 | 连续运行测试的连接数(每个连接例程) |
| delay | 0 | 发送 HEADERS 和 RST_STREAM 帧之间等待的时间(毫秒) |
| ignoreGoAway | false | 如果为 true,GOAWAY 流不会导致接收例程终止。相反,它会等待直到超过 10 秒没有收到任何帧。 |
| monitor | false | 启用性能监控 |
| monitorDelay | 100 | 测试响应延迟之间等待的时间(毫秒) |
| monitorLog | ./monitor.log | 写入监控延迟日志的文件 |
| routines | 1 | 要攻击的流数量 |
| skipValidation | true | 如果为 true,服务器证书将不会被验证(这是默认行为——我们不在乎安全性,因为我们毕竟是攻击者) |
| timeout | 1000 | 等待新帧的时间,超过则认为连接尝试无效并停止 |
| url | https://localhost:433/ | 要攻击的目标 URL |