Sunday, December 26, 2021

Exploiting Velocity Template in dotCMS v21.11 - Full Privilege Escalation

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.

Original report

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

The RCE payload for Velocity only works in older versions, so in this case is not possible.

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

In the UserModel class, line 211, theres a method call setUserId. The interesting part about the user id, is that our privilege level is tied to it, so if we alter our id to a high user id we can get the same level of privilege that this high user have.


If we look at the database for the user ids we see some default one's


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

Template

By just opening the template page to view the result, and reloading the same page we now have full privilege


Video PoC








No comments:

Post a Comment

Using a feature to takeover your account - Hacking an SSO implementation

This week, I found a super cool bug that allowed me to steal any account in the vulnerable application. The target was a private bug bounty ...