H1RD SECURITY

XML, DTDs y Entidades (XXE 1)

La vulnerabilidad de XML External Entity o XXE (como se la conoce) se basa en un sistema deficiente al parsear los XMLs que recibe la aplicación web, permitiendo la inyección de entidades externas de XML posibilitando ataques como conseguir ficheros del servidor de producción o ejecución de código. En el fondo, sucede igual que en el SQL injection (SQLi) nunca te fíes de lo que recibes del usuario.

Ejemplo de un ataque usando la vulnerabilidad Xml External Entity (XXE)
Ejemplo de un ataque usando la vulnerabilidad Xml External Entity (XXE)

XML

Para poder entender que es un XXE, lo primero que necesitamos entender que es es un XML y lo que se considera una entidad. XML significa Extensible Markup Language, es decir es un lenguaje de Marcado Extensible, parecido al HTML pero en vez de mostrar los datos, el XML los describe. Su función principal es ayudar a pasar información entre varias aplicaciones, ya que una aplicación sabe que y como tiene que enviar la información y la aplicación que espera, sabe que tiene que recibir.

Esto es un ejemplo de un XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8" ?>
<Edit_Mensaje>
     <Mensaje>
          <Remitente>
               <Nombre>Nombre del remitente</Nombre>
               <Mail> Correo del remitente </Mail>
          </Remitente>
          <Destinatario>
               <Nombre>Nombre del destinatario</Nombre>
               <Mail>Correo del destinatario</Mail>
          </Destinatario>
          <Texto>
               <Asunto>
                    Este es mi documento con una estructura muy sencilla 
                    no contiene atributos ni entidades...
               </Asunto>
               <Parrafo>
                    Este es mi documento con una estructura muy sencilla 
                    no contiene atributos ni entidades...
               </Parrafo>
          </Texto>
     </Mensaje>
</Edit_Mensaje>

El código de arriba es un ejemplo básico de un XML, donde se puede ver los datos estructurados, un tipo llamado edit_mensaje, que contiene un mensaje, y este a la vez esta separado en remitente, destinatario, y texto.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="UTF-8" ?>
<Show_Mensajes>
     <Mensaje>
          <Remitente>
               <Nombre>Nombre del remitente</Nombre>
               <Mail> Correo del remitente </Mail>
          </Remitente>
          <Destinatario>
               <Nombre>Nombre del destinatario</Nombre>
               <Mail>Correo del destinatario</Mail>
          </Destinatario>
          <Texto>
               <Asunto>
                    Este es mi documento con una estructura muy sencilla 
                    no contiene atributos ni entidades...
               </Asunto>
               <Parrafo>
                    Este es mi documento con una estructura muy sencilla 
                    no contiene atributos ni entidades...
               </Parrafo>
          </Texto>
     </Mensaje>
     <Mensaje>
          <Remitente>
               <Nombre>Nombre del remitente</Nombre>
               <Mail> Correo del remitente </Mail>
          </Remitente>
          <Destinatario>
               <Nombre>Nombre del destinatario</Nombre>
               <Mail>Correo del destinatario</Mail>
          </Destinatario>
          <Texto>
               <Asunto>
                    Este es mi documento con una estructura muy sencilla 
                    no contiene atributos ni entidades...
               </Asunto>
               <Parrafo>
                    Este es mi documento con una estructura muy sencilla 
                    no contiene atributos ni entidades...
               </Parrafo>
          </Texto>
     </Mensaje>

</Show_Mensajes>

En este caso, es parecido al anterior pero es un xml que acepta listas.

DTD

El DTD significa la Definición Tipo Documento, es el fichero que se ocupa de decirle al parser del XML (motor del XML) como esta formado el XML.

Por ejemplo, este seria el xml anterior con un DTD.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE Edit_Mensaje SYSTEM "Edit_Mensaje.dtd">
<Edit_Mensaje>
     <Mensaje>
          <Remitente>
               <Nombre>Nombre del remitente</Nombre>
               <Mail> Correo del remitente </Mail>
          </Remitente>
          <Destinatario>
               <Nombre>Nombre del destinatario</Nombre>
               <Mail>Correo del destinatario</Mail>
          </Destinatario>
          <Texto>
               <Asunto>
                    Este es mi documento con una estructura muy sencilla 
                    no contiene atributos ni entidades...
               </Asunto>
               <Parrafo>
                    Este es mi documento con una estructura muy sencilla 
                    no contiene atributos ni entidades...
               </Parrafo>
          </Texto>
     </Mensaje>
</Edit_Mensaje>

Y el DTD seria este:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!-- Este es el DTD de Edit_Mensaje -->

<!ELEMENT Mensaje (Remitente, Destinatario, Texto)*>
<!ELEMENT Remitente (Nombre, Mail)>
<!ELEMENT Nombre (#PCDATA)>
<!ELEMENT Mail (#PCDATA)>
<!ELEMENT Destinatario (Nombre, Mail)>
<!ELEMENT Nombre (#PCDATA)>
<!ELEMENT Mail (#PCDATA)>
<!ELEMENT Texto (Asunto, Parrafo)>
<!ELEMENT Asunto (#PCDATA)>
<!ELEMENT Parrafo (#PCDATA)>

En el caso del ejemplo, el DTD viene referenciado a un fichero externo, no tiene porque podría venir integrado en el propio XML.

Las entidades del DTD

Las entidades del DTD, son un mecanismo simple de remplazo, por ejemplo si usaremos en el xml algunos caracteres, este podria hacer que fuese no valido, hay dos tipos de entidades, los parámetros de entidades, y las entidades generales.

Entidades generales

Estas entidades se declaran en el DTD pero la sustitución la realiza el parser, según lo marcado por el DTD. En el ejemplo siguiente se puede ver un ejemplo de una entidad general.

1
    <!ENTITY gt       "&#62;"> 

La estructura de una entidad general es la siguiente:

1
    <!ENTITY nombre_de_la_entidad "literal">

En este caso, nombre_de_la_entidad seria el nombre de la variable por la que sustituiremos, y literal el valor por el cual sustituiremos.

Tambien podemos extraer el valor del literal de un fichero que nosotros digamos, con SYSTEM

1
    <!ENTITY nombre_de_la_entidad SYSTEM "ruta_de_sistema">

O podemos extraer ese valor de una URL externa, con PUBLIC, un ejemplo de ello seria:

1
    <!ENTITY nombre_de_la_entidad PUBLIC  "identificador_publico" "url_de_un_documento">

Los parámetros de entidad

Los parámetros de entidad es una manera de crear variables internas del DTD que ayudan a que no se repita codigo.

En el ejemplo, %Inline seria un parámetro de entidad.

1
2
3
4
5
6
7
8
9
10
11
 <!ENTITY % Inline "(#PCDATA | a | br | span | bdo | map | object | 
                        img | tt | i | b | big | small | em | strong | dfn | 
                        code | q | samp | kbd | var | cite | abbr | acronym | 
                        sub | sup | input | select | textarea | label | 
                        button | ins | del | script)*">        
            
    <!ELEMENT p %Inline;>
    
    <!ELEMENT h1 %Inline;>
    
    <!ELEMENT h2 %Inline;>

La vulnerabilidad del XXE

Si has prestado atención, seguramente te hayas preguntado, que pasaría si en la entidad System, le paso la ruta de otro fichero, o en Public le paso otra url, pues allí empieza el XXE.

En el proximo articulo de este post, entrare en profundidad con la vulnerabilidad de XML External Entities.

Hasta la proxima