XXE (Extensible Markup Language External Entity) is a common type of injection which occurs in applications that fail to sanitize XML input; This is particularly common with web services. The XML input in a webservice can be considered as a description of data so that two systems can have a common language to communicate with despite being different in nature. There are a number of XXE forms available; Some key concepts to understand :
- SYSTEM – This is a literal that tells XML that it is communicating with an external (remote) entity
- DTD definitions (External) i.e. we can add custom descriptions to the webservice.
- Parametized entities – Entities that can assign values to other entities ; they are denoted using a % sign.
- General Entities – Regular variables referenced with a & sign.
The Setup
The nature of the XXE in this case is an out of band channel; The good thing about it is that our payloads will be picked by the trusted application hence limiting the ability of the firewall to flag the attack; The bad part is there’s quite a bit of manual labour with the payloads 😀
Basically this setup offered the following challenges
- The XXE was out of band meaning we had to channel our output elsewhere not directly on the page 🙂
- There was an IPS blocking direct attacks so we had to deviate “abit” from the norm.
If this was put in a relationship context it would end up being something similar to the scenario below:
Attack Setup and components
- xxe_client.py – used to initiate connections to the target and send instructions to invoke dtd files from our attack server
- server.py – simple python script to run the python simpleHTTPServer Module but add some logging functionality to log results to file for us to process later therefore not so necessary if you don’t wanna do that.
- DTD files – actual attack payloads that will be downloaded by the trusted application and passed by its XML parser.
Attack workflow
As mentioned the attack takes a slight deviation from the norm ; To put it into context we will go through the chain of downloading the passwd file. The client side would be a connector to the server and would look as below:
- When we run this it will send a request to the server ; The XML parser on the application will first process the %remote parameter which we assigned a value for our attack server to download and process the DTD file called getFileEncoded.dtd.
- The last 2 parameters are to be passed back by our malicious DTD and will be explained below to see what they will be hydrated with.
- The result would be as below:
- The error above is misleading and one would think the attack has failed however on your listener script where the DTD is hosted we have the content as below:
- Once the DTD is processed by the application , the xxepayload parameter will be populated with a local variable to run on the server i.e. base64 version of the passwd file
- The internal parameter entity will create a general entity called xxe which will contain a URL to our attack server and appended the contents of the file we just read.
- The parser will read all this and process it and run it on our server where we log the request as is seen below:
The result can be base64 decoded to get the result in plain text as below:
The scripting of all these actions for ease as explained above can be found on github.