A typical web application can be stated mainly of two types a Static and a Dynamic Web application. A static web app does not take any input from the user and the response for every page will always be same. But on the other hand, a dynamic web app renders the web application depending upon the actions or data provided by the user.

A dynamic web app can allow the user any number of actions such as clicking on a button, moving mouse to a particular point, etc. Also, it can allow a user to provide the data in some specific formats such as JSON, XML, plain text etc.

Let’s take a scenario where a user submits a form and the form inherently submits a crafted XML document to the server for processing and get the response back from the server. Due to XML document being passed onto the server, the XML document can be modified on the fly and if the server has not made any proper sanitization checks then the same can cause damage to the server i.e. information theft, command execution etc.

An XML External Entity (XXE) vulnerability arises when the data passed between the browser and the server is XML, and the server parses the XML data without sanitization.

How it works?

A sample application vulnerable to XXE vulnerability is demonstrated in this section.

For the sample application to work, your system should have docker. The guide to install the same can be found on Docker Installation

Run vulnerable XXE application using the command below.

docker run --rm -it -p5000:5000 --name xxe projectasuras/xxe 

The vulnerable application can run on localhost also, but for demonstration of this tutorial, we will be using the IP assigned to container.

Initially, find the container_id of the running container using the following command:

docker ps

Now, let’s try to find the IP assigned to this running container using the following command:

docker inspect <container id> | grep IP

Alternatively, instead of using container_id, we can also use the container name which is xxe (as mentioned in the docker run command).

Now, let”s open the browser and visit the URL http://<container ip>:5000 to open the vulnerable application.

Note

This sample application consists of a login page (for the sake of demonstration, password field is ignored).

The application show cases the learning information about our mighty asuras. Some of the asuras such as ravana, hiranyakashipu, bali, nishumbha, andhaka and so on.

Now, let’s learn about the mighty bali asura. The username is bali and password can be anything (as not validated).

Important

This is a dummy application, and therefore the password field is neglected, but in production applications always add proper login checks.

The following are the learnable details of mighty asura bali:

Normal login form, what wrong can be in it.

Let’s open our application through BurpSuite proxy and see the request being sent to the server.

If you are unfamiliar with using a proxy middleware like BurpSuite then you can checkout our wiki for Web Application Interceptor.

Once you have opened the BurpSuite and correctly configured with the browser proxy extension, login again such that BurpSuite can capture those packets.

Navigate to Proxy > HTTP history (on BurpSuite) and check the HTTP requests:

If you look closely, the HTTP history tab contains a request with /login endpoint which was triggered when the Login button was hit at the homepage of the application.

The HTTP request is a POST request containing a parameter named xmlInput with the following value:

%3Cinput%3E%3Cusername%3Ebali%3C%2Fusername%3E%3Cpassword%3Ebali%3C%2Fpassword%3E%3C%2Finput%3E

The above input looks like a URL encoded input. Let’s try to decode the URL using urldecoder.org.

The value is not a URL but an XML input formatted as URL, consisting of username and password fields.

Let’s try to Repeat this /login request in our BurpSuite instance, Right click on the /login request and Select Send to Repeater option.

Once triggered, open the Repeater tab in BurpSuite.

Now, we will send the same request without any modification again, and let’s see whether we have received same output or not.

Voila!!! We are able to see the bali asura details. Let’s try to modify bali in the <username> tag to ravana and hit Send.

As we can see the details of ravana asura. Now, let’s try to execute the actual payload for fetching the contents of /etc/passwd file.

The payload used in our example application is as follows:

<!DOCTYPE root [
    <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<input>
    <username>
        &xxe;
    </username>
    <password>
        asura
    </password>
</input>

But, wait a sec! The above payload is a XML file, but we need URL encoded XML file. Let’s try to URL encode this message from urlencoder.org.

Copy the URL encoded payload to BurpSuite Repeater section and hit Send.

In the above response, you can successfully read the contents of /etc/passwd file.

In the above example, we have demonstrated the XXE vulnerability. There is a Github repository by PayloadsAllTheThings consisting of different XXE payloads, which you can try on this vulnerable application.

In the next section of this series, we will be understand the payload and mitigation measures.