Safety with real examples is always interesting.
Today we’ll talk about the SSRF attack, when you can force the server to make arbitrary requests to the Internet through the img tag.
So, I was recently engaged in penetration testing on two projects simultaneously, on two of them this vulnerability was revealed. Screenshots are taken directly from the reports, therefore all unnecessary information is smeared.
Attack description
Attack name: the server makes arbitrary requests to the Internet while generating a PDF document.
Description: PDF is generated on the server side from a fully rendered html page with all external resources. The documents contained data entered by the user. Without proper filtering, you can substitute your external resources in server rendering. In this case, let it be the
it-band.by/10gb.blob file (supposedly 10 Gb in size).
Worst scenario:
- Ddos attack from the inside, when the system needs to download 100 gigabytes of data for rendering in order to render several PDF documents at once. As a result, this leads to a lack of network or memory resources, which in turn can lead to system down.
- A malicious user can use the server as a platform to attack other resources.
- A malicious user obtains the external IP addresses of internal servers for direct attacks, bypassing web application firewalls (WAF) and balancers.
Risk assessment (Likelihood * Impact): Medium (5) * High (7) = High (35) (in both systems, the risk was rated as high, although with different ratios)
Interestingly:
- One system used wkhtmltopdf to render html2pdf, the second one ran Firefox, loaded the page there and took a screenshot. In any case, both systems immediately render both pages, execute all the code there, and only then make PDF from this.
- XSS server protection was installed on both systems, but instead of using the input data escape, both systems used html purifying, which cleared all iframes, scripts, css, forms, and so on. But html purifying in both systems considered
img src="https://it-band.by/10Gb.blob?t=12345.1"/
safe html code.
Now go through the steps and screenshots
1) Make such a file locally, in an attempt to later fill it in whole or in part.
2) In the beginning, you need to find vulnerable user fields.
System 1. Failed to insert only one img tag
System 2. I managed to insert about 20 tags right away
3) Next, we generate the PDF document.
System 1. Generated PDF
System 2. Generated PDF
4) And now we climb onto our server to see if there were requests for our large 10Gb.blob file.
System 1. We get the server IP address and software, with the help of which the PDF document was generated, nmap showed another open port, which no one had seen before, by the found IP address.
System 2. It can be seen that the server tried to download 20 files of 10 gigabytes. We also get the address of one of the servers and the version of Firefox used.
Total. In both systems, errors have already been fixed. In the first system, instead of html purifying, escaping is done both during the processing of user data and during the generation of a PDF document; in the second system, any absolute links to external resources are cut during user data processing.
Updated.
While I got to the publication of the article, cases from 2 more systems were added.
Another system (let's call System 3) did not pass the check for this type of vulnerability in two places at once: through HTML Injection and CSS Injection.
System 3. Html injection with downloading 20 times of a live picture 13 Mb (in the total 260Mb)
System 3. CSS Injection
System 3. What do we see on the attacking server when rendering a PDF (all 20 downloads of a 13Mb picture are successful)
What the output was for System 3:
1) Got the addresses of the servers that render, and what they use for rendering. In this case, HeadlessChrome.
2) The generation of one PDF document took about 5 minutes, then chrome simply fell. Imagine, if you run 10K of such requests, then for a while the generation servers will, in principle, stop responding to requests from other users.
System 4. The SSRF attack here was carried out not through the img tag, but through XSS, when my favorite payload was executed on the server during rendering, and the server launched arbitrary Javascript code while generating the PDF Document. Compared to previous cases, more complex attacks on other systems can be carried out here.
System 4. Rendered PDF with arbitrary JS code executed on the server side
Premise 1. Systems require the development of not only the rules of the incoming firewall, but also the outgoing one, or the development of infrastructure with separate network segments or servers, of which there is generally no access to the outside.
Premise 2. When finding even the smallest vulnerability, you must always look for the worst-case scenarios of its use and impact on the business. Business can only work with risks, the technical side, unfortunately, is of little interest to them.
The above information is provided only for educational and educational purposes, how to do their systems is not necessary.
Denis Koloshko, CISSP, Penetration Tester