The article contains analysis on how remote code execution was achieved from Path traversal vulnerability on Openfire — CVE-2023–32315.
All it needed was lousy user management functionality ;)
Discalimer:
As a responsible netizen and believer of NOT helping script kiddies with ammunition. The proof of concept code and plugin that can be used for RCE is purposefully not shared. If you are interested in reading more about Open fire plugin here is the sample code — https://github.com/igniterealtime/openfire-exampleplugin
Tale of Path Traversal to Remote Code execution but we shall not start with the debugging, patch analysis rather learn more about the CVE-2023–32315.
For readers who dont know what is XMPP server, XMPP is a protocol commonly used in peer-to-peer and group communication.
While many legitimate companies and applications leverage this amazing protocol. At some point Jabber communications were at its pinnacle at where only way to directly communicate with cybercriminal on underground forums was either using XMPP (Jabber) or ICQ.
While the trend has shifted to many more alleged privacy oriented and encrypted communication channels such as Keybase, Telegram, TOX and more.
Switching back to our original topic to gain more understanding on the vulnerability.
About Vulnerability
On May 26, 2023, Openfire is an XMPP server. The Openfire’s administrative console, a web-based application, was found to be vulnerable to a path traversal attack. On successful exploitation this permitted an unauthenticated user to access restricted pages in the Openfire Admin Console reserved for administrative users.
Vulnerability affects — All versions of Openfire that have been released since April 2015, starting with version 3.10.0.
Vulnerability patched — Openfire release 4.7.5 and 4.6.8.
Github advisory — (GHSA-gw42-f939-fhvm) for mitigation advice.
Now reading this advisory my inner hacker got fired up to figure out what is happening under the hood and if we can gain Remote code execution. The shared Proof of concept was limited to mere single URL.
URL — http://localhost:9090/setup/setup-s/%u002e%u002e/%u002e%u002e/log.jsp
On personal note, I love reverse engineering, doing patch analysis and writing n-day exploits especially for internet facing applications that help in gaining initial access and conduct remote code execution. The reason being such vulnerabilities are often exploited to conduct nefarious activities such as lateral movement, crypto currency mining, hosting malicious pages, malware command and control, DDoS, and lot more.
Detailed Analysis
To start with analysis, quickly grabbed Linux installation .deb file from Github and installed the older vulnerable version.
On visiting the Proof of concept URL depending upon version you will be greeted with below image, this confirms the instance is vulnerable, on patched instances it would redirect you to login.jsp.
http://localhost:9090/setup/setup-s/%u002e%u002e/%u002e%u002e/log.jsp
Post installation, you can either traverse through multiple directories and files installed by Openfire for debugging or for convenience and easy access in single place you can use these following commands on Linux-based system
# To extract contents of DEB package into subsequent directory
ar vx openfire_4.7.4_all.deb
# To generate file directory structure and store in text file
ls -laRh openfire_4.7.4/ | tee file_tree.txt
# Additionally - If you are on Kali Linux
# - Java Decompiler to access JAR and class files
sudo apt-get update
sudo apt install jd-gui
The root cause of the vulnerability was pretty clear and understandable after reading JIRA issue tracker at OF-2595 .
What triggered vulnerability?
The vulnerability was triggered due to Jetty filter (AuthCheckFilter) which is responsible for authentication and can be completely circumvented using a path traversal attack that makes use of the non-standard UTF-16 based character encoding for dot characters. The issue also mentions possibility of remote code execution by installing plugin.
Historical resemblance
Similar vulnerability was reported back in 2008 — CVE-2008–6508. (Refer — JM-1489 ) to which security measures for path traversal were added.
Additionally, Metasploit module was submitted to exploit the vulnerability by abusing Install Plugin feature that intakes input as “.jar” and “.war” file. (Refer — openfire_auth_bypass.rb )
The Metasploit module verified vulnerability using URL containing log.jsp and used plugin-admin.jsp to upload backdoor for remote code execution.
Reading all this information, I was pretty excited and naive thinking all I have to do is make some basic changes in the original exploit code and there will be pwning!
Quickly, I created a basic Python-based code to try the replicate and we were about to hit a wall — reason being implementation of CSRF Token and boundaries which failed the above mentioned exploit code which only supports JSESSIONID cookie.
Fired up curl to check response of the vulnerable URL and we were greeted with Set-Cookie: JSESSIONID but where is CSRF Token??
If you are familiar with Java web apps the .JSP endpoints are mapped into web.xml file which always comes handy, grabbed all the endpoints we had total of 129 endpoints.
To understand URL response to our bypass wrote a quick hacky script to extract URL, Status Code, Title and Cookies.
#!/bin/bash
# Get me cookies and status - getcookies.sh
# Read the text file line by line
while IFS= read -r url; do
# Retrieve the HTTP status code, HTML title, and cookies using curl and grep
http_status=$(curl -s -o /dev/null -w "%{http_code}" "$url")
title=$(curl -s "$url" | grep -o "<title>[^<]*</title>" | sed -e 's/<title>//g' -e 's/<\/title>//g')
cookies=$(curl -sI "$url" | grep -i '^Set-Cookie:' | cut -d ' ' -f 2-)
# Print the URL, HTTP status code, HTML title, and cookies
echo "URL: $url"
echo "HTTP Status: $http_status"
echo "Title: $title"
echo "Cookies: $cookies"
echo "-------------------------------------------"
done < "$1"
Output
Till this point, we have list of endpoints with their response and mainly CSRF Token.
Since I had already had python script to exploit and install plugin, implemented csrf token support and finally we were greeted with DISAPPOINTMENT. It failed no matter what you add, I guess learning from previous abuse for RCE the developer made sure to add additional security measure.
Restart
Coming back to square one proxied all the requests to burpsuite and started browsing other functionalities of Open Fire web application. During the course found two features that seemed really promising — installation via DWR (Direct Web Remoting) and User Administration.
What is Direct Web Remoting?
Direct Web Remoting, or DWR, is a Java open-source library that helps developers write web sites that include Ajax technology. It allows code in a web browser to use Java functions running on a web server as if those functions were within the browser.
The Openfire application uses DWR to remotely install jar plugins from remote URL.
On Successful installation
When you replicate the same thing with vulnerable URL and make sure to add DWRSESSIONID to call, everything works absolutely great just a tiny problem it generates response for browser to take care of installation (or maybe failed to understand). We get successful installation but the installation of new plugin is no where to be found.
throw 'allowScriptTagRemoting is false.';
//#DWR-INSERT
//#DWR-REPLY
//#DWR-START#
(function(){
if(!window.dwr)return;
var dwr=window.dwr._[0];
dwr.engine.remote.handleCallback("1","0",{hashCode:1913536328,successfull:true,url:"https:\/\/igniterealtime.org\/projects\/openfire\/plugins\/1.0.0\/agentinformation.jar",version:"1.0.0"});
})();
//#DWR-END#
BOOM TIME
With last resort remaining, I finally replicated the user management functionality from Burp suite and wrote a simple bash script that does following
- Extracts JSESSION ID and CSRF Token
- Uses single session
- Calls exploit URL
- Gives me backdoor Administrator level account for ultimate pwn.
- On gaining administrator role — the possibilities are limitless you have Install plugin feature for remote code execution .
Proof of concept video
During the course of analysis following tools were used:
- Burp suite
- JD-GUI
- Bash / Python custom scripts
Note — If you are planning to use python for writing the exploit, you need to figure out how to stop automated encoding using requests or else you will be stuck in loop to find out does my script displays 404 Not found. ;)
Mitre techniques generated via ChatGPT (added only relevant ones):
- T1223: External Remote Services
- T1609: Exploit Public-Facing Application
- T1210: Exploitation for Client Execution
Until then!