Challenge #4: SSRF local file inclusion

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.

Local files can be subject to the same mistaken assumptions that internal APIs have: developers think they can never be accessed from the Internet.

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, 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 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:


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.

Catcoin is the hot new crypto currency that everyone is talking about. The following form is for a financial web app that will allow you to pick the API that is used to query the current price of catcoin. You can choose either http://internal_api:8484/get_cat_coin_price_v1/ or http://internal_api:8484/get_cat_coin_price_v2/ by entering it into the input textfield. Unbeknownst to the developers, you can actually enter any URL or IP address that you want. Solve this challenge by stealing the /etc/shadow or /etc/passwd files.