First of all, I'm not a native english speaker, sorry for any mistake I made here.
Hello everyone, this blog post is about a full privilege escalation I got in dotCMS by abusing the velocity engine.
This flaw as reported to the dotCMS team over huntr and is now fixed.
dotCMS template editing
dotCMS allow us with a little permission level to edit templates to our pages, and as I said, it uses the Velocity engine.
Attacker mindset
So what we can do with Velocity?
- We can inspect the toolbox.xml file and search for classes that we have access, normally only the velocity classes are detailed, but in some cases, custom classes are also available and can lead to more advanced attacks. (Velocity tools)
- We can also grep for context.put, this method allow the velocity engine to access a specified object, some objects can lead to better opportunities
Context example by velocity docs
import java.io.StringWriter; import org.apache.velocity.VelocityContext; import org.apache.velocity.Template; import org.apache.velocity.app.Velocity; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.MethodInvocationException; Velocity.init(); VelocityContext context = new VelocityContext(); context.put( "name", new String("Velocity") ); Template template = null; try { template = Velocity.getTemplate("mytemplate.vm"); } catch( ResourceNotFoundException rnfe ) { // couldn't find the template } catch( ParseErrorException pee ) { // syntax error: problem parsing the template } catch( MethodInvocationException mie ) { // something invoked in the template // threw an exception } catch( Exception e ) {} StringWriter sw = new StringWriter(); template.merge( context, sw );
Searching for context.put
By just using grep we can find a loot of code that call context.put
One interesting usage is in the file ./src/main/java/com/dotcms/rendering/velocity/util/VelocityUtil.java, here in line 390 we see that context.put is used in an object called 'user'. So by definition we can access the user object, lets try something.
Calling user methods
Before reading the user class to search for methods, lets try a simple test. To use the user object in the template editing, we need to call it by the name "user" (defined at first argument in the context.put call), we can try just to use a simple default method like toString and see if it works
Result:
As we can see, the method seems to work. Now lets see what interesting methods we have in the User class (src\main\java\com\liferay\portal\model\User.java)
The User class
One thing interesting to notice is that we are not tied only to this class, but we can also access a superclass
In this case we can also call methods defined in the UserModel class (src\main\java\com\liferay\portal\model\UserModel.java)
So what we can do with full control over methods call in the user Object? We can go to a full privilege escalation.
Abusing the set's methods
If you are a little familiar with OOP you may now about getters and setters, these are methods used to retrieve/change variables in a object. We are especially interested in the 'change' part
Side note: The changes we made over direct methods call are not saved in the database, but are tied to our session, so in this case we can 'change' some variables just as we stay logged
setUserId method
For example 'system', this one is a default user that have a lot of privileges. So if we call setUserId("system"), we may have a privilege escalation here
Exploitation
By just opening the template page to view the result, and reloading the same page we now have full privilege







