原文:
https://medium.com/@andrewaeva_55205/how-dangerous-is-request-splitting-a-vulnerability-in-golang-or-how-we-found-the-rce-in-portainer-7339ba24c871
一天晚上,我坐下来,决定看看优步基础设施的安全性,启动一个扫描仪,我的眼睛看到了主机data-07.uberinternal.com,我使用nmap,端口9000被发现。它是一个鲜为人知的网络服务——Portainer。
经过几分钟的搜索,在https://github.com/portainer/portainer上找到了受害者。它最终成为Docker容器编排的一个流行的开源解决方案。在演示http://demo.portainer.io/之后,很明显Docker容器是通过Docker API管理的,但是允许访问Docker API是不安全的,所以TCP代理方案是通过Websocket接口使用的。代理不需要身份验证,因为请求包含唯一的容器标识符- id。它充当特定容器的API键。
代理方式:
HTTP-upgrade请求发送:

这个查询是针对Docker api的,POST /exec/uuid/start。
然后建立一个Websocket连接,该连接通过TCP代理到容器,用户可以在网站上运行命令。
经过仔细研究源代码发现了SSRF漏洞。

这段代码出了什么问题?
问题是,用户控制execID,它被连接到HTTP请求的路径中。这是Websocket连接建立时传递的id参数。因此,我们可以尝试使遍历POST /exec/…/任何东西/开始。很好,现在我们控制请求到Docker API的路径,但它能给我们什么?
通过从文档中阅读文档,很明显什么都没有。我们被阻止从请求路径的末尾开始。
想了一会儿,我想起了HTTP_pipelining。允许在同一个TCP连接中发送多个HTTP请求的技术。要发送多个请求,您必须能够传递CRLF控制字符。
摇人摇来了@kyprizel和@buglloc。
Golang的0day
@buglloc在标准Golang库中发现CRLF注入。这是因为查询参数没有通过urlencode传递。我们向Golang安全团队报告了这个问题,补丁在一天内就准备好了- https://go-review.googlesource.com/c/go/+/159157他们决定删除所有的控制字符(这是好的,这是很多人做的)。事实证明,他们已经知道这个问题,做了修复,但不小心回滚了。总是检查您是否没有回滚新版本中的安全错误修复!
http中CRLF注入的示例。NewRequest:

这段代码显示了CRLF注入功能,这意味着我们可以将头文件添加到Docker API请求中。
这种类型的漏洞称为请求拆分。
http管道
现在我们可以在请求Docker API时使用HTTP管道。
作为一个例子,我们将要求Docker API通过从我们的主机jf2958pei4fqzxnwktp1snmvtmzcn1.burpcollaborator.net下载映像来创建映像。
通过用换行符%0a分隔header,将请求发送到前端。


然后请求将到达Docker API:

在我们的服务器jf2958pei4fqzxnwktp1snmvtmzcn1.burpcollaborator.net上,我们将收到一个Docker映像的HTTP请求。

因此,请求拆分帮助我们利用了SSRF漏洞,并获得了向本地Docker API发出任意请求的能力。
有关该漏洞的信息被发送给了Portainer作者和Uber安全团队。从Portainer作者修复。该漏洞被收录为CVE-2018-12678。另外,我们在Dr.Web服务器上发现了Portainer,我们也报告了这个问题。
本文迁移自知识星球“火线Zone”