A different way to attack certain reverse proxies

3 years ago 148
BOOK THIS SPACE FOR AD
ARTICLE AD

discodamone

In this post I will discuss a web security edge case which may change the way you approach proxy mechanisms, whether for defense or offense. All of this information has been published for the purpose of education and with the hope of a safer internet.

Let’s say a website has the path /images-prod-abc/* which, when requested, proxies the request to hxxps://s3.amazonaws.com/images-prod-abc/*. This is a somewhat common situation, although less common now that the preferred format is hxxps://bucketname.s3.amazonaws.com/*.

The proxy mechanism does something similar to the following:

checks if the path begins with /images-prod-abc/takes the path and appends it to hxxps://s3.amazonaws.com/makes a request to that URLreturns the response to the user that originally requested /images-prod-abc/*

The problematic edge case involves an inconsistency between the check for if the path begins with /images-prod-abc/ and the appending of the path to the s3 bucket URL.

Specifically, the check for if the path began with /static/ was performed after shortening the URL. Likely, this happened due to the use of a library that automatically shortened URLs. For example, this can happen unintentionally in javascript with the use of the URL constructor. Then, the unshortened path was appended to hxxps://s3.amazonaws.com/.

As an attacker, when thinking about a proxy mechanism that forwards the request to s3.amazonaws.com/images-prod-abc/, one goal is to be able to escape the images-prod-abc bucket to achieve XSS. By taking advantage of the inconsistency between the check performed on the path and the appending of the path to the s3 bucket URL, XSS is possible. The proof-of-concept is hxxps://example.com/attackerbucket/%2e%2e%2fimages-prod-abc/poc.html. Here is how it works:

The web server receives a request for /attackerbucket/../images-prod-abc/poc.html. The request has been URL-decoded before parsing (which is also quite common). The reason the “../” had to be URL-encoded before sending the request is that browsers will automatically shorten URLs, and if hxxps://example.com/attackerbucket/../images-prod-abc/poc.html was visited by a user, the browser would shorten it to hxxps://example.com/images-prod-abc/poc.html before sending the request.The vulnerable code checks if the shortened path begins with /images-prod-abc/. This check passes because the shortened path is /images-prod-abc/poc.html.The vulnerable code appends the unshortened path to hxxps://s3.amazonaws.com/ to get hxxps://s3.amazonaws.com/attackerbucket/../images-prod-abc/poc.htmlYou might wonder how AWS will treat the URL. To AWS, the requested object is named “../images-prod-abc/poc.html” and resides in the bucket “attackerbucket”

Now we have an html object being requested from the bucket named “attackerbucket”, but how can we serve an object with this name? Trying to upload using the s3 CLI does not work because the s3 CLI uses the URL hxxps://attackerbucket.s3.amazonaws.com/../images-prod-abc/poc.html, and gives a 400 error because many web servers validate the path to prevent traversing past the root. To work around this, I ended up using the following option in the s3 CLI:

--endpoint-url s3.amazonaws.com

This changes the URL requested by the CLI to be hxxps://s3.amazonaws.com/attackerbucket/../images-prod-abc/poc.html, and the upload works.

Now, visiting the original proof-of-concept URL achieves XSS on the correct domain name.

Read Entire Article