XML External Entity (XXE) Vulnerability - Part 3 (Local DTD Enumeration)



In the second part of XXE vulnerability, we learned about the basic XXE and saw an example of how to read sensitive files using an external entity. Still, sometimes due to secure XML parser configuration or strict network environment, the XML parser does not read the sensitive file or remote DTD we defined in an XML document. In that case, we have to use another approach that we will see in this blog. 

In the third part of XXE Vulnerability, we will learn how to enumerate Local DTDs and exploit them to exfiltrate sensitive files and data. 


Let's see an example.

I am using one vulnerable web application that takes XML as input and creates some diagrams based on the data provided in XML


Now I will define the External entity to read the /etc/passwd file, and when I click on preview, I get the error nullEnclosed Exception 

So, in this case, we can not directly read sensitive files using an external entity

<?xml version="1.0"?>
<!DOCTYPE svg [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg
    xmlns="http://www.w3.org/2000/svg" width="12cm" height="12cm">
    <test>&xxe;</test>
    <g style="fill-opacity:0.7; stroke:black; stroke-width:0.1cm;">
        <circle cx="6cm" cy="2cm" r="100" style="fill:red;"
                transform="translate(0,50)" />
        <circle cx="6cm" cy="2cm" r="100" style="fill:blue;"
                transform="translate(70,150)" />
        <circle cx="6cm" cy="2cm" r="100" style="fill:green;"
                transform="translate(-70,150)"/>
    </g>
</svg>{codeBox}

`


Now I will again click on the preview button using the same XML and intercept in request in Burp Suite. 

As we can see, XML data is URL encoded. 


After intercepting the request, I will send the request to the repeater 



As we can see, XML is URL encoded, so I will select the XML, Right Click, then click the convert section, and choose URL and URL Decode to decode the URL encoding.



After URL decoding, I will change the file path that we defined in the external entity to any non-exist file and also display the text. Our goal here is to generate an error when we try to access non exist file.

<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///appsecworld">
]>
<svg
    xmlns="http://www.w3.org/2000/svg" width="12cm" height="12cm">
    <text>&xxe;</text>
    <g style="fill-opacity:0.7; stroke:black; stroke-width:0.1cm;">
        <circle cx="6cm" cy="2cm" r="100" style="fill:red;"
                transform="translate(0,50)" />
        <circle cx="6cm" cy="2cm" r="100" style="fill:blue;"
                transform="translate(70,150)" />
        <circle cx="6cm" cy="2cm" r="100" style="fill:green;"
                transform="translate(-70,150)"/>
    </g>
</svg>{codeBox}


Now I will again perform the URL encoding by simply using Hackvector Extension.



After sending the request, we got the response that contained the error No such file or directory.


Now, We will send the request to the intruder, clear all selected payload positions, and select non-exist file as the payload position



In the Intruder payload section, I will paste the list of the common existing dtd file paths and start the attack.

Local DTD files list: https://github.com/GoSecure/dtd-finder/blob/master/list/dtd_files.txt




Once the attack is complete, click on Filter at the Top. In filter by search, enter No such file or directory and select Negative search.
This filter gives a response that doesn't contain No such file or directory (an error we get from the request that we sent via a repeater)



There is only one dtd that is present locally (/usr/share/xml/fontconfig/fonts.dtd)



I will send the request to the repeater. 



Now we will overwrite one of its entity to exfiltrate the data, from the below link, we can check the payloads for local DTDs

Payloads for local DTD: https://github.com/GoSecure/dtd-finder/blob/master/list/xxe_payloads.md

I will use the payload for fonts.dtd because it is present in Local.



Copy the payload and paste it into the request that we just sent in the repeater, change the message to svg and enter the file that we want to read, and send the request



As we can see, data of /etc/passwd file is present in the response. 


Overall process

  • Generate error for No file found
  • Enumerate local dtd and filter the file that is present
  • Use payload to overwrite the entity to exfiltrate the data




Sahil Gupta

Application Security | DevSecOps | Secure SDLC | Penetration Tester (Web and API) | CEHv10 | IBM Certified Cybersecurity Analyst Professional

Previous Post Next Post

Contact Form