Challenge #3: SSRF bypass webhook

How should I approach this?

+

This is a capture the flag (CTF) webapp designed to teach software developers the fundamentals of application security (AppSec). Software developers learn best when reading and writing code. Most CTFs are catered towards pentesters who predominantly use a variety of tools for CTFs and in their day jobs. While certainly a more efficient approach, this does not, however, translate well for a software developer trying to learn AppSec.

How is a software developer supposed to learn how to write secure code if all they learn how to do from a CTF is click a few buttons and enter some input into a text field? That is why the purpose of this CTF is to reframe the concept of AppSec in terms of code.

There are 3 hints for every challenge. One hint will show you the exact code of the server-side vulnerability that you are trying to exploit. It is one thing to read a description of a vulnerability, and a whole another thing to actually see a working example of the code. Another hint will show you the exact code of the exploit and how to run it. Technically this is less of a hint and more just the answer to how to solve the challenge, but let's not get too hung up on semantics.

The next logical step is to provide the diff between what the vulnerable code looks like and what the secure code looks like. This is accessible to anyone who solves the challenge, which considering the exploit is provided if you cannot figure out how to write it on your own, is literally anyone.

And finally, as if this wall of text wasn't long enough, there is even more to it. If you want to run the webapp locally just follow the instructions on this README. Make any modifications you want. Add code, remove code, break things, figure out how to fix them. This is what I believe to be the most effective way for a developer to learn a concept: through code.

A common mistake developers make is to always assume that internal APIs, that is something that is not accessible from the Internet at large, can never be accessed from the outside.

What is SSRF?

SSRF (server-side request forgery) is when an attacker can trick the server into performing HTTP requests on the attacker's behalf. Examples of HTTP requests that can be potentially dangerous for a web application are requests to a private IP address (i.e., one that is not accessible from the public Internet such as 127.0.0.1), requests to an internal admin API, or requests that use the file:// schema to access internal files on the network.

How might an attacker pull this off? They simply need a server endpoint that accepts a URL or an IP address as input. A webhook is a common feature these days that offers such a vector to attackers. The intended functionality of a webhook is to provide a way for client applications to receive notifications about events in real-time. But instead of supplying a valid public IP address, what if an attacker supplies a private IP address?

For example, suppose your web application runs on one of the major cloud providers such as AWS or Azure and has a webhook endpoint. If an attacker provides the IP address 169.254.169.254 as input to the endpoint, then they might be able to access sensitive data from the metadata service running on the cloud instance. Note that an attacker won't always receive a response after inputting in a private IP address or URL. However, this does not mean that the attack was not successful. It could be an instance of blind SSRF which is harder to exploit, but just as impactful if successful.

In plain English: there are internal URLs and IP addresses that only a web server can access because it is inside "the network." Think of this concept of "the network" as something similar to your home wifi. A random person on the Internet cannot access the IP address of your computer on your home wifi under normal conditions. A web server is simultaneously on its internal network and public facing on the Internet. This is what allows it to do all the stuff is supposed to do, while still being accessible to anyone with an Internet connection. An attacker can only talk to the web server, they cannot access the internal URLs and IP addresses that the web server is able to. So the attacker "tricks" the web server into fetching those privileged items on their behalf without ever directly accessing them.

Heard about it in the news?

SSRF is arguably the most popular vulnerability being exploited today. It is not easy to defend against, and it can cause a lot of damage. Here are three recent examples of it being exploited:

Challenge

Hint #1: Generic Hint

+

If you are unsure on how to proceed, then the following may help:

You can enter the input necessary to exploit this challenge manually through your browser, or you can use an automated tool such as Burp Suite or OWASP ZAP. However, since this CTF is focused specifically on the code side of application security, neither of those solutions will be presented here.

The exploit code and instructions on how to run it is presented in the third hint. However, you are encouraged to attempt to write the exploit code yourself before looking at the answer. In order to do this, you need to understand what fields are being set in the HTTP request being sent to the server from the browser. This is so that you can craft your own HTTP request from the script you write. You can use your browser's developer tools to figure out this information or you can use a tool that can decrypt encrypted traffic on your computer. Burp Suite and OWASP ZAP both offer this feature in addition to their automated pentesting. I personally used mitmproxy when writing the exploit scripts for this site because it has a lot fewer features than those other tools, and therefore is a lot simpler to use.

Hint #2: What does the server-side vulnerability look like?

+

File truncated for brevity. Click here to view full file.

Hint #3: Couldn't figure out the answer? Here is the exploit

+

View the exploit README to run the exploits locally.

File truncated for brevity. Click here to view full file.

This web server has a functionality built for webhooks. However, you can abuse this functionality to access an internal admin API. The only thing you know is that the internal API can be accessed through http://internal_api