Just like a knife with two cutting edges, this is a story of a double-edged
Server-Side Request Forgery (SSRF) vulnerability which was successfully exploited to achieve and demonstrate both server and client-side security impact which is not very common to come across, at least in my own experience.
I was looking into a private bug bounty program that belongs to an organization offering a network monitoring solution so while poking around and testing out their various features, I ran some network tests using their agent then I took notice of this small feature that allows users to export the results of the test by sending you a PDF copy by e-mail. The request was the following:
To my surprise, when I received the PDF report in the e-mail, it was literally a screenshot of the result’s web page so I went back to double check the endpoint and got intrigued by
location parameter. I assumed the backend was probably taking a screenshot of the page at
/v4/export/synthetics/tests/780/results and e-mailing it to the user.
To verify my assumption, I changed the value of
location parameter to point to another authenticated route within the application, such as
Bingo! it worked as I received a PDF screenshot of that authenticated web page, so I was curious how this feature could be implemented in the backend and if there is any way we can point it to a different host, internal or external. I decided to run some tests as follows:
The PDF report contained a screenshot of a
404 error which I was already familiar with, therefore I went with the assumption that the backend was most likely taking the value of
location parameter, appending it to the host and then taking a screenshot, i.e:
If that is the case, then we can try common SSRF bypasses such as:
.example.com which, should they work, would result in the backend issuing an HTTP request to:
Well, both did work and received the below PDF report in the e-mail:
Since we have a confirmed SSRF, we need to maximize its security impact by attempting to hopefully exploit it against their internal network, so naturally, the first test I ran was pointing the
location parameter to internal hosts using various common techniques as described in this repository.
I tried payloads like
@spoofed.burpcollaborator.net that points to the loopback address,
301 redirection, etc. but unfortunately, none of them worked as I was receiving a blank PDF report.
I looked for more internal hosts other than the typical ones which seem to be blacklisted, therefore I did a quick subdomains reconnaissance using
Amass but it didn’t yield anything interesting so I searched on Github and I found a repository that referenced
https://redash.iad1.████████.com which appears to be an internal host that was alive but not publicly accessible.
I quickly set the
location parameter value to
@redash.iad1.████████.com and got this PDF report in the mailbox:
Well, that escalated quickly! The host was running an instance of
Redash with the login credentials auto-saved in plain-text. I thought they might be running other DevOps tools under
.iad1.████████.com, so I manually fuzzed some popular project names, such as:
puppet.iad1.████████.com was the jackpot!
puppet is a software used to manage the infrastructure from servers’ configuration, deployment to orchestration, etc. That was the only guess I needed because I received a 10 pages PDF report which literally listed all of their internal hosts as you can see:
I tried to hit a few of these internal endpoints and they seemed to be all accessible:
At this point, we have a nicely exploitable SSRF to report to the program but I decided to explore the vulnerable endpoint a bit further. There are three important notes that I initially dismissed if you refer back to our previous HTTP request:
- The GET endpoint was not protected against CSRF attacks.
- It takes a screenshot of any authenticated web page.
- It sends the screenshot to the address provided in
Consequently, by sending a specially crafted URL to a legitimate user, I can screenshot any authenticated page of theirs and send the report to my own e-mail address so the exploit would be as simple as:
Clicking on the above link would take a screenshot of
/v4/settings/users web page and then e-mail it to
firstname.lastname@example.org which is the attacker’s email address - this was disclosing information for any other authenticated endpoint like networks agents at
/v4/synthetics/agents, network classifications at
Afterwards, I set up an HTTP logger at
requestcatcher.com then pointed the
location parameter to my webhook
@testing1337.requestcatcher.com. Unexpectedly, the HTTP request was found to be leaking my account’s e-mail address as well as API key through the its headers:
Therefore, we can leverage this endpoint to leak any organization’s email and API key associated with their account by simply misleading the user to click on:
At this point, I decided to wrap up my research and submitted a comprehensive report to the program which fixed and rewarded it their maximum bounty award. I’d like to thank ninetynine for their collaboration and thank you for taking time to read until the end.