SSD Advisory – dotCMS H2 Database Remote Code Execution

Vulnerabilities Summary
The following advisory describes an SQL Injection in dotCMS 3.6.0 H2 Database that allows attackers to Remote Code Execution.

Credit
An independent security researcher has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program.

Vendor response
We contacted the vendor back in December 2016 and they responded with:
H2 is not a production DB for us. It is just for testing and trying out dotCMS. We do not support it in production or on public servers

Please note that since this vulnerability will not be fixed, default installations of dotCMS that don’t switch from H2 to some other database are vulnerable. In addition, the only warning found on the web site of dotCMS related to H2 is:
Important: H2DB should NOT be used for a production in environment.

Which doesn’t explain the lack of security due to dotCMS using an H2 database.

Vulnerability Details
dotCMS offers a Tomcat server with a preconfigured dotCms installation, the Tomcat server listens by default on public port 8080 (tcp/http) for incoming requests to the web panel.

Using an unauthenticated connection it is possible to visit the the’CategoriesServlet‘ servlet. The getCreateSortChildren() function of the ‘H2CategorySQL‘ class suffers of an SQL injection vulnerability into the ‘inode‘ parameter of a GET request, when the ‘reorder‘ parameter is set to ‘TRUE‘.

H2 allows stacked queries to be performed. In addition, the underlying H2 database offers the ‘SCRIPT TO ‘ construct. Through this it is possible to store arbitrary Java code into a newly created .jsp script.

A remote attacker, could then create an arbitrary script into an accessible web path and execute arbitrary code/commands against the target server.

Vulnerable code
The vulnerable code can be found in:

The servlet can be contacted without prior authentication.

com.dotmarketing.servlets.JSONCategoriesServlet decompiled class:

At line 51, the ‘inode‘ parameter is received from a GET request;
At line 55, the ‘reorder‘ paramter is received, too;
At line 94, if ‘reorder‘ is set to TRUE, the sortChildren() function is called with the controlled ‘inode‘ parameter;

sortChildren() from the decompiled com.dotmarketing.portlets.categories.business.CategoryFactoryImpl class:

At line 657, the ‘inode‘ parameter is passed to getCreateSortChildren();
At line 658, the returned ‘sql‘ string is executed;

com.dotmarketing.portlets.categories.business.CategorySQL :

Decompiled com.dotmarketing.portlets.categories.business.H2CategorySQL class:

The ‘inode’ parameter is concatenated into a query without prior sanitization, arbitrary sql commands can be injected and the code allows multi-queries.

Proof of Concept

https://blogs.securiteam.com/index.php/feed