对 Windows IIS HTTP/2 PING FLOOD 拒绝服务漏洞(CVE-2019-9512)的分析
0x01 漏洞描述
Microsoft Windows最近修复了一个拒绝服务漏洞。该漏洞是由于在向Web服务器连续发送HTTP / 2 Ping帧(不要与ICMP Ping混淆)时资源耗尽所致。此漏洞最初是由Netflix的Jonathan Looney报告给Microsoft的,并且已下发编号CVE-2019-9512。
远程未经身份验证的攻击者可以通过发送大量HTTP / 2 Ping帧来利用此漏洞,成功的利用会在目标系统上导致拒绝服务的情况。
0x02 漏洞分析
Windows Internet信息服务器(IIS)是Windows操作系统附带的Internet服务的集合。IIS包括一个能够提供静态和动态内容的HTTP服务器。IIS支持各种Web技术,包括HTML,ASP,ASP.NET,JSP,PHP和CGI。IIS包括对新版本的HTTP协议的支持:HTTP/2。此功能由http.sys内核模式驱动程序提供。
HTTP / 2是超文本传输协议的现代标准。它通过提供以下功能,对广泛使用的HTTP / 1.1标准进行了改进:提供用于将来扩展的HTTP版本协商,使用加权流的多个请求的复用以及HTTP头的数据压缩。HTTP/2是一种二进制协议,保留了HTTP /1.1的许多用法和语义,包括其方法,状态代码和标头字段。现代浏览器(例如Google Chrome,Mozilla Firefox和Microsoft Edge)和Web服务器(例如Microsoft IIS,nginx,Apache httpd)都支持HTTP/2。尽管HTTP/2并未强制执行基于TLS的安全传输,但这些实现仅允许HTTP/2通过TLS进行传输。TLS握手中的端点使用应用程序层协议协商(ALPN)TLS扩展来协商应用程序层协议,目前包括以下内容:HTTP/1.1,SPDY/2,SPDY/3和各种HTTP/2标识符(h2,h2-17,h2-14,h2c,h2c-17)。Microsoft IIS支持h2 ALPN扩展,其中TLS握手完成后立即交换HTTP / 2数据。
HTTP/2连接以24字节魔术连接开头:
PRI * HTTP/2.0\x0d\x0a\x0d\x0aSM\x0d \x0a\x0d\x0a
在此序列之后,交换一系列帧,这是从SETTINGS帧开始的HTTP/2中编码数据的基本单位。所有帧都有固定长度的9字节报头,后跟可变长度的payload。框架的结构如下:
所有多字节整数均采用big-endian格式。
HTTP/2 Ping帧(帧类型= 0x6)是一种机制,用于测量来自发送方的最小往返时间,以及确定空闲连接是否仍在起作用。可以从任何端点发送Ping帧。除帧头外,Ping帧还必须在payload中包含8个字节的数据。发送人可以包括其选择的任何值。不包含ACK标志的Ping帧的接收者必须发送一个ACK标志作为响应,并以相同的payload发送Ping帧。Ping响应的优先级应高于其他任何帧。Ping帧不与任何单个流相关联,并且其流标识符应设置为0。
Windows内核模式HTTP驱动程序中存在一个拒绝服务漏洞http.sys。将基于Windows的Web服务器(如IIS)配置为HTTPS时,默认情况下它将启用对HTTP/2的支持,http.sys用于处理通过TLS的传入HTTP / 2请求。为每个HTTP / 2连接http.sys维护一个状态。当http.sys收到Ping帧时,HTTP!UxDuoParsePing()将调用函数以建立此状态并分配内存。内存分配发生在函数中HTTP!UxDuoAllocateParcel(),从中调用HTTP!UxDuoParsePing()。如果恶意攻击者发送连续的Ping帧流,将分配大量资源来处理这些帧。该函数还会分配额外的内存HTTP!UxDuoParse(),该内存会调用HTTP!UxDuoParsePing()。功能HTTP!UxDuoParsePing() 如果不允许速率限制可以从客户端接受和处理的Ping帧数,则会导致大量资源耗尽。
请注意,在的修补版本中http.sys,该HTTP!UxDuoParsePing()函数调用新引入的函数HTTP!UxDuoApplyPingFrameDosPrevention()。此新功能利用注册表设置HTTP2MaxPingsPerMinute,该设置限制客户端在服务器关闭连接之前每分钟可以发送到服务器的ping的最大数量。此项位于注册表中的HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters。
通过发送连续的HTTP / 2帧流,攻击者可以在受影响的目标服务器上造成大量的资源耗尽,从而导致潜在的服务拒绝状况-尤其是在使用源计算机的分布式网络的情况下。
0x03 源码分析
以下代码段摘自http.sys版本10.0.14393.2828。
为了触发条件,攻击者启动与目标服务器的TLS连接,并使用“ h2” ALPN扩展值协商HTTP / 2。然后,攻击者将HTTP / 2魔术字节和多个Ping帧发送到目标主机。在服务器保持这些连接的持续时间内,服务器将在处理这些帧时触发该漏洞。
0x04 补丁修复
Microsoft在8月发布了针对此漏洞的补丁并将其分配CVE-2019-9512。除了使用供应商提供的补丁程序外,管理员还需要配置服务器以限制接受的HTTP / 2数据包的数量。这可能取决于每个服务器上运行的环境和服务。管理员必须在注册表编辑器中添加“ HTTP2MaxPingsPerMinute”设置。可以在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters找到此密钥。
0x05 分析总结
将基于Windows的Web服务器(如IIS)配置为HTTPS时,默认情况下它将启用对HTTP/2的支持,http.sys用于处理通过TLS的传入HTTP / 2请求。为每个HTTP / 2连接http.sys维护一个状态。当http.sys收到Ping帧时,HTTP!UxDuoParsePing()将调用函数以建立此状态并分配内存。内存分配发生在函数中HTTP!UxDuoAllocateParcel(),从中调用HTTP!UxDuoParsePing()。如果恶意攻击者发送连续的Ping帧流,将分配大量资源来处理这些帧。该函数还会分配额外的内存HTTP!UxDuoParse(),该内存会调用HTTP!UxDuoParsePing()。功能HTTP!UxDuoParsePing() 如果不允许速率限制可以从客户端接受和处理的Ping帧数,则会导致大量资源耗尽。
应该是趋势的研究员在Fuzzing Windows Internet信息服务器(IIS)时发现的,这种洞对分布式计算资源的消耗影响很大。