一. HTTP请求走私攻击
HTTP(Hyper Text Transfer Protocol,超文本传输协议)是万维网服务器传输超文本至本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
简单的网络环境中,我们直接通过浏览器访问服务器,但是由于很多静态资源需要在服务器提供,这种方式无疑是大大增加了web服务器的负荷。
在稍微复杂的网络环境中,为了提升用户的浏览速度,提高使用体验,减轻服务器的负担,很多网站都用上了CDN加速服务,即在源站的前加上一个具有缓存功能的反向代理服务器,用户可直接从代理服务器获取静态资源,而无需从源站所在服务器中获取。另一方面,这个反向代理可以隐藏web服务器的真实IP,所以很多中小型网站都采用类似方案。常见拓扑图如下:
一般来说,反向代理服务器与后端的源站服务器之间,会重用TCP链接。这也很容易理解,用户的分布范围是十分广泛,建立连接的时间也是不确定的,这样TCP链接就很难重用,而代理服务器与后端的源站服务器的IP地址是相对固定,不同用户的请求通过代理服务器与源站服务器建立链接,这两者之间的TCP链接进行重用,也就顺理成章了。
HTTP走私原理
当我们向代理服务器发送一个比较模糊的HTTP请求时,由于两者服务器的实现方式不同,可能代理服务器认为这是一个HTTP请求,然后将其转发给了后端的源站服务器,但源站服务器经过解析处理后,只认为其中的一部分为正常请求,剩下的那一部分被作为走私请求,当该部分对正常用户的请求造成了影响之后,就实现了HTTP走私攻击。
HTTP请求走私漏洞是因为前端的反向代理服务器和后端的Web服务器,对同一个请求的理解不一致造成的。因此,针对同一个HTTP请求,不同的服务器可能会产生不同的处理结果,这样就产生了安全风险。
如上图,攻击者恶意构造一个用户请求。这个请求被前端服务器理解为两个完整的请求,而后端服务器理解为一个请求和一个不完整的请求,于是后端服务器会等待正常用户的访问请求,只有将“不完整”请求与正常请求拼接后才对其响应。
HTTP走私演示
根据破坏请求的方式不同,一般将HTTP走私分为几种不同的情形(CL:Content-Length, TE:Transfer-Encoding):
Ø CL!=0 Ø CL-CL Ø CL-TE Ø TE-CL Ø TE-TE
下面演示CL-TE的攻击方式。所谓CL-TE,就是当收到存在两个请求头的请求包时,前端代理服务器只处理Content-Length请求头,而后端服务器会遵守RFC2616的规定,忽略掉Content-Length,处理Transfer-Encoding请求头。
Lab 地址:https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te
连续发送几次请求就可以获得该响应:
由于前端服务器处理Content-Length,所以这个请求对于它来说是一个完整的请求,请求体的长度为6,如下:
0\r\n \r\n G
当请求包经过代理服务器转发给后端服务器时,后端服务器处理Transfer-Encoding,当它读取到0\r\n\r\n时,认为已经读取到结尾了,但是剩下的字母G就被留在了缓冲区中,等待后续请求的到来。
当我们重复发送请求后,发送的请求在后端服务器拼接成了类似如下这种请求:
GPOST / HTTP/1.1\r\n Host: ......
服务器在解析时就会产生报错。
利用http走私攻击,攻击者可以进行绕过前端服务器的安全控制、获取前端服务器重写请求字段、获取其他用户的请求、进行缓存投毒等攻击。
防御建议
针对http走私攻击,通用的防御措施大概有三种:
Ø 禁用代理服务器与后端服务器之间的TCP连接重用。
Ø 使用HTTP/2协议。
Ø 前后端使用相同的服务器。
二. H2C走私攻击
通过HTTP走私,攻击者可以访问内部的服务器甚至是获得各种提权的机会。当前HTTP/1.1被广泛应用,但也暴露出一些问题,比如容易出现请求走私,使用HTTP/2可以解决走私,但是HTTP/2并不能完全防止走私。
下面我们演示通过HTTP/2 without TLS(h2c)将HTTP/1.1连接升级到HTTP/2并且可以Bypass反向代理的访问控制,并且保持一个TCP长连接,导致HTTP请求不受反向代理的控制直接传送到后端服务器。
HTTP/2协议与H2C交换
通常HTTP/2协议在第一个HTTP请求之前,使用h2字符串进行标识,h2c是在Web协议从HTTP/1.1升级到HTTP/2的步骤中使用的标头。根据RFC-7540文档的描述,仅当客户端和服务器均支持HTTP/2时,才能使用HTTP / 2协议。
如何检测服务端是否支持HTTP/2:
1:客户端发起如下请求:
GET / HTTP/1.1 Host: test.example.com Connection: Upgrade, HTTP2-Settings Upgrade: h2c
2:如果支持HTTP/2,则服务器响应:
HTTP/1.1 101 Switching Protocols Connection: Upgrade Upgrade: h2c [ HTTP/2 connection ...
3:如果不支持HTTP/2,则服务器响应:
Server ignored
如何将HTTP/1升级为HTTP/2:
当HTTP/1.x要升级到HTTP/2,标识符、HTTP2-Settings标头和Upgrade标头需要出现在http请求中。标识符的类型包括HTTP的h2c和HTTPS的h2。当Upgrade: h2c时,则以纯文本形式传递HTTP/2:
GET / HTTP/1.1 Host: test.example.com Connection: Upgrade, HTTP2-Settings Upgrade: h2c HTTP2-Settings: <base64url encoding ofHTTP/2 SETTINGS payload>
在服务器支持HTTP/2时,它将101 Switching protocol转发到客户端并建立TLS连接(HTTP/2)与客户端进行通信。在这种情况下,使用TLS-ALPN协议。
在此过程中,使用APLN扩展名,客户端向服务器提供版本列表,然后服务器选择一个版本。同理,使用https时,HTTP/2选择h2。当直接使用HTTP/2时,通过TLS-ALPN进行协议协商之后,进行TLS连接。
H2C走私原理
许多Web服务都使用反向代理。在此过程中,当需要进行101 Switching时,代理服务器将充当中介,无需任何操作。通过阅读RFC文档和TLS中关于HTTP/2配置文档,里面声明只有明文连接才可以使用h2c升级,并且转发时不应包含HTTP2-Settings头。
具体走私流程如下图:
1、客户端将HTTP/1.1升级请求发送到反向代理(发送了错误的标头);
2、代理将请求转发到后端,后端返回101 Swiching协议的响应,并准备接收HTTP/2通信;
3 .代理从后端服务器收到101响应时,将创建TCP隧道;
4 .客户端从代理接收到101响应时,将重新用现有TCP连接并执行HTTP/2初始化;
5 .客户端使用HTTP/2多路复用,发送针对受限资源的违法请求;
6 .由于代理服不监视TCP通信(HTTP通过策略),因此它将违法请求发送到受限页面;
7 .服务器响应,转发到TLS隧道,实现走私。
H2C走私演示
这里使用docker环境试验H2C走私,服务器使用nginx,docker-compose将模拟三条代理链,如下表所示。
TCP端口 | 描述 |
8000 | HTTP h2c后端 |
8001 | HAProxy->h2c后端(不安全的默认配置) |
8002 | nginx->h2c后端(不安全自定义配置) |
8003 | Nuster->HAProxy->h2c后端(多层代理的不安全配置) |
这些代理链将导致启用h2c的Golang后端,如下图:
所有代理都拒绝访问h2c后端上可访问的/flag节点。我们尝试通过在端口8001上运行的HAProxy服务器访问禁止的端点,如下图:
使用h2cSmuggler工具来确认代理的不安全配置,如下图:
使用h2cSmuggler执行h2c升级,通过代理对HTTP/2流量进行隧道传输,并从后端请求/flag端点,绕过代理的访问控制,如下图:
如上所示,我们成功绕过了代理的访问控制来访问内部的HTTP接口!
防御建议
H2C具有减少带宽的能力,所以它非常适合用于低延迟的内部网络通信(微服务),避免了TLS的管理和(有争议但经常被提及的)性能开销。因此,流行的web框架通常支持一个配置选项来支持h2c升级,但是支持升级不是默认的,需要手动开启。如果前端代理配置不安全,在微服务中使用h2c可能会增加被成功攻击的可能性。
降低代理服务器上h2c走私的风险方式:
1、需要WebSocket支持:仅允许值WebSocket用于HTTP/1.1升级头(例如,upgrade:WebSocket)。
2、不需要WebSocket支持:不转发Upgrade请求头。
要使h2c走私成功,需要将升级头(有时是连接头)从边缘服务器成功转发到支持h2c升级的后端服务器。此配置可以发生在任何反向代理、WAF或负载平衡器上。
默认情况下,以下服务在代理传递过程中会转发Upgrade和Connection标头,从而使开箱即用的H2C走私成为可能:
Ø HAProxy
Ø Traefik
Ø Nuster
默认情况下,这些服务在代理通常过程中不转发Upgrade和Connection标头,但可以以不安全的方式配置(通过传递未过滤的Upgrade和Connection标头):
Ø AWS ALB/CLB
Ø NGINX
Ø Apache
Ø Squid
Ø Varnish
Ø Kong
Ø Envoy
Ø Apache Traffic Server
参考链接
https://v0w.top/2020/12/20/HTTPsmuggling
https://labs.bishopfox.com/tech-blog/h2c-smuggling-request-smuggling-via-http/2-cleartext-h2c
https://www.anquanke.com/post/id/220996
来源:freebuf.com 2021-04-08 13:46:38 by: 星河工业安全
请登录后发表评论
注册